首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

Win32 開發入門(7):非矩形視窗——SetWindowRgn 多邊形視窗實作

     編輯:關於C++

SetWindowRgn 改變視窗形狀

預設視窗為矩形,呼叫 SetWindowRgn 可設定任意形狀區域:


int SetWindowRgn(HWND hWnd, HRGN hRgn, BOOL bRedraw);
  • hRgn:由 CreatePolygonRgn 建立的多邊形區域控制代碼
  • bRedraw:視窗已顯示時設 TRUE 觸發重繪
  • 注意:區域控制代碼交由系統管理,**不可** 自行呼叫 DeleteObject

建立五邊形視窗範例

視窗類別與建立

使用 WS_POPUP 移除標題列與邊框,建立視窗後立即設定區域:


WNDCLASS wc = {};
wc.lpszClassName = L"MyApp";
wc.hbrBackground = CreateSolidBrush(RGB(254,239,180));
wc.lpfnWndProc = WindowProc;
wc.hInstance = hThisApp;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.hCursor = LoadCursor(hThisApp, IDC_ARROW);
RegisterClass(&wc);

HWND hwnd = CreateWindow(L"MyApp", L"我的應用", WS_POPUP,
                         300, 140, 400, 400, NULL, NULL, hThisApp, NULL);

POINT pts[5] = {{200,0}, {0,160}, {120,400}, {285,400}, {400,160}};
HRGN rgn = CreatePolygonRgn(pts, 5, WINDING);
SetWindowRgn(hwnd, rgn, FALSE); // 視窗尚未顯示,bRedraw=FALSE
ShowWindow(hwnd, nShow);

五邊形視窗外觀

WM_PAINT 繪製裝飾線條

使用 PolyDraw 繪製多段連續/不連續線條:


case WM_PAINT: {
    PAINTSTRUCT ps; BeginPaint(hwnd, &ps);
    HPEN pen = CreatePen(PS_DASHDOTDOT, 1, RGB(255,0,0));
    auto orgObj = SelectObject(ps.hdc, pen);
    
    // 定義點座標與操作類型 (PT_MOVETO/PT_LINETO)
    POINT lnpts1[5] = {{200,50}, {180,360}, {220,360}, {60,120}, {340,120}};
    BYTE bts1[5] = {PT_MOVETO, PT_LINETO, PT_LINETO, PT_MOVETO, PT_LINETO};
    PolyDraw(ps.hdc, lnpts1, bts1, 5);
    
    // 其他線段...
    SelectObject(ps.hdc, orgObj);
    DeleteObject(pen);
    EndPaint(hwnd, &ps);
} return 0;

完整程式碼清單


#include <Windows.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hThisApp, HINSTANCE hPrevApp, LPSTR cmdlint, int nShow) {
    WNDCLASS wc = {};
    wc.lpszClassName = L"MyApp";
    wc.hbrBackground = CreateSolidBrush(RGB(254,239,180));
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hThisApp;
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.hCursor = LoadCursor(hThisApp, IDC_ARROW);
    RegisterClass(&wc);
    
    HWND hwnd = CreateWindow(L"MyApp", L"我的應用", WS_POPUP,
                             300, 140, 400, 400, NULL, NULL, hThisApp, NULL);
    if (hwnd == NULL) return -1;
    
    POINT pts[5] = {{200,0}, {0,160}, {120,400}, {285,400}, {400,160}};
    HRGN rgn = CreatePolygonRgn(pts, 5, WINDING);
    SetWindowRgn(hwnd, rgn, FALSE);
    ShowWindow(hwnd, nShow);
    
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
        case WM_PAINT: {
            PAINTSTRUCT ps; BeginPaint(hwnd, &ps);
            HPEN pen = CreatePen(PS_DASHDOTDOT, 1, RGB(255,0,0));
            auto orgObj = SelectObject(ps.hdc, pen);
            
            POINT lnpts1[5] = {{200,50}, {180,360}, {220,360}, {60,120}, {340,120}};
            BYTE bts1[5] = {PT_MOVETO, PT_LINETO, PT_LINETO, PT_MOVETO, PT_LINETO};
            PolyDraw(ps.hdc, lnpts1, bts1, 5);
            
            POINT lnpts2[2] = {{200,50}, {220,360}};
            BYTE bts2[2] = {PT_MOVETO, PT_LINETO};
            PolyDraw(ps.hdc, lnpts2, bts2, 2);
            
            POINT lnpts3[2] = {{180,360}, {60,120}};
            BYTE bts3[2] = {PT_MOVETO, PT_LINETO};
            PolyDraw(ps.hdc, lnpts3, bts3, 2);
            
            POINT lnpts4[2] = {{220,360}, {340,120}};
            BYTE bts4[2] = {PT_MOVETO, PT_LINETO};
            PolyDraw(ps.hdc, lnpts4, bts4, 2);
            
            SelectObject(ps.hdc, orgObj);
            DeleteObject(pen);
            EndPaint(hwnd, &ps);
        } return 0;
        case WM_DESTROY:
            PostQuitMessage(0); return 0;
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}

重點整理

  • SetWindowRgn + CreatePolygonRgn 實作非矩形視窗
  • WS_POPUP 移除標題列與邊框,配合弧形區域更自然
  • 區域控制代碼 **不可** 自行刪除,系統會自動管理
  • PolyDraw 結合點陣列與操作碼陣列 (PT_MOVETO/PT_LINETO) 高效繪製複雜線條
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved