不规则窗体多用于程序启动窗口,要实现不规则窗体,背景一般都会采用贴图的方式,图片格式首先肯定是png格式了。 加载png图片,这里建议用GDI+接口实现比较方便: 1、GDI+资源初始化 // 库声明 - #include <GdiPlus.h>
- using namespace Gdiplus;
- ULONG_PTR gdiplusToken;
- GdiplusStartupInput gdiplusStartupInput;
- GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
复制代码2、png图片的加载 - char szFileName[] = ".\\res\\BkImage.png";
- int nszBufSize = strlen(szFileName) + 1;
- DWORD nwszBufSize = MultiByteToWideChar(CP_ACP, 0, szFileName, nszBufSize, NULL, 0);
- wchar_t * wszFileName = new wchar_t[nwszBufSize];
- wmemset(wszFileName, 0, nwszBufSize);
- int nRet = MultiByteToWideChar(CP_ACP, 0, szFileName, nszBufSize, wszFileName, nwszBufSize);
- Gdiplus::Image * pImage = Gdiplus::Image::FromFile(wszFileName);
- if (pImage->GetLastStatus() != Ok)
- {
- // 加载失败了
- }
- delete pImage;
- pImage = NULL;
- delete wszFileName;
- wszFileName = NULL;
复制代码3、窗体背景的绘制: - BOOL OnInitDialog()
- {
- // 修改窗体为分层窗口,窗体将不会再响应WM_PAINT消息
- ModifyStyleEx(0, WS_EX_LAYERED);
- // 或SetWindowLong(m_hWnd, GWL_EXSTYLE, GetWindowLong(m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
- // 绘制代码
- DrawBackgroundImage();
- }
- void DrawBackgroundImage()
- {
-
- //获取窗口绘图DC句柄
- HDC hDC = ::GetDC(m_hWnd);
- //创建与窗口绘图DC兼容的内存DC
- HDC hMemDC = ::CreateCompatibleDC(hDC);
- //获取窗体客户区显示区域大小
- CRect rcClient;
- GetClientRect(rcClient);
- //分配与窗体客户区显示区域大小相等的背景位图内存空间(绘图画布)
- BITMAPINFO bitmapinfo;
- bitmapinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bitmapinfo.bmiHeader.biBitCount = 32;//32位位图支持alpha透明度
- bitmapinfo.bmiHeader.biHeight = rcClient.Height();
- bitmapinfo.bmiHeader.biWidth = rcClient.Width();
- 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);
- //开始画图操作,直接对hMemDC操作,就不要用hDC了
- DrawBk(hMemDC, rcClient);
- //内存绘制好的图像更新到窗口
- CPoint DestPt(0, 0);
- CSize psize(rcClient.Width(), rcClient.Height());
- BLENDFUNCTION blendFunc32bpp;
- blendFunc32bpp.AlphaFormat = AC_SRC_ALPHA;
- blendFunc32bpp.BlendFlags = 0;
- blendFunc32bpp.BlendOp = AC_SRC_OVER;
- blendFunc32bpp.SourceConstantAlpha = 255;
- ::UpdateLayeredWindow(m_hWnd, hDC, NULL, &psize, hMemDC, &DestPt, 0, &blendFunc32bpp, ULW_COLORKEY);
- //释放资源
- ::SelectObject(hMemDC, hOldBitmap);
- ::DeleteObject(hBitmap);
- ::DeleteDC(hMemDC);
- ::ReleaseDC(m_hWnd, hDC);
- }
复制代码这种方法实现的效果图(蓝色背景是Windows桌面背景):
VC++ 不规则窗体的实现(一)
窗体边缘显示非常圆润,效果非常好,由于窗体将不会响应WM_PAINT消息了,所以窗体内显示的所有子控件都无法正常显示出来了,如果需要显示就只有在DrawBackgroundImage里面进行自绘了。 4、GDI+资源释放 - GdiplusShutdown(gdiplusToken);
复制代码优点:窗体显示效果好。
缺点: 子控件没法显示,需要自绘。 附加:无标题栏窗口的移动,只需要在ON_WM_LBUTTONDOWN消息事件里面添加如下代码即可: - PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, 0L);
复制代码
|