トップ回答者
他アプリのコンテキストメニューを非表示にする方法

質問
-
こんにちは
いつもお世話になっております。
ご存じの方教えてください。
多くのWindowアプリには右クリックによるコンテキストメニューが用意されているケースが多いですが、
たとえば、ForegroundにいるWindowのコンテキストメニューを無効にする方法はあるでしょうか?
疑似コード
HWND fgWin = ::GetForegroundWindow();
コンテキストメニューを無効にする( fgWin ); <---(1)
~~~~~~~ <さまざまな処理>
コンテキストメニューを有効に戻す( fgWin ); <---(2)
上記の(1)(2)が知りたいのです。
よろしくお願いいたします。
すべての返信
-
kokuchin さんからの引用 今回は右クリックしたときに出るメニューのみが非表示したい対象となります。
そのメニューを出す方法はキーボード操作(アプリケーションキー、Shift + F10キー)の他に、アプリによっては左クリックや他の条件で表示することもあります。
右クリックだけ封じれば良いのですか?
さて、そのような関数が存在するかですが、ないと思われます。
(他のアプリの動作を阻害する目的であること、また汎用性に欠ける処理であることから存在しないのではと推測)
実現できるとすれば、グローバルフックが必要になるとみられますが、コンテキストメニューを全ての場合に封じるのは難しいんじゃないかなと思います。(右クリックを奪うぐらいはできるはず)
グローバルフックを仕掛けるにはフック用のDLLとして適切にコードを実装していく必要がありますので、関数を呼ぶだけでは済みません。
グローバルフックがどのようなものかは、検索してみて下さい。 -
Azulean さんからの引用 kokuchin さんからの引用 今回は右クリックしたときに出るメニューのみが非表示したい対象となります。
実現できるとすれば、グローバルフックが必要になるとみられますが、コンテキストメニューを全ての場合に封じるのは難しいんじゃないかなと思います。(右クリックを奪うぐらいはできるはず)
グローバルフックを仕掛けるにはフック用のDLLとして適切にコードを実装していく必要がありますので、関数を呼ぶだけでは済みません。
グローバルフックがどのようなものかは、検索してみて下さい。
ありがとうございます。
実はそのグローバルフックを行ってぶつかった壁なんですが、
任意のウィンドウ上でマウスの右クリックを伴う操作(たとえば左クリックしながら右クリックなど)をすると自作のオリジナルメニューが出るしかけなんですが、同時にそのアプリ特有のコンテキストメニューが出る場合があるということなんです。(8割ほどは別の方法で回避できているんですが・・・)
ちょっと他の回避策を考えてみます。
-
村尾DOS さんからの引用 WM_CONTEXTMENUをフックするのは駄目ですか?
なるほど。右クリックのフックだけを仕掛けていてうまくいっていないのであれば可能性はありますね。
きちんとこのメッセージに対して処理を書いていればそれだけで済むかもしれませんが、無視してWM_RBUTTONDOWN/WM_RBUTTONUPとかに書いている可能性もあるので、そちらもフォローしてっと。
でも、こちらを読む限り、WM_RBUTTONUPをDefWindowProcに渡さなければ(なかったことにすれば)、WM_CONTEXTMENUは生成されないようにも読めます。
実際に試していないので不確かです。
-
とりあえず、別の方法でやりたいことは実現できました。
お応えくださった皆様ありがとうございました。
んで、どうやったかなんですが、たとえば左クリックを押しながら右クリックというケースの場合、
マウスフックのプロシージャ内で
(1)WM_LBUTTUNDOWNでフラグON
(2)WM_RBUTTUNDOWNでフラグONなら、非ゼロを返す
これにより、WM_RBUTTUNDOWNで発動するコンテキストメニューを抑制
(3)WM_RBUTTUNUPでフラグONなら、自作の別メニューを表示
ここで仮にウィンドウを表示するなら、非ゼロを返せばWM_RBUTTUNUPで発動するコンテキストメニュー
を抑制できますが、私の自作メニューはポップアップなため、メニューを閉じないと制御が呼び出し側に
返りません。つまりメニューを表示している間に、カーソル直下の窓のコンテキストメニューが表示されてし
まうってことです。
これを回避するため、WM_RBUTTUNUP時に、小さなダミーのWindow(サイズゼロで可)を作ってこれを
強制的にForegroundにします。(ただし単にSetForegroundWindowでは失敗する場合がほとんどなので
工夫が必要。)こうすることで、カーソル直下にあった窓がForegroundから外れてコンテキストメニューが
表示されなくなります。
教えていただいた案も試そうとしましたが、どうも私のソフトではうまくいかなかったです。
もっとスマートな方法があったらいいのですが・・・ (まあ、この方法でもソース自体は単純ですけど)