問題タブ [layered-windows]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
windows - UpdateLayeredWindow の呼び出し後もレイヤード ウィンドウが WM_PAINT メッセージを受信する
UpdateLayeredWindow()
アプリには、視覚的な表現を処理するために使用するレイヤード ウィンドウがいくつかあります。レイヤード ウィンドウに関する MSDN の記事によると、「アプリケーションを使用しているときは、他の描画メッセージUpdateLayeredWindow()
に応答する必要はありません。」WM_PAINT
それらは非レイヤード ウィンドウと同じメッセージ ハンドラーの一部を共有していたのでWM_PAINT
、ターゲットがレイヤード ウィンドウの場合は処理から早く戻ることにしました。
もちろん、これは 1 つの大きな問題を引き起こしました: 階層化されたウィンドウの 1 つがメッセージを受け取った場合、入力キューは終わりのないメッセージWM_PAINT
ストリームであふれてしまいWM_PAINT
ます。ウィンドウは検証されず、ペイントする必要があると考え続けるため (検証やBeginPaint()
ing などを行わずにハンドラーから戻るべきではありません)、この最終結果は理にかなっていますが、意味をなさないものは何ですか?を使用していたウィンドウには影響しないため、そもそもメッセージを受け取ったのはこのためUpdateLayeredWindow()
です。
ウィンドウのピクセルの再描画が必要になるたびにではなく、時々発生するだけで、確実に発生するわけではありません。DefWindowProc()
階層化されたウィンドウがメッセージを受け取ったときに戻って正気を取り戻しましたWM_PAINT
が、理解できない何かが起こっているように感じます. そして、この問題がめったに現れなかったことを考えると、これがさらに微妙な問題を隠しているのではないかと心配しています. UpdateLayeredWindow()
時折WM_PAINT
メッセージを取得するために使用しているウィンドウに期待される動作ですか? 私がそれを正しく扱う限り、それは問題ですか?
必要に応じて追加情報: ウィンドウはUpdateLayeredWindow()
作成直後に呼び出され、その後はそのまま残されます (変更されないため、再度呼び出されることはありません)。C++ と win32 API を使用し、MFC は使用しません。
c# - ウィンドウシッター-レイヤードウィンドウのカラーキーイングとクリックスルー
私は数年前にVisualBasic6でウィンドウシッターを作成しました。これは、レイヤードウィンドウのカラーキーイングを使用して、フォームを無痛で非長方形にしました。
今週初めにC#でウィンドウシッターを書き直そうとしましたが、古いコードが混乱していると判断し、フォームのクライアント長方形内のクリックがフォームによってキャッチされたのに対し、VB6バージョンのクリックは以下の場合に落ち込んだことに気付きました。表示されている部分をクリックしませんでした。もちろん、これは非常に重要な問題です。
レイヤードWindowsAPIを手動で呼び出す(VB6)と、私が知らないTransparancyKeyプロパティ(.Net)との間にいくつかの違いはありますか、それともここにもっとありますか?
wpf - Windowsでオーバーレイグラフィックを描画するための最良の方法は何ですか?
さまざまなカスタムウィンドウタイプを作成する必要があるWin32アプリケーションを使用しています。特に、これらのウィンドウは、多くの場合、長方形ではないか、影があるか、ほとんどが透明です。
現在、WS_EX_LAYERED
withを使用しUpdateLayeredWindow
て、任意のグラフィックを描画できる透明なウィンドウを作成しています。ただし、階層化されたウィンドウには制限があり、階層化された子ウィンドウを作成することも、階層化されたウィンドウで「通常の」Win32コントロールを適切にホストすることもできません。
私たちのコードベースは数年前のもので、主にWin32とGDIを使用していますが、現在、最新のテクノロジーを検討しています。
WPFでカスタムウィンドウ処理を行うことを検討しましたが、「空域」の問題について読んだ内容が気になります。WPFは、レイヤードウィンドウを使用してピクセルごとのアルファブレンディングを実現しているようです。そのため、以前に経験した制限にも悩まされているようです。
Direct2Dについては(実際には何も)よくわかりませんが、そのテクノロジーは興味深いかもしれません。ただし、オーバーレイウィンドウを実行できることへの参照は見つかりません。
だから、これはすべて私の問題に私をもたらします:Windowsの下でオーバーレイウィンドウを実行するための最良の技術は何ですか?(少なくともVistaとWin7、XPがあればいいのですが)
私はいくつかの、特に優れた技術を無視していますか?任意の提案をいただければ幸いです。
com - レイヤード ウィンドウと COM ドラッグ イメージ
メイン ウィンドウ、レイヤード ウィンドウを表示し、COM ドラッグ アンド ドロップを実装するプログラムがあります。一般的に言えば:
- 通常のトップレベルウィンドウを作成します。
- WS_EX_LAYERED と UpdateLayeredWindow/SetLayeredWindowAttributes を使用してレイヤード ウィンドウを作成します (両方試しました)。レイヤード ウィンドウは、1 で作成したウィンドウの上に配置されます。レイヤード ウィンドウは子ウィンドウではありません。
- 次に、COM の DoDragDrop 関数を使用してドラッグ アンド ドロップを開始します。IDropSource::QueryContinueDrag では、ImageList_BeginDrag、ImageList_DragMove などを呼び出します。
問題は、COM が表示しているドラッグ イメージ (イメージ リスト内のイメージ) が、レイヤード ウィンドウの上ではなく下に表示されることです。レイヤード ウィンドウの上にカーソルが表示されます (予想どおり)。下から上に、私が得ているレイヤーは次のとおりです。
- メインウィンドウ(下)
- COMドラッグ画像
- レイヤード ウィンドウ
- カーソル(上)
それは次のとおりです。
- メインウィンドウ(下)
- レイヤード ウィンドウ
- COMドラッグ画像
- カーソル(上)
KB943326「Windows Server 2003 または Windows XP で、重なっている階層化されたウィンドウが正しい順序で表示されない」(" http://support.microsoft.com/kb/943326 ") を既に適用しましたが、違いはありませんでした。
XP SP2 を実行しています。
アイデアが尽きてしまったので、何か提案をいただければ幸いです...
ありがとう、蘇グリーン
winapi - Win32: ドロップ シャドウを非長方形のレイヤード ウィンドウに反映させる方法は?
WS_EX_LAYERED拡張スタイルを追加して、レイヤード ウィンドウを作成しました。
Windows は、クロマ キー カラー値として黒を使用します。問題を明確にするために、黒の大きな境界線を残します。
ウィンドウが構築された後、クロマキー カラーとして黒を使用するように指示します。
ポップアップ レイヤード ウィンドウが部分的に透明に表示されます。
問題は最後のステップです。Windows XP 以降で利用できるCS_DROPSHADOWクラス スタイルを使用して、ドロップ シャドウを作成します。
ドロップ シャドウが表示されますが、影は元の四角形のウィンドウを囲んでおり、レイヤード ウィンドウによって提供されるウィンドウの透明度は考慮されていません。
ドロップシャドウが非長方形のレイヤードウィンドウを尊重するようにする、どこかで見逃した魔法のオプションを誰かが知っていますか?
この問題が発生する別の例は、6px のパディング/マージンを含めない場合です。Windows® テーマによって描画されるヒント ウィンドウは、四角形ではありません。これにより、ウィンドウが透明になる小さな隙間が残りますが、ドロップ シャドウは表示されません。
Internet Explorer からのこのヒントからわかるように、Microsoft はそれを機能させることに成功しました。
Windowstooltips
クラス ヒント ウィンドウの拡大図。SpyXXを使用すると、そのウィンドウ rect とクラス スタイルを取得できます。
SpyXX 言います:
したがって、すべてがウィンドウ自体が 104x20 ピクセルであり、ドロップ シャドウがウィンドウ自体の外側にあることを示しています。(これは と一致していCS_DROPSHADOW
ます。)
tooltips
次に、ウィンドウ クラスのスタイルを確認します。
CS_SAVEBITS
興味深いことに、 ( 0x800
);は使用しません。これは、小さくて寿命の短いウィンドウに役立ちます。
CS_DROPSHADOW
( )も使用しません0x20000
。それで、自分のウィンドウの外でどのように描画しているのだろうか?
注:透明なレイヤード ウィンドウは、領域よりも優先される手法として文書化されています。
編集:レイヤード Windows は Windows 2000 で使用されています。CS_DropShadow は XP で追加されました。
windows - 窓の外に描く方法は?
Windowstooltips
クラスのヒント ウィンドウを見ると、ヒント ウィンドウの実際の四角形の外側にドロップ シャドウが描画されていることがわかります。
SpyXXを使用すると、ツールチップのウィンドウ四角形とクラス スタイルを取得できます。
表示されるドロップ シャドウは、描画されているウィンドウの物理的な外側にあることがわかります。窓の外にいるときに、窓の周りに影を描くにはどうすればよいですか?
注:影は、標準CS_DROPSHADOW
のクラス スタイルを使用して描画されません。私はこれを実験的に確認しており、SpyXXのウィンドウのクラス スタイルも確認できます。使用しませんCS_DROPSHADOW
:
では、どうすればウィンドウの外に描画できますか?
注:デスクトップ DC で描画しようとするとアウトです。Greg Schechter のRedirecting GDI、DirectX、および WPF アプリケーションから:
画面への描画と画面からの読み取り -- ひどい!
最後に、リダイレクトの話題なので、GetDC(NULL) を使用して画面に書き込むか、XOR ラバーバンド行を実行しようとするなど、特に危険な方法の 1 つに画面への書き込みがあります。2 つあります。画面への書き込みが悪い大きな理由:
高価です...画面への書き込み自体は高価ではありませんが、通常、画面への書き込み時にXORのような読み取り-変更-書き込み操作を行うため、ほとんどの場合、画面からの読み取りが伴います。ビデオ メモリ サーフェスからの読み取りは非常にコストがかかり、DWM との同期が必要であり、GPU パイプ全体と DWM アプリケーション パイプが停止します。
それは予測不可能です...どうにかして実際のプライマリに到達してそれに書き込むことができた場合、プライマリに書き込んだものがどれくらい画面に残るかについての予測可能性はありません. UCE はそれを認識していないため、画面で他に何を更新する必要があるかによって、次のフレーム リフレッシュでクリアされるか、非常に長い間存続する可能性があります。(とにかく、プライマリへの直接書き込みを許可していません。まさにその理由です...たとえば、DirectDrawプライマリにアクセスしようとすると、アクセスしているアプリケーションが終了するまでDWMがオフになります)
c++ - レイヤード ウィンドウで InvalidateRect を呼び出した後、OnPaint で空の更新矩形を取得する
透明なウィンドウで InvalidateRect を呼び出すと、空の更新長方形が表示される理由を理解しようとしています。アイデアは、ウィンドウに何かを描画したことです (描画のアルファが一時的に 1/255 に切り替えられます)。次に、それを完全な透明モード (つまり、アルファが 0) に切り替えて、デスクトップ & デスクトップ上の画面上で図面を移動できるようにします。
描画を移動しようとすると、境界の四角形を取得し、それを使用して InvalidateRect を呼び出します。
InvalidateRect(m_hTarget, &winRect, FALSE);
winRect が実際に正しいこと、m_hTarget が正しいウィンドウであること、およびその四角形が winRect を完全に取り囲んでいることを確認しました。
CWnd から派生した m_hTarget に対応するクラスの OnPaint ハンドラーに入ります。そこで CPaintDC を作成しますが、更新用の四角形 (dcPaint.m_ps.rcPaint) にアクセスしようとすると、常に空になります。この四角形は、画面を更新する必要があるかどうかを判断する関数に渡されます (透明なウィンドウの場合は UpdateLayeredWindow を使用)。
ここで空でない四角形をハードコードすると、残りのコードは正しく機能し、画面上で図面を移動できます。
InvalidateRect で「FALSE」パラメータを「TRUE」に変更しようとしましたが、効果はありませんでした。また、標準の CDC を使用してから、OnPaint ハンドラーで BeginPaint/EndPaint メソッドを使用して、CPaintDC が奇妙なことをしていないことを確認しましたが、同じ結果が得られました。
私が使用しているコードは、もともと不透明なウィンドウ用に設計されたものです。m_hTarget が不透明なウィンドウに対応する場合、同じ関数呼び出しのセットにより、正しい (つまり、空ではない) 四角形が OnPaint に渡されます。ただし、ウィンドウがレイヤー化されると、正しく機能しないようです。
c++ - ウィンドウを常に最前面に表示する -- メニューを含む (win32)
常に最前面に表示されるレイヤード ウィンドウが必要ですが、メニュー (スタート メニューを含む) など、その上に描画される特定の画面要素があります。
アプリケーションのウィンドウまたは子ウィンドウに、別のアプリケーションのメニューの上に描画するのに十分なトップネス プロパティを持たせる方法はありますか? または、現在アクティブなアプリケーションのメニューが常に上に描画されるようにする、ウィンドウに組み込まれているものはありますか?
実際、私はメニューがどのように機能するかをよく理解していません。したがって、より多くのものをカバーすることを期待して、ウィンドウを「メニューのように機能させる」ことを試みても意味がないかもしれません。
delphi - レイヤードウィンドウのシステムメニュー?
Delphi 2009のレイヤードウィンドウとシステムメニューに問題があります。つまり、レイヤードウィンドウ(境界線がない)にはシステムメニューがありません。システムメニューとは、アプリケーションのアイコンをクリックするか、タイトルバーを右クリックするか、(Windows 7ではShiftキーを追加して)タスクバーのアプリケーションを右クリックしたときに表示されるメニューを指します。 :
このようなレイヤードウィンドウのタスクバーアイコンを右クリックするなどしてシステムメニューにアクセスしようとすると、代わりにレイヤードウィンドウが表示されます。どうしてこれなの?設定するスタイルや、処理するイベントはありますか?
これは、問題を示す急いで作成されたデモです。ただし、bsNoneボーダースタイルを使用すると、どのような形式でも実際に再現できます。
winapi - Windowsのスキニングエンジン:「ダーティ」な領域のみを描画しますか、それともウィンドウ全体を一度に描画しますか?
アルファブレンドでカスタムシェイプのウィンドウを描画できるスキニングエンジンを作りたいです。つまり、レイヤードウィンドウ(UpdateLayeredWindow)を使用します。典型的なウィンドウには、その背景の中に、10×10からたとえば300×150ピクセルの範囲の他の数十のビットマップが含まれます。最悪の場合、これらの要素のほとんどは30fpsまでのスムーズなアニメーションになります。すべてがアルファブレンドされ、これにはDirect2Dを使用します(はい、古いバージョンのWindowsではサポートされていません)。一般的に、Winampの最新のスキンエンジンが最も近い例です。
これらすべてを考慮し、最新のPCのパフォーマンスを考慮に入れると、ウィンドウ全体を1フレームごとに再描画できますか、それともある種のクリップ長方形に制限する必要がありますか?