私は最近、デフォルトで表示されるときにデフォルトで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);
}
アプリケーションの一番上にMessageBoxを表示するには
コード
//Should be MessageBox.Show() below
MessageBox.Show(this, "My top most message");
デフォルトではMB_TOPMOST
ではない理由
MB_TOPMOSTがデフォルトの場合、
MessageBox
は「システムモーダル」モードで表示され、そのフォームの一番上に表示されます。また、「システムモーダル」モードはMessageBox
toBlockメッセージが正常に消えるまでウィンドウは 'アプリケーションモーダル'モードになります。
参照リンク
提案されたソリューションは、ダイアログが一番上に表示されるはずのウィンドウへのハンドルまたは参照を取得できる場合に機能します。ただし、これは常に可能または簡単に達成できるとは限りません。
このようなシナリオでは、could_User32.dll
_のWin232 MessageBox
APIを使用しますが、よりシンプルな管理ソリューションも利用できます:
_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 )。
MessageBox
を表示する場合、その所有者を最初の引数として提供します。たとえば、Form
インスタンス呼び出しから呼び出す場合:
MessageBox.Show(this, "Message");
最初の引数として、それを所有するウィンドウへの参照を提供します。
メッセージボックス(および一般的なモーダルフォーム)は、アプリケーションのすべてのウィンドウの上部にnotを表示します。 ownerの上にのみ表示されます。メッセージボックス(または他のモーダルフォーム)をスプラッシュスクリーンの上部に配置する場合は、その所有者をスプラッシュフォームインスタンスに設定します。
より完全なコードを貼り付けようとしましたが、間違いなく機能しています
[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);
}
}
上記の答えは、オブジェクト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
}
多くのための: