LAYERED窗口是与普通窗口不同的窗口,这个窗口可以提供复杂的形状,可以使用alpha混合特效,而且,由系统自动构图和重绘layered窗口,因此,在这种窗口的WM_PAINT消息,我们基本上不用的。也正因为如此,layered窗口可以平滑的渲染。

要创建layered窗口,在我们调用CreateWIndow的时候,指定WS_EX_LAYERED样式,在mfc中,如果是对话框,我们可以在对话框的属性中选中layered属性。在单文档或是对话框中,我们可以使用cwnd的一个方法,叫ModifyStyle来添加窗口样式,我们还可以在wm_create消息中,我们使用SetWindowLong和GetWindowLong来设置窗口样式。在完成这一切之后,msdn上说明,这个时候,窗口并不会显示,而要等到调用SetLayeredWindowAttributes or UpdateLayeredWindow才会显示。但是这里就有一个问题来了,我们应该在何处调用呢,我在学习的时候,就在CreateWindow之后就调用了,然后再进入消息循环,结果没有出来,当然也是出来不了的。这个函数要在我们创建窗口以后,在消息响应和用户的命令响应需要更新窗口外貌的地方调用,这里所说的更新窗口外貌不要和窗口重绘混淆,这里所谓的更新窗口外貌是指的窗口的某个元素改变,例如,我移动鼠标到某个位置,显示一个图标,如果没有元素的改变,如果像普通窗口一样,在最大化,最小化等操作需要重绘的时候,这一切对于layered窗口,都是由系统自动帮我们完成的。说到这里,也许你开始迷糊了,不要紧,下面继续。

这里有点,我要说的就是,layered上面的所有元素都是我们自己使用gdi或是gdi+函数画出来的,你不画,就什么都没有。而普通的窗口都是大部分由系统帮我们绘制的,如按钮,窗口颜色等外貌。继续接着上面说的,调用那两个函数SetLayeredWindowAttributes or UpdateLayeredWindow,这两个函数造成的效果不同,因此呢,底层的机制也有所不同,但是各有特点,在调用了这两个函数之后,窗口就可以显示出来了。下面分别说明这两个函数。

首先是SetLayeredWindowAttributes,这个函数使用起来很简单,也因此功能有限,这个函数只能在我们普通的窗口之上产生半透明的效果,不能产生不规则的窗口,也就是说,使用这个函数,只给我们带了了半透明效果,别的还是和普通窗口一样,仍然要处理WM_PAINT消息。如下图:

这两幅图中,左边没有没有使用的情况和使用了SetLayeredWindowAttributes的对比。这里我设置的是全透明。这个函数第一次在WM_CREATE中使用,在需要改变透明度的地方,再次调用:

case WM_CREATE:
{
DWORD dwExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);   
                if ((dwExStyle & 0x80000) != 0x80000)   
                {   
                    SetWindowLong(hWnd, GWL_EXSTYLE, dwExStyle ^ 0x80000);   
                 } 
SetLayeredWindowAttributes(hWnd,RGB(255,255,255),NULL,LWA_COLORKEY);
}
break;

再次调用的时候,就只用调用SetLayeredWindowAttributes而不用在调用样式设置。

下面讲一下UpdateLayeredWindow这个函数使用起来要稍微多做一些工作。当我们要实现复杂的窗口的时候,就要这个函数,这个窗口之所以可以实现不规则的窗口,就是因为,它使用我们画的方式实现的,只有有像素的地方,才可以接收到消息,所以这里有一点要注意的就是,使用的图片的格式,就是可以保留透明通道的,因为想jpg这样的图标,透明的地方使用白色代替,其实仍然是有像素的,白色像素,那么要使用复杂的图形,我们在画的时候,完成以后,要保存为png和tiff格式,因为这些图片保留的透明通道,然后我建议使用gdi+来画,因为它容易使用,而且支持的图片格式更多。ok,现在讲到了画图,那么我们gdi+画在哪里呢,用什么dc呢,这里呢,我们就是用GetDC获取窗口句柄的DC,但是呢,我们不能直接使用这个DC画图,我们必须要创建一个兼容DC,也就是一个内存DC,在这个内存DC上画图,先来看看代码:

