跳轉到內容

Windows 程式設計/GDI 和繪圖

來自華夏公益教科書

此頁面為Windows 程式設計書籍中的一個存根。您可以透過擴充套件它來提供幫助。


本頁將討論使用 Windows GDI 庫進行圖形和繪圖。

GDI 是 Windows 的原始圖形 API。但是,DirectX 圖形基礎架構 現在推薦用於其改進的 GPU 函式使用、alpha 混合抗鋸齒[1]

裝置上下文

[編輯 | 編輯原始碼]

裡面有什麼?以及它們的預設值

GDI 物件(每種型別一個)Windows 版本設定函式獲取函式
畫筆零寬度黑色畫筆(表示在任何縮放比例下 1 畫素寬度)2SelectObject(SelectPen、SelectBrush、SelectFont)GetCurrentObject
畫刷白色實心畫刷2
字型系統預設字型2
調色盤系統預設調色盤(見下文)3SelectPalette
顏色空間?4SetColorSpace
目標點陣圖(不適用於元檔案上下文)取決於建立 DC 的函式2SelectObject(SelectBrush)
裁剪區域取決於建立 DC 的函式2GetClipRgn(GetClipBox)
數字
對映模式、縮放和偏移量1 單位 = 1 畫素,原點 = 左/上2Get/Set MapMode、WindowOrgEx、WindowExtEx、ViewportOrgEx、ViewportExtEx
變換矩陣(旋轉、剪下、縮放、偏移量)平等4SetWorldTransform、ModifyTransformGetWorldTransform
文字顏色,也用於涉及 blt 操作的黑白黑色2SetTextColorGetTextColor
背景顏色,用於文字 / 網格畫刷 / 虛線背景和一些 blt 操作白色2SetBkColorGetBkColor
斜接限制(銳利多邊形角的裁剪)10.0F(線寬的十倍)4SetMiterLimitGetMiterLimit
畫刷原點(用於對齊圖案畫刷)0/02SetBrushOrgExGetBrushOrgEx
列舉和布林開關
啟用高階 GDI 函式4SetGraphicsModeGetGraphicsMode
複雜多邊形內或外(PolyFillMode)交替規則2SetPolyFillModeGetPolyFillMode
文字對齊頂部/左側2SetTextAlignGetTextAlign
文字 / 網格畫刷 / 虛線輸出是否具有不透明背景顏色有背景2SetBkModeGetBkMode
點陣圖在 blt 操作中如何拉伸?3SetStretchBltModeGetStretchBltMode
畫筆 / 畫刷和表面如何組合(布林運算)複製畫筆2SetROP2GetROP2
其他
路徑(準備好的線)空路徑4BeginPath、EndPath ...-
上下文堆疊2SaveDCRestoreDC

待續...

畫刷物件

[編輯 | 編輯原始碼]

Windows 使用畫刷來繪製顏色並使用預定義的圖案填充區域。畫刷的最小尺寸為 8X8 畫素,並且與畫筆類似,具有三個基本特徵:大小、圖案和顏色。由於其 8X8 畫素的最小尺寸,畫刷被認為具有圖案,而不是像畫筆那樣的樣式。圖案可以是實色、網格、對角線或任何其他使用者定義的組合,甚至是點陣圖圖案。

case WM_PAINT:
{
    /* This will paint a red rectangle */
    HDC holdBrush; 
    HDC hdc = BeginPaint(hwnd, &ps);
    HBRUSH hBrush = CreateSolidBrush(RGB(255,0,0));

    holdBrush = SelectObject(hdc, hBrush);
    Rectangle(hdc, 10, 10, 100, 100); 
    DeleteObject(hBrush);
    /* Memory management has been omitted for brevity */
    EndPaint(hwnd, &ps); 
    break; 
}

畫刷物件背後是什麼?

在建立時,請參見 LOGBRUSH 結構 修改
顏色(RGB 顏色,可以在實現時進行抖動) SetDCBrushColor
樣式(實心、網格或點陣圖) -
點陣圖(對於點陣圖樣式) -
實現時的隱藏欄位
引用裝置上下文(跟蹤實現是否仍然有效) UnrealizeObject
裝置相關,可能是抖動的點陣圖,通常為 8x8 尺寸 -

請注意,點陣圖圖案畫刷的行為與網格畫刷不同,即使點陣圖看起來像網格。網格畫刷是透明的,而點陣圖畫刷是不透明的。如果使用黑白點陣圖,黑色將被替換為裝置上下文的文字顏色,白色將被替換為背景顏色。(這正是 BitBlt() 的行為。)SetBkMode() 不會起作用。但是,DC 的 ROP2 會起作用。

畫筆物件

[編輯 | 編輯原始碼]

畫筆用於建立繪製的形狀周圍的邊框。

可見欄位,請參見 LOGPEN 結構 Windows 版本 修改
寬度,以水平(!) 邏輯單位表示,0 = 1 畫素 2 -
樣式(實心或某種點線) 2 -
使用者點線樣式(對於使用者選擇的樣式) 4 -
顏色 2 SetDCPenColor
畫刷(內容:見上文) 4 -
幾何/裝飾標誌 4 -
提示如何繪製線端 4 -
提示如何繪製線連線 4 -
隱藏欄位
引用裝置上下文(跟蹤其他隱藏欄位的有效性) 2 UnrealizeObject?
以裝置畫素表示的寬度 2 -
給定顏色的調色盤索引 2 -
用於填充寬線的裝置相關點陣圖 2 -

導致寬度大於 1 裝置畫素(而不是邏輯單位)的線將作為具有繞線規則的多邊形繪製。線顏色永遠不會進行抖動,除非使用具有實心畫刷的 ExtCreatePen。

字型物件

[編輯 | 編輯原始碼]

字型用於以各種樣式和尺寸顯示文字和符號。Windows 2(非常基本)、3.1(引入 TrueType)和 4+(Unicode;世界變換旋轉和映象;傾斜度可能與旋轉不同)之間的字型管理存在內部較大差異。

請參見 LOGFONT 結構以瞭解可見欄位。

隱藏欄位包括

  • 引用裝置上下文
  • 裝置相關點陣圖字體表示

因此,將字型選擇到裝置上下文(SelectObject)可能很耗時,尤其是對於大型亞洲字型和大型字型尺寸,需要從 TrueType 模板中“繪製”所有字形到點陣圖中。此外,與所有 GDI 物件一樣,最好不要在一個上下文之間選擇一個物件,因為使隱藏檔案失效可能是一個耗時的過程。請注意,任何 GDI 物件都不能選擇到多個 DC 中。

基本繪圖

[編輯 | 編輯原始碼]

在 Windows 中,繪圖通常由 WM_PAINT 訊息處理。以下是繪製紅色正方形的示例

case WM_PAINT:
{
	PAINTSTRUCT ps;
	BeginPaint(hwnd, &ps);
	
	// RECT defines the upper-left and lower-right corners of a rectangle
	RECT rectangle = {50, 50, 250, 250};
	HBRUSH hbr = CreateSolidBrush(RGB(125, 0, 0));
	
	FillRect(ps.hdc, &rectangle, hbr);
	
	DeleteObject(hbr);
	EndPaint(hwnd, &ps);
}
break;

首先,我們建立 PAINTSTRUCT 變數 ps。這是一個包含有關繪畫操作的資訊的資料結構。下一行呼叫 BeginPaint。這將初始化 ps,然後用相關資訊填充它。對於此示例,我們只需要 pshdc 成員。這是一個指向我們視窗裝置上下文的控制代碼。接下來,我們建立一個矩形。這包含我們要繪製此矩形的左上角和右下角座標。座標相對於視窗客戶區的左上角。我們還必須建立一個畫刷,否則 Windows 將不知道要使用什麼顏色來繪製矩形。最後,我們呼叫 FillRect,並傳遞引數 ps.hdc、指向 rectangle 的指標和 hbr(我們的畫刷)。這會將矩形直接繪製到我們視窗的裝置上下文,然後從那裡繪製到螢幕上。在每次繪畫操作後,都需要清理我們使用的任何 GDI 物件,在本例中為 hbrps

高階提示

[編輯 | 編輯原始碼]

由於 Windows 應該響應 WM_PAINT 和 WM_PRINTCLIENT,因此編寫 WM_PAINT 處理程式的一般規則如下

case WM_PRINTCLIENT: OnPaint((HDC)wParam, NULL); break;
case WM_PAINT: {
  PAINTSTRUCT ps;
  BeginPaint(hwnd, &ps);
  OnPaint(ps.hdc, &ps.rcPaint);	// It's a good idea to manage the update area. Other PAINTSTRUCT fields are of less usefulness.
  EndPaint(hwnd, &ps);
}break;
// Somewhere else
void OnPaint(HDC dc, RECT* rcUpdate) {
 ...
}

元檔案

[編輯 | 編輯原始碼]

下一章

[編輯 | 編輯原始碼]
  1. QuinnRadich. "Windows 圖形架構概述 - Win32 應用". learn.microsoft.com. 檢索於 2023-04-11.
華夏公益教科書