在早期的 Windows 程式開發中,開發者主要依賴 GDI (Graphics Device Interface,圖形裝置介面) 在視窗中繪製圖形、文字與影像。然而,GDI 的功能相當有限,尤其在影像處理方面表現不足。GDI+ 作為 GDI 的增強版本,不僅保留了原有功能並加以優化,更引入了二維向量圖形、文字渲染、影像處理、區域、路徑以及圖形資料矩陣等豐富的類別庫。其中 Graphics 類別是 GDI+ 的核心,絕大多數繪圖操作皆可透過它完成。
相較於 GDI,GDI+ 新增了漸變畫筆、樣條曲線、持久化路徑物件、矩陣與矩陣轉換、Alpha 混色、色彩校正、反鋸齒以及中繼資料等特性。但 GDI+ 並不支援 GDI 中的 AND、OR、XOR 等光柵操作 (ROP),也缺乏硬體加速支援。特別是 XOR 光柵操作,是實現圖元動態定位「橡皮筋」技術的關鍵。此外,GDI+ 在影像處理速度上並無明顯優勢。因此,在實際開發中常需結合兩者優勢,進行混合編程。
在 Visual C++ .NET 2003 中,開發者可使用 MFC 或托管 C++ (Managed Extensions for C++) 進行圖形開發。MFC 將 Windows API 封裝為面向物件的類別庫,可直接使用 CDC 類別或呼叫 GDI API。托管 C++ 則建立在標準 C++ 之上,支援 .NET Framework 的自動記憶體管理與跨語言互操作。
由於托管與非托管環境的差異,GDI API 無法像在 MFC 中那樣直接在托管 C++ 中呼叫。不過,GDI+ 的 Graphics 類別提供了 GetHdc 與 ReleaseHdc 方法,可取得或釋放與 Graphics 物件關聯的裝置內容句柄 (HDC),從而實現與 GDI 的互操作。
GDI API 屬於非托管程式碼,其資料類型與托管 C++ 不同,也非 COM 物件,因此必須透過平台調用 (P/Invoke) 來使用。P/Invoke 允許托管程式碼呼叫 DLL 中實現的非托管函數,需引用 System::Runtime::InteropServices 命名空間。
DllImport 屬性指定 DLL 名稱、進入點、字元集、呼叫慣例等。LineTo 函數using namespace System::Runtime::InteropServices;
typedef void* HDC;
[DllImport("gdi32", EntryPoint="LineTo")]
extern "C" bool LineTo(HDC hDC, int nXEnd, int nYEnd);
此範例展示了如何將 GDI32.DLL 中的 LineTo 函數匯入托管 C++,使其可在托管環境中直接呼叫。