void CMPFDlg::DrawUI(void)
{
HDC hDC=::GetDC(m_hWnd);
HDC hMemDC=::CreateCompatibleDC(hDC);
BITMAPINFO bitmapinfo;
bitmapinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapinfo.bmiHeader.biBitCount = 32;
bitmapinfo.bmiHeader.biHeight = 1000;
bitmapinfo.bmiHeader.biWidth =800;
bitmapinfo.bmiHeader.biPlanes = 1;
bitmapinfo.bmiHeader.biCompression=BI_RGB;
bitmapinfo.bmiHeader.biXPelsPerMeter=0;
bitmapinfo.bmiHeader.biYPelsPerMeter=0;
bitmapinfo.bmiHeader.biClrUsed=0;
bitmapinfo.bmiHeader.biClrImportant=0;
bitmapinfo.bmiHeader.biSizeImage = bitmapinfo.bmiHeader.biWidth * bitmapinfo.bmiHeader.biHeight * bitmapinfo.bmiHeader.biBitCount / 8;
HBITMAP hBitmap=::CreateDIBSection (hMemDC,&bitmapinfo, 0,NULL, 0, 0);
HBITMAP hOldBitmap = (HBITMAP)::SelectObject (hMemDC,hBitmap);
///
Graphics g(hMemDC);
Image image(L"MF\\mf1.png");
RectF destRect(0, 0, 500, 500);
RectF PlayAndPause(175,212,146,69);
g.DrawImage(&image, destRect);
Image imagehighlight(L"MF\\highlight.png");
Image imagePlay(L"MF\\play.png");
Image imagePause(L"MF\\pause.png");
if(PlayOrPause==0)
{
g.DrawImage(&imagePlay,PlayAndPause);
}
else
{
g.DrawImage(&imagePause,PlayAndPause);
}
RectF openR(193, 26, 110, 110);
RectF upR(30, 196, 110, 110);
RectF nextR(358, 196, 110, 110);
RectF menuR(193,370, 110, 110);
RectF centerR(195, 195, 110, 110);
if(IsOpen==1)
{
g.DrawImage(&imagehighlight,openR);
}
if(IsUp==1)
{
g.DrawImage(&imagehighlight,upR);
}
if(IsNext==1)
{
g.DrawImage(&imagehighlight,nextR);
}
if(IsMenu==1)
{
g.DrawImage(&imagehighlight,menuR);
}
if(IsCenter==1)
{
g.DrawImage(&imagehighlight,centerR);
}
//
Rect rectK(198,323,100,12);
Rect rectP(197,324,vol,10);
Pen pen(Color(200,0,0,200), 2.0f); 
SolidBrush solidBrush(Color(150,200, 0, 200));
g.DrawRectangle(&pen,rectK);
g.FillRectangle(&solidBrush,rectP);
 
///
BLENDFUNCTION blendFunc32bpp;
blendFunc32bpp.AlphaFormat = AC_SRC_ALPHA;
blendFunc32bpp.BlendFlags = 0;
blendFunc32bpp.BlendOp = AC_SRC_OVER;
blendFunc32bpp.SourceConstantAlpha =tran;

SIZE size={500,500};
POINT pt={0,0};

::UpdateLayeredWindow(m_hWnd,hDC,NULL,&size,hMemDC,&pt,0,&blendFunc32bpp,ULW_ALPHA);

::SelectObject (hMemDC,hOldBitmap);
::DeleteObject(hBitmap);
::DeleteDC(hMemDC);
::ReleaseDC(m_hWnd,hDC);

}

我们创建了内存DC,下面为什么还要创建一个位图呢,因为我们创建了内存DC之后,默认情况下,这个DC中可画位图的空间是1*1个空间,而且颜色位黑白的,所以,我们必须创建一个一定大小和颜色格式的位图,然后选入这个DC当中,然后我就可以在这个DC中画图了,有关位图的详细,参考msdn。然后我们用这个配置好的内存DC,我们来初始化GDI+对象,然后用它来画图,最后还有一个结构体BLENDFUNCTION,它用来设置混合选项和透明度选项,也完成之后,我们就调用UpdateLayeredWindow函数,传递对应的参数,刚才我们画的窗口就出来了,代码中还有系列的if语句,就是用来根据用户的操作的改变来改变我们所画的内容的。如下:

if(PlayOrPause==1)
{
PlayOrPause=0;
this->DrawUI();
player->Pause();
this->UpdateThumbarButton();
}

在这里我点击了播放按钮,那么我就要把界面上的play改变成pause,所以我就设置了一个bool值,playorpause,然后调用上面的代码重新画图,并更新显示。所以呢,你就可以通过设置BOOL值来控制你界面上元素的状态,然后每次需要更新的时候,都调用一次上面的代码,我这里把它写在了drawUI这个函数里,所以每次我只用调用这个就ok了,我们在理解这种窗口的时候,一定要和原来的窗口概念区别开来。否则,不好理解。

画的丑了点,呵呵,我们技术好,或是使用网上的元素,画一些立体效果的,如按钮一样的图出来。酷狗的魔方窗口就是这样的。

//

要注意的就是我们创建的位图必须要足够的大,如果小于我们画的图的大小,绘图就会失败,那么运行的时候,在任务栏有窗口图标,但是桌面上没有窗口。

现在总结一下:首先是设置窗口样式,支持layered,然后就是获取dc,创建内存dc,创建位图,将位图选入内存dc,用这个dc绘图,最后调用UpdateLayeredWindow显示。

