《Windows程序設計》讀書筆記------------->>設備內容句柄之二

這一節主要是書商設備內容的第二部分,地址在這裏: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呼叫釋放時,都會丟失。如果您的程序需要使用非內定的設備內容屬性,則您必須在每次取得設備內容句柄時初始化設備內容:

case WM_PAINT:
        
    hdc 
= BeginPaint (hwnd, &ps) ;
        
    
//設備內容屬性
        
    
//繪製窗口顯示區域
        
    EndPaint (hwnd, 
&ps) ;
        
    
return 0 ;

雖然在通常情況下這種方法已經很令人滿意了,但是您還可能想要在釋放設備內容之後,仍然保存程序中對設備內容屬性所做的改變,以便在下一次呼叫GetDC和BeginPaint時它們仍然能夠起作用。爲此,可在登錄窗口類別時,將CS_OWNDC旗標納入窗口類別的一部分:

wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC ;

現在,依據這個窗口類別所建立的每個窗口都將擁有自己的設備內容,它一直存在,直到窗口被刪除。如果使用了CS_OWNDC風格,就只需初始化設備內容一次,可以在處理WM_CREATE消息處理期間完成這一操作:

case        WM_CREATE:
        
      hdc 
= GetDC (hwnd) ;
        
//初始化設備內容屬性
        
       ReleaseDC (hwnd, hdc) ;

這些屬性在改變之前一直有效。

CS_OWNDC風格隻影響GetDC和BeginPaint獲得的設備內容,不影響其它函數(如GetWindowDC)獲得的設備內容。以前不提倡使用CS_OWNDC風格,因爲它需要內存;現在,在處理大量圖形的Windows NT應用程序中,它可以提高性能。即使用了CS_OWNDC,您仍然應該在退出窗口消息處理程序之前釋放設備內容。

某些情況下,您可能想改變某些設備內容屬性,用改變後的屬性進行繪圖,然後恢復原來的設備內容。要簡化這一過程,可以通過如下呼叫來保存設備內容的狀態:

idSaved = SaveDC (hdc) ;

現在,可以改變一些屬性,在想要回到呼叫SaveDC前存在的設備內容時,呼叫:

RestoreDC (hdc, idSaved) ;

您可以在呼叫RestoreDC之前呼叫SaveDC數次。

大多數程序寫作者以不同的方式使用SaveDC和RestoreDC。然而,更像彙編語言中的PUSH和POP指令,當您呼叫SaveDC時,不需要保存傳回值:

SaveDC (hdc) ;

然後,您可以更改某些屬性並再次呼叫SaveDC。要將設備內容恢復到一個已經保存的狀態,呼叫:

RestoreDC (hdc, -1) ;

這就將設備內容恢復到最近由SaveDC函數保存的狀態中。

 

 

設置畫筆(後面的內容文章本身寫的就很簡單了,沒有什麼寫的必要了,就把關鍵的留下來吧)

 ①使用標準畫筆:
BLACK_PEN是Windows提供的三種現有畫筆之一,其它兩種是WHITE_PEN和NULL_PEN,NULL_PEN什麼都不畫。您也可以自己自訂畫筆。
Windows程序以句柄來使用畫筆。

HPEN hPen ;

呼叫GetStockObject,可以獲得現有畫筆的句柄。例如,假設您想使用名爲WHITE_PEN的現有畫筆,可以如下取得畫筆的句柄:

hPen = GetStockObject (WHITE_PEN) ;

現在必須將畫筆選進設備內容:

SelectObject (hdc, hPen) ;

目前的畫筆是白色。在這個呼叫後,您畫的線將使用WHITE_PEN,直到您將另外一個畫筆選進設備內容或者釋放設備內容句柄爲止。

您也可以不定義hPen變量,而將GetStockObject和SelectObject呼叫合併成一個敘述:

SelectObject (hdc, GetStockObject (WHITE_PEN)) ;

如果想恢復到使用BLACK_PEN的狀態,可以用一個敘述取得這種畫筆的句柄,並將其選進設備內容:

SelectObject (hdc, GetStockObject (BLACK_PEN)) ;

SelectObject的傳回值是此呼叫前設備內容中的畫筆句柄。如果啓動一個新的設備內容並呼叫

hPen = SelectObject (hdc, GetStockobject (WHITE_PEN)) ;

則設備內容中的目前畫筆將爲WHITE_PEN,變量hPen將會是BLACK_PEN的句柄。以後通過呼叫

SelectObject (hdc, hPen) ;
就能夠將BLACK_PEN選進設備內容。

在使用畫筆等GDI對象時,應該遵守以下三條規則:

  • 最後要刪除自己建立的所有GDI對象。
     
  • 當GDI對象正在一個有效的設備內容中使用時,不要刪除它。
     
  • 不要刪除現有對象。
     

這些規則當然是有道理的,而且有時這道理還挺微妙的。下面我們將舉些例子來幫助理解這些規則。

CreatePen函數的語法形如:

hPen = CreatePen (iPenStyle, iWidth, crColor) ;

七種畫筆樣式

對於PS_SOLID、PS_NULL和PS_INSIDEFRAME畫筆樣式,iWidth參數是畫筆的寬度。iWidth值爲0則意味着畫筆寬度爲一個圖素。現有畫筆是一個圖素寬。如果指定的是點劃線或者虛線式畫筆樣式,同時又指定一個大於1的實際寬度,那麼Windows將使用實線畫筆來代替。在與定義一個填入區域的函數一起使用時,PS_INSIDEFRAME畫筆樣式還有另外一個奇特之處:對於除了PS_INSIDEFRAME以外的所有畫筆樣式來說,如果用來畫邊界框的畫筆寬度大於1個圖素,那麼畫筆將居中對齊在邊界框在線,這樣邊界框線的一部分將位於邊界框之外;而對於PS_INSIDEFRAME畫筆樣式來說,整條邊界框線都畫在邊界框之內。
CreatePen的crColor參數是一個COLORREF值,它指定畫筆的顏色。對於除了PS_INSIDEFRAME之外的畫筆樣式,如果將畫筆選入設備內容中,Windows會將顏色轉換爲設備所能表示的最相近的純色。PS_INSIDEFRAME是唯一一種可以使用混色的畫筆樣式,並且只有在寬度大於1的情況下才如此。
 
您可以通過如下呼叫來改變Windows背景色
SetBkColor (hdc, crColor) ;

與畫筆色彩所使用的crColor參數一樣,Windows將這裏的背景色轉換爲純色。可以通過用GetBkColor來取得設備內容中定義的目前背景色。

通過將背景模式轉換爲TRANSPARENT,可以阻止Windows填入空隙:

SetBkMode (hdc, TRANSPARENT) ;

可以通過以下呼叫在設備內容中設定新的繪圖模式

SetROP2 (hdc, iDrawMode) ;
各種繪圖模式如下表:

畫筆(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 hBrush ;
hBrush 
= GetStockObject (GRAY_BRUSH) ;
SelectObject (hdc, hBrush) ;
來使用包含如下6個的系統畫刷:WHITE_BRUSH、LTGRAY_BRUSH、GRAY_BRUSH、DKGRAY_BRUSH、BLACK_BRUSH和NULL_BRUSH
也可以自定義
HBRUSH CreateSolidBrush(
  COLORREF crColor   
// brush color value
);


hBrush = CreateHatchBrush (iHatchStyle, crColor) ;

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