vs2010 button 控件背景透明化处理

本文介绍在VS2010环境下实现控件透明化及图片自适应的方法,针对不同分辨率下的显示问题,通过定制MFC消息及OwnerDraw属性调整,确保button控件在各种分辨率下保持美观。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

外部用户有一个需求,在Windows系统下利用一个小工具完成机器的识别和鉴定,也就是常见的获取并生成设备唯一性序列码,类似实现windows一机一码激活的功能,为日后系统授权做技术储备。

收到任务后分析,从交互体验方面考虑以cmd窗口给用户提示设备信息过于敷衍不适合,要以图形化的界面形式给用户呈现设备的序列码信息;从技术实现角度考虑,要获取硬件信息c或者c++语言对底层支撑比较友好,是不二之选(其它语言咱也不熟悉^^)。基于这两个方面的考虑,可选择的开发工具还是不少,比如:QT、VS系列等,由于仅仅实现一个小功能,QT的发布策略实在是过于臃肿,而VS仅提供一个exe文件就能完成所有功能,没有理由不选它。

没想到,十多年前用的vc6.0现在已经发展到一系列工具,2010/2013/2015版本众多,眼花缭乱,这次因为有安装包就没有过多犹豫的选择了vs2010,也没想到进化中的vs给了我当头一棒,看似简单的功能想要实现却累到肝痛~~仅以本文纪念下曾经的利器,想说懂你有点难。也希望在痛苦额定摸索过程中,把1、2个点的解决方案进行透彻的总结,达到看了就会,拿来就能用的目的。如果恰好你也有类似的需求,希望能不走弯路直接解决问题,留出时间享受生活。

机器序列码的原理比较简单,就是获取设备多种硬件信息,通过某种加密或抗扰算法结合成为一串不可逆且唯一的数据,作为区分的依据以此来映射和对应到某台机器。类似的算法网络上很多,基本通过主板、网卡、cpu信息,辅助以MD5、base64等算法就能实现,不算难点就不在这里多费口舌。

这次重点讲述在不同分辨率下,图片的自适应和button控件实现贴图功能。实质是一样的,就是在性能指标越来越高的机器面前,如何把软件颜值尽可能的调到最优,吸引和留住到用户。

问题描述:

buttoncontrol控件表面,加载一张bmp图片,自测加载以及控件按压功能无误,表现十分完美,还原度视觉效果都不错。没费多大功夫,本以为这就成了,换到测试同学手里一番操作,就成了这个样子相当尴尬。

仔细一问是分辨率调整到2560*1600,而开发机器的分辨率最高设置到1680*1650,当时就想用户哪有这么高配的设备,据理力争后谁也说服不了谁。收到用户的反馈真有一批次高配的设备需要生成序列码,而且分辨率设置为2560*1600。逃是逃不了的,继续乖乖的解决吧。带着明确的问题去寻找答案,也没当回事,结果还是太年轻痛苦的序幕拉开了。

网络上大部分的答案分为两类,锁定控件大小和bmp图片根据控件尺寸自适应。思路都看懂了但含糊不清的描述和支离破碎的代码以及复杂的MFC消息机制没有一个能解决实际问题,一个下午过去了丝毫没有进展,痛定思痛只能另寻出路。图示都是堵死的路,支离破碎的优秀代码代表~~~

重新整理思路,思索故障现场有三张图片,两个控件,在不同的分辨率下产生不一致的拉伸比率造成,减少变量的个数应该可以减少拉伸比率的差异,相对来说更好控制。带着这个思路,自然而然的将背景图与控件的bmp贴图合一处理,一张图片在同一个比率下拉伸,不会产生不一致的现象,也就能解决button控件在贴图的效果下,拉伸比例不一致产生的控件和图片尺寸不一致的故障。剩下就只有一个难点需要解决,那就是button控件透明化,隐藏在背景图按钮位置的下方,否则button的默认背景图会覆盖在地图之上,完全看不到背景图的按钮图标效果。如图示

这个解决过程也破费一番功夫,中间查阅多个帖子都是一知半解,没有一个完整可靠地处理线索,最终结合多个帖子总算是解决了控件透明化的功能。这个大坑省略几百字直接敲黑板说答案,总共三个步骤完成:

步骤一,在rc资源中添加一个MFC消息,定制化消息融入MFC消息体系中的一环。鼠标落在控件实体上,右击添加消息的控件,在弹出对话框选择消息Tab蓝,找到WM_CTLCOLOR消息,以系统默认函数名称OnCtlColor进行“确定”。

 步骤二,在OnCtlColor函数中做处理,因为这个函数作用域范围是系统全局处理入口,程序加载运行所有控件的绘制消息都会进入这个函数并处理。本需求只对指定的button控件才做处理,所以需要对控件对应的ID做限制和判断,其它控件退出不做额外处理。经过筛选后,成功将button控件透明化,漂亮的背景按钮图标清晰的显示出来。如图示

 处理代码示例

 关键处理有两处,分别是:

  1. SetBkMode(TRANSPARENT) // 设置背景为透明,使得控件和背景图颜色一样
  2. SRCCOPY,复制来源的图像,即背景图,达到将控件本身透明化处理的效果

步骤三,如果只看到步骤二其实你还是不能解决控件透明化问题,因为这时的OnCtlColor消息无法被MFC监测并转发到用户程序模块处理,猜测消息会在MFC逻辑内部被丢弃。因为你没有告诉MFC消息控制中心,这个消息需要在用户态去做额外的处理~

解决办法是需要在button控件属性中设置Owner Draw 为 TRUE,消息就会递交到OnCtlColor处理函数,你就能按照步骤二的处理去实现控件透明化功能。

Owner Draw实质就是开启控件绘制机制,在系统显示效果的基础上,提供给用户定制化控件显示效果的途径,根据需要做调整和美化,拉满效果。

回顾总结一下,vs2010是十多年前的技术工具,强大且完备,同时内部控制逻辑复杂难懂,一旦缺少某个环节的知识点,就无法想象程序执行的结果,当然也有没有静下心来去识别原理和机制,只从简单解决问题的目标去寻找快捷答案。

也不能套用现在的开发工具去理解vs的强大之处,可能是我不太懂你,还得继续舔你^^

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值