none
他アプリのコンテキストメニューを非表示にする方法 RRS feed

  • 質問

  • こんにちは

    いつもお世話になっております。

     

    ご存じの方教えてください。

     

    多くのWindowアプリには右クリックによるコンテキストメニューが用意されているケースが多いですが、

    たとえば、ForegroundにいるWindowのコンテキストメニューを無効にする方法はあるでしょうか?

     

     疑似コード

           HWND fgWin = ::GetForegroundWindow();
                

                  コンテキストメニューを無効にする( fgWin );     <---(1)

     

                       ~~~~~~~       <さまざまな処理>

     

                  コンテキストメニューを有効に戻す( fgWin );  <---(2)

     

     

    上記の(1)(2)が知りたいのです。

     

    よろしくお願いいたします。

    2008年9月2日 15:48

回答

すべての返信

  • コンテキストメニューを無効にするとは、右クリックやキーボードのアプリケーション キー(右側のWindowsキーの隣にありそうなキー)を押してもメニューを表示しないようにすると言うことですか?

     

    もしそうだとしたら、フックが必要になりそうな気がしますが…。

    2008年9月2日 22:04
    モデレータ
  •  Azulean さんからの引用

    コンテキストメニューを無効にするとは、右クリックやキーボードのアプリケーション キー(右側のWindowsキーの隣にありそうなキー)を押してもメニューを表示しないようにすると言うことですか?

     

    もしそうだとしたら、フックが必要になりそうな気がしますが…。

     

    いつもありがとうございます。

    今回は右クリックしたときに出るメニューのみが非表示したい対象となります。

     

    よろしくお願いいたします。

    2008年9月2日 23:35
  •  kokuchin さんからの引用

    今回は右クリックしたときに出るメニューのみが非表示したい対象となります。

    そのメニューを出す方法はキーボード操作(アプリケーションキー、Shift + F10キー)の他に、アプリによっては左クリックや他の条件で表示することもあります。

    右クリックだけ封じれば良いのですか?

     

     

    さて、そのような関数が存在するかですが、ないと思われます。

    (他のアプリの動作を阻害する目的であること、また汎用性に欠ける処理であることから存在しないのではと推測)

     

    実現できるとすれば、グローバルフックが必要になるとみられますが、コンテキストメニューを全ての場合に封じるのは難しいんじゃないかなと思います。(右クリックを奪うぐらいはできるはず)

    グローバルフックを仕掛けるにはフック用のDLLとして適切にコードを実装していく必要がありますので、関数を呼ぶだけでは済みません。

    グローバルフックがどのようなものかは、検索してみて下さい。
    2008年9月3日 14:09
    モデレータ
  •  Azulean さんからの引用
     kokuchin さんからの引用

    今回は右クリックしたときに出るメニューのみが非表示したい対象となります。

    実現できるとすれば、グローバルフックが必要になるとみられますが、コンテキストメニューを全ての場合に封じるのは難しいんじゃないかなと思います。(右クリックを奪うぐらいはできるはず)

    グローバルフックを仕掛けるにはフック用のDLLとして適切にコードを実装していく必要がありますので、関数を呼ぶだけでは済みません。

    グローバルフックがどのようなものかは、検索してみて下さい。

     

    ありがとうございます。

    実はそのグローバルフックを行ってぶつかった壁なんですが、

    任意のウィンドウ上でマウスの右クリックを伴う操作(たとえば左クリックしながら右クリックなど)をすると自作のオリジナルメニューが出るしかけなんですが、同時にそのアプリ特有のコンテキストメニューが出る場合があるということなんです。(8割ほどは別の方法で回避できているんですが・・・)

     

    ちょっと他の回避策を考えてみます。

    2008年9月3日 17:57
  • WM_CONTEXTMENUをフックするのは駄目ですか?
    2008年9月7日 1:34
  •  村尾DOS さんからの引用

    WM_CONTEXTMENUをフックするのは駄目ですか?

    なるほど。右クリックのフックだけを仕掛けていてうまくいっていないのであれば可能性はありますね。

    きちんとこのメッセージに対して処理を書いていればそれだけで済むかもしれませんが、無視してWM_RBUTTONDOWN/WM_RBUTTONUPとかに書いている可能性もあるので、そちらもフォローしてっと。

     

    でも、こちらを読む限り、WM_RBUTTONUPをDefWindowProcに渡さなければ(なかったことにすれば)、WM_CONTEXTMENUは生成されないようにも読めます。

    実際に試していないので不確かです。

    http://msdn.microsoft.com/en-us/library/ms647592.aspx

    2008年9月7日 2:28
    モデレータ
  •  村尾DOS さんからの引用
    WM_CONTEXTMENUをフックするのは駄目ですか?

     

    ありがとうございます。なるほどです。

    フックは不慣れなので調べながらになりますが、試してみたいと思います。

    2008年9月9日 1:42
  • あまり良い方法ではないかもしれませんが、user32.dll の TrackPopupMenu, TrackPopupMenuEx を一時的に奪って、エラーを返すようにしてみるというのは如何でしょうか?

    2008年9月9日 12:17
  • とりあえず、別の方法でやりたいことは実現できました。

    お応えくださった皆様ありがとうございました。

     

    んで、どうやったかなんですが、たとえば左クリックを押しながら右クリックというケースの場合、

     

    マウスフックのプロシージャ内で

      (1)WM_LBUTTUNDOWNでフラグON

      (2)WM_RBUTTUNDOWNでフラグONなら、非ゼロを返す

         これにより、WM_RBUTTUNDOWNで発動するコンテキストメニューを抑制

      (3)WM_RBUTTUNUPでフラグONなら、自作の別メニューを表示

         ここで仮にウィンドウを表示するなら、非ゼロを返せばWM_RBUTTUNUPで発動するコンテキストメニュー

         を抑制できますが、私の自作メニューはポップアップなため、メニューを閉じないと制御が呼び出し側に

         返りません。つまりメニューを表示している間に、カーソル直下の窓のコンテキストメニューが表示されてし

         まうってことです。

         これを回避するため、WM_RBUTTUNUP時に、小さなダミーのWindow(サイズゼロで可)を作ってこれを

         強制的にForegroundにします。(ただし単にSetForegroundWindowでは失敗する場合がほとんどなので

         工夫が必要。)こうすることで、カーソル直下にあった窓がForegroundから外れてコンテキストメニューが

         表示されなくなります。

     

    教えていただいた案も試そうとしましたが、どうも私のソフトではうまくいかなかったです。

    もっとスマートな方法があったらいいのですが・・・ (まあ、この方法でもソース自体は単純ですけど)

     

    2008年9月16日 16:56