概要
有時候希望在相同的代碼路徑中混合使用GDI和GDI +繪圖操作。當您編寫允許GDI和GDI +互操作的代碼時,請記住一些注意事項。本文概述了這些注意事項,並提供了其他信息來幫助您成功編寫此類代碼。
更多信息
雖然可以將GDI和GDI+代碼混合使用,但是必須遵守一定的規則。通常,您不應該將GDI和GDI +調用交錯在一個目標對象上。例如,圍繞HDC
包裝一個Graphics
對象是可以的,但是在Graphics
對象被銷燬之前,您不應該直接從GDI訪問HDC
。
本文介紹了GDI和GDI +之間互操作性的四個主要場景:
- 在由屏幕支持的GDI +圖形對象上使用GDI
- 在由位圖支持的GDI +圖形對象上使用GDI
- 在GDI HDC上使用GDI +
- 在GDI內存HBITMAP上使用GDI +
在由屏幕支持的GDI+圖形對象上使用GDI
在屏幕支持的GDI+ Graphics對象上使用GDI的一個例子就是繪製一個“橡皮筋”或“焦點”矩形。GDI+目前不支持光柵操作(ROPs),因此如果需要R2_XOR
筆操作,則必須直接使用GDI。在這種情況下,您可以使用Graphics::GetHDC()
來獲取GDI輸出指向的HDC
。GDI +輸出不應該在HDC
生命週期的圖形對象上進行嘗試(也就是直到調用Graphics::ReleaseHDC()
)。
在位圖所支持的GDI+圖形對象上使用GDI
當爲位圖支持的Graphics
對象而不是屏幕調用Graphics::GetHDC()
時,會創建一個內存HDC
,並創建一個新的HBITMAP
並將其選入內存HDC
中。這個新的內存位圖不是使用原始位圖的圖像進行初始化,而是使用一個標記模式,它允許GDI +跟蹤對位圖的更改。通過使用GDI代碼對內存位圖所做的任何更改,都會在對哨兵模式的更改中變得明顯。當Graphics::ReleaseHDC()
被調用時,這些更改被複制回原始位圖。由於內存位圖未用位圖的圖像進行初始化,因此以這種方式獲得的HDC
應被視爲“只寫”,因此不適合與ROP一起使用,其使用需要能夠讀取目標,如R2_XOR
。此外,這種方法的性能成本也很高,因爲GDI +必須將更改複製回原始位圖。
在GDI HDC
上使用GDI+
通過使用以HDC
爲參數的Graphics構造函數,可以方便地在HDC
上使用GDI +。Graphics類的繪圖成員可以用這種方式在HDC
上繪圖。一旦Graphics對象被附加到HDC
,在Graphics
對象被銷燬或超出範圍之前,不應該在HDC
上執行GDI操作。如果在HDC
上需要GDI輸出,則可以在使用原始HDC
之前銷燬Graphics
對象,或者使用Graphics::GetHDC()
獲取新的HDC
,然後按照本文前面所述的規則進行互操作,同時在GDI +目的。
在GDI內存HBITMAP
上使用GDI+
將HBITMAP作爲參數的GDI +位圖構造函數不使用實際的源HBITMAP作爲位圖的後備圖像。而是在構造函數中創建圖像副本,即使在執行析構函數期間,也不會將更改寫回原始位圖。新的位圖可以被認爲是“在創建時複製”,因此爲了讓GDI +從GDI中獲取HBITMAP
內存,並將這些更改應用於HBITMAP
,需要使用類似下面的方法:
- 列表內容
- 創建一個
DIBSection
。 - 將
DIBSection
選擇到內存HDC
中。 - 要使用GDI +繪製
DIBSection
,請圍繞HDC包裝一個Graphics
對象。 - 要使用GDI繪製
DIBSection
,請銷燬Graphics
對象,然後使用HDC
。 - 銷燬圖形對象,然後清除
HDC
中的DIBSection
選項。
稍後,如果需要,可以從DIBSection
構造一個位圖,並將其用作Graphics::DrawImage()
中的源圖像。