パフォーマンスに関する考慮事項とベスト プラクティス

このトピックでは、デスクトップ ウィンドウ マネージャー (DWM) API を使用するための一連のベスト プラクティスについて説明します。

このトピックは、次のセクションで構成されています。

DWM のアプリケーション プラクティス

アプリケーションでドット/インチ (dpi) のスケーリングを処理する場合は、プログラムのマニフェストで dpi 対応フラグを設定するか、プログラムの初期化中に SetProcessDPIAware 関数を呼び出すことによって、アプリケーションを dpi 対応として宣言し、自動スケーリングを防止できます。

DWM コンポジションを有効にすると、隠されたアプリケーションは WM_PAINT メッセージを受信しなくなり、再レンダリングは求められません。 各ウィンドウのコンテンツは、画面イメージを作成するために既に使用できます。

ヒット テストの目的で、最上位の WS_EX_TRANSPARENT ウィンドウを WS_EX_LAYERED スタイルと組み合わせる必要があります。 クラシックの意味でWS_EX_TRANSPARENTは、リダイレクトを使用せずに、同じスレッドに属するウィンドウの階層内の子ウィンドウに役立ちますが、最上位レベルのウィンドウを対象としたものではありません。

領域またはレイヤーを使用して、シェイプウィンドウまたはブレンドウィンドウを作成します。 Windows Vista 以降のバージョンの Windows では、最上位ウィンドウの一部のみをカスタム描画しても、描画されていない領域で目的の古いコンテンツが提供されないことに注意してください。

GetDCOrgEx などの API を使用して、特定の実際の値を決定できます。 リダイレクトされたウィンドウのデバイス コンテキスト (DC) がある場合、 GetDCOrgEx によって返される配信元は、画面上のウィンドウの配信元と一致しません。 原点は、代わりにウィンドウのバックバッファー サーフェスの原点になります(0、0)。

それ以外のすべてが失敗した場合は、 DwmSetWindowAttribute 関数を呼び出してウィンドウレンダリングを無効にします。

DWM の描画プラクティス

プライマリディスプレイサーフェスに直接描画しないでください。 これにより、アプリケーションがプライマリ デバイスサーフェスを解放するまで、DWM はコンポジションを強制的に無効にします。

アプリケーションで独自のダブル バッファリングを提供する必要があるかどうかを評価します。 DWM は実質的にコンテンツをダブル バッファーし、ウィンドウを 1 つのフレームに表示します。

ディスプレイ DC から読み取ったり、ディスプレイ DC に書き込んだりしないでください。 DWM ではサポートされていますが、パフォーマンスが低下するため、お勧めしません。

クライアント以外の領域での描画は避けてください。 この領域はアプリケーションからアクセスでき、描画は Microsoft Win32 API でサポートされていますが、これを行うと、ウィンドウに含まれるガラス枠が失われる可能性があります。

重複しない限り、Windows グラフィックス デバイス インターフェイス (GDI) と Microsoft DirectX を混在させないでください。 ミキシングが必要な場合は、GDI コンテンツを DirectX ソフトウェア サーフェイスに描画し、画面に合成する前に組み合わせるか、別のウィンドウで描画します。

Windows GDI+ の代わりに BitBlt 関数または StretchBlt 関数を使用して、描画用の図面を表示します。 GDI+ は、ソフトウェア レンダリングを使用して一度に 1 つのスキャン行をレンダリングします。 これにより、アプリケーションでちらつきが発生する可能性があります。

DWM Blur-Behind クライアント リージョン

ぼかし効果のレンダリングは、CPU とグラフィックス処理装置 (GPU) の両方でリソースを大量に消費する操作です。 アプリケーション開発者は、過剰なリソースを消費しないように、クライアント領域のぼかしを使用することの影響を考慮するよう促されます。 次の場合は特に注意する必要があります。

  • クライアント領域のぼかしのサイズが大きくなると予想される場合は、ぼやけた領域自体に更新が行われなくてもかまいません。 ウィンドウのぼやけた領域で更新が発生し、CPU と GPU のコストが発生した場合に、ぼかしをレンダリングする必要があります。 さらに、ウィンドウでのウィンドウ操作 (移動/サイズ変更/切り替え) では、より多くのコストが発生します。
  • ぼやけたクライアント領域で大幅な更新が予想される場合。 これには、すべての更新でぼかしを再描画し、過剰なリソースを消費する必要があります。
  • ぼかしが重要な領域をカバーすることが予想され、その領域の更新も必要な場合は、クライアント領域をぼかしないことを強くお勧めします。