這一節主要是書商設備內容的第二部分,地址在這裏:http://www.ai86.cn/book/windows_programming/5.htm#205002
設備內容裏面包含了很多寫字、畫畫使用的屬性,這些如果不指定直接都是可以用的,那麼就是默認值了。但是,如果被改變了,這些屬性會在釋放設備句柄時失去。所以記得隨改隨用,在釋放前用了。具體擁有的屬性在下面這個表裏面有:
設備內容屬性 |
默認值 |
修改該值的函數 |
取得該值的函數 |
Mapping Mode |
MM_TEXT |
SetMapMode |
GetMapMode |
Window Origin |
(0, 0) |
SetWindowOrgEx OffsetWindowOrgEx |
GetWindowOrgEx |
Viewport Origin |
(0, 0) |
SetViewportOrgEx OffsetViewportOrgEx |
GetViewportOrgEx |
Window Extents |
(1, 1) |
SetWindowExtEx SetMapMode ScaleWindowExtEx |
GetWindowExtEx |
Viewport Extents |
(1, 1) |
SetViewportExtEx SetMapMode ScaleViewportExtEx |
GetViewportExtEx |
Pen |
BLACK_PEN |
SelectObject |
SelectObject |
Brush |
WHITE_BRUSH |
SelectObject |
SelectObject |
Font |
SYSTEM_FONT |
SelectObject |
SelectObject |
Bitmap |
None |
SelectObject |
SelectObject |
Current Position |
(0, 0) |
MoveToEx LineTo PolylineTo PolyBezierTo |
GetCurrentPositionEx |
Background Mode |
OPAQUE |
SetBkMode |
GetBkMode |
Background Color |
White |
SetBkColor |
GetBkColor |
Text Color |
Black |
SetTextColor |
GetTextColor |
Drawing Mode |
R2_COPYPEN |
SetROP2 |
GetROP2 |
Stretching Mode |
BLACKONWHITE |
SetStretchBltMode |
GetStretchBltMode |
Polygon Fill Mode |
ALTERNATE |
SetPolyFillMode |
GetPolyFillMode |
Intercharacter Spacing |
0 |
SetTextCharacterExtra |
GetTextCharacterExtra |
Brush Origin |
(0, 0) |
SetBrushOrgEx |
GetBrushOrgEx |
Clipping Region |
None |
SelectObject SelectClipRgn IntersectClipRgn OffsetClipRgn ExcludeClipRect SelectClipPath |
GetClipBox |
保存設備內容
通常,在您呼叫GetDC或BeginPaint時,Windows用默認值建立一個新的設備內容,您對屬性所做的一切改變在設備內容用ReleaseDC或EndPaint呼叫釋放時,都會丟失。如果您的程序需要使用非內定的設備內容屬性,則您必須在每次取得設備內容句柄時初始化設備內容:
hdc = BeginPaint (hwnd, &ps) ;
//設備內容屬性
//繪製窗口顯示區域
EndPaint (hwnd, &ps) ;
return 0 ;
雖然在通常情況下這種方法已經很令人滿意了,但是您還可能想要在釋放設備內容之後,仍然保存程序中對設備內容屬性所做的改變,以便在下一次呼叫GetDC和BeginPaint時它們仍然能夠起作用。爲此,可在登錄窗口類別時,將CS_OWNDC旗標納入窗口類別的一部分:
現在,依據這個窗口類別所建立的每個窗口都將擁有自己的設備內容,它一直存在,直到窗口被刪除。如果使用了CS_OWNDC風格,就只需初始化設備內容一次,可以在處理WM_CREATE消息處理期間完成這一操作:
hdc = GetDC (hwnd) ;
//初始化設備內容屬性
ReleaseDC (hwnd, hdc) ;
這些屬性在改變之前一直有效。
CS_OWNDC風格隻影響GetDC和BeginPaint獲得的設備內容,不影響其它函數(如GetWindowDC)獲得的設備內容。以前不提倡使用CS_OWNDC風格,因爲它需要內存;現在,在處理大量圖形的Windows NT應用程序中,它可以提高性能。即使用了CS_OWNDC,您仍然應該在退出窗口消息處理程序之前釋放設備內容。
某些情況下,您可能想改變某些設備內容屬性,用改變後的屬性進行繪圖,然後恢復原來的設備內容。要簡化這一過程,可以通過如下呼叫來保存設備內容的狀態:
現在,可以改變一些屬性,在想要回到呼叫SaveDC前存在的設備內容時,呼叫:
您可以在呼叫RestoreDC之前呼叫SaveDC數次。
大多數程序寫作者以不同的方式使用SaveDC和RestoreDC。然而,更像彙編語言中的PUSH和POP指令,當您呼叫SaveDC時,不需要保存傳回值:
然後,您可以更改某些屬性並再次呼叫SaveDC。要將設備內容恢復到一個已經保存的狀態,呼叫:
這就將設備內容恢復到最近由SaveDC函數保存的狀態中。
設置畫筆(後面的內容文章本身寫的就很簡單了,沒有什麼寫的必要了,就把關鍵的留下來吧)
①使用標準畫筆:
BLACK_PEN是Windows提供的三種現有畫筆之一,其它兩種是WHITE_PEN和NULL_PEN,NULL_PEN什麼都不畫。您也可以自己自訂畫筆。
Windows程序以句柄來使用畫筆。
呼叫GetStockObject,可以獲得現有畫筆的句柄。例如,假設您想使用名爲WHITE_PEN的現有畫筆,可以如下取得畫筆的句柄:
現在必須將畫筆選進設備內容:
目前的畫筆是白色。在這個呼叫後,您畫的線將使用WHITE_PEN,直到您將另外一個畫筆選進設備內容或者釋放設備內容句柄爲止。
您也可以不定義hPen變量,而將GetStockObject和SelectObject呼叫合併成一個敘述:
如果想恢復到使用BLACK_PEN的狀態,可以用一個敘述取得這種畫筆的句柄,並將其選進設備內容:
SelectObject的傳回值是此呼叫前設備內容中的畫筆句柄。如果啓動一個新的設備內容並呼叫
則設備內容中的目前畫筆將爲WHITE_PEN,變量hPen將會是BLACK_PEN的句柄。以後通過呼叫
就能夠將BLACK_PEN選進設備內容。
在使用畫筆等GDI對象時,應該遵守以下三條規則:
- 最後要刪除自己建立的所有GDI對象。
- 當GDI對象正在一個有效的設備內容中使用時,不要刪除它。
- 不要刪除現有對象。
這些規則當然是有道理的,而且有時這道理還挺微妙的。下面我們將舉些例子來幫助理解這些規則。
CreatePen函數的語法形如:
七種畫筆樣式 |
與畫筆色彩所使用的crColor參數一樣,Windows將這裏的背景色轉換爲純色。可以通過用GetBkColor來取得設備內容中定義的目前背景色。
通過將背景模式轉換爲TRANSPARENT,可以阻止Windows填入空隙:
可以通過以下呼叫在設備內容中設定新的繪圖模式:
各種繪圖模式如下表:
畫筆(P):目標(D): | 1 1 | 1 0 | 0 1 | 0 0 | 布爾操作 | 繪圖模式 |
結果: | 0 | 0 | 0 | 0 | 0 | R2_BLACK |
0 | 0 | 0 | 1 | ~(P | D) | R2_NOTMERGEPEN | |
0 | 0 | 1 | 0 | ~P & D | R2_MASKNOTPEN | |
0 | 0 | 1 | 1 | ~P | R2_NOTCOPYPEN | |
0 | 1 | 0 | 0 | P & ~D | R2_MASKPENNOT | |
0 | 1 | 0 | 1 | ~D | R2_NOT | |
0 | 1 | 1 | 0 | P ^ D | R2_XORPEN | |
0 | 1 | 1 | 1 | ~(P & D) | R2_NOTMASKPEN | |
1 | 0 | 0 | 0 | P & D | R2_MASKPEN | |
1 | 0 | 0 | 1 | ~(P ^ D) | R2_NOTXORPEN | |
1 | 0 | 1 | 0 | D | R2_NOP | |
1 | 0 | 1 | 1 | ~P | D | R2_MERGENOTPEN | |
1 | 1 | 0 | 0 | P | R2_COPYPEN(內定) | |
1 | 1 | 0 | 1 | P | ~D | R2_MERGEPENNOT | |
1 | 1 | 1 | 0 | P | D | R2_MERGEPEN | |
1 | 1 | 1 | 1 | 1 | R2_WHITE |
畫刷決定了一個填充區域(比入說一個正方形的中間)的樣式:
您可以用
hBrush = GetStockObject (GRAY_BRUSH) ;
SelectObject (hdc, hBrush) ;
來使用包含如下6個的系統畫刷:WHITE_BRUSH、LTGRAY_BRUSH、GRAY_BRUSH、DKGRAY_BRUSH、BLACK_BRUSH和NULL_BRUSH
也可以自定義:
COLORREF crColor // brush color value
);