none
既定ボタンへのマウスポインタを自動で移動【他スレッドからのMessageBox.Show()】 RRS feed

  • 質問

  • 現在、C#にて.Net Windowsアプリケーションを開発中です。@並平と申します。

    本アプリはクライアント的な位置づけで、GUIからの操作を受け付けて、他アプリとの通信によってコマンド送受信を行っております。
    このため、通信系スレッドがいくつかあり、通信で異常(送信不能など)が発生した際には、
    通信系スレッドからForm1のDispMsgBox()を呼び出します。
    Form1のDispMsgBox()は、通信系スレッドからの呼び出しとなるため、delegateを使用してInvokeしていますが、
    単純にMessageBox.Show()の呼び出しで、メッセージボックスの表示時に
    既定ボタン①にマウスポインタが自動的に移動するようにデフォルトボタンを指定しております。

    ※マウスの設定で「ポインタを自動的に既定のボタン上に移動する」の設定は行っています。

    この状況で、通信系スレッドからForm1のDispMsgBox()呼び出しを行った際、
    既定ボタンにマウスポインタが移動せずに困っております。
    尚、Form1側でDispMsgBox()の呼び出しを行った際は正常にポインタが自動で移動します。

    通信スレッドの生成時に何か小細工が必要なのでしょうか?
    知識不足により、ご教授頂けますと大変助かります。

     public partial class Form1 : Form
     {
      private deleDispMsgBox DeleDispMsgBox;

      public Form1()
      {
       InitializeComponent();
       DeleDispMsgBox = new deleDispMsgBox(DispMsgBox);
      }

      private delegate DialogResult deleDispMsgBox(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon);

      public DialogResult DispMsgBox(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon)
      {
       if (this.InvokeRequired)
       {
        return (DialogResult)this.Invoke(DeleDispMsgBox, text, caption, buttons, icon);
       }
       return MessageBox.Show(text, caption, buttons, icon, MessageBoxDefaultButton.Button1);
      }
     }

     

    2009年5月13日 8:36

回答

  • フォーカスはOKボタンに移動していましたので、
    正しくは既定のボタンは有効した。
    つまりは、MessageBox.Show()というよりもマウスドライバもしくはOSの
    問題ということとで自己認識致しました。
    結局、マウスポインタが移動しないので、解決ではありませんが・・・。
    • 回答としてマーク 並平 2009年5月14日 2:31
    2009年5月14日 2:28

すべての返信

  • この状況で、通信系スレッドからForm1のDispMsgBox()呼び出しを行った際、
    既定ボタンにマウスポインタが移動せずに困っております。
    尚、Form1側でDispMsgBox()の呼び出しを行った際は正常にポインタが自動で移動します。

    通信スレッドの生成時に何か小細工が必要なのでしょうか?
    知識不足により、ご教授頂けますと大変助かります。

    下記のようなコードを書いてみましたが、再現できません。
    何か別の要因があるのではないでしょうか?

    スレッドの作り方、DispMsgBoxの呼び出し方あたりが読み取れるようなコードを書いて頂くか、別プロジェクトに切り出して再現させる例を書いてみて頂けませんか。

    private void TestMethod()
    {
        Thread.Sleep(3000);
        DispMsgBox("test", "Test", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
    }
    
    private void button2_Click(object sender, EventArgs e)
    {
        Thread t = new Thread(new ThreadStart(TestMethod));
        t.SetApartmentState(ApartmentState.STA);
        t.Start();
    }
    
    private void button3_Click(object sender, EventArgs e)
    {
        Thread t = new Thread(new ThreadStart(TestMethod));
        t.SetApartmentState(ApartmentState.MTA);
        t.Start();
    }
    

    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    2009年5月13日 14:44
    モデレータ
  • スレッドなど全くの無関係でした。大変失礼致しました。

    MessageBox.Show()の引数において、MessageBoxButtons.OKを指定すると
    マウスポインタが移動しないという現象でした。
    その他、MessageBoxButtons.OKCancelなどを指定した場合には
    問題ないことを確認致しました。

    OKボタン1個である場合、MessageBoxDefaultButton.Button1は有効ではなかったということです。
    掲題の質問とは少々ズレてしまいましたが、これはこれで困りました。
    既定のボタンが指定できないとなると、マウスポインタが移動しません。

    対処方法をご存知でしたら、
    ご教授頂けませんでしょうか。

     

    2009年5月14日 2:08
  • フォーカスはOKボタンに移動していましたので、
    正しくは既定のボタンは有効した。
    つまりは、MessageBox.Show()というよりもマウスドライバもしくはOSの
    問題ということとで自己認識致しました。
    結局、マウスポインタが移動しないので、解決ではありませんが・・・。
    • 回答としてマーク 並平 2009年5月14日 2:31
    2009年5月14日 2:28
  • Windows APIのMessageBox()を直接呼び出してみましたが、移動しませんでした。
    OS側の問題ということになります。
    ちなみに確認はWindows Vista SP2、Windows 7 beta で、両方ともダメでした。
    2009年5月14日 3:58
  • 佐祐理様 調査ありがとうございます。

    OS仕様を調査する知識もないため、MessageBox似の独自Formを作成し
    FormのAcceptButtonプロパティに既定ボタンを設定するというEsc対応を取りました。
    本対応では、表示するボタン数に関わらず既定ボタンへのマウスポインタ移動を確認致しました。

    納得はいきませんが、本件CLOSEさせて頂きます。
    皆様、ありがとうございました。
    2009年5月14日 6:32