目标
上一篇不规则窗体虽然实现了,但是图形有锯齿,给人以上世纪的老古董感觉,跟酷炫不搭边。今天就要用高级一些的技术做出完美的光滑的无锯齿的不规则窗体。
计划&方案
PNG图片本身就是带透明效果的,把此图片作为窗体,用GDI+将其实现。
那么什么是GDI+呢?先要说一说GDI, Graphics Devices Interface,图形设备接口,负责系统与绘图程序之间的信息交换,处理所有Windows图形程序的输出。而GDI+是其增强版,xp时代是其一个子系统,负责在显示屏幕和打印设备输出信息。程序员根据其提供的众多函数来实现图形程序编程,不用关心图形硬件的实现细节。
正所谓:任凭弱水三千,我只取一瓢饮。这是我第一次接触GDI+,只是在程序中用到了一些函数,照猫画虎会用几个函数而已。
本文的重点函数是:UpdateLayeredWindow,

BOOL WINAPI UpdateLayeredWindow(_In_      HWND hwnd,//窗口句柄_In_opt_  HDC hdcDst,//当前窗口HDC_In_opt_  POINT *pptDst,//_In_opt_  SIZE *psize,_In_opt_  HDC hdcSrc,_In_opt_  POINT *pptSrc,_In_      COLORREF crKey,_In_opt_  BLENDFUNCTION *pblend,_In_      DWORD dwFlags
);

请参看官网:http://msdn.microsoft.com/en-us/library/windows/desktop/ms633556(v=vs.85).aspx

实践
一、 GDI+在VS2012上的配置
VS2012上已经有了GDI+支持,不用单独下载安装包了。现在只需项目中引入gdiplus.lib和加入头文件即可。Properties-Configuration Properties -Linker - Input - Additional Dependencies 加入“gdiplus.lib”。
为了在全工程使用gdi+,在stdafx.h中加入头文件的包含和使用命名空间。

#include "gdiplus.h"
using namespace Gdiplus; 

二、 GDI+的初始化

//在应用初始化时,启动gdi+
BOOL CXXXApp::InitInstance()
{...//use GDIplus beginGdiplusStartupInput gdiplusStartupInput; GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);//use GDIplus end...
}
//在程序退出时,关闭gdi+
int CXXXApp::ExitInstance()
{//close gdiplus environmentGdiplusShutdown(m_gdiplusToken);return CWinApp::ExitInstance();
}

三、 将png图片加入到项目资源
当我们在Resource界面添加资源时,Add Resource界面只有Icon和Bitmap,而没有PNG可选,不要理它,我们只管Import就好了,你会发现加入PNG图片后,PNG文件夹就神奇的在资源界面出现了。

四、  将图片载入到内存
借用一个很酷的函数,通过它将各种格式的图片载入到内存中。如下:

///resurceID: resource ID
///imgType: type of image
///pImg: pointer to image
BOOL CAfloatWindowDlg::ImageFromIDResource(UINT resurceID,LPCTSTR imgType,Image * &pImg)
{HINSTANCE hInst = AfxGetResourceHandle();HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(resurceID),imgType); // typeif (hRsrc){// load resource into memoryDWORD len = SizeofResource(hInst, hRsrc);BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc);if (lpRsrc){// Allocate global memory on which to create streamHGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);BYTE* pmem = (BYTE*)GlobalLock(m_hMem);memcpy(pmem,lpRsrc,len);IStream* pstm;CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);// load from streampImg=Gdiplus::Image::FromStream(pstm);// free/release stuffGlobalUnlock(m_hMem);pstm->Release();FreeResource(lpRsrc);return TRUE;}}return FALSE;
}

五、 将窗口背景换成你的图片
参考了蝴蝶钟的源码,最重要的是看UpdateLayeredWindow的使用。

BOOL CAfloatWindowDlg::UpdateDisplay(Image *image, int Transparent)
{int imageWidth = 240;int imageHeight = 240;//magic number of my image width and heightHDC hdcTemp=GetDC()->m_hDC;m_hdcMemory=CreateCompatibleDC(hdcTemp);HBITMAP hBitMap=CreateCompatibleBitmap(hdcTemp,imageWidth,imageHeight);SelectObject(m_hdcMemory,hBitMap);if(Transparent<0||Transparent>100) Transparent=100;m_Blend.SourceConstantAlpha=int(Transparent*2.55);//1~255, if you want to change transparent, modify this.HDC hdcScreen=::GetDC (m_hWnd);RECT rct;GetWindowRect(&rct);POINT ptWinPos={rct.left,rct.top};Graphics graph(m_hdcMemory);Point points[] = { Point(0, 0), Point(imageWidth, 0), //widthPoint(0, imageHeight)//height};graph.DrawImage(image,points,3);//Do it!SIZE sizeWindow={imageWidth,imageHeight};POINT ptSrc={0,0};DWORD dwExStyle=GetWindowLong(m_hWnd,GWL_EXSTYLE);if((dwExStyle&0x80000)!=0x80000)SetWindowLong(m_hWnd,GWL_EXSTYLE,dwExStyle^0x80000);BOOL bRet=FALSE;bRet= UpdateLayeredWindow( m_hWnd,hdcScreen,&ptWinPos,&sizeWindow,m_hdcMemory,&ptSrc,0,&m_Blend,2);graph.ReleaseHDC(m_hdcMemory);::ReleaseDC(m_hWnd,hdcScreen);hdcScreen=NULL;::ReleaseDC(m_hWnd,hdcTemp);hdcTemp=NULL;DeleteObject(hBitMap);DeleteDC(m_hdcMemory);m_hdcMemory=NULL;return bRet;
}

六、 结束
至此我们的事例就完成了重要的功能,运行结果如下图。


锯齿什么的,不用担心了。
源码在此,并增加了动画。请参考。
参考:
《GDI+ 透明窗口.UpdateLayeredWindow》 http://blog.csdn.net/zdl1016/article/details/3298744
《GDI+编程小结》  http://blog.csdn.net/byxdaz/article/details/5972759

VC++玩转炫酷悬浮窗3---GDI+完美实现不规则窗体相关推荐

  1. 魔域传说显示与服务器断开连接,玩法炫酷升级《魔域传说》公测开启

    今日,1073<魔域传说>将在10点开启正式公测,游戏以以穿越800年间为线索,就此展开一场惊心动人的魔幻冒险.在逼真色彩与光影流转间尽显西方魔幻风格的魅力.规模宏大的世界地图在配以曲折的 ...

  2. Android模仿360动态悬浮窗,像360悬浮窗那样,用WindowManager实现炫酷的悬浮迷你音乐盒(下)...

    悬浮窗 在上一篇文章像360悬浮窗那样,用WindowManager实现炫酷的悬浮迷你音乐盒(上)中我粗粗的向大家介绍了WindowManager和WindowManager.LayoutParams ...

  3. 像360悬浮窗那样,用WindowManager做一个炫酷的悬浮迷你音乐盒(下)

    *本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 在上一篇文章像360悬浮窗那样,用WindowManager实现炫酷的悬浮迷你音乐盒(上)中我粗粗的向大家介绍了WindowMan ...

  4. 像360悬浮窗那样,用WindowManager实现炫酷的悬浮迷你音乐盒(下)

    悬浮窗 在上一篇文章像360悬浮窗那样,用WindowManager实现炫酷的悬浮迷你音乐盒(上)中我粗粗的向大家介绍了WindowManager和WindowManager.LayoutParams ...

  5. 像360悬浮窗那样,用WindowManager做一个炫酷的悬浮迷你音乐盒(上)

    *本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 记得上一篇讲的是用RotateDrawable实现网易云音乐唱片机效果,而今天我要讲的是如何用WindowManager去实现一个 ...

  6. php仿多玩我的世界盒子,多玩我的世界盒子最新版悬浮窗

    软件介绍 多玩我的世界盒子最新版悬浮窗是一款适用于我的世界的手游盒子,此款手游辅助工具支持玩家开悬浮窗,让玩家方便寻找一些自己想要的工具,功能多样,各种皮肤模组为玩家一手呈现,还有功略玩法及经验交流哦 ...

  7. 多玩悬浮窗如何在服务器内显示,多玩我的世界盒子怎么打开悬浮窗,多玩我的世界盒子打开悬浮窗教程...

    多玩我的世界盒子怎么打开悬浮窗教程 一.首先手机里必须有,否则以后就无法取得进展.第一步是打开更多的游戏盒. 二.点击进入找到我们要使用的功能,然后点工具栏.这里是关闭状态,选择打开浮动窗口. 四.打 ...

  8. [译] CSS 变量实现炫酷鼠标悬浮效果

    原文: Stunning hover effects with CSS variables 我的博客:[译] CSS 变量实现炫酷鼠标悬浮效果 我最近从Grover网站上的有趣的悬停动画中获得灵感.将 ...

  9. python大游戏_玩游戏就能学Python?太炫酷了!

    原标题:玩游戏就能学Python?太炫酷了! 要说现在最火的语言,那一定是Python了. 各种排行榜里,Python的排名都是蹭蹭蹭地往上涨.Python也确实是最适合新手入门的语言了,语法简单,应 ...

最新文章

  1. 帕斯卡三角形与道路问题
  2. Script:优化crs_stat命令的输出
  3. 直播 | DPDK中国技术峰会2017
  4. 建立集群间ssh信任关系
  5. input发送a.jax_JAX-RS 2.0:服务器端处理管道
  6. UI标签库专题十一:JEECG智能开发平台 DictSelect (数据字典下拉选择框)
  7. bzoj3110 [Zjoi2013]K大数查询
  8. 变相解决Unidac无法向Postgresql传游标RefCursor的问题
  9. 管理感悟:不能放任下属,必须定时检查工作
  10. 木兰宽松许可证(MulanPSL v2)解析
  11. 蓝色妖姬 t3200 linux连接
  12. 聚类总结(中)——密度聚类
  13. 3DGIS合伙人招募
  14. [TCP灵魂之问]TCP 的拥塞控制、慢启动、慢启动阈值、拥塞避免、快速重传和快速恢复
  15. 认识一下身边的互联网---经典互联网书籍阅读总结
  16. python vue+flask 跨域请求
  17. 多穿立体库系统四向车PLC流程控制
  18. VRChat模型上传需要注意些什么?
  19. 算法 —— 排序 —— 优先队列
  20. 高效管理时间的黄金法则

热门文章

  1. 用于异常检测的深度神经网络模型融合
  2. Android中本地图片资源以及视频录音资源的获取
  3. python里的set的discard和remove的区别
  4. 让ADOBE系列软件恢复英文版
  5. AE中如何解除锁定的资源文件
  6. 红包雨高并发问题解决方案
  7. QTest 单元测试框架及单元测试思考
  8. CTR 预测理论(八):Embedding 质量评估方法总结
  9. python下载卫星云图合成gif
  10. BertModel和BertForMaskedLM使用介绍