Windows界面编程(3) 异形窗体 普通版2014-01-09 csdn MoreWindows上一篇《Windows界面编程第二篇 半透明窗体》介绍了先使用SetWindowLong为窗体加上WS_EX_LAYERED属 性,再使用SetLayeredWindowAttributes调整窗体的透明度。本篇将使用这二个函数来完成另一个实用的功 能——异形窗口(异形窗体)。异形窗口的原理很简单,首先加载一张位图画刷作窗口背景,然后设 置透明色就可以使得窗口由矩形变成任意形状。这样使得窗口的显示更加美观。下面 先简单介绍下Win32 SDK方式创建窗口的流程(按《Windows程序设计》中的大体流程):1.设置 WNDCLASS类型的变量,这个变量将描述窗口的风格、窗口消息处理函数、程序图标、光标、窗口背景画刷等 待。2.使用RegisterClass将WNDCLASS类型的变量注册下。3.使用CreateWindow或 CreateWindowEx创建窗口,这里可以设置窗口的初始位置、初始大小、扩展属性等等。4.通过 ShowWindow和UpdateWindow将窗口显示出来。5.窗口显示完成后,在WinMain()函数中添加消息处理 :MSG msg;while (GetMessage(&msg, NULL, 0, 0)){ TranslateMessage(&msg); DispatchMessage (&msg);}通过这五步就完成了一个窗口的创建了。对于窗口消息函数,一般只要 在WM_DESTROY消息中调用下PostQuitMessage(0);其它的消息都可以使用默认消息处理函数DefWindowProc。对于异形窗口,可以在WM_CREATE即窗口初始化时设置好透明色就完成了窗口形状的改变,不过为了 支持鼠标对窗口的拖曳,还要在WM_LBUTTONDOWN消息中加入:PostMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);这样,异形窗口就可以在屏幕上像普通窗口一样的移动了。完整 的源代码如下所示(下载地址:http://download.csdn.net/download/morewindows/4966815):
// 异形窗口1窗口背景使用位图画刷再指定透明色//By MoreWindows-(http://blog.csdn.net/MoreWindows)#include <windows.h>const char szAppName[] = "异形窗口1 MoreWindows-(http://blog.csdn.net/MoreWindows)";/** 函数名称: GetWindowSize* 函数功能: 得到窗口的宽高* hwnd窗口句柄* pnWidth 窗口宽* pnHeight窗口高 */void GetWindowSize(HWND hwnd, int *pnWidth, int *pnHeight);/** 函数名称: InitBitmapWindow* 函数功能: 位图窗口初始化* hinstance 进程实例* hBitmap 位图句柄* nCmdshow显示方式-与ShowWindow函数的第二个参数相同 */BOOL InitBitmapWindow(HINSTANCE hinstance, HBITMAP hBitmap, int nCmdshow);// 位图窗口消息处理函数LRESULT CALLBACK BitmapWindowWndPrco(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParm);int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){//设置窗口背景画刷为图片画刷,再指定透明颜色即可以创建透明区域。HBITMAPhBitmap;hBitmap = (HBITMAP)LoadImage(NULL, "Kitty.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);if (hBitmap == NULL){MessageBox(NULL, "位图加载失败", "Error", MB_ICONERROR);return 0;}if (!InitBitmapWindow(hInstance, hBitmap, nCmdShow))return 0;MSG msg;while (GetMessage(&msg, NULL, 0, 0)){TranslateMessage(&msg);DispatchMessage(&msg);}DeleteObject(hBitmap);return msg.wParam;}BOOL InitBitmapWindow(HINSTANCE hinstance, HBITMAP hBitmap, int nCmdshow){HWND hwnd;WNDCLASS wndclass;wndclass.style = CS_VREDRAW | CS_HREDRAW;wndclass.lpfnWndProc = BitmapWindowWndPrco; wndclass.cbClsExtra= 0;wndclass.cbWndExtra= 0;wndclass.hInstance = hinstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);wndclass.hbrBackground = CreatePatternBrush(hBitmap);//位图画刷wndclass.lpszMenuName= NULL;wndclass.lpszClassName = szAppName;if (!RegisterClass(&wndclass)){MessageBox(NULL, "Program Need Windows NT!", "Error", MB_ICONERROR);return FALSE;}BITMAP bm;GetObject(hBitmap, sizeof(bm), &bm);hwnd = CreateWindowEx(WS_EX_TOPMOST,szAppName,szAppName, WS_POPUP,CW_USEDEFAULT, CW_USEDEFAULT, bm.bmWidth, bm.bmHeight,NULL,NULL,hinstance,NULL);if (hwnd == NULL)return FALSE;ShowWindow(hwnd, nCmdshow);UpdateWindow(hwnd);return TRUE;}LRESULT CALLBACK BitmapWindowWndPrco(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParm){static HDC s_hdcMem;static HBRUSH s_hBackBrush;switch (message){case WM_CREATE:{// 设置分层属性SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);// 设置透明色COLORREF clTransparent = RGB(0, 0, 0);SetLayeredWindowAttributes(hwnd, clTransparent, 0, LWA_COLORKEY);}return 0;case WM_KEYDOWN: switch (wParam){case VK_ESCAPE: //按下Esc键时退出SendMessage(hwnd, WM_DESTROY, 0, 0);return 0;}break;case WM_LBUTTONDOWN: //当鼠标左键点击时可以拖曳窗口PostMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0); return 0;case WM_DESTROY:PostQuitMessage(0);return 0;}return DefWindowProc(hwnd, message, wParam, lParm);}void GetWindowSize(HWND hwnd, int *pnWidth, int *pnHeight){RECT rc;GetWindowRect(hwnd, &rc);*pnWidth = rc.right - rc.left;*pnHeight = rc.bottom - rc.top;}