DOBON.NET DOBON.NETプログラミング掲示板過去ログ

透明なフォームの作成

環境/言語:[XP、VB.NETまたたC#、.NET Framework1.1]
分類:[.NET]

フリーのツールでよくあるような付箋や透明時計のような
処理を実装しようとしています。
デスクトップにフォームを表示し、その上にはラベルやグリッド、
ボタンなど標準的なコントロールを配置します。
そこでフォーム全体を透過して、表示だけでなくクリックや
マウスの移動などの入力処理自体を下にあるアプリケーションで
受け取れるようにしたいと思っています。

そこでTransparencyKeyを設定してフォームを透明にすると、
フォームのうえをクリックしたときは下のアプリをクリックできるのですが
ボタンなどは押せてしまいます。
ラベルやボタンなどは透過させても、クリックなどの処理は
受け取ってしまうみたいです。

ラベルやボタン、その他の色がついている部分に関しても
入力処理をそのまま下のアプリへ渡す方法はないでしょうか。
フォームで受け取って、それを擬似的にVBで処理して
下へ伝えるというのはなるべく避けたいと思っています。
■No26396に返信(つみひさんの記事)
> そこでTransparencyKeyを設定してフォームを透明にすると、
> フォームのうえをクリックしたときは下のアプリをクリックできるのですが
> ボタンなどは押せてしまいます。

Opacity あるいは TransparencyKey を設定したうえで、

    Protected Overrides ReadOnly Property CreateParams() As CreateParams
        Get
            Const WS_EX_TRANSPARENT As Integer = &H20
            Dim cp As CreateParams = MyBase.CreateParams
            cp.ExStyle = cp.ExStyle Or WS_EX_TRANSPARENT
            Return cp
        End Get
    End Property

と記述しておけば、マウス操作が透過されます。
この場合には、TopMost プロパティも True にしておいた方がよいでしょう。
回答ありがとうございます。
遅くなって申し訳ありません。
こんな簡単にできたんですね。
最初の書き込みのあとも調べていて

SetWindowLong(Me.Handle, GWL.ExStyle, _
_InitialStyle Or WS_EX.Layered Or WS_EX.Transparent)
SetLayeredWindowAttributes(Me.Handle, 0, _
255 * 0.7, LWA.Alpha)

を使用したサンプルをみつけたのですが、
内部的には同じでしょうか。

それともうひとつ、このやり方の場合、
ボタンひとつだけは押せるような状態で残しておくとかは無理ですよね。
コンテキストメニューや、フォームの移動のために
極一部だけ残しておきたいのですが。
もうひとつフォームを用意しておいて追随するような状態にするしかないのかな
と、魔界の仮面弁士さんなどが以前、他のBBSで書いていたのを見つけました。
■No26398に返信(つみひさんの記事)
> を使用したサンプルをみつけたのですが、
そのコードは、Opacity プロパティに 70% (0.7)という値を指定した場合と
同じ結果になります。レイヤードウィンドウを利用する場合、「部分透過」なら
TransparencyKey、「全体半透明」なら Opacity プロパティを使えますので、
このためだけに、わざわざ API を使う必要は無いでしょう。

レイヤード ウィンドウの API が必要になるのは、両方同時に適用したい場合
(部分的な半透明化など)ですが、提示されたコードはそうなってはいません。


> それともうひとつ、このやり方の場合、
> ボタンひとつだけは押せるような状態で残しておくとかは無理ですよね。
レイヤードウィンドウ全体が透過対象となります。


> もうひとつフォームを用意しておいて追随するような状態にするしかないのかな
どうしても別 Form を用意したくないのであれば、たとえばマウスカーソル位置を
追跡して、その座標に応じてマウス透過用の WS_EX_TRANSPARENT を
切り替えるようにすれば、単一 Form だけでも一応は実装できるかと思います。

ちなみに、起動後に WS_EX_TRANSPARENT の指定を切り替えるような場合には
CreateParams の変更を反映させるために、MyBase.UpdateStyles() メソッドを
呼び出すようにします。

> コンテキストメニューや、フォームの移動のために
> 極一部だけ残しておきたいのですが。
別フォームを併用して実装するのも一つの手ですが、あるいは仕様を変えて、
たとえばタスクトレイなどから、WS_EX_TRANSPARENT の On/Off を
切り替えられるな作りにするという案もあるかと思います。

あるいは、特定のキー(たとえば Shift)を押している間は、マウス操作を
有効にするような設計にするとか。
  • 題名: Re[4]: 透明なフォームの作成
  • 著者: つみひ
  • 日時: 2010/02/11 22:38:23
  • ID: 26400
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
詳しい説明までありがとうございます。

> たとえばタスクトレイなどから、WS_EX_TRANSPARENT の On/Off を
> 切り替えられるな作りにするという案もあるかと思います。
初期の開発ではこのようなタスクトレイからの操作を予定しています。

その次の段階でショートカットキーでの切替や、提示していただいたような

> あるいは、特定のキー(たとえば Shift)を押している間は、

というようなものを考えています。
それに加えボタンひとつ分なら残しておいても
邪魔にならないだろうということで、一部だけ残しておけたらなと思いました。
とりあえず教えていただいたようにマウスの位置で判断するか、
またはフォームを用意するかでやってみようと思います。
ありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板