当我们使用了这个样式的窗口以后,我们就不能像以前一样,在资源编辑器中,在对话框上画空间,因为这个是显示不出来的,也收不到控件的消息。因为这个窗口只显示我们画的东西,不是我们在内存DC中画的,就不显示。

实现LAYERED窗口相关推荐

  1. Layered Windows窗口的半透明效果

    介绍: Layered Windows是windows窗口中的一类,提供类似半透明的效果(阿尔法混合).半透明效果是字面上有能看出来的,但实际上根据MSND,该类型的窗口还能更好的支持非矩形的窗口,使 ...

  2. [随笔]关于如何实现鼠标穿透窗口和窗口半透明

    资料准备 WS_EX_TRANSPARENT | WS_EX_LAYERED WM_NCHITTEST & return HTTRANSPARENT SetLayeredWindowAttri ...

  3. Win32 窗口篇(3)

    1.11 如何显示或隐藏窗口的标题栏 使用ModifyStyle方法改变参数来更改窗体样式 void CDemoDlg::OnTest1() {//删除标题栏风格ModifyStyle(WS_CAPT ...

  4. WPF如何给窗口设置透明png的图片背景

    在 WPF 中,如果想做一个背景透明的异形窗口,基本上都要设置 WindowStyle="None".AllowsTransparency="True" 这两个 ...

  5. Windows核心编程_窗口透明组件不透明

    经过前几篇对界面编程的学习,已经对Windows窗口消息有了更加深刻的理解,今天就教大家写一个窗口透明而组件却不透明的小示列! 这个demo并不难,而且还非常的简单,如果你看过我的前几篇针对界面编程写 ...

  6. Duilib异形窗口

    源码下载:https://gitee.com/Ailsc/Duilib.git 一步搞定:指定窗口属性layered="true",之后按照正常的UI布局即可. <Windo ...

  7. 关于duilib在Layered Window下绘制文字不正常的BUG

    最近在做一个小玩具,C++上面实在是没什么好用的或者轻量级的开源DUI库了,duilib算是比较出名的一个,不过这玩意好几年没人维护,之前据说pc微信也用过这个开发,所以有意试试.用了一段时间感觉,这 ...

  8. mfc 子窗口 跟随 主窗口

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明 http://shujiantang.blogbus.com/logs/29644154.html 前不久做了一个MFC项目.项目做完 ...

  9. WPF 制作高性能的透明背景异形窗口(使用 WindowChrome 而不要使用 AllowsTransparency=True)

    在 WPF 中,如果想做一个背景透明的异形窗口,基本上都要设置 WindowStyle="None".AllowsTransparency="True" 这两个 ...

  10. Windows窗口、控件和对话框

    from:http://www.zbitedu.com/?action-viewthread-tid-24616 Windows窗口.控件和对话框 windows应用程序是通过窗口(window).控 ...

最新文章

  1. R语言限制性立方样条(RCS, Restricted cubic spline)分析:基于logistic回归模型、南非心脏病数据集(South African Heart Disease)
  2. php 自学 经验,学习PHP:PHP学习的几个问题经验总结
  3. android4被淘汰,这五类安卓手机已经被淘汰,购买时别贪便宜,需慎重考虑!
  4. pymysql.err.IntegrityError: (1062, Duplicate entry 'roxml-ROXML' for key 'PRIMARY')
  5. 微信QQ聊天记录分析工具-微Q
  6. 产品经理第一课上海站圆满结束,下一站你定!
  7. centos 6 x64 mysql_CentOS 6.x版本升级Mysql
  8. linux ntp连接失败,linux ntp服务器连接异常
  9. mysql join性能_Mysql Join语法解析与性能分析
  10. python数值计算速度_提高python数值计算速度
  11. android_Media
  12. intellij idea 2016.3.5 控制台取消行数限制
  13. 《人性的枷锁》读后感范文4500字
  14. 中央财经大学python期末考试答案_大学mooc2020用Python玩转数据题库及期末考试答案...
  15. c语言分数乘法,武汉小学数学六年级
  16. MongoDB与物联网应用讲座
  17. Windows中常用文件拷贝工具的评测和对比
  18. 101个CV模型集体开源,魔搭社区视觉AI深度解析
  19. 论文速递-ANALYSIS OF VISUAL REASONING ON ONE-STAGE OBJECT DETECTION
  20. SpringCloud 微服务工具集v1.1

热门文章

  1. 在VUE框架的WEB网页端播放海康威视RTSP视频流完全方案
  2. 反编译软件JD-GUI
  3. IMDB电影评论文本分类
  4. zmq Pub-Sub 模式
  5. 计算文本相似度的常用算法
  6. 阿里企业邮箱收费版与免费版有哪些规格和功能上的区别?
  7. 图扑软件数字孪生挖掘机实现远程操控
  8. startup_stm32xxxx.s文件问题
  9. 许纪霖《中华传统文化30讲》读书笔记
  10. 张尧浠:美股反弹避险情绪降温、黄金迎美零售看回撤力