zoukankan      html  css  js  c++  java
  • Windows界面编程第三篇 异形窗体 普通版

     上一篇《Windows界面编程第二篇 半透明窗体》介绍了先使用SetWindowLong为窗体加上WS_EX_LAYERED属性,再使用SetLayeredWindowAttributes调整窗体的透明度。本篇将使用这二个函数来完成另一个实用的功能——异形窗口(异形窗体)。

    异形窗口的原理很简单,首先加载一张位图画刷作窗口背景,然后设置透明色就可以使得窗口由矩形变成任意形状。这样使得窗口的显示更加美观。

        下面先简单介绍下Win32 SDK方式创建窗口的流程(按《Windows程序设计》中的大体流程):

    1.设置WNDCLASS类型的变量,这个变量将描述窗口的风格、窗口消息处理函数、程序图标、光标、窗口背景画刷等待。

    2.使用RegisterClassWNDCLASS类型的变量注册下。

    3.使用CreateWindowCreateWindowEx创建窗口,这里可以设置窗口的初始位置、初始大小、扩展属性等等。

    4.通过ShowWindowUpdateWindow将窗口显示出来。

    5.窗口显示完成后,在WinMain()函数中添加消息处理:   

           MSGmsg;

          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. //   异形窗口1  窗口背景使用位图画刷再指定透明色 
    2. //By MoreWindows-(http://blog.csdn.net/MoreWindows) 
    3. #include <windows.h> 
    4.  
    5. constchar szAppName[] = "异形窗口1 MoreWindows-(http://blog.csdn.net/MoreWindows)"
    6.  
    7. /*
    8. * 函数名称: GetWindowSize
    9. * 函数功能: 得到窗口的宽高
    10. * hwnd      窗口句柄
    11. * pnWidth   窗口宽
    12. * pnHeight  窗口高
    13. */ 
    14. void GetWindowSize(HWND hwnd,int *pnWidth, int *pnHeight); 
    15.  
    16.  
    17. /*
    18. * 函数名称: InitBitmapWindow
    19. * 函数功能: 位图窗口初始化
    20. * hinstance 进程实例
    21. * hBitmap   位图句柄
    22. * nCmdshow  显示方式-与ShowWindow函数的第二个参数相同
    23. */ 
    24. BOOL InitBitmapWindow(HINSTANCE hinstance,HBITMAP hBitmap, int nCmdshow); 
    25.  
    26. // 位图窗口消息处理函数 
    27. LRESULT CALLBACK BitmapWindowWndPrco(HWND hwnd,UINT message, WPARAM wParam,LPARAM lParm); 
    28.  
    29.  
    30. int APIENTRY WinMain(HINSTANCE hInstance, 
    31.                     HINSTANCE hPrevInstance, 
    32.                      LPSTR     lpCmdLine, 
    33.                     int       nCmdShow) 
    34.     //设置窗口背景画刷为图片画刷,再指定透明颜色即可以创建透明区域。 
    35.     HBITMAP  hBitmap; 
    36.     hBitmap = (HBITMAP)LoadImage(NULL,"Kitty.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); 
    37.     if (hBitmap == NULL) 
    38.     { 
    39.         MessageBox(NULL, "位图加载失败", "Error", MB_ICONERROR); 
    40.         return 0; 
    41.     } 
    42.     if (!InitBitmapWindow(hInstance, hBitmap, nCmdShow)) 
    43.         return 0; 
    44.  
    45.     MSG msg; 
    46.     while (GetMessage(&msg, NULL, 0, 0)) 
    47.     { 
    48.         TranslateMessage(&msg); 
    49.         DispatchMessage(&msg); 
    50.     } 
    51.     DeleteObject(hBitmap); 
    52.  
    53.     return msg.wParam; 
    54.  
    55.  
    56. BOOL InitBitmapWindow(HINSTANCE hinstance,HBITMAP hBitmap, int nCmdshow) 
    57.     HWND hwnd; 
    58.     WNDCLASS wndclass; 
    59.      
    60.     wndclass.style       = CS_VREDRAW | CS_HREDRAW; 
    61.     wndclass.lpfnWndProc = BitmapWindowWndPrco;  
    62.     wndclass.cbClsExtra  = 0; 
    63.     wndclass.cbWndExtra  = 0; 
    64.     wndclass.hInstance   = hinstance;    
    65.     wndclass.hIcon       = LoadIcon(NULL, IDI_APPLICATION); 
    66.     wndclass.hCursor     = LoadCursor(NULL, IDC_ARROW); 
    67.     wndclass.hbrBackground = CreatePatternBrush(hBitmap);//位图画刷 
    68.     wndclass.lpszMenuName  = NULL; 
    69.     wndclass.lpszClassName = szAppName; 
    70.      
    71.     if (!RegisterClass(&wndclass)) 
    72.     { 
    73.         MessageBox(NULL, "Program Need Windows NT!", "Error", MB_ICONERROR); 
    74.         return FALSE; 
    75.     } 
    76.  
    77.     BITMAP bm; 
    78.     GetObject(hBitmap,sizeof(bm), &bm); 
    79.     hwnd = CreateWindowEx(WS_EX_TOPMOST, 
    80.                         szAppName, 
    81.                         szAppName,  
    82.                         WS_POPUP, 
    83.                         CW_USEDEFAULT,  
    84.                         CW_USEDEFAULT,  
    85.                         bm.bmWidth,  
    86.                         bm.bmHeight, 
    87.                         NULL, 
    88.                         NULL, 
    89.                         hinstance, 
    90.                         NULL); 
    91.     if (hwnd == NULL) 
    92.         return FALSE; 
    93.      
    94.     ShowWindow(hwnd, nCmdshow); 
    95.     UpdateWindow(hwnd); 
    96.      
    97.     return TRUE; 
    98.  
    99. LRESULT CALLBACK BitmapWindowWndPrco(HWND hwnd,UINT message, WPARAM wParam,LPARAM lParm) 
    100.     static HDC s_hdcMem; 
    101.     staticHBRUSH s_hBackBrush; 
    102.      
    103.     switch (message) 
    104.     { 
    105.     case WM_CREATE: 
    106.         { 
    107.             // 设置分层属性 
    108.             SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); 
    109.             // 设置透明色 
    110.             COLORREF clTransparent = RGB(0, 0, 0); 
    111.             SetLayeredWindowAttributes(hwnd, clTransparent, 0, LWA_COLORKEY); 
    112.         } 
    113.         return 0; 
    114.  
    115.          
    116.     case WM_KEYDOWN:  
    117.         switch (wParam) 
    118.         { 
    119.         case VK_ESCAPE: //按下Esc键时退出 
    120.             SendMessage(hwnd, WM_DESTROY, 0, 0); 
    121.             return 0; 
    122.         } 
    123.         break
    124.      
    125.  
    126.     case WM_LBUTTONDOWN: //当鼠标左键点击时可以拖曳窗口 
    127.         PostMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);  
    128.         return 0; 
    129.  
    130.  
    131.     case WM_DESTROY: 
    132.         PostQuitMessage(0); 
    133.         return 0; 
    134.     } 
    135.     return DefWindowProc(hwnd, message, wParam, lParm); 
    136.  
    137. void GetWindowSize(HWND hwnd,int *pnWidth, int *pnHeight) 
    138.     RECT rc; 
    139.     GetWindowRect(hwnd, &rc); 
    140.     *pnWidth = rc.right - rc.left; 
    141.     *pnHeight = rc.bottom - rc.top; 

    运行结果如下:

    现在总结下异形窗口的创建,先通过创建位图画刷来做窗口的背景画刷,再通过SetWindowLong为窗体加上WS_EX_LAYERED属性,然后使用SetLayeredWindowAttributes指定窗口的透明色来完成窗口形状的调整。为了支持鼠标的拖曳,在WM_LBUTTONDOWN消息中作了特殊处理,使得异形窗口可以像普通窗口一样在屏幕上移动。

    本篇程序中的异形窗口的大小是无法设置的,只能和位图一样。下一篇《Windows界面编程第四篇 异形窗体 高富帅版》将介绍窗口大小可以指定的异形窗口。欢迎继续浏览。

  • 相关阅读:
    lambda Join /Group by/ Contains
    PDF ITextSharp
    sql server基本流程语句
    easyui DateTimeBox OK
    Axuer 网页
    蓝桥杯- 煤球数目-java
    蓝桥杯-有奖猜谜-java
    蓝桥杯-打印大X-java
    蓝桥杯- 移动距离-java
    蓝桥杯-加法变乘法-java
  • 原文地址:https://www.cnblogs.com/jinsedemaitian/p/5589196.html
Copyright © 2011-2022 走看看