• 跟我一起玩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函数。

  • 相关阅读:
    Spark Streaming 应用实例
    Spark Streaming 应用实例
    利用 Spark Streaming 构建高效健壮的流数据计算系统注意事项
    利用 Spark Streaming 构建高效健壮的流数据计算系统注意事项
    Kafka 集群搭建步骤
    Kafka 集群搭建步骤
    php微信开发-tp5下验证服务器的代码
    php微信公众号开发,入门篇(实现了关注公众号发送欢迎信息,发关键词自回复)
    【php技术】PHP错误类型和屏蔽方法
    自制在线富文本编辑器,精简完整版
  • 原文地址:https://www.cnblogs.com/weekbo/p/8681901.html
Copyright © 2020-2023  润新知