VC实现顶层窗口的透明与实现子窗口的透明【重点:子窗口透明处理】

本人在vc开发过程中,多次因窗口透明而煞费苦心,在本人的前一文章《UpdateLayeredWindow与SetLayeredWindowAttributes》中已经指明实现窗口的透明方法,在过往实际的开发过程中我也一直沿袭这一做法,但也并不是屡试不爽,实际应用过程中的缺陷暴露如下:

(1)SetLayeredWindowAttributesUpdateLayeredWindow两个API函数只能适用于层级窗口,也就是非子窗口;

(2)UpdateLayeredWindow方法效率比SetLayeredWindowAttributes效率高,但是它是通过绘制到某一个内存中间设备上下文后,将设备上下文拷贝到指定层级窗口上实现的,也就是所有的绘制都必须在内存设备上下文实现,甚至包括所有子控件,所以通过它实现透明,父窗口上的所有子控件“不见了”,所以应特别注意[这也是经验总结,切记!],但好处是指定不透明度为255时候,它自动从使用的png的alpha[当然不一定是png贴图,只要贴图有alpha通道]通道去透明窗口,也就是透明度就是图片的透明度,否则不使用贴图情况当然可以使用const
透明常亮指定透明度;SetLayeredWindowAttributes透明也有两种方式,第一种是通过指定COLORREF crKey,
掩码色,也就是参数2指定为要剔除的掩码色【窗口自动将所有背景中为crkey的掩码色的背景完全透明】,当然使用掩码色方法的时候必须指定 DWORD dwFlags为LWA_COLORKEY,即使用掩码色透明;第二种方式就是不使用掩码色,而是使用透明度去透明而不关心你背景颜色到底如何,只是将整个窗口加上一层透明度,这时crkey忽略填写0,将bAlpha不透明度指定成0-255的任意值,0指完全透明,255指完全不透明,此时指定 DWORD dwFlags为LWA_ALPHA.

BOOL SetLayeredWindowAttributes(      

    HWND hwnd,
    COLORREF crKey,
    BYTE bAlpha,
    DWORD dwFlags
);通过对比可以知道SetLayeredWindowAttributes中第一种透明方法是逐个去掉掩码色位置的像素,而UpdateLayeredWindow是通过二进制与操作实现的,所以UpdateLayeredWindow效率要高很多很多;
(3)由于是层级窗口,在实际应用中将透明窗口都设置为透明窗口导致的问题是,切换到其他页面的时候,必须手动去隐藏改层级窗口,如果手动SetParent这层级窗口就失效,调用后自动带上WS_CHILD属性导致层级窗口透明无法实现;
(4)最小化后再显示,透明窗口显示比其他窗口快,感觉覆盖在其他窗口上的透明窗口“不是一伙的”,失联了一般;
(5)透明窗口单独跑到桌面上去了,应用程序最小化不可见;


以上是使用层级窗口透明的方法以及使用该方法暴露的若干问题,针对以上问题,为了完善或避免以上方法,我一直在寻找使得子窗口透明的方法,不巧,偶然中使用中空画刷,这才让我恍然大悟:中空HOLLOW_BRUSH就等于NULL_BRUSH,含义就是不使用画刷,也就是不做画刷填充,不填充其实就是透明,提到这边不知道各位网友是否已经想到实现子窗口透明的方法?算了,不卖关子了,听我细细道来:首先窗口以及窗口上的子控件绘制成什么样的背景是通过什么方法告知窗口的,这里提的字很关键, 是告知不是让你代码实现,对!就是通过OnCtlColor的返回值来告知父窗口到底将本窗口或本窗口子控件背景默认绘制成啥颜色,置于具体是返回本窗口还是本窗口子控件是通过OnCtlColor的参数UINT nCtlColor类型指定的,当为CTLCOLOR_DLG时就是指定窗口的背景色,当是CTLCOLOR_EDIT时告知编辑框的背景色,CTLCOLOR_BUTTON告知按钮默认的背景色...
通过以上指点分析,我们只要截获ON_WM_CTLCOLOR消息,然后在该处理函数不论是什么类型都返回空画刷也就是return (HBRUSH)GetStockObject(HOLLOW_BRUSH);即可,这时候该窗口就透明了【该窗口指定为其他窗口的子窗口后,则子窗口也透明】,如果还想再该透明子窗口上划线、画矩形等实现OnLbuttonDown、OnLbuttonup和OnMouseMove消息函数,在OnEraseBkGround处理函数中绘制即可!简单吧?

好,以上就是实现窗口透明的3种方法(内行4种透明方式,包括setlayeredwindowattributes的两种),如果还是不明白子窗口透明,我这里有相应的Demon,大家可以去下载,希望各位都有收获,这才是我共享的力量!

