zoukankan      html  css  js  c++  java
  • 跟我一起玩Win32开发(7):多边形窗口

    通常情况下,窗口都是一个矩形,不过,调用下面这个函数,可以自定义窗口的形状。

    [cpp] view plain copy
     
    1. int SetWindowRgn(  
    2.     __in  HWND hWnd,  
    3.     __in  HRGN hRgn,  
    4.     __in  BOOL bRedraw  
    5.   );  


    第一个参数是窗口的句柄,第二个参数也是一个句柄——HRGN,一个多边形的区域,可以用CreatePolygonRgn函数来创建。第三个参数指定函数调用成功后是否重画窗口,如果窗口还没有显示,就不必了,如果窗口已经显示,可以考虑设为TRUE。

    我们创建用于显示窗口形状的区域句柄HRGN可以不显示用DeleteObject函数删除,因为MSDN上面有这么一句话:In particular, do not delete this region handle. The system deletes the region handle when it no longer needed.

    OK,理论知识准备好了,下面就趁温暖打铁,实战一下吧。

    接下来我们要做出这个模样的窗口。

    由于这个形状是固定的,只需要设置一次即可,所以,我不打算在处理WM_PAINT消息的时候来设置多边形区域,改为在CreateWindow成功后就设置,设置之后再ShowWindow。

    [cpp] view plain copy
     
    1. WNDCLASS wc = {};  
    2. wc.lpszClassName = L"MyApp";  
    3. wc.hbrBackground = CreateSolidBrush(RGB(254, 239, 180));  
    4. wc.lpfnWndProc = WindowProc;  
    5. wc.hInstance = hThisApp;  
    6. wc.style = CS_HREDRAW | CS_VREDRAW;  
    7. wc.hCursor = LoadCursor(hThisApp, IDC_ARROW);  
    8. RegisterClass(&wc);  
    9. HWND hwnd = CreateWindow(L"MyApp",  
    10.     L"我的应用",  
    11.     WS_POPUP,  
    12.     300,140,400,400,  
    13.     NULL,NULL,hThisApp,NULL);  
    14. if(hwnd == NULL)  
    15.     return -1;  
    16. POINT pts[5] =   
    17. {  
    18.     { 200, 0},   
    19.     { 0, 160 },  
    20.     { 120, 400 },  
    21.     { 285, 400 },  
    22.     { 400, 160 }  
    23. };  
    24.   
    25. HRGN rgn = CreatePolygonRgn(pts, 5, WINDING);  
    26. SetWindowRgn(hwnd, rgn, FALSE);  
    27. //DeleteObject(rgn);  
    28. ShowWindow(hwnd,nShow);  
    29.    //UpdateWindow(hwnd);  


    为了去掉标题栏和边框,我在CreateWindow的时候,使用WS_POPUP。

    不过,这窗口好像有点单调,于是,我想着能画些什么东西在上面,故也处理了WM_PAINT消息。

    [cpp] view plain copy
     
    1. case WM_PAINT:  
    2.     {  
    3.         PAINTSTRUCT ps;  
    4.         BeginPaint(hwnd, &ps);  
    5.         //创建红色的pen  
    6.         HPEN pen= CreatePen(PS_DASHDOTDOT, 1, RGB(255,0,0));  
    7.         //把pen选择到设备上下文  
    8.         auto orgObj = SelectObject(ps.hdc, pen);  
    9.         //第一部分  
    10.         POINT lnpts1[5] =   
    11.         {  
    12.             {200,50}, {180,360}, {220, 360}, {60,120}, {340,120}  
    13.         };  
    14.         BYTE bts1[5] =  {PT_MOVETO, PT_LINETO, PT_LINETO,  PT_MOVETO, PT_LINETO };  
    15.         PolyDraw(ps.hdc,lnpts1,bts1,5);  
    16.         // 第二部分  
    17.         POINT lnpts2[2] = { {200,50}, {220,360} };  
    18.         BYTE bts2[2] = { PT_MOVETO, PT_LINETO};  
    19.         PolyDraw(ps.hdc, lnpts2, bts2, 2);  
    20.         // 第三部分  
    21.         POINT lnpts3[2] = {{180,360}, {60,120}};  
    22.         BYTE bts3[2] = {PT_MOVETO, PT_LINETO};  
    23.         PolyDraw(ps.hdc, lnpts3, bts3, 2);  
    24.         // 第四部分  
    25.         POINT lnpts4[2] = {{220,360}, {340,120}};  
    26.         BYTE bts4[2] = {PT_MOVETO, PT_LINETO};  
    27.         PolyDraw(ps.hdc, lnpts4, bts4, 2);  
    28.         SelectObject(ps.hdc, orgObj);  
    29.         // 删除HPEN  
    30.         DeleteObject(pen);  
    31.         EndPaint(hwnd, &ps);  
    32.     }  
    33.     return 0;  


    画些线条上面,让窗口可视区域看上去不那么单调。

    下面是完整的代码清单。

    [cpp] view plain copy
     
    1. #include <Windows.h>  
    2.   
    3. LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);  
    4.   
    5. int WINAPI WinMain(HINSTANCE hThisApp,  
    6.                     HINSTANCE hPrevApp,  
    7.                     LPSTR cmdlint,  
    8.                     int nShow)  
    9. {  
    10.     WNDCLASS wc = {};  
    11.     wc.lpszClassName = L"MyApp";  
    12.     wc.hbrBackground = CreateSolidBrush(RGB(254, 239, 180));  
    13.     wc.lpfnWndProc = WindowProc;  
    14.     wc.hInstance = hThisApp;  
    15.     wc.style = CS_HREDRAW | CS_VREDRAW;  
    16.     wc.hCursor = LoadCursor(hThisApp, IDC_ARROW);  
    17.     RegisterClass(&wc);  
    18.     HWND hwnd = CreateWindow(L"MyApp",  
    19.         L"我的应用",  
    20.         WS_POPUP,  
    21.         300,140,400,400,  
    22.         NULL,NULL,hThisApp,NULL);  
    23.     if(hwnd == NULL)  
    24.         return -1;  
    25.     POINT pts[5] =   
    26.     {  
    27.         { 200, 0},   
    28.         { 0, 160 },  
    29.         { 120, 400 },  
    30.         { 285, 400 },  
    31.         { 400, 160 }  
    32.     };  
    33.   
    34.     HRGN rgn = CreatePolygonRgn(pts, 5, WINDING);  
    35.     SetWindowRgn(hwnd, rgn, FALSE);  
    36.     //DeleteObject(rgn);  
    37.     ShowWindow(hwnd,nShow);  
    38.     //UpdateWindow(hwnd);  
    39.   
    40.     // 消息循环  
    41.     MSG msg;  
    42.     while(GetMessage(&msg, NULL, 0, 0))  
    43.     {  
    44.         TranslateMessage(&msg);  
    45.         DispatchMessage(&msg);  
    46.     }  
    47.   
    48.     return 0;  
    49. }  
    50.   
    51. LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)  
    52. {  
    53.     switch(msg)  
    54.     {  
    55.     case WM_PAINT:  
    56.         {  
    57.             PAINTSTRUCT ps;  
    58.             BeginPaint(hwnd, &ps);  
    59.             //创建红色的pen  
    60.             HPEN pen= CreatePen(PS_DASHDOTDOT, 1, RGB(255,0,0));  
    61.             //把pen选择到设备上下文  
    62.             auto orgObj = SelectObject(ps.hdc, pen);  
    63.             //第一部分  
    64.             POINT lnpts1[5] =   
    65.             {  
    66.                 {200,50}, {180,360}, {220, 360}, {60,120}, {340,120}  
    67.             };  
    68.             BYTE bts1[5] =  {PT_MOVETO, PT_LINETO, PT_LINETO,  PT_MOVETO, PT_LINETO };  
    69.             PolyDraw(ps.hdc,lnpts1,bts1,5);  
    70.             // 第二部分  
    71.             POINT lnpts2[2] = { {200,50}, {220,360} };  
    72.             BYTE bts2[2] = { PT_MOVETO, PT_LINETO};  
    73.             PolyDraw(ps.hdc, lnpts2, bts2, 2);  
    74.             // 第三部分  
    75.             POINT lnpts3[2] = {{180,360}, {60,120}};  
    76.             BYTE bts3[2] = {PT_MOVETO, PT_LINETO};  
    77.             PolyDraw(ps.hdc, lnpts3, bts3, 2);  
    78.             // 第四部分  
    79.             POINT lnpts4[2] = {{220,360}, {340,120}};  
    80.             BYTE bts4[2] = {PT_MOVETO, PT_LINETO};  
    81.             PolyDraw(ps.hdc, lnpts4, bts4, 2);  
    82.             SelectObject(ps.hdc, orgObj);  
    83.             // 删除HPEN  
    84.             DeleteObject(pen);  
    85.             EndPaint(hwnd, &ps);  
    86.         }  
    87.         return 0;  
    88.     case WM_DESTROY:  
    89.         PostQuitMessage(0);  
    90.         return 0;  
    91.     }  
    92.     return DefWindowProc(hwnd, msg, wParam, lParam);  
    93. }  

    关于绘图方面的东东,后面会专门介绍,这里重点是说一下SetWindowRgn函数。

  • 相关阅读:
    [saiku] 系统登录成功后查询Cubes
    216. Combination Sum III
    215. Kth Largest Element in an Array
    214. Shortest Palindrome
    213. House Robber II
    212. Word Search II
    211. Add and Search Word
    210. Course Schedule II
    分硬币问题
    开始学习Python
  • 原文地址:https://www.cnblogs.com/weekbo/p/8681901.html
Copyright © 2011-2022 走看看