• 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 }

      运行效果:

      

  • 相关阅读:
    Windows驱动开发-设备读写方式
    Windows驱动开发-r3和r0通信
    Windows驱动开发-内核常用内存函数
    Windows驱动开发-DeviceIoControl函数参数dwIoControlCode
    Windows驱动开发-派遣函数格式
    Windows驱动开发-符号链接和设备名
    windows驱动不要签名
    git使用问题二删除远程仓库文件,本地保留不动
    git使用问题一新建本地仓库添加远程合并推送
    秦汉
  • 原文地址:https://www.cnblogs.com/csqtech/p/5892951.html
Copyright © 2020-2023  润新知