預設視窗為矩形,呼叫 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);

使用 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) 高效繪製複雜線條