|
撰/ahliu
繪圖對於視窗程式是非常重要的,否則我們想不出甚麼理由要用 API 而非 standard library。由於繪圖函數多不勝數,也沒有一個程式可用盡所有繪圖函數,故此初學者必先了解視窗程式繪圖的理論,了解視窗繪圖的機制和內部流程後,方能順利實踐。 用來繪字的GDI函數以下我們所講的都是 GDI (Graphics Device Interface) 函數,GDI 函數專責處理程式介面和顯示卡的資料傳送,我們只需建立一個 device context handler (HDC) 就能使用 GDI 函數。例如: TextOut(hdc,x,y,psString,iLength);

hdc 的資料型態為 HDC,通常用以下兩種方法去建立及初始化: 1)PAINTSTRUCT ps;
hdc = BeginPaint(hwnd,&ps);
2)hdc = GetDC(hwnd);
當中以第一種呼叫方法的效率較佳,繪圖速度也較高,因為 device context 的數目是有限的,故呼叫後必需利用以下函數釋放 DC: 1)EndPaint(hwnd,&ps);
2)ReleaseDC(hdc);
其實 GDI 函數都是一些易明、有語意的指令,初學者應能很快適應。 更新視窗畫面每當程式接收到 WM_PAINT 指令時,就會把整個視窗或部分視窗重繪,在主程式的 CALLBACK 函數中,你可以在處理 WM_PAINT 訊息時加入以下繪圖指令: HDC hdc;
PAINTSTRUCT ps;
switch(iMsg)
{
case WM_PAINT:
hdc = BeginPaint(hwnd,&ps);
TextOut(hdc,100,100,psString,strlen(psString));
EndPaint(hwnd,&ps);
return 0;
}
這樣每當視窗要重繪時 (e.g. 最大化或最小化時),就會在 (100,100) 上顯示 psString 的內容,在此我們不妨討論一下 TextOut 這個最常用的函數。 TextOut(hdc,x,y,psString,iLength);
當中: hdc = handle of device context
x = x 座標
y = y 座標
psString = 字串指標
iLength = 字串長度
請留意,psString 中不應有 ASCII 控制字元 (i.e. ASCII code > 128)。 假若我們要在視窗不需重繪的情形下繪圖 (e.g. 顯示你在鍵盤上鍵入的字元),就要多做一個步驟。其實程式接收 WM_PAINT 後,只會重繪 Invalid 的範圍 (i.e. 被覆蓋或破壞的視窗範圍),只有在視窗被移動或被其他視窗覆蓋才會自動發放 WM_PAINT 訊息,繼而重繪視窗,但按鍵卻不能自動把某視窗範圍變成 Invalid,故此我們需人手呼叫 InvalidateRect 函數: InvalidateRect(hwnd,&rect,TRUE);
hwnd = window's handler
rect = 長方形的左上角及右下角的座標
rect.left = 左上角的 x 座標
rect.top = 左上角的 y 座標
rect.right = 右下角的 x 座標
rect.bottom = 右下角的 y 座標
請留意,InvalidateRect 的第二個參數是長方形結構的地址而非長方形結構變數本身。呼叫這函數後,視窗就會自動發放 WM_PAINT 訊息去重繪視窗。 其他 GDI 函數包括 DrawText、Ellipse、Pie、Rectangle、RoundRect等繪圖函數,還有繪圖物件函數,包括 LoadBitmap、LoadImage、CreateFont等,稍後會為大家介紹,或讀者可自行參看 API 參考書。 本章的 Source Code (TextOut函數)可按此下載。
本章的 Source Code (Invalidate函數)可按此下載。
相關文件:
- TextOut Sample
- TextOut Source Code
- Invalidate Source Co
發表日期:2004-06-21
|
|
|