2004年06月13日

背景が透明なウィンドウの作り方(1/2)

環境
Visual C++.NET 2003
ライブラリ
MFC 7.1
OS
Win2000以降

以下のような背景が透明なウィンドウの作り方です。

20040613_transparent.png

ウィンドウの透明な部分をクリックしても、ちゃんと応答するウィンドウになるようにします。

まず、どの方法を使って実現するか考えてみます。候補を以下に挙げてみます。

  • SetWindowRgnによりウィンドウを変形させる方法
  • PaintDesktopにより壁紙をウィンドウに表示する方法
  • レイヤードウィンドウにして透明にする方法

先頭から一つずつ検討してみます。

SetWindowRgnによりウィンドウを変形させる方法。
BeginPath/TextOut/EndPathでテキストの形をしたリージョンが作成できるようなので、これを使い、文字の形をしたウィンドウにすれば上手くいきそうではあるのですが、
文字以外の部分(透明な部分)をクリックすると、背後のウィンドウが応答してしまいます。 これは困りますね。
結局透明な部分をクリックしたときに応答する方法が分からなかったので(システムフックを使えば不可能ではなさそうですが、大変そうです)、この方法はボツです。

PaintDesktopにより壁紙をウィンドウに表示する方法。
このAPIは、デスクトップの壁紙を指定したデバイスコンテキストに描画するAPIです。
デスクトップの壁紙をウィンドウに表示すれば、透明なウィンドウのように見えるはずです。 壁紙の部分をクリックしても、問題なく応答できます。
しかし、メモリデバイスコンテキストに対して描画できないという大きな問題がありまして、 上記画像のようなウィンドウを描画しようとすると、ディスプレイデバイスに 背景描画→テキストという順番で描画する必要があり、ちらつきが発生します。 いろいろと頑張ればちらつきを多少抑えることはできますが、なくすことはできません。 他に方法がなければ諦めてこの方法を使うことにしますが、とりあえず他の方法を考えてみます。他のウィンドウの上に表示すると透明には見えませんしね。

レイヤードウィンドウにして透明にする方法
レイヤードウィンドウはWin2000から追加された機能です。拡張ウィンドウスタイルにGWL_EXSTYLE を指定して、SetLayeredWindowAttributesによりカラーキーやアルファ値を指定することにより透明にきます。
しかし、このレイヤードウィンドウも問題がありまして、透明にしたい部分を黒にしておき、カラーキーを黒にすれば透明にできるのですが、なんと透明にした部分をクリックすると背後にあるウィンドウが応答してしまいます。
アルファ値を指定して透明にすると、テキストまで透明になってしまいますし、どうもうまく行きません。

しかし、このレイヤードウィンドウを2つ重ねればどうやら望みの透明なウィンドウが 実現できそうです。

以下次回に続く・・・

投稿者 MASATO : 2004年06月13日 11:45 | トラックバック
コメント
コメントする









名前、アドレスを登録しますか?