4.不规则窗口(二)

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 }

  运行效果:

  

原文地址:https://www.cnblogs.com/csqtech/p/5892951.html