Win32:窓の外に絵を描くにはどうすればよいですか?
-
19-09-2019 - |
質問
窓を見る tooltips
クラスヒントウィンドウ、ドロップシャドウが描画されていることがわかります 外 ヒントウィンドウの実際の長方形。
使用する スパイXX - ツールヒントのウィンドウ四角形とクラス スタイルを取得できます。
Rectangle: (440, 229)-(544, 249), 104x20
Restored Rect: (440, 229)-(544, 249), 104x20
Client Rect: (0, 0)-(104, 20), 104x20
表示されるドロップ シャドウは物理的なものであることがわかります。 外 描かれている窓。窓の外に影を描くにはどうすればよいですか? 外 うちの窓?
注記: 影は標準では描画されません CS_DROPSHADOW
クラススタイル。 私はこれを実験的に確認しました。また、ウィンドウのクラススタイルも確認できます。 スパイXX;それは使用しません CS_DROPSHADOW
:
Windows Styles: 94000001
WS_POPUP 80000000
WS_VISIBLE 10000000
WS_CLIPSIBLINGS 4000000
TTS_ALWAYSTIP 1
Extended Styles: 00080088
WS_EX_LAYERED 80000
WS_EX_TOOLWIN 80
WS_EX_TOPMOST 8
では、窓の外に絵を描くにはどうすればよいでしょうか?
注記: デスクトップに絵を描こうとしたらDCが出ました。グレッグ・シェクターの作品より GDI、DirectX、および WPF アプリケーションのリダイレクト:
画面から描画して読む - baaaad!
最後に、私たちはリダイレクトのトピックを使用しているため、特に危険な練習の1つは、GETDC(null)を使用してそれを書くか、xorラバーバンドラインなどを実行しようとすることを通じて、画面に書き込むことです。画面に書き込むことが悪い理由は2つあります。
高いです...画面自体への書き込みは高価ではありませんが、画面に書き込む際にXORのような読み取りワイト操作を通常行うため、画面からの読み取りがほとんど常に伴います。ビデオメモリサーフェスからの読み取りは非常に高価で、DWMとの同期が必要であり、GPUパイプ全体とDWMアプリケーションパイプを失速させます。
それは予測不可能です...どういうわけか実際のプライマリに到達して書くことができた場合、プライマリーに書いたものが画面上に残る期間について予測可能性はありません。UCEはそれについて知らないため、次のフレームの更新でクリアされるか、画面上で他に更新する必要があるものに応じて、非常に長い間持続する可能性があります。(とにかくプライマリーへの直接的な書き込みを本当に許可していません。その理由から...たとえば、DirectDrawプライマリにアクセスしようとすると、アクセスアプリケーションが終了するまでDWMがオフになります。
解決
あなたが説明した方法で窓の外に絵を描くことはできません。
デスクトップを右クリックして、プロパティ/外観/効果に移動し、「メニューの下に影を表示する」のチェックを外します。あなたにはもう影はありません。
要するに、これはプログラムではなくウィンドウマネージャーの製品であるということです。
他のヒント
質問:1 つのウィンドウの外側をどうやって描くのですか?答え:内側に描く 別の 窓!
最初に注意すべきことは、ツールチップ クラスは実際には する 使用 CS_DROPSHADOW
スタイル - ただし、これは クラス スタイルではなく、 窓 スタイルなので、 クラス Spy++ プロパティ ダイアログのタブをクリックして見つけます。ご覧のとおり、 tooltips_class32
Windows には確かにこれがあり、他にもいくつかあります。
しかし、それは次の疑問につながるだけです。 それ 仕事?Windows は、影を描画するためのヘルパー HWND を作成することでこれを実装しているようです。おそらく、影を付けているウィンドウと同じサイズと形状の別のポップアップ ウィンドウを作成し、グレーで塗りつぶし、メイン ウィンドウの直下に配置して、それは WS_EX_LAYERED アルファブレンディングを使用して影を透明にし、エッジの周りでフェードアウトできるようにします。また、自分のウィンドウの 1 つに別のタイプのシャドウ効果を追加したい場合は、同じまたは類似のテクニックを自分で使用することを妨げるものはありません。
つまり、長い話を簡単に言うと、 独自のウィンドウの外側に描画したい場合は、描画したい一般領域にヘルパー透明ウィンドウを作成し、代わりにそのヘルパー ウィンドウ上に描画します。
--
さて、Spy++ でこれらのヘルパー シャドウ ウィンドウの 1 つを見つけようとしても、あまり見つかりません。とは異なり、 tooltip_class32
ウィンドウは存続期間が長く、必要に応じて表示/非表示を繰り返すだけですが、これらのシャドウ ウィンドウはさらにとらえどころのない生き物です。これらは必要な間だけ作成されるため、シャドウを使用するツールチップやポップアップ メニュー、または他のウィンドウが存在するときに Spy++ を更新する必要があります。これは、ツールチップやメニューのほとんどは、シャドウを移動するとすぐに消えてしまうため、注意が必要です。マウスをクリックして Spy++ に切り替えます。しかし、Spy++ 自身のツールバーのツールチップはそのまま残ることがわかりました。Spy++ を起動し、ツールバーの項目にカーソルを合わせて、 F5
ツールヒントとシャドウが表示されている間に HWND ツリーを更新します。ここで下にスクロールすると、ツリー内の 3 番目と 4 番目に表示されている HWND がツールチップ自体であることがわかります。その直後に、 SysShadow
窓。残念ながら、ツールチップとシャドウはすでに消えているため、その HWND のプロパティ ダイアログを取得しようとすると、「無効なウィンドウ」メッセージを含む空のプロパティ ダイアログが表示されます。SysShadow がどのように動作するか、SysShadow 自体がどのようなスタイルを使用しているかなどを実際に調べて確認したい場合は、次のような長期間有効なポップアップを備えたターゲット アプリを作成できます。 CS_DROPSHADOW
その後、Spy++ で自由に探索できるようになります。
(最後に、これらの影は、Vista 以降、アプリ ウィンドウが別のアプリ ウィンドウの上に重なっているときに表示される影とは完全に異なるものであることに注意してください。このタイプの影は Aero Glass モードの一部であり、同じモードで処理されます。 デスクトップ構成マネージャー これにより、ガラスのタイトルバー効果が追加され、影を実装するためにヘルパー ウィンドウを使用したり、必要としたりしません。)
その影がウィンドウ マネージャー自体と密接に関係しているとしても、私は驚かないでしょう。結局それを決めるのは窓口管理者です 何 窓がペイントされる どれの それ自体の一部と いつ それはできるよ。ウィンドウマネージャーがすべてを制御できるようになった場合、その影を描くのはロケット科学とは思えません。