読者です 読者をやめる 読者になる 読者になる

syghの新フラグメント置き場

プログラミングTipsやコード断片の保管場所です。お絵描きもときどき載せます。

WPFレイヤードウィンドウのヒットテストを無効化

(これは2012-08-24に書いた故OCNブログの記事を移植したものです)

WPFレイヤード ウィンドウを作る場合、

  • WindowStyle="None"
  • Background="Transparent"
  • AllowsTransparency="True"

のように設定するだけで簡単に実現できます。ピクセル単位のアルファ透過も簡単です。ネイティブWin32のDirect2D/Direct3Dレイヤード ウィンドウを作るときは相当苦労したのに……

で、レイヤード ウィンドウのヒット テストを無効化したいとき、ルート要素(Window)のIsHitTestVisibleをFalseにしただけでは無効になりません。P/Invokeを使って、GetWindowLong()/SetWindowLong() Win32 APIによりネイティブの拡張ウィンドウ スタイルWS_EX_TRANSPARENTを設定してやる必要があります。詳しくはココWPFのWindowは、ButtonとかのVisual要素とは違って、内部でWin32 API(GDI)を使って実装されてるっていう証拠ですね。他にも、WindowStyleにNoneを指定すると、ウィンドウを最大化・最小化するときなどのアニメーションがなくなってしまうのですが、これは同様にWS_CAPTIONスタイルを指定することで一部のアニメーションを復活させることができるようです。

WPFに限らず、レイヤード ウィンドウを使うとHUD (Head-up Display) が簡単かつきれいに作れそう。なお、一時的に表示をON/OFFしたいときは、Visibilityの制御ではなくOpacityをいじったほうがよさそうです(Visibilityを操作すると、Windowのアクティブ状態が変動してしまう)。