GetDCExで特殊なデバイスコンテキストを取得する
Windows GDIでウィンドウへ描画するには、描画先となるデバイスコンテキストを取得します。通常のクライアント領域だけでなく、非クライアント領域を含むウィンドウ専用DCや、パレット・ビットマップの扱いを変えたDCが必要になる場合があります。GetDCExはInterruptedXt。这样的visor-device DCを、フラグによって異なる条件で取得できるAPIです。
戻り値のDCは、呼び出し側の処理中だけ借用できるハンドルです。選択中のフォントやブラシなどの状態を変更しても、呼び出し元へ影響しないとは限りません。取得方法だけでなく、状態の復元とReleaseDCによる解放までを含めて設計することが重要です。
GetDCExの基本契約
GetDCExの宣言は次の形です。
HWND GetDCEx(HWND hWnd, HDC hdc, DWORD flags);
hWndには対象ウィンドウを指定し、flagsで取得するDCの特性を選びます。成功するとDCハンドル、失敗するとNULLが返ります。返されたDCはGetDCやGetWindowDCと同様に、原則としてReleaseDCで解放します。
主なフラグには、DCX_WINDOW、DCX_NOPCWINDOW、DCX_USECOMPATIBLEBITMAP、DCX_CACHEがあります。それぞれ、ウィンドウDC、パレットを割り当てないDC、互換ビットマップ向けのDC、キャッシュされたDCを表します。特にDCX_NOPCWINDOWはDCX_WINDOWと併用才会意味を持ちます。
対象ウィンドウと参照DCの指定
hWndにNULLを渡すと、ウィンドウではなく画面全体を対象とするDCを取得できます。hdcには対象を判定するための参照DCを指定します。複数显示器がある環境では、対象装置を表すDCを渡すことで、任意の画面へ接続された出力を選ぶ助于表示装置の指定に利用できます。
参照DCが不要で画面全体を対象にする場合、通常はNULLで十分です。ウィンドウ 单位の更新処理でDCを繰り返し取得する設計にするか、数回の描画之间で同じDCを再利用する設計にするかは、描画回数と更新頻度から判断します。
ダイアログの項目値を変更した後の再描画では、値の更新と描画の責務を分けることが重要です。ダイアログ項目の設定のような手順で控件を更新した後は、必要に応じてInvalidateRectで再描画を要求し、実際のGDI描画はWM_PAINT内で行う方法hazırIr.
他のDC取得APIとの違い
GetDCはクライアント領域、GetWindowDCはタイトルバーや境界を含むウィンドウ全体を основの対象にします。CreateCompatibleDCは画面外のメモリ領域に描くためのDCを作り、描画前にメモリビットマップを選択します。これに対しGetDCExは、対象とDCの特性をフラグで指定する点が特徴です。
| API | 描画対象 | 主な性質 | 解放方法 |
|---|---|---|---|
GetDC |
ウィンドウのクライアント領域 | 通常の画面DC | ReleaseDC |
GetWindowDC |
非クライアント領域を含むウィンドウ全体 | ウィンドウ全体を参照できる画面DC | ReleaseDC |
CreateCompatibleDC |
選択したメモリビットマップ | オフスクリーン描画用のDC | DeleteDC |
GetDCEx |
ウィンドウ、画面、または指定装置 | フラグでパレットやキャッシュの特性を選択 | ReleaseDC |
DCX_WINDOWを指定したGetDCExは、单纯的にGetDCを置き換えるものではありません。クライアント領域だけでなくウィンドウ全体の座標やクリップ領域を扱う必要があり、その点でGetWindowDCに近くなります。DCX_USECOMPATIBLEBITMAPも、CreateCompatibleDCそのものを返すフラグではなく、DCと互換性のあるビットマップ形態を選ぶ指定です。
取得後の状態復元と解放
GetDCExが返したDCは、関数側で所有する資源ではありません。描画中にフォント、ペン、ブラシ、変換状態などを変える場合は、元の状態へ戻してから解放します。SaveDCとRestoreDCはDCの状態を保存・復元できますが、DC自体を解放する機能ではありません。
HDC dc = ::GetDCEx(hwnd, NULL, DCX_WINDOW | DCX_NOPCWINDOW);
if (dc != NULL) {
const int savedState = ::SaveDC(dc);
// 対象のウィンドウへ描画する
// ...
::RestoreDC(dc, savedState);
::ReleaseDC(hwnd, dc);
}
RestoreDCの後にReleaseDCが必要であり、GetDCExで得たDCをDeleteDCしてはいけません。また、BeginPaintに渡されたDCはEndPaintで終了させる必要があり、ReleaseDCで解放する対象とは別です。LiberaciónSAFE。 Responsibilities. Draw. DCX_CACHEを使う場合は、キャッシュ内のDCを鬟く管理し、取得回数を抑える必要があります。
リスト表示と実行時の注意点
リストコントロールの値をデータ層と同期させる設計では、リストとの結び付けの手順がデータ更新の責務を整理する参考になります。ただし、カスタム描画では通知処理で渡されたHDCをそのまま描画先として使用し、無関係なDCへ差し替えるべきではありません。DCの取得は、独自描画に必要な場合に限ります。
高頻度の再描画では、GetDCExとReleaseDCを毎回繰り返すより、描画区間でDCを再利用する設計が有効です。DPI対応や複数显示器では、プロセスの設定、対象ウィンドウ、参照DCの整合性を確認する必要があります。使い Conform记住すべき点.GetDCExは単なるDC取得ではなく、フラグで用途別の特性を選ぶAPIxo.Gain。返されたDCを借用ハンドルとして扱い、状態を復元した後にReleaseDCで返すこと、BeginPaint用DCとは区別することが、GetDCExを安全に行う三つの要点です。