子窗口透明:http://download.csdn.net/detail/lixiang987654321/8846755
层级窗口透明以及子窗口透明:http://download.csdn.net/detail/lixiang987654321/8847067
				
时间: 2024-11-08 01:55:36

VC实现顶层窗口的透明与实现子窗口的透明【重点:子窗口透明处理】的相关文章

[Selenium]通过Selenium实现在当前浏览器窗口点击一个图标之后,弹出另外一个窗口,关闭这个窗口,再回到原来的窗口进行操作

public void clickReportIcon(){ String initialWindowHandle = driver.getWindowHandle(); //保存原始的浏览器窗口 page.getReportIcon().click(); //这个操作之后将会弹出另外一个浏览器窗口 Set <String> set = driver.getWindowHandles(); set.remove(initialWindowHandle); assert set.size()==

Mac开发——设置关闭窗口之后点击Dock中的图标可以再次打开窗口

1 /** 2 设置关闭窗口之后点击Dock中的图标可以再次打开窗口 3 */ 4 -(BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag 5 { 6 if (flag) { 7 return NO; 8 }else{ 9 [_window makeKeyAndOrderFront:self]; 10 return YES; 11 } 12 }

[WPF疑难] 模式窗口被隐藏后重新显示时变成了非模式窗口

原文:[WPF疑难] 模式窗口被隐藏后重新显示时变成了非模式窗口 [WPF疑难] 模式窗口被隐藏后重新显示时变成了非模式窗口 周银辉 现象: 大家可以试试下面这个很有趣但会带来Defect的现象:当我们将子窗口按照ShowDialog()的方式显示出来的时候,很明显该窗口是模式化的(即主窗口等待该窗口的返回,主窗口将不相应用户输入),但如果此时将子窗口的Visibility设置成Visibility.Hidden来隐藏窗口,然后再将Visibility设置成Visibility.Visible来

剑指Offer(Java版)第六十七题:给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。 例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口, 他们的最大值分别为{4,4,6,6,6,5}。

/*给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值.例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}: 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4

pb数据窗口如何按当前列的值过滤下拉数据窗口(翻译)

假设我们的订单系统,有"新增"."待定"."提交"."取消"四种状态,新增的定单只能修改为"取消"和"待定"状态,"待定"的订单只能改变为"取消"和"提交"的状态."取消"和"提交"状态的订单得订单状态不能被改变. 现在我们假设数据窗口把所有的订单都显示了出来,显示的列有"订单号

在一个窗口中显示多个视频,并在每个子窗口左上角显示系统时间,函数cvShowManyImages是改写的

#include <cv.h> #include <highgui.h> #include <stdio.h> #include <stdarg.h> #include <time.h> void cvShowManyImages(char* title, int nArgs, ...){ IplImage *img; IplImage *DispImage; int size; int i; int m, n; int x, y; int w,

精通 VC++ 实效编程280例 - 01 窗口[转]

窗口是屏幕上的一个矩形区域.窗口分为3种:重叠窗口.弹出窗口和子窗口.每个窗口都有由系统绘制的“非客户区”和应用程序绘制的“客户区”.在 MFC 中,CWnd 类为各种窗口提供了基类. 1 通过 HWND 获得 CWnd 指针 通过 HWND 获得 Cwnd 指针可以调用 Cwnd::FromHandle 函数. 1 2 3 4 5 6 7 8 void CDemoDlg::OnButton1() {     HWND hWnd = GetSafeHwnd();  //获得当前窗口的句柄    

浏览器扩展系列————透明浏览器窗口的实现

原文:浏览器扩展系列----透明浏览器窗口的实现 首先先看一下效果图: 本实现是基于WPF,VS版本2008 SP1. 先说一下在Winform中的实现方法:很简单通过设置窗体的opacity来实现,或者还可以设置TransparentKey来实现某种颜色透明.但是在WPF中则如何实现呢? 通过设置窗体的opacity,那么得到结果就是webbrowser整体消失了.因为这里面涉及到WPF中“空域”的问题,相关的文章如下: http://blogs.msdn.com/changov/archiv

透明窗口(窗口上面文字图片等内容不透明)的实现

本文讨论通过SetLayeredWindowAttributes来实现本文的目的. SetLayeredWindowAttributes的实现必须将窗口设置为WS_EX_LAYERED的扩展风格.   然而,只有WS_POPUP窗口才能设置WS_EX_LAYERED的扩展风格.这就意味着只能够在POPUP的窗口中实现透明窗口,而在WS_CHILD风格的窗口中是不能够实现的. 当初我就是试了半天发现不行的. SetLayeredWindowAttributes的原型如下: [cpp] view p