web-dev-qa-db-ja.com

MessageBox TopMostではないのはなぜですか?

私は最近、デフォルトで表示されるときにデフォルトでMessageBoxesが一番上のフォームではないことを発見し、他のウィンドウの上にメッセージボックスを表示したくない状況を誰かが知っているのだろうかと思いましたか?

アプリケーションの読み込み中にスプラッシュスクリーンを表示し始めたときに問題が見つかりました。プログラムはまだ実行されているように見えましたが、スプラッシュスクリーンの背後に入力を待っているMessageBoxがありました。メッセージボックスを呼び出したスレッドとは別のスレッドに表示されるため、スプラッシュの上に表示されなかったのはこのためだと思います。しかし、これは、MessageBoxにデフォルトでMB_TOPMOSTフラグがない理由をまだ説明していませんか?

編集

より明確にするために:最後に、メッセージボックスを作成するために最後にこれに似た何かをしなければならなかった、コードはメモリから書いたように正確ではありません)

[DllImport("User32.dll")]
private int extern MessageBox(windowhandle, message, caption, flag);
public static void MessageBox(windowhandle, string message, string caption)
{
    MessageBox(windowhandle, message,caption, MB_TOPMOST);
}
41
Sayse

アプリケーションの一番上にMessageBoxを表示するには

コード

//Should be MessageBox.Show() below
MessageBox.Show(this, "My top most message");

デフォルトではMB_TOPMOSTではない理由

MB_TOPMOSTがデフォルトの場合、MessageBoxは「システムモーダル」モードで表示され、そのフォームの一番上に表示されます。また、「システムモーダル」モードはMessageBox toBlockメッセージが正常に消えるまでウィンドウは 'アプリケーションモーダル'モードになります。

参照リンク

  1. MSDNフォーラム-一番上のウィンドウとしてメッセージボックスを表示する方法
  2. SO-アプリがトレイに最小化されたときに前面に表示されるC#MessageBox
29
Harsh Baid

提案されたソリューションは、ダイアログが一番上に表示されるはずのウィンドウへのハンドルまたは参照を取得できる場合に機能します。ただし、これは常に可能または簡単に達成できるとは限りません。

  • ウィンドウはスプラッシュスクリーンであり、ビジネスロジックと密結合しないでください
  • ウィンドウは現在のものとは別のクラスまたはライブラリによって作成されます
  • ウィンドウは制御できません。つまり、サードパーティ(ネイティブ)ライブラリからです。

このようなシナリオでは、could_User32.dll_のWin232 MessageBox AP​​Iを使用しますが、よりシンプルな管理ソリューションも利用できます:

_MessageBox.Show(new Form { TopMost = true }, "Hello, I'm on top!");
_

コード_new Form { TopMost = true }_は、メッセージボックスダイアログウィンドウに継承される_MB_TOPMOST_プロパティを持つ非表示フォームを作成します。その結果、他のすべてのウィンドウの上に表示されます。 new Form()インラインを使用すると、副作用がなく、視覚的な外観がなく、ガベージコレクターによって通常どおりに破棄されます。

注:まだフォーム内にいない場合は、名前空間を忘れないでください。これは_System.Windows.Forms.MessageBox_ではなく_System.Windows.MessageBox_です! (ありがとう、 ser1 )。

67
Abel

MessageBoxを表示する場合、その所有者を最初の引数として提供します。たとえば、Formインスタンス呼び出しから呼び出す場合:

MessageBox.Show(this, "Message");

最初の引数として、それを所有するウィンドウへの参照を提供します。

メッセージボックス(および一般的なモーダルフォーム)は、アプリケーションのすべてのウィンドウの上部にnotを表示します。 ownerの上にのみ表示されます。メッセージボックス(または他のモーダルフォーム)をスプラッシュスクリーンの上部に配置する場合は、その所有者をスプラッシュフォームインスタンスに設定します。

3
Sina Iravanian

より完全なコードを貼り付けようとしましたが、間違いなく機能しています

    [CLSCompliant(false)]
    [DllImport("user32.dll", EntryPoint = "MessageBox")]
    public static extern int MessageBoxUser32(int hWnd, String text, String caption, uint type);

    const uint MB_TOPMOST = 0x00040000;
    const uint MB_OK  = 0x00000000;
    const uint MB_OKCANCEL = 0x00000001;
    const uint MB_ABORTRETRYIGNORE = 0x00000002;
    const uint MB_YESNOCANCEL = 0x00000003;
    const uint MB_YESNO = 0x00000004;
    const uint MB_RETRYCANCEL = 0x00000005;

     public static void ShowMessageBox(string message, bool topMost = true
        , string title = null, MessageBoxButtons buttons = MessageBoxButtons.OK)
    {
        if(topMost)
        {
            uint mbv = MB_TOPMOST;

            if (buttons == MessageBoxButtons.OK)
                mbv |= MB_OK;
            if (buttons == MessageBoxButtons.OKCancel)
                mbv |= MB_OKCANCEL;
            if (buttons == MessageBoxButtons.AbortRetryIgnore)
                mbv |= MB_ABORTRETRYIGNORE;
            if (buttons == MessageBoxButtons.YesNoCancel)
                mbv |= MB_YESNOCANCEL;
            if (buttons == MessageBoxButtons.YesNo)
                mbv |= MB_YESNO;
            if (buttons == MessageBoxButtons.RetryCancel)
                mbv |= MB_RETRYCANCEL;

            MessageBoxUser32(0, message, title == null ? string.Empty : title, MB_TOPMOST);
        }
        else
        {
            MessageBox.Show(message, title == null ? string.Empty : title, buttons);
        }
    }
1
Alen Wesker

上記の答えは、オブジェクトNew FormでSystem.iDisposable.Disposeを呼び出す必要があるという事実を除いて、明らかに正しいです。

MessageBoxButtons buttons = MessageBoxButtons.YesNo;
MessageBoxIcon icon = MessageBoxIcon.Error;
string message = Resources.ResourceManager.GetString("MESSAGE");
string caption = Resources.ResourceManager.GetString("TITLE");
DialogResult result;
Form form;
using (form = new Form())
{
    form.TopMost = true;
    result = MessageBox.Show(form, caption, message, buttons, icon);
}
if (result == DialogResult.Yes)
{
    // do something with the result
}

多くのための:

Top-Most-MessageBoxの例

1
Michael Hall