在非纯色背景上,叠加背景透明的BUTTON和STATIC_TEXT控件

简介:

例子:我们要把这个十字准星叠到一个BUTTON控件上,BUTTON位于一个非纯色的背景的窗口上。显示时,紫红色(RGB 0xFF00FF)区域要被挖去,而显示底下的背景。资源图片如下图

实现:
1、按照以前的经验,如果这个Button由我们自己CreateWindowEx建立起来的话,只要在RegisterClass的WNDCLASS结构体里,把HBRUSH设置成GetStockObject(NULL_BRUSH),并且在WM_PAINT消息里首先做SetBkMode(TRANSPARENT)就可以了。但由于现在走了GWES和eVC里RESOURCE文件结合的方法提高开发速度,所以我们不能回到自己CreateWindow的原始时代了。应该考虑在MS制定的GWES游戏规则里跳舞。

2、首先实现图片的去色。实际上很容易,从网上的资料看,以前还得做个单色“掩色”hdc, 然后怎么怎么处理。而WINCE已经把这个功能做好了,提供函数TransparentBlt。
现在我画上去的按钮成这样了:

问题很明显,图像本身是达到去色的目的了,但是按钮的背景仍然是灰色刷子刷出来的,必须把按钮背景变成透明的。

2、首先我想到在WM_DRAWITEM消息里做SekBkMode,没有效果。然后非常想把已注册的WNDCLASS改掉,于是找到函数SetClassLong和GetClassLong,并且INDEX参数给出了GCL_HBRBACKGROUND类型。一切看起来都很美好。于是我写了这样的代码
HBRUSH hbr = GetStockObject(NULL_BRUSH);
int nReturn = SetWindowLong(hWnd, GCL_HBRBACKGROUND, (int)hbr);
结果编译不让过,说没有GCL_HBRBACKGROUND这个东东。我查了下STANDARDSDK_500给出的头文件,里面的确没有GCL_HBRBACKGROUND的定义。于是干脆翻出VS2005在XP下的SDK,硬是找到了GCL_HBRBACKGROUND = (-10). 好,我就强制
SetWindowLong(hWnd, -10, (int)hbr)
结果编译过去了,运行起来nReturn = 0. 伤心啊。再试一把,
HBRUSH hbr = GetWindowLong(hwnd, -10)
运行结果hbr = NULL. 伤心啊,拔凉拔凉的啊。仔细看WINCE产品文档,虽然对用表格列出了一大堆nIndex,但是下面小字Remarks写了“The only values supported for the nIndex parameter are GCL_HICON and GCL_STYLE”,最多再加个GCL_HCURSOR,其他的参数类型WINCE都不支持。我日,浪费感情。

3、在父窗口的PROC里抓住WM_CTLCOLORBTN消息,在里面搞点鬼
case WM_CTLCOLORBTN:
{
 HBRUSH hbr = (HBRUSH)GetStockObject(NULL_BRUSH);
 SetBkMode( HDC(wParam), TRANSPARENT );
 return (int)hbr;
}
郁闷了,父窗口不画这个区域,BUTTON自己又不擦背景,桌面的字都透出来了。像下图这样:

然后我画了个把小时搞InvalidateRect, ValidateRect, 对着那点小地方折腾半天,父窗口还是不愿意画上子窗口的区域,真像开工作会议时的扯皮,不是本部门负责的区域,坚决不做,打死也不做。这就是为什么文章标题强调“非纯色背景”了。如果是纯色背景,我在这里设置好HBRUSH的颜色就搞定了,麻烦就麻烦在为了透明而用NULL_BRUSH才出了问题。

4、吃过饭,灵光了,想到个很容易的方法。昨天经理刚批评我不踏实做事,喜欢找捷径。嘿嘿这次又被我抄个小捷径了:我先前在代码里已经保留了父窗口背景的hdcOffScreen,现在把子窗口区域的部分拿过来,先画到子窗口上,然后再把子窗口的十字准星叠加上去。实际上,前面一直想的是如何去除背景色,这篇文章的标题也这样写,而实际上背景色根本没被去掉,只是上面又覆盖了一层父窗口的背景图而已,逆向思维。

case WM_DRAWITEM:
{
 LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)lParam;
 if( lpDIS->CtlID = IDC_CROSS )
 {
  BitBlt( lpDIS->hDC,  //这个是BUTTON窗口的hdc device,而不是background的,所以我们从{0,0}画起
            0,
     0,
     button.nWidth, //CROSS图片的宽和高
     button.nHeight,
     BackGround.hdcOffScreen,  //父窗口上背景图的OffScreen hdc, 也就是画在内存里的那份
     button.x,  //CROSS按钮在背景图上的左上角坐标。我们把背景图上那个区域的内容先画到BUTTON的hdcDevice上面,作为BUTTON窗口的背景。
     button.y,
     SRCCOPY );

  TransparentBlt( lpDIS->hDC,
     0,
     0,
     button.nWidth,
     button.nHeight,
     button.hdcOffScreen, //这次就把CROSS图片在画在内存里的那份hdcOffScreen拿出来,画到hdcDevice上
     0,
     0,
     button.nWidth,
     button.nHeight,
     0x00FF00FF);

  break;
 }
}


