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

Win32 GDI+ 繪圖入門:CreateWindow 雙緩沖、Graphics 對象、筆刷繪製

     編輯:C++ 入門

項目結構

標準 Win32 窗口程序 + GDI+ 初始化/關閉,在 WM_PAINT 中使用 Graphics 繪製矩形、線條、圖片。

關鍵代碼片段

1. GDI+ 初始化與關閉

ULONG_PTR gdiplusToken;
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
// ... 窗口循環 ...
GdiplusShutdown(gdiplusToken);

2. 窗口類註冊與創建

WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_HREDRAW|CS_VREDRAW, WndProc,
    0, 0, hInstance, LoadIcon(NULL,IDI_APPLICATION),
    LoadCursor(NULL,IDC_ARROW), (HBRUSH)(COLOR_WINDOW+1),
    NULL, L"GDIPlusWindow", NULL };
RegisterClassEx(&wc);

HWND hwnd = CreateWindowEx(0, L"GDIPlusWindow", L"GDI+ Demo",
    WS_OVERLAPPEDWINDOW, 100, 100, 600, 400, NULL, NULL, hInstance, NULL);

3. WM_PAINT 中繪圖(單緩沖)

case WM_PAINT: {
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hwnd, &ps);
    Graphics graphics(hdc); // 包裝 HDC
    
    // 紅筆畫線
    Pen pen(Color(255, 255, 0, 0)); // ARGB
    graphics.DrawLine(&pen, 0, 0, 500, 500);
    
    // 實心刷填矩形
    SolidBrush brush(Color(255, 0, 255, 0)); // 綠色
    graphics.FillRectangle(&brush, 100, 100, 200, 150);
    
    // 繪製圖片
    Image img(L"test.png");
    graphics.DrawImage(&img, 300, 100);
    
    EndPaint(hwnd, &ps);
    break;
}

4. 雙緩沖防閃爍(推薦)

case WM_PAINT: {
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hwnd, &ps);
    RECT rc; GetClientRect(hwnd, &rc);
    int w = rc.right - rc.left, h = rc.bottom - rc.top;
    
    // 創建兼容 DC 和位圖
    HDC memDC = CreateCompatibleDC(hdc);
    HBITMAP memBmp = CreateCompatibleBitmap(hdc, w, h);
    HBITMAP oldBmp = (HBITMAP)SelectObject(memDC, memBmp);
    
    // 在內存 DC 繪圖
    Graphics memG(memDC);
    memG.Clear(Color::White);
    // ... 繪圖操作 ...
    
    // 一次性複製到屏幕
    BitBlt(hdc, 0, 0, w, h, memDC, 0, 0, SRCCOPY);
    
    // 清理
    SelectObject(memDC, oldBmp);
    DeleteObject(memBmp);
    DeleteDC(memDC);
    EndPaint(hwnd, &ps);
    break;
}

5. 擴展:WM_NCHITTEST 自定義標題欄提示

case WM_NCHITTEST: {
    POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
    ScreenToClient(hwnd, &pt);
    LRESULT hit = DefWindowProc(hwnd, message, wParam, lParam);
    const wchar_t* tips[] = {
        [HTCLIENT]=L"客戶區", [HTCAPTION]=L"標題欄",
        [HTCLOSE]=L"關閉按鈕", [HTMAXBUTTON]=L"最大化",
        [HTMINBUTTON]=L"最小化", [HTLEFT]=L"左邊框",
        [HTRIGHT]=L"右邊框", [HTTOP]=L"上邊框",
        [HTBOTTOM]=L"下邊框", [HTTOPLEFT]=L"左上角",
        [HTTOPRIGHT]=L"右上角", [HTBOTTOMLEFT]=L"左下角",
        [HTBOTTOMRIGHT]=L"右下角", [HTSYSMENU]=L"系統菜單"
    };
    if (hit >= HTCLIENT && hit <= HTBOTTOMRIGHT && tips[hit])
        SetWindowText(hwnd, tips[hit]);
    return hit;
}

編譯配置

  • 鏈接 gdiplus.lib:專案屬性 → 鏈接器 → 輸入 → 附加依賴項
  • 包含 gdiplus.h,命名空間 using namespace Gdiplus;
  • 字符集:Unicode (VS 默認)

常見問題

  1. GDI+ 未初始化:必須在創建 Graphics 前調用 GdiplusStartup
  2. 圖片不顯示:路徑相對工作目錄,建議用絕對路徑或資源嵌入
  3. 字體模糊:graphics.SetTextRenderingHint(TextRenderingHintAntiAliasGridFit)
  4. 高 DPI 模糊:Manifest 聲明 dpiAware 或 SetProcessDpiAwareness
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved