Windows中的GDI


Windows 圖形設備接口(Graphics Device Interface, GDI)使應用程序能夠在視頻顯示器使用圖形和格式化文本。

1. 設備環境

設備環境是Windows中內部使用的數據結構,它定義了GDI函數在顯示設備特定區域的工作方式。要想在某個區域輸出文字或繪製圖形,必須先獲取該區域的設備句柄。
首先看下面的部分代碼:

case WM_PAINT:
{
	PAINTSTRUCT ps;
	HDC hdc = ::BeginPaint(hwnd, &ps);
	::TextOut(hdc, 0, 0, TEXT("Hello GDI"), strlen("Hello GDI"));
	::EndPaint(hwnd, &ps);
	return 0;
}

表示在客戶區繪製文字,Hello GDI
如果不想在 WM_PAINT 消息中繪製,可以使用函數 GetDC 函數

case WM_LBUTTONDOWN:
{
	HDC hdc = ::GetDC(hwnd);
	::SetTextColor(hdc, RGB(255, 0, 0));
	::SetBkColor(hdc, RGB(0, 255, 255));
	::TextOut(hdc, 0, 20, TEXT("Hello GDI"), strlen("Hello GDI"));
	::ReleaseDC(hwnd, hdc);
	return 0;
}

表示按下鼠標時在座標 (0,20)的位置繪製 Hello GDI,下面說一下 GetDCBeginPaint 函數的區別

  • BeginPaint 函數獲取窗口客戶區無效區域的設備句柄。
  • GetDC 函數獲取客戶區整個區域的設備句柄。不只是客戶區的無效區域。當然,GetDCReleaseDC 不能使客戶區中任何可能無效的區域有效。

當響應鼠標點擊函數的時候,DC 結構成員的設置並沒有被保存下來,下一次使用GDI函數的時候設備環境仍然使用Windows的默認值,要想讓Windows每次對DC的設置保存下來,只要在註冊窗口時,向 WNDCLASSEX 的結構的 style 成員添加一個 CS_OWNDC 標誌就可以了。

wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;

顏色使用宏 RGB(r, g, b) 表示
GetRValueGetGValueGetBValue 可以從 COLORREF 獲取各分量值

使用函數 SetPixel 函數設置一個像素值

COLORREF SetPixel (HDC hdc, int X, int Y, COLORREF crColor)

使用函數 GetPixel 獲取獲取一個像素值

COLORREF GetPixel(HDC hdc, int nXPos, int nYPos)

2. 繪製線條

繪製線條的函數有繪製單條直線 LineTo 、繪製多條直線 PolylinePolylineTo 、畫貝塞爾曲線 PolyBezierPolyBezierTo 、繪製弧線 ArcArcTo

繪製直線只需要指定開始座標,然後以直線的另一個座標爲參數調用 LineTo 函數,下面時繪製一條座標從(0, 0)到(100,100)的直線

::MoveToEx(hdc, 0, 0, nullptr);
::LineTo(hdc, 100, 100);

DC的數據結構中有一個當前點,LineTo 函數就是從當前點繪製一條直線到參數指定點,並把這個點設置爲新的當前點。如果要設置當前點的位置可以使用函數 MoveToEx

BOOL MoveToEx(HDC hdc, int X, int Y, LPPOINT lpPoint)

DC 結構還有一個畫筆句柄,每次繪畫時,GDI 函數都會使用此句柄設置畫筆。畫筆對象規定了線條的寬度、顏色和風格。
要想改變DC中默認的畫筆,可以使用Windows中預定義的畫筆對象,也可以創建新的畫筆對象。預定義的畫筆對象僅有三種 BLACK_PENWHITE_PENNULL_PEN 分別爲黑色畫筆、白色畫筆和空畫筆。

HPEN hPen = (HPEN)::GetStockObject(BLACK_PEN);
HPEN oldPen = (HPEN)::SelectObject(hdc, hPen);

使用函數 GetStockObject 函數選擇好對象句柄後,就可以使用函數 SelectObject 將對象選入DC中。
使用函數 CreatePen 函數可以創建自定義畫筆對象

HPEN CreatePen(int fnPenStyle, int nWidth, COLORREF crColor)

  • fnPenStyle: 畫筆得風格,取值有PS_DOLIDPS_DASHPS_DOTPS_DASHDOT
  • nWdith: 畫筆得寬度
  • color: 畫筆得顏色

下面代碼繪製一條直線:

case WM_PAINT:
{
	PAINTSTRUCT ps;
	HDC hdc = ::BeginPaint(hwnd, &ps);
	//::TextOut(hdc, 0, 0, TEXT("Hello GDI"), strlen("Hello GDI"));

	HPEN nPen = ::CreatePen(PS_SOLID, 1, RGB(255, 255, 0));
	HPEN nOldPen = (HPEN)::SelectObject(hdc, nPen);
	::MoveToEx(hdc, 10, 10, nullptr);
	::LineTo(hdc, 100, 100);

	::SelectObject(hdc, nOldPen);
	::DeleteObject(nPen);
	::EndPaint(hwnd, &ps);
	return 0;
}

3. 繪製區域

繪製直線得時候使用畫筆,填充區域使用畫刷。繪製時,使用當前畫筆繪製邊線,使用當前畫刷填充區域。

  • Rectangle(hdc, x1, y1, x2, y2) 填充矩形
  • Ellipse(hdc, x1, y1, x2, y2) 矩形內切橢圓填充
  • Polyon(hdc, lpPoint, 5) 線輪廓

跟畫筆一樣可以使用系統默認得畫刷,也可以使用自定義畫刷

HBRUSH hBrush = ::CreateSolidBrush(RGB(255, 0, 0));
HBRUSH hOldBrush = (HBRUSH)::SelectObject(hdc, hBrush);
::Rectangle(hdc, 10, 10, 200, 200);

::SelectObject(hdc, hOldBrush);
::DeleteObject(hBrush);

函數 CreateSolidBrush 輸入唯一得參數就是畫刷得顏色。函數 CreateHatchBrush 函數創建得畫刷可以指定特定風格得線條:

HBRUSH CreateHatchBrush(
	int fnStyle,			// 線條的風格
	COLORREF clrref			// 圖案線條的顏色
)
  • fnStyle 的風格可以爲 HS_BDIAGLOBALHS_FDIAGLOBALHS_CROSSHS_HORIZONTALHS_DIAGCROSSHS_VERTICAL

可以使用 GetStockObject 函數獲取一些常用的畫刷對象,常用的預定義對象有 BLACK_BRUSH(黑色畫刷)DKGRAY_BRUSH(深黑色畫刷)GRAY_BRUSH(灰色畫刷)LTGRAY_BRUSH(淺灰色畫刷)WHITE_BRUSH(白色畫刷)NULL_BRUSH(空畫刷)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章