如何让窗口控件半透明(控件在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(); //获取光标相对于控件的 ...
随机推荐
- Jemter
1.我们需要创建批量数据 2.jemter连接数据库 3.调用外部数据 4.我要获取的值原本服务器返回的结果是:以下是左边界和右边界.提取想要的数值
- 利用d3.js绘制雷达图
利用d3,js将数据可视化,能够做到数据与代码的分离.方便以后改动数据. 这次利用d3.js绘制了一个五维的雷达图.即将多个对象的五种属性在一张图上对照. 数据写入data.csv.数据类型写入typ ...
- configure JAAS for jboss 7.1 and mysql--reference
Hello all, In this tutorial we are going to configure JAAS for jboss 7.1 and mysql for Form based au ...
- 微信,QQ这类IM app怎么做——谈谈Websocket
前言 关于我和WebSocket的缘:我从大二在计算机网络课上听老师讲过之后,第一次使用就到了毕业之后的第一份工作.直到最近换了工作,到了一家是含有IM社交聊天功能的app的时候,我觉得我现在可以谈谈 ...
- 如何在macos下创建文件或者文件夹的快捷方式
用的时间久了就发现一次次的打开finder的次数多了,每次打开每次都要一层层的去点开一个个文件夹,太复杂了,然而右键也没有windows中发送到快捷方式到桌面的选项 于是Google一下,按住comm ...
- C#学习第五天
字符串的处理 string可作char的只读数组 下面这段字符表示访问每个字符: string myString="A string."; char myChar=myString ...
- fastjson反序列化
package cn.jsonlu.passguard.utils; import com.alibaba.fastjson.JSON; import java.lang.reflect.Type; ...
- (转)PHP函数之error_reporting(E_ALL ^ E_NOTICE)详细说明
在看帝国cms的connect.php是发现第一句是error_reporting(E_ALL ^ E_NOTICE);以前也没注意过这个语句,知道是设置错误提示的,但不清楚具体怎样设置使用.下面从网 ...
- Android Studio使用教程图文详解
谷歌表示Android Studio 1.0 能让开发者“更快更有生产力”,并认为它可以代替 Eclipse,同时为Eclipse 用户提供迁移步骤.代码自动提示.运行响应速度.都比Eclipse来的 ...
- 认识CSS样式
CSS全称为“层叠样式表 (Cascading Style Sheets)”,它主要是用于定义HTML内容在浏览器内的显示样式,如文字大小.颜色.字体加粗等. 如下列代码: p{ font-size: ...