最终效果如图


5、用这个方法同样可以实现静态文本控件的“透明”显示, 不过这就不是在WM_DRAWITEM消息里做响应了,而是在WM_CTLCOLORSTATIC消息里,参考代码如下:

case WM_CTLCOLORSTATIC:
{
 HDC hdc = (HDC)wParam;
 HWND hWnd = (HWND)lParam;

 SetTextColor(hdc, FontColor); //设置文本颜色
 BitBlt(hdc, ...) //把父窗口的背景图抓出对应坐标和长宽的一块来当我们的背景。
 SetBkMode(hdc, TRANSPARENT); //设置文本区域背景透明,这是必要的。除了按钮的背景外,文本自己还有个底
 return (int)GetStockObject(NULL_BRUSH); //返回一个透明刷子,不然后面会把我们BitBlt上去的背景图给刷没了。
}


本文转自Walzer博客园博客,原文链接:http://www.cnblogs.com/walzer/archive/2007/04/14/713239.html,如需转载请自行联系原作者


相关实践学习
利用云备份Cloud Backup实现ECS文件备份
当您已使用ECS,并在云盘中保存文件后,可能会遭遇病毒勒索,文件误删除的情况。本场景主要介绍如何使用HBR为ECS文件备份,保证数据安全并可及时恢复。
相关文章
STM32F103标准外设库——SysTick系统定时器(八)
STM32F103标准外设库——SysTick系统定时器(八)
1246 0
STM32F103标准外设库——SysTick系统定时器(八)
|
Web App开发 应用服务中间件 nginx
|
Java 测试技术 API
SpringBoot单元测试快速写法问题之复杂的业务逻辑设计有效的单元测试如何解决
SpringBoot单元测试快速写法问题之复杂的业务逻辑设计有效的单元测试如何解决
|
10月前
|
自然语言处理 搜索推荐 BI
有哪些好用的待办事项提醒软件?主流7款大对比
随着生活和工作节奏的加快,待办事项提醒软件成为了我们的“救命神器”。本文评测了7款主流的待办事项软件:板栗看板、Todoist、Microsoft To Do、TickTick、Google Keep、Any.do 和滴答清单,从功能、适用场景和优缺点等方面进行对比,帮助你找到最适合自己的那一款。无论是团队协作、个人时间管理还是生活与工作的平衡,总有一款能满足你的需求。
3939 1
|
12月前
|
API 开发工具 Android开发
从安装到打包,手把手教你如何在Uno Platform上部署跨平台应用——一篇详尽的开发者指南
【9月更文挑战第7天】Uno Platform 是一个跨平台应用开发框架,利用UWP API构建Web、iOS、Android等多平台应用。本文详述了安装Uno Platform SDK、配置项目支持跨平台、添加主方法以及使用命令行工具进行应用打包的过程,助您快速上手 Uno Platform 并部署应用。通过简单的代码示例,让开发者轻松掌握从安装到发布的核心步骤。
857 2
|
JSON NoSQL 数据可视化
|
Linux PHP Apache
centos7安装php8
centos7安装php8
675 1
|
数据采集 人工智能 JavaScript
selenium滑块解锁实现的研究
本文介绍了如何应对滑块解锁验证,这是一种常见的网站防爬策略。首先,需获取滑块及背景元素,计算偏移量,然后使用`selenium`的`actionChains`模拟滑动。通过缓动函数如`ease_out_quart`创建滑动轨迹,以增加真实性。然而,某些网站的滑块验证极其复杂,可能需要人工智能解决。此外,还讨论了使用JavaScript进行浏览器页面滚动,包括对整个页面和特定元素内滚动条的滚动操作。
|
开发者 iOS开发 C#
Uno Platform 入门超详细指南:从零开始教你打造兼容 Web、Windows、iOS 和 Android 的跨平台应用,轻松掌握 XAML 与 C# 开发技巧,快速上手示例代码助你迈出第一步
【8月更文挑战第31天】Uno Platform 是一个基于 Microsoft .NET 的开源框架,支持使用 C# 和 XAML 构建跨平台应用,适用于 Web(WebAssembly)、Windows、Linux、macOS、iOS 和 Android。它允许开发者共享几乎全部的业务逻辑和 UI 代码,同时保持原生性能。选择 Uno Platform 可以统一开发体验,减少代码重复,降低开发成本。安装时需先配置好 Visual Studio 或 Visual Studio for Mac,并通过 NuGet 或官网下载工具包。
1341 0
|
监控 Oracle 关系型数据库
PolarDB 在多云环境下的部署与管理
【8月更文第27天】随着云计算的普及和发展,越来越多的企业开始采用多云策略来分散风险、优化成本并提高业务灵活性。阿里云的 PolarDB 是一种兼容 MySQL、PostgreSQL 和 Oracle 的关系型数据库服务,它提供了高性能、高可用性和自动化的管理功能。本文将探讨如何在多云环境下部署和管理 PolarDB 实例,并提供一些实用的代码示例。
283 0