前幾天學習了windows下程式設計的訊息處理機制,同時接著學習了如何處理WM_PAINT訊息, 並在第4課中簡單的論述了
捲軸的處理,今天下班後感覺不是特別的累,因此看了看Windows 的GDI的基礎內容,下面將晚上學習的總結貼出來,請各位
大俠批評指正。
哈哈, 感覺入門以後越往後學就越順暢,同時感覺難度也在逐漸的增大, 希望可以儘快的把那本書看完,好接下來看看那個關於
核心編程的書.....
還不知道怎麼用window的IDE編程環境,利用它來繪製應用程式介面, 不過沒關係,我想我在看看執行個體就應該會明白的.....
閑話少說,下面來看我今天的總結:
5、 GDI圖形基礎
圖形裝置介面(GDI:Graphics Device Interface)是windows的子系統,負責在標準輸出裝置和印表機上顯示圖形。
1) 應用程式通過GDI顯示視覺資訊
2) windows系統本身也使用GDI來顯示使用者介面對象: 菜單、捲軸、表徵圖和游標等
5.1 GDI的結構
從應用程式的觀點來看,GDI由一大堆的系統函數呼叫和相關的資料類型、宏和結構
5.1.1 GDI原理
win98和winNT的圖形主要由gdi32.dll動態連結程式庫輸出的函數來處理;在win98中,GDI32.dll實際上利用16位的gdi.exe
動態連結程式庫來執行許多函數, 而在NT中,16位的GDI.exe僅用來實現16位的程式。
動態連結程式庫在進行顯示的過程中將呼叫顯示器或者印表機的驅動程式常式, 顯示驅動程式存取顯示的控制硬體,印表機驅動程式
則將GDI命令轉換為印表機能理解的代碼或者命令。因此不同類型的顯示器或印表機需要不同的裝置驅動程式。
GDI的主要目的: 支援與裝置無關的圖形設計和輸出;windows程式應該能夠在windows支援的任意輸出裝置上正確的執行。
1)圖形裝置的分類:
位映像裝置:以圖點構成的數組來表示映像; 例如:顯示卡、點陣印表機和雷射印表機
向量裝置:使用線來繪製映像
2)windows圖素座標系統
windows預設使用圖素座標系統。
傳統圖形語言使用虛擬座標系: 水平和垂直範圍從0 ~ 32767
WindowsGDI允許使用兩種座標系統之一: 使用虛擬座標系,是程式獨立於硬體之外
使用裝置座標系,完全適應硬體裝置提供的編程環境
5.1.2 GDI函數呼叫
GDI函數分類:
1) 取得(或建立)、釋放(或清除)裝置內容的函數
GetDC、ReleaseDC
BeginPaint、EndPaint
2)取得有關裝置內容資訊的函數
GetSystemMetrics
GetTextMetrics
3)繪圖函數
Textout
4)設定和取得裝置內容參數的函數
裝置內容的屬性決定有關繪圖函數如何工作的細節
SetTextColor來指定TextOut函數所繪製文字的顏色
SetTextAlign指定TextOut函數中字串的開始位置應該在字串的右邊還是預設的左邊
5)使用GDI對象的函數
Exp:
預設時使用GDI繪製的繪製的所有直線都是實線並且具有一個標準的寬度, 當需要改變線寬
和線型時,不能通過改變裝置內容的屬性來實現,而只能通過一個邏輯畫筆來實現。
要改變線型和線寬可以通過在CreatePen、CreatePenIndirect或ExtCreatePen函數中指定這些
特徵來建立一個邏輯畫筆, 這些函數傳回一個邏輯畫筆的控制代碼。要使用這個畫筆,需要將畫筆控制代碼選進裝置內容
。通常認為裝置內容中目前選中的畫筆就是裝置內容的一個屬性,這樣畫任何線就使用這個畫筆,當不再需要的
時候可以取消裝置內容中的畫筆,並清除畫筆對象。
在不需要畫筆的時候清除是必要的,但不是必須的,因為畫筆佔用了分配的記憶體空間。
GDI對象除了畫筆以外,還用於建立填入封閉地區的畫刷、字型、位元影像以及GDI的其他一些方面。
GDI基本圖形
直線和曲線: 線條是所有向量圖形繪製的基礎
GDI支援:直線、矩形、橢圓、圓、圓弧、貝瑟爾曲線,以及折線
線條由裝置內容中目前選中的畫筆繪製。
填入地區:
一系列的直線或者曲線封閉了一個地區時,該地區可以使用目前GDI畫刷對象進行填圖,這個畫刷
可以是實心色彩、圖案,或者是在地區內垂直或者水平重複的位元影像映像。
位元影像:
位元影像是位的矩形數組,這些位對應於顯示裝置上的圖素,它們是位映像圖形的基礎工具。
位元影像通常:
用於在顯示器或者印表機上顯示複雜的映像
用於顯示必須快速繪製的小映像,游標、表徵圖以及在應用工具條上出現的按鈕等。
文字:
文字是顯示系統中最複雜的對象之一。
GDI的其他部分
映像模式和變換:
window預設以圖素為單位進行繪圖,還支援以英寸、毫米等其他單位繪圖。
Metafile
以二進位形式儲存的GDI命令集合,用於通過剪貼簿傳遞圖形
繪圖區域:
繪圖區域是任意複雜的地區,通常定義為較簡單的繪圖區域的組合
路徑:
是GDI內部儲存的直線和曲線的集合,路徑可以用於繪圖、填入圖形和剪裁,還可以轉換為繪圖區域。
剪裁:
繪圖可以限制在顯示地區的某一部分,這就是所謂的剪裁,剪裁地區可以是矩形,也可以不是矩形,剪裁
通常是通過地區或者路徑來定義的。
調色盤:
自訂調色盤通常限於256色的顯示器
列印:
5.2 裝置內容
如果想在一個圖形輸出裝置上繪圖,首先必須擷取裝置內容的控制代碼,並將控制代碼傳回程式,獲得使用裝置的許可權,然後才能
進行繪圖。
windowsGDI函數通過返回的裝置內容控制代碼作為一個參數,向windows標識您想在其上進行繪圖的裝置。
裝置內容中包含許多確定GDI函數如何在裝置上工作的當前屬性, 這些屬性允許傳遞給GDI函數的參數只包含起始的座標
或者尺寸資訊,而不必包含裝置內容的其他所有資訊。
如果需要改變裝置內容屬性需要通過裝置內容屬性設定函數完成。
5.2.1 取得裝置內容控制代碼
windows提供了多種擷取裝置內容控制代碼的方法,如果在處理一個訊息時取得了裝置內容控制代碼,那麼應該在訊息處理完畢後
(退出視窗函數)之前釋放他,一旦釋放了控制代碼,他就不在有效。
方法一:
在處理WM_PAINT訊息時通過BeginPaint函數取得裝置內容控制代碼
Exp:
hdc=BeginPaint(hwnd,&ps);
其他行程式
EndPaint(hwnd,&ps);
Tip:
變數ps是一個PAINTSTRUCT結構類型的變數,該結構的hdc欄位是BeginPaint傳回的裝置內容控制代碼,
PAINTSTRUCT結構還包含一個名為rcPaint的RECT結構,rcPaint定義一個包含視窗顯示地區無效範圍的矩形,
使用BeginPaint獲得的裝置內容控制代碼只能在這個地區內繪圖。BeginPaint函數呼叫使無效地區變為有效。
方法二:
在處理非WM_PAINT訊息時取得裝置內容控制代碼
Exp:
hdc=GetDC(hwnd);
其他行程式
ReleaseDC(hwnd,hdc);
Tip:
這種方式擷取的裝置內容控制代碼,允許在整個顯示地區繪圖,並且這個函數呼叫不會使顯示地區的無效地區變為有效。
方法三:
擷取整個視窗的裝置內容控制代碼
Exp:
hdc=GetWindowDC(hwnd);
其他行程式
ReleaseDC(hwnd,hdc);
Tip:
這個裝置內容處理顯示地區外,還包括視窗的標題列、菜單、捲軸和架構。
如果需要用這個函數呼叫必須攔截處理WM_NCPAINT訊息;windows利用這個訊息在非顯示地區繪圖。
方法四:
BeginPaint、GetDC、GetWindowDC均與特定的視窗相關。
可以取得不是與特定視窗先關的裝置內容控制代碼,利用CreateDC函數
Exp:
hdc=CreateDC(pszDriver,pszDevice,pszOutput,pData);
其他行程式
DeleteDC(hdc);
例如可以通過:
hdc=CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL);
在視窗之外寫入畫面一般是不恰當的,但是對於一些不同尋常的程式來說這樣非常方便。
當僅僅需要擷取一個裝置內容的裝置內容資訊而不需進行繪製時,可以使用CreateC來取的一個資訊內容的控制代碼,
CreateC函數的參數與CreateDC的相同。
Exp:
hdc=CreateC(TEXT("DISPLAY"),NULL,NULL,NULL); //當然不能用這個資訊往裝置內容上鞋東西。
使用位元影像時取得一個記憶體裝置內容有時是非常有用的:
Exp:
hdcMem=CreateCompatibleDC(hdc);
其他行程式
DeleteDC(hdcMem);
Tip:
可以將位元影像選擇記憶體裝置內容,然後使用GDI函數在位元影像上繪圖。
Metafile:
metafile是一些GDI呼叫的集合,以二進位編碼,可以通過取得metafile裝置內容來建立metafile:
Exp:
hdcMeta=CreateMetaFile(pszFilename);
其他行程式
hmf=CloseMetaFile(hdcMeta);
Tip:
在metafile裝置內容有效期間,任何用hdcMeta所作的GDI呼叫都變成metafile的一部分而並不會顯示,在
呼叫CloseMetaFile之後,裝置內容控制代碼變為無效,並且CloseMetaFile函數返回一個執行metafile(hmf)的控制代碼。
5.2.2 取得裝置內容資訊
一個裝置內容通常指一個實際顯示裝置,通常可以取得有關該裝置的資訊: 例如顯示器大小和色彩顯示能力。可以通過
GetDeviceCaps函數來取得這些訊息。
Exp:
iValue=GetDeviceCaps(hdc,iIndex);
Tip:
iIndex為WINGDI.H標頭檔中定義的29個宏之一。
例如:
iIndex為HORZRES將使GetDeviceCaps傳回裝置的寬度(單位為圖素), iIndex為VERTRES時GetDeviceCaps將
返回裝置的高度資訊。如果hdc是印表機裝置內容控制代碼,則GetDeviceCaps將返回印表機顯示地區的高度和寬度(單位
是圖素)。
以上內容純屬一孔之見, 歡迎各位彎腰找板磚....................
越多越好啊, 我好收集板磚自己蓋房,現在樓價這麼高,自己蓋房是個不錯的選擇.....
哈哈...............