レイヤードウィンドウを使用して滑らかなウィンドウ境界を作成する

StackOverflow https://stackoverflow.com/questions/745404

  •  09-09-2019
  •  | 
  •  

質問

私たちは、ほとんどのウィンドウにさまざまな丸みを帯びたエッジを備えたスキン アプリを開発しています。私はウィンドウ領域を使用して非長方形の形状を定義していますが、ピクセルは完全に不透明か完全に透明のどちらかしかないため、これによって生じるギザギザのエイリアシングにほとんど誰もが反対しています。

私はレイヤード ウィンドウを使用してこれに対する解決策を考え出しましたが、これがさまざまなシステムで確実に実行される (そしてできればうまく実行される) ことを確認したいので、誰かがより良いアイデアや方法を持っているかどうかを確認したいと考えています。私がやっていることを最適化します。レイヤード ウィンドウには win2000 以降が必要であることはわかっていますが、それは他の理由ですでに要件になっているため、問題ありません。いくつかの基本的なテストでは、Vista では問題ないようですが、まだ保証はありません。

私がやることは次のとおりです。コントロールやテキスト、その他そのウィンドウを構成するものを含むウィンドウ (A と呼びます) があります。ウィンドウ B をウィンドウ A の子として持っていますが、ウィンドウ B は WS_CHILD ではなく WS_POPUP スタイルを持っているため、A の領域の外側に配置でき、A のコントロールの上に描画されます。ウィンドウ B にも WS_EX_LAYERED スタイルがあり、初期化時に次のように呼び出します。 レイヤードウィンドウの更新 ULW_ALPHA フラグと、アルファ チャネルを持つ 32 ビット ビットマップを含むソース DC を使用して、ピクセルごとのアルファで描画できるようにします。

ウィンドウ B のソース DC で使用されるビットマップは、ウィンドウの背景から完全な透明度に滑らかにブレンドしたい、ウィンドウの境界線の周囲のピクセルにすぎません。私は 2 つのウィンドウのアプローチ全体をスキップして、単一レイヤーのウィンドウを使用します。ただし、UpdateLayeredWindow を使用している場合、典型的な WM_PAINT メッセージなどの代わりにメモリに保持されているバッファーから描画され、インタラクティブな子コントロール (および子ウィンドウ) を適切に動作させるには、かなりの手間がかかるように思えます (おそらく、すべての場合に動作するわけではありません)。

つまり、基本的にはすべての子コントロールなどを備えたウィンドウ A に、ウィンドウ B がその上に直接フローティングし、滑らかな境界線を描きます。WM_MOVE メッセージなどに応答して、ウィンドウ B を一緒に移動します。また、ウィンドウ B を無効にしてフォーカスや入力を取得できないようにしています (ウィンドウの大部分など、不透明度がゼロの部分はすでにクリックされています)。内部部分はすでにピッキングから除外されています)。

ちなみに、私が言いたいことをもう少しわかりやすく示すために、ピースがどのように見えるかをここに示します。

したがって、これは機能しますが、これが本当に最善の方法であるかどうかはわかりません。質問が 2 つあります。

  • これは許容できると思われますか? それとも、明らかにひどいことが何かありますか?
  • 現在動作しているように、ゼロ以外の不透明度データを持つピクセルはほとんどありませんが、ウィンドウのサイズ (最大 1024x768) のオフスクリーン バッファーを使用しているようです。オーバーヘッドの価値はあるでしょうか。そして、それを別々の境界部分に切り分けてそれらを合成するというさらなる複雑さはありますか?
役に立ちましたか?

解決

私の製品は、私は、各ウィンドウにアタッチ少しのタブを描画するレイヤードウィンドウを使用しています。私は、エイリアシングのない滑らかな丸めを取得するために、レイヤードウィンドウを使用していました。私がこれまでに実行しただけで厄介な問題は、一部のOpenGLのウィンドウがDWMなしのWindows XPおよびVista上の階層ウィンドウの上に落書きということです。その低レベルの問題とMicrosoftがひどく参考にされていません。あなたのレイヤードウィンドウが消え、Google Earthのを開くと、メインレンダリングウィンドウの上にアプリケーションをドラッグして、それを再現することができます。

他のヒント

私は一つのことを発見しました:別のフレーム片が途中で空のピクセルの大きな広がりと、1つの巨大なフレームウィンドウを持つよりもはるかに高速にレンダリングすることができました。私は、実際の数字を持っていますが、ちょうどその両方をしようとする簡単なテストから、フルフレームウィンドウで複数のウィンドウが重なるとき、顕著な遅延がありましたが、そのフレームは小さな部品に切断されたとき、それははるかにきびきびしていません。自分のデバイスコンテキストで複数の階層のウィンドウを持つのどのようなオーバーヘッドあまり寄与しない、とピクセルの広大を持つ(空白またはない!)、まだ多くの負荷を貢献します。

  1. RDP および VM (Hyper-V および VMWare) でテストすることを忘れないでください。
  2. いくつかの gfx カードとネットブックおよびラップトップ (該当する場合) を試してください。
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top