如何让窗口控件半透明(控件在Paint自己时,首先向主窗口询问,获取主窗口上控件所在区域的背景图)
在网上关于窗口视觉效果,有2个问题被问得最多:
第一个是如何让窗口边框有阴影效果?
第二个是如何让窗口控件有半透明效果?
对于第一个问题,我们的答案是用双层窗口模拟或是用Layered Window。
在XP下可以直接在注册窗口类时用CS_DROPSHADOW风格,系统就会自动让你的窗口附加上阴影效果,实际上系统也是通过双层窗口来实现的;当然我们也可以用自己的窗口来模拟阴影效果,只要让阴影窗口永远跟随我们的目标窗口就可以了。
如果用Layered Window, 我们只要一个窗口,通过让窗口支持Alpha通道,最后UpdateLayeredWindow, 即可实现阴影效果。
对于第二个问题,我们通常的答案是用双层窗体或是DirectUI。
因为Windows绘画是以DC为单位,而主窗口和内部控件是居于不同的DC, 所以他们不能半透明融合在一起。
另外只有Pop up的窗口才能支持Layered Window,所以只有Pop up的窗口才能实现半透明效果,所以我们通常用双层窗口来模拟控件的半透明,也就是说窗口上面的控件其实是通过一个Pop up窗口模拟出来的。所以用这种方式实现控件的半透明效果,性能比较差,也只能实现一些简单的界面。
还有一种控件半透明的方式是用DirectUI,所有的窗口控件都通过在主窗口上绘画模拟出来,实现半透明效果自然也很容易了。
所以既要实现窗口的阴影效果,又要让内部控件半透明,最终极的方式还是用WS_EX_LAYERED风格的DirectUI窗口。
其实另外还有一种既不用DirectUI,也不用双层窗口,也能实现控件半透明的方法。
该方法的关键是控件在Paint自己时,首先向主窗口询问,获取主窗口上控件所在区域的背景图,然后控件先将此背景画到自己的DC上,然后在再画自己,这样可以让控件看起来像是直接画在主窗口上一样。
当然该方法也只能针对一些简单的UI,如果子窗口层次很多,或是控件个数很多,都会有性能影响。
核心代码如下:
{
CWindow wnd = hWnd;
CWindow wndParent = hwndParent;
CClientDC dcParent = wndParent;
CRect rcParent;
wndParent.GetWindowRect(&rcParent);
CDC dcCompat1;
dcCompat1.CreateCompatibleDC(dcParent);
CBitmap bmpCompat1;
bmpCompat1.CreateCompatibleBitmap(dcParent, rcParent.Width(), rcParent.Height());
HBITMAP hOldBmp1 = dcCompat1.SelectBitmap(bmpCompat1);
wndParent.SendMessage(WM_PRINTCLIENT, (WPARAM) (HDC) dcCompat1, (LPARAM)(PRF_ERASEBKGND | PRF_CLIENT | PRF_NONCLIENT));
CRect rcWin;
wnd.GetWindowRect(&rcWin);
CDC dcCompat2;
dcCompat2.CreateCompatibleDC();
CBitmap bmpCompat2;
bmpCompat2.CreateCompatibleBitmap(dcCompat1, rcWin.Width(), rcWin.Height());
HBITMAP hOldBmp2 = dcCompat2.SelectBitmap(bmpCompat2);
CRect rcSnap = rcWin;
::MapWindowPoints(NULL, wndParent, (LPPOINT) (LPRECT) &rcSnap, 2);
dcCompat2.BitBlt(0, 0, rcWin.Width(), rcWin.Height(), dcCompat1, rcSnap.left, rcSnap.top, SRCCOPY);
HBRUSH hBrush = ::CreatePatternBrush(bmpCompat2);
dcCompat1.SelectBitmap(hOldBmp1);
dcCompat2.SelectBitmap(hOldBmp2);
return hBrush;
}
下面是一个简单的Demo:
Demo源代码: TransparentControl Demo
http://www.cppblog.com/weiym/archive/2012/08/23/187998.html
如何让窗口控件半透明(控件在Paint自己时,首先向主窗口询问,获取主窗口上控件所在区域的背景图)的更多相关文章
- jquery 获取父窗口的元素、父窗口、子窗口
一.获取父窗口元素: $("#父窗口元素ID",window.parent.document):对应javascript版本为window.parent.document.getE ...
- 获取父窗口元素或者获取iframe中的元素(相同域名下)
jquery方法 在父窗口中获取iframe中的元素 //方法1 $("#iframe的ID").contents().find("iframe中的元素"); ...
- Atitit.获取swing ui 按钮控件的id 与名字 与JPDA 调试体系
Atitit.获取swing ui 按钮控件的id 与名字 与JPDA 调试体系 1. Swing Inspector是一个Java Swing/AWT用户界面分析和调试工具,功能与firebug类似 ...
- C#之菜单控件、主窗体打开子窗体、GroupBox控件使用
一.背景 一年前有学习过C#,但没有在项目中去实际做APP,重新捡起来应用到项目中.我同事本来做好一个CANOPEN设备管理的界面,由于近期搜索了别人的开发的界面,我觉得有很多东西要重新安排,以及我已 ...
- 扩展BindingList,防止增加、删除项时自动更新界面而不出现“跨线程操作界面控件 corss thread operation”异常
在做界面程序时,常常需要一些数据类,界面元素通过绑定等方式显示出数据,然而由于UI线程不是线程安全的,一般都需要通过Invoke等方式来调用界面控件.但对于数据绑定bindingList而言,没法响应 ...
- javascript获取asp.net服务器端控件的值
代码如下: <%@ Page Language="C#" CodeFile="A.aspx.cs" Inherits="OrderManage_ ...
- Winform 获取当前单击的控件名称 和 向窗体添加控件
Winform如何获取当前单击的控件名称,比如有100个Button 和一个button_Click()的按钮事件 ,分别点击不同按钮后显示所点击的按钮名称?private void button_C ...
- 如何获取Iframe的页面控件的值
有时候我们在页面需要使用iframe的方法来引用另一个页面,虽然个人建议不要使用iframe哈,但是有些时候是没得法了才使用的咯,那么在使用的过程中也会遇到某一些问题,我将自己遇到的问题记录下来方便以 ...
- MFC获取光标相对于控件所在行
获取光标在控件上所在的行数 /*editControl为Edit Control的变量*/ CPoint point = editControl.GetCaretPos(); //获取光标相对于控件的 ...
随机推荐
- Hard 不用+号实现两个数之和 @CareerCup
例子: 759+674 1)不考虑进位: 323 2)只考虑进位:1110 3)两者之和:1433 递归求解c package Hard; /** * Write a function that ...
- Angular2学习
1.新建项目 2.新建Model public class TodoItem { public int Id { get; set; } public string Key { get; set; } ...
- C++中一个函数隐藏的有趣例子
函数隐藏是一个函数的定义或声明导致其他一些函数不可见. 函数A隐藏函数B的条件: 1. 两个函数具有相同的函数名称 2. 具有不同的作用域.所谓定义域函数定义或声明的位置,如全局作 ...
- C#快速剔除字符串中不合法的文件名或者文件路径字符
C#快速剔除字符串中不合法的文件名 string strFileName= "文件名称"; StringBuilder rBuilder = new StringBuilder( ...
- Linux shell入门基础(六)
六.Shell脚本编程详解 将上述五部分的内容,串联起来,增加对Shell的了解 01.shell脚本 shell: # #perl #python #php #jsp 不同的脚本执行不同的文本,执行 ...
- Manacher算法求回文半径
http://wenku.baidu.com/link?url=WFI8QEEfzxng9jGCmWHoKn0JBuHNfhZ-tKTDMux34CeY8UNUwLVPeY5HA3TyoKU2XegX ...
- Java中的浅复制和深复制 Cloneable clone
先看一个简单案例 public class Test { public static void main(String args[]) { Student stu1 = new ...
- 9.16noip模拟试题
题目描述 在幻想乡,东风谷早苗是以高达控闻名的高中生宅巫女.某一天,早苗终于入手了最新款的钢达姆模型.作为最新的钢达姆,当然有了与以往不同的功能了,那就是它能够自动行走,厉害吧(好吧,我自重).早苗的 ...
- JavaScript Unicode字符操作
charCodeAt() 方法 定义和用法charCodeAt() 方法可返回指定位置的字符的 Unicode 编码.这个返回值是 0 - 65535 之间的整数.方法 charCodeAt() 与 ...
- iOS GorupBy
转自: IOS 数组分组 Grouped NSArray 1 2 3 4 5 6 7 8 NSMutableSet *set=[NSMutableSet set]; [_list enumera ...