1.不规则窗口
如果想改变不规则窗口的大小怎么做呢?用鼠标已经没办法了,因为看不到边框了。
(1)通过工具将图片缩放后,在执行程序 - 虽然可以,但是太麻烦
(2)在绘制窗口背景时,使用StretchBlt函数来缩放图片
2.不规则窗口的要素
WS_EX_LAYERED属性、以位图为窗口背景(自己贴图或位图画刷)、指定透明色
1 HBITMAP g_hBitmap; 2 3 void GetWindowSize(HWND hWnd, int *pnWidth, int *pnHeight) 4 { 5 RECT rc = { 0 }; 6 GetWindowRect(hWnd, &rc); 7 *pnWidth = rc.right - rc.left; 8 *pnHeight = rc.bottom - rc.top; 9 } 10 11 LRESULT CALLBACK BitmapWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParm) 12 { 13 static HDC s_hdcMem; //放置缩放后的位图 14 switch (message) 15 { 16 case WM_CREATE: 17 //设置分层属性 18 SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED); 19 //设置透明色 20 COLORREF clTransparent = RGB(0, 0, 0); 21 SetLayeredWindowAttributes(hWnd, clTransparent, 0, LWA_COLORKEY); 22 //缩放位图 23 //加载位图到hdcTemp中 24 HDC hdc = GetDC(hWnd); 25 HDC hdcTemp = CreateCompatibleDC(hdc); 26 SelectObject(hdcTemp, g_hBitmap); 27 //得到窗口大小 28 int nWidth, nHeight; 29 GetWindowSize(hWnd, &nWidth, &nHeight); 30 //创建与窗口大小相等且能容纳位图的HDC 31 s_hdcMem = CreateCompatibleDC(hdc); 32 HBITMAP hbmp = CreateCompatibleBitmap(hdc, nWidth, nHeight); 33 SelectObject(s_hdcMem, hbmp); 34 //将原位图缩放到窗口大小 35 BITMAP bm; 36 GetObject(g_hBitmap, sizeof(bm), &bm); 37 StretchBlt(s_hdcMem, 0, 0, nWidth, nHeight, hdcTemp, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); 38 //释放资源 39 DeleteDC(hdcTemp); 40 ReleaseDC(hWnd, hdc); 41 return 0; 42 case WM_KEYDOWN: 43 if (VK_ESCAPE == wParam) 44 { 45 SendMessage(hWnd, WM_DESTROY, 0, 0); 46 return TRUE; 47 } 48 break; 49 case WM_LBUTTONDOWN: 50 //当鼠标左键点击时可以拖曳窗口 51 PostMessage(hWnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0); 52 return TRUE; 53 case WM_ERASEBKGND: //在窗口背景中直接贴图 54 HDC hdc = (HDC)wParam; 55 int nWidth, nHeight; 56 GetWindowSize(hWnd, &nWidth, &nHeight); 57 BitBlt(hdc, 0, 0, nWidth, nHeight, s_hdcMem, 0, 0, SRCCOPY); 58 return TRUE; 59 case WM_DESTROY: 60 DeleteDC(s_hdcMem); 61 PostQuitMessage(0); 62 return 0; 63 } 64 return DefWindowProc(hWnd, message, wParam, lParm); 65 } 66 67 BOOL InitBitmapWindow(HINSTANCE hInstance, int nWidth, int nHeight, int nCmdShow) 68 { 69 WNDCLASS wndclass = { 0 }; 70 wndclass.cbClsExtra = 0; 71 wndclass.cbWndExtra = 0; 72 wndclass.hInstance = hInstance; 73 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 74 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); 75 wndclass.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);//窗口背影画刷为空 76 wndclass.lpfnWndProc = BitmapWindowProc; 77 wndclass.lpszMenuName = NULL; 78 wndclass.lpszClassName = L"Hello"; 79 wndclass.style = CS_VREDRAW | CS_HREDRAW; 80 81 if (!RegisterClass(&wndclass)) 82 { 83 MessageBox(NULL, L"Program Need Windows NT!", L"Error", MB_ICONERROR); 84 return FALSE; 85 } 86 HWND hWnd = CreateWindowEx(WS_EX_TOPMOST, L"Hello", L"HelloKitty", 87 WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT, 88 nWidth,nHeight,NULL,NULL,hInstance,NULL); 89 if (hWnd == NULL) 90 { 91 return FALSE; 92 } 93 ShowWindow(hWnd, nCmdShow); 94 UpdateWindow(hWnd); 95 return TRUE; 96 } 97 98 int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) 99 { 100 //先创建一个无背影画刷窗口, 101 //然后在WM_CREATE中并指定透明颜色, 缩放位图后加载至s_hdcMem中. 102 //最后在WM_ERASEBKGND中用s_hdcMem贴图即可 103 g_hBitmap = (HBITMAP)LoadImage(NULL, L"kitty.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); 104 if (g_hBitmap == NULL) 105 { 106 MessageBox(NULL, L"位图加载失败", L"Error", MB_ICONERROR); 107 return 0; 108 } 109 //设置异形窗口大小 110 BITMAP bm; 111 GetObject(g_hBitmap, sizeof(bm), &bm); 112 int nWindowWidth = bm.bmWidth; 113 int nWindowHeight = bm.bmHeight + 100; //拉高100高度 114 if (!InitBitmapWindow(hInstance, nWindowWidth, nWindowHeight, nCmdShow)) 115 { 116 return -1; 117 } 118 MSG msg; 119 while (GetMessage(&msg, NULL, 0, 0)) 120 { 121 TranslateMessage(&msg); 122 DispatchMessage(&msg); 123 } 124 DeleteObject(g_hBitmap); 125 return 0; 126 }
运行效果: