VC++玩转炫酷悬浮窗3---GDI+完美实现不规则窗体
目标
上一篇不规则窗体虽然实现了,但是图形有锯齿,给人以上世纪的老古董感觉,跟酷炫不搭边。今天就要用高级一些的技术做出完美的光滑的无锯齿的不规则窗体。
计划&方案
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+完美实现不规则窗体相关推荐
- 魔域传说显示与服务器断开连接,玩法炫酷升级《魔域传说》公测开启
今日,1073<魔域传说>将在10点开启正式公测,游戏以以穿越800年间为线索,就此展开一场惊心动人的魔幻冒险.在逼真色彩与光影流转间尽显西方魔幻风格的魅力.规模宏大的世界地图在配以曲折的 ...
- Android模仿360动态悬浮窗,像360悬浮窗那样,用WindowManager实现炫酷的悬浮迷你音乐盒(下)...
悬浮窗 在上一篇文章像360悬浮窗那样,用WindowManager实现炫酷的悬浮迷你音乐盒(上)中我粗粗的向大家介绍了WindowManager和WindowManager.LayoutParams ...
- 像360悬浮窗那样,用WindowManager做一个炫酷的悬浮迷你音乐盒(下)
*本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 在上一篇文章像360悬浮窗那样,用WindowManager实现炫酷的悬浮迷你音乐盒(上)中我粗粗的向大家介绍了WindowMan ...
- 像360悬浮窗那样,用WindowManager实现炫酷的悬浮迷你音乐盒(下)
悬浮窗 在上一篇文章像360悬浮窗那样,用WindowManager实现炫酷的悬浮迷你音乐盒(上)中我粗粗的向大家介绍了WindowManager和WindowManager.LayoutParams ...
- 像360悬浮窗那样,用WindowManager做一个炫酷的悬浮迷你音乐盒(上)
*本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 记得上一篇讲的是用RotateDrawable实现网易云音乐唱片机效果,而今天我要讲的是如何用WindowManager去实现一个 ...
- php仿多玩我的世界盒子,多玩我的世界盒子最新版悬浮窗
软件介绍 多玩我的世界盒子最新版悬浮窗是一款适用于我的世界的手游盒子,此款手游辅助工具支持玩家开悬浮窗,让玩家方便寻找一些自己想要的工具,功能多样,各种皮肤模组为玩家一手呈现,还有功略玩法及经验交流哦 ...
- 多玩悬浮窗如何在服务器内显示,多玩我的世界盒子怎么打开悬浮窗,多玩我的世界盒子打开悬浮窗教程...
多玩我的世界盒子怎么打开悬浮窗教程 一.首先手机里必须有,否则以后就无法取得进展.第一步是打开更多的游戏盒. 二.点击进入找到我们要使用的功能,然后点工具栏.这里是关闭状态,选择打开浮动窗口. 四.打 ...
- [译] CSS 变量实现炫酷鼠标悬浮效果
原文: Stunning hover effects with CSS variables 我的博客:[译] CSS 变量实现炫酷鼠标悬浮效果 我最近从Grover网站上的有趣的悬停动画中获得灵感.将 ...
- python大游戏_玩游戏就能学Python?太炫酷了!
原标题:玩游戏就能学Python?太炫酷了! 要说现在最火的语言,那一定是Python了. 各种排行榜里,Python的排名都是蹭蹭蹭地往上涨.Python也确实是最适合新手入门的语言了,语法简单,应 ...
最新文章
- 帕斯卡三角形与道路问题
- Script:优化crs_stat命令的输出
- 直播 | DPDK中国技术峰会2017
- 建立集群间ssh信任关系
- input发送a.jax_JAX-RS 2.0:服务器端处理管道
- UI标签库专题十一:JEECG智能开发平台 DictSelect (数据字典下拉选择框)
- bzoj3110 [Zjoi2013]K大数查询
- 变相解决Unidac无法向Postgresql传游标RefCursor的问题
- 管理感悟:不能放任下属,必须定时检查工作
- 木兰宽松许可证(MulanPSL v2)解析
- 蓝色妖姬 t3200 linux连接
- 聚类总结(中)——密度聚类
- 3DGIS合伙人招募
- [TCP灵魂之问]TCP 的拥塞控制、慢启动、慢启动阈值、拥塞避免、快速重传和快速恢复
- 认识一下身边的互联网---经典互联网书籍阅读总结
- python vue+flask 跨域请求
- 多穿立体库系统四向车PLC流程控制
- VRChat模型上传需要注意些什么?
- 算法 —— 排序 —— 优先队列
- 高效管理时间的黄金法则