`
snzipeng
  • 浏览: 22138 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

[转]循序渐进实现仿QQ界面(五):半透明窗体与不透明控件

阅读更多

本篇演示实现仿QQ界面的中间客户区。QQ是可以调整界面透明度的,但是调整了透明度却连中间客户区也变得半透明了。客户区毕竟是软件最重要的部分,是要与用户交互的,透明了就影响操作了,因此这里的客户区不学QQ,始终不透明。要实现不透明控件,只能创建一个弹出窗口,遮住主界面的客户区域,然后设定与主界面连动,即始终跟着主窗口移动及调整尺寸。这个方法并不是很好,但却几乎是唯一的方法。为什么说几乎是唯一的方法呢?的确存在着另外的解决方案,但是这个方法太麻烦了,在此讨论一下这个方法。

实现半透明窗体,不透明控件,应该有不少朋友碰到过这个问题:为什么设定了窗口透明,窗口上的子窗口及控件也变得透明了?这个是受系统限制的,创建一个窗口,这个窗口区域就相当于一块画布,最终系统要在这块画布上绘制出窗口标题,客户区,控件等等,而窗口和控件绘制时的GetDC,BeginPaint等不过是获取到了跟自己相关的这块画布的一部分,在限定的区域内绘制,最终是画到这块画布上,系统最后显示窗口就是在桌面上显示这块画布,透明度也是认这块画布,因此上面的子窗口及控件也一起变得透明了。另建一个弹出式窗口,相当于创建了另一块画布,就不受主窗口的透明度限制。

知道了原因,现在来讨论如何不创建弹出式窗口,实现不透明控件。透明窗口有两种实现方法,一种是调用SetLayeredWindowAttributes,设定统一的窗口透明度,既整个窗口采用同样的透明度,QQ2009和这里的演示程序采用的就是这个方法,这个方法不创建弹出窗口是无法实现不透明控件的,因为想要控件不透明,就必须在控件区域采用不同的透明度,SetLayeredWindowAttributes无法做到,只能通过调用另一个函数UpdateLayeredWindow来实现可指定不同区域不同透明度的窗口,API代码大致如下:

C/C++ code
HDC hdc,hMemDC; RECT rc; GetWindowRect(hWnd,&rc); POINT ptSrc = {0,0}; POINT ptWinPos = {rc.left,rc.top}; SIZE szWin = {rc.right-rc.left,rc.bottom-rc.top}; BLENDFUNCTION stBlend = { AC_SRC_OVER, 0,255,AC_SRC_ALPHA}; hdc = GetWindowDC(m_hWnd); hMemDC = CreateCompatibleDC(hdc); SelectObject(hMemDC,hbmp); //hbmp为整个窗口贴图 UpdateLayeredWindow(hWnd,hdc,&ptWinPos,&szWin,hMemDC,&ptSrc,0,&stBlend,ULW_ALPHA);


最关键的部分就是SelectObject(hMemDC,hbmp);实现不同区域不同透明度,全在这个选入设备的hbmp的图象数据,Windows的32位色图像的像素数据是COLORREF类型,0x00bbggrr格式,关键就在最高位的字节0x00,UpdateLayeredWindow是认这个字节来设定透明度,0x00为全透明,0xFF为不透明,这个字节的集合有个专门名称叫ALPHA通道。设定hbmp图象每一个像素的这个最高位字节数据,就可以实现像素级别的透明度。网上应该能搜到大把利用PNG图片实现半透明窗口的例子,因为PNG图片是可以带ALPHA通道的,解码PNG图片,自然就有了ALPHA通道,即设定了这个最高位字节,就不需要用代码来一个个像素指定透明度了。实现这样的半透明窗口是这样一个过程:首先要用双缓冲,创建与窗口相同大小的内存图象,然后在这个内存图象上绘制窗口的各个部分,标题栏,背景等等,一般是用PNG图片实现,这样就不用逐个像素指定透明度了,最后把这个内存图象绘制到窗口。想实现不透明控件,就要把控件区域的ALPHA通道值设为0xFF,然而不幸的是,几乎所有的GDI操作,除了TransparentBlt,那些最常用的BitBlt,TextOut,FillRect等等都是忽略ALPHA通道的,绘制过后这些区域的ALPHA值都变成了0,即全透明。因此想要实现不透明控件,就要实现所有控件的自绘,使控件绘制到内存图象上,常规GDI操作过后再设定这些区域的ALPHA值为0xFF。是不是头大了?这个方法太麻烦了,而且仅仅是为了在半透明窗口上实现不透明控件这样一个效果,代价太大,因此并不实用。QQ2009所用的DirectUI应该能很容易实现这个效果,但是并没实现,估计跟执行效率有关,因为这种像素级透明的程序在绘制时很耗时,调整窗口大小时可能会有延迟现象,在速度慢一点的机器上更是明显。

现在来讲模仿QQ的客户区,有很多种方法,这里选用相对比较简单的方法,有更好的解决方案欢迎留言讨论。首先是上部的搜索栏,当然是子类化EDIT控件进行自绘,处理WM_NCCALCSIZE消息加大其非客户区,画个外方内圆的边框。在编辑框输入内容后会有个自绘的下拉列表出来,这个其实跟点了“更改外观”按钮后出现的界面调色对话框是一样的,不过是把那对话框改一下表现形式,然后搬到编辑框下面,就不演示了,还有右边会出现清除和执行按钮,又是贴图,属于非典型编辑框功能,也不演示了,有兴趣的可以自己完成。

然后是侧边栏,看起来是TAB控件的功能,其实用工具栏更简单一些,添加TBSTYLE_BUTTON|TBSTYLE_CHECKGROUP类型的按钮就跟TAB控件的效果差不多。怎么绘制前面一篇已经讲过了,收起和展开只是隐藏和显示而已。最重要的好友列表部分,这个要用到TAB控件了,调整窗口尺寸时3个标签的宽度是跟着变的,这个需要创建TAB控件时指定TCS_FIXEDWIDTH窗口类型,子类化后在WM_SIZE消息里发送TCM_SETITEMSIZE消息调整标签的宽度。标签需要自绘,鼠标点击上面的下拉箭头会弹出菜单,这个需要在WM_LBUTTONDOWN消息里判断一下,子类化后其实想干什么都行,只是麻烦一点罢了:)点击标签后下面列表子窗口的滑动效果切换也很简单,把两个窗口并排然后连续移动就可以,不过因为刷新的关系,可能会有重影,如果想要更好的效果,应该是把子窗口截图,然后用双缓冲绘制出滑动效果,这里就简单一点,不用这个方法了。

好友列表,群列表和最近联系人列表是用ListBox控件实现,本来不需要子类化,不过ListBox不支持鼠标移到选项上的高亮功能,因此还是实现了子类化,处理WM_MOUSEMOVE消息进行判断。好友列表里面是有“我的好友”,“陌生人”,“黑名单”等分类的,这些分类选项的高度与用户项的高度不同,因此创建控件时需要指定LBS_OWNERDRAWVARIABLE类型,还有ListBox控件默认是会计算控件高度并调整尺寸适应列表项的高度,不会在客户区显示不完整的列表选项,这个功能我们不需要,因此还需指定LBS_NOINTEGRALHEIGHT类型,不自动调整高度,再指定一下LBS_HASSTRINGS|LBS_NOTIFY|WS_VSCROLL常规类型,然后就是在父窗口的WM_DRAWITEM消息里进行列表选项的自绘了。加入选项时需要指定选项的高度,为了区分分类选项和用户信息选项,通过发送LB_SETITEMDATA消息绑定了不同的数据,这样就能通过绑定的DATA来确定如何绘制。点击分类选项是可以收起/展开该类下的用户列表的,本来想收起时通过设定其下的用户列表高度为0来实现,结果发现LB_SETITEMHEIGHT消息只能设定选项的高度为1~255之间的值,残念,只能是收起时删掉用户列表,展开时再添加进来。用户列表项高亮状态时会有“发送短信”,“发送邮件”等按钮,这里只演示了“发送邮件”按钮,同样是通过静态文本控件实现,前面一篇文章已经讲过了。信息提示和右键菜单这里就不演示了,那个菜单项实在太多,看着就害怕:)

现在看看程序的截图:



差不多快完成了,还差滚动条和异型菜单,下一篇再说了。

演示程序下载地址:http://download.csdn.net/source/2059841

分享到:
评论

相关推荐

    循序渐进实现仿QQ界面

    ### 循序渐进实现仿QQ界面:关键技术点解析 #### 一、园角矩形与双缓冲贴图窗口 为了实现仿QQ界面中的园角矩形效果,开发者需要掌握如何利用Windows API来创建园角矩形区域。具体做法如下: 1. **使用...

    循序渐进实现仿QQ界面(一):

    序渐进实现仿QQ界面(一):园角矩形与双缓冲贴图窗口 - CSDN论坛 - CSDN.NET.mht

    循序渐进实现仿QQ界面(四)

    在本教程中,我们将深入探讨如何“循序渐进实现仿QQ界面(四)”。这个教程是基于VC6,一个经典的Microsoft Visual C++ 6.0集成开发环境,虽然现在可能较旧,但它仍然是学习Windows应用程序开发的良好平台。在本阶段...

    C#仿迅雷资讯半透明窗体(控件不透明)

    在C#编程中,创建一个半透明窗体但控件保持不透明是一项常见的需求,这在设计用户界面时可以提供独特的视觉效果。本教程将详细解释如何实现这一目标,并探讨在移动窗体时可能出现的问题以及可能的解决方案。 首先,...

    仿QQ界面程序(5)

    编译有问题的,请到以下地址去看: ... 循序渐进实现仿QQ界面(五):半透明窗体与不透明控件的配套源码,文章请见: http://blog.csdn.net/ringphone/archive/2010/02/11/5306231.aspx

    窗体全透明但窗体上的控件不透明.zip

    1.QQ:513187410 2.保证无毒 3.简单,方便,实用 4.实例可以自行改用 5.如有非法,本人无法律责任,由改动代码人负责! 6.需要更多本人作品,查找标签“朱建强” 7.请下载,杀毒后再使用! 本人Delphi开发7年,有C++,IOS,...

    vs2013_winform实现360_QQ窗体与控件

    在本文中,我们将深入探讨如何使用Visual Studio 2013 (VS2013) 和 Windows Forms (WinForms) 技术来实现类似360和QQ的自定义窗体与控件。Windows Forms是.NET Framework中的一个用户界面框架,它提供了丰富的控件库...

    winform实现360、QQ窗体与控件

    在标题"winform实现360、QQ窗体与控件"中,我们讨论的是如何利用WinForm以及GDI+技术来模仿或实现类似于360安全卫士和QQ的窗口样式和自定义控件。GDI+是.NET Framework中的图形设备接口,它提供了绘制2D图形、文本和...

    C#WinForm仿qq窗体拖到windows窗体边上时,自动隐藏C#WinForm

    ### C# WinForm 实现QQ风格窗口边缘自动隐藏功能 #### 概述 在本篇文章中,我们将探讨如何使用 C# 和 WinForms 技术来实现一个类似 QQ 的窗口效果:当用户将窗口拖拽至屏幕边缘时,窗口会自动隐藏(即缩入屏幕边缘...

    2008-边框半透明窗体

    在Windows编程中,创建具有半透明边框的窗体是一项常见的需求,特别是在开发桌面应用程序时,为了实现更加美观和现代的用户界面。2008年,随着.NET Framework的不断发展,开发者开始利用C#和ASP.NET等技术来实现这一...

    C#与halcon视觉软件窗体控件设计

    6. 实现通信:在窗体控件与Halcon之间建立通信,将处理结果更新到窗体上,或者根据用户在窗体上的操作调整视觉处理参数。 7. 性能优化:由于视觉处理可能涉及大量的计算,因此需要注意性能优化,例如使用多线程处理...

    C#弹窗控件,仿QQ右下角弹出窗体

    以上就是创建C#弹窗控件,仿QQ右下角弹出窗体所需的关键技术点。项目中的"弹窗控件.sln"是解决方案文件,包含整个项目的配置和引用;"弹窗控件.suo"是用户选项文件,存储了开发者个人的IDE设置;"弹窗控件"可能是...

    仿QQ登陆界面 仿QQ登陆界面

    仿QQ登录界面的设计,旨在模仿QQ的经典风格,同时融入创新元素,以提供更友好的用户体验。下面我们将详细探讨如何实现这样一个界面。 一、界面布局 1. 布局结构:仿QQ登录界面通常采用简洁明了的布局,主要分为上...

    循序渐进Linux 第2版

    《循序渐进Linux 第2版》PDF下载 试读

    c# 仿qq窗体自动伸缩

    在C#编程中,仿QQ窗体自动伸缩是一项常见的需求,主要涉及到Windows窗体(Windows Forms)的应用程序设计。QQ窗体的自动伸缩功能可以让窗口根据内容或用户操作自动调整大小,提供良好的用户体验。以下是一些实现这一...

    Vb仿做的QQ2010主界面窗体,有动态效果

    标题中的“Vb仿做的QQ2010主界面窗体,有动态效果”表明这是一个使用Visual Basic(Vb)编程语言开发的项目,目的是模仿QQ2010版本的主用户界面,并且包含了动态效果。这个项目可能是为了学习、实践或者展示如何使用...

    仿QQ主界面分组菜单的C#窗体源代码

    仿QQ主界面分组菜单的C#窗体源代码 仿QQ主界面菜单的C#窗体源代码,虽然没有QQ的精细,但是但帮出了主要思路,至于细节就请细心的编程者慢慢修改完善,它完成了像QQ主窗体上分组菜单一样的功能,另外还有小头像功能...

    仿QQ界面程序(2)

    缺头文件的,请到下面文章的地址去看。 循序渐进实现仿QQ界面(二):贴图按钮的三态模拟的配套源码,文章请见:http://blog.csdn.net/ringphone/archive/2010/01/10/5171490.aspx

    QT实现高仿QQ QT实现QQ界面

    本项目"QT实现高仿QQ QT实现QQ界面"旨在通过QT框架来复刻QQ的经典界面,从而展示如何利用QT库来创建类似QQ这样的即时通讯软件的用户界面。下面将详细介绍这个项目可能涉及的关键知识点: 1. **QT Widgets模块**:QT...

    VB 仿QQ窗体靠边自动隐藏

    【VB 仿QQ窗体靠边自动隐藏】是一种在Visual Basic (VB)编程环境中实现的窗口特效技术,它使得应用程序的窗体能够模仿QQ聊天窗口的行为,即当窗体靠近屏幕边缘时,窗体会自动隐藏或者吸附到屏幕边缘,提供更便捷的...

Global site tag (gtag.js) - Google Analytics