ほとんどのウィンドウにさまざまな丸みを帯びたエッジを持つスキンアプリを開発しています。私はウィンドウ領域を使用して非長方形の形状を定義していますが、ピクセルは完全に不透明または完全に透明にしかできないため、ほとんどすべての人がギザギザのエイリアシングに反対しています。
レイヤードウィンドウを使用してこれに対する解決策を考え出しましたが、これがさまざまなシステムで実行される(そしてうまくいけばうまくいく)ことを確認したいと思います。私がしていることを最適化します。階層化されたウィンドウにはwin2000以降が必要ですが、それは他の理由ですでに必要であるため、問題ありません。いくつかの基本的なテストから、Vistaでは問題ないように見えますが、それはまだ保証されていません。
私がしていることは次のとおりです。私はウィンドウを持っており、それをAと呼び、コントロールとテキスト、およびそのウィンドウを構成するものは何でもあります。ウィンドウAの子としてウィンドウBがありますが、WS_CHILDではなくWS_POPUPスタイルであるため、Aの領域の外側に配置でき、Aのコントロールの上に描画されます。ウィンドウBにもWS_EX_LAYEREDスタイルがあり、初期化時に、ULW_ALPHAフラグを使用してUpdateLayeredWindowを呼び出し、アルファチャネルを使用して32ビットビットマップを使用してソースDCを呼び出し、ピクセルごとのアルファで描画します。
ウィンドウBのソースDCで使用されるビットマップは、ウィンドウの背景から完全な透明度にスムーズにブレンドしたいウィンドウの境界の周りのピクセルにすぎません。2つのウィンドウのアプローチ全体をスキップし、単一のレイヤードウィンドウを使用します。ただし、UpdateLayeredWindowを使用している場合は、通常のWM_PAINTメッセージなどの代わりに、メモリに保持されているバッファーから取得され、取得しようとします。インタラクティブな子コントロール(および子ウィンドウ)をうまく機能させることは、非常に面倒なことのように聞こえます(そして、おそらくすべてに対して機能するわけではありません)。
つまり、基本的にはウィンドウAであり、すべての子コントロールなどがあり、ウィンドウBはその上に直接浮かんでいて、滑らかな境界線を描画しています。WM_MOVEメッセージなどに応答するために、ウィンドウBを一緒に移動し、ウィンドウBを無効にして、フォーカスや入力を取得できないようにします(ウィンドウBの一部、たとえば大部分など、不透明度がゼロの部分があるため、クリックはすでに通過しています。その内部の部分の、すでにピッキングから除外されています)。
キックの場合、これがどのように見えるかを示し、私がもう少し良い意味を示しています。
- ウィンドウAの背景。完全に透明なピクセルをマスクするためにシアンが使用されています。
- ウィンドウBのビットマップ。アルファチャネル(もちろん写真にはありませんが、jpgです)があり、黒以外のピクセルを透明にブレンドします。
- 結合された結果
だから、それは機能しますが、それが本当にこれを行うための最良の方法であるかどうかはわかりません。2つの質問があります:
- これは許容できるように聞こえますか、それとも明らかにひどいことはありますか?
- 現在は機能しているため、ウィンドウのサイズ(最大1024x768)のオフスクリーンバッファを使用しているようですが、不透明度データがゼロ以外のピクセルはごくわずかですが、オーバーヘッドに見合う価値があります。そして、それを別々の境界部分に分割し、それらを一緒に合成するという追加の複雑さ?