GDI和GDI +之間的互操作性

概要

有時候希望在相同的代碼路徑中混合使用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,需要使用類似下面的方法:

  1. 列表內容
  2. 創建一個DIBSection
  3. DIBSection選擇到內存HDC中。
  4. 要使用GDI +繪製DIBSection,請圍繞HDC包裝一個Graphics對象。
  5. 要使用GDI繪製DIBSection,請銷燬Graphics對象,然後使用HDC
  6. 銷燬圖形對象,然後清除HDC中的DIBSection選項。

稍後,如果需要,可以從DIBSection構造一個位圖,並將其用作Graphics::DrawImage()中的源圖像。

發佈了115 篇原創文章 · 獲贊 176 · 訪問量 32萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章