いくつかの MesageBoxButtons を表示し、DialogResult 値を返す C# Framework 3.5 でカスタム MessageBox を作成する必要があります。ユーザーの反応がない場合、一定のタイムアウト時間が経過すると、MessageBox が閉じて null が返されます。
私は DmitryG's answer hereに従いましたが、マイナーな変更が加えられました:
static DialogResult? dialogResult_ = null;
public AutoClosingMessageBox(string text, string caption, int timeout, MessageBoxButtons msbb)
{
_caption = caption;
_timeoutTimer = new System.Threading.Timer(OnTimerElapsed,
null, timeout, System.Threading.Timeout.Infinite);
dialogResult_ = MessageBox.Show(text, caption, msbb);
}
public static DialogResult? Show(string text, string caption, int timeout, MessageBoxButtons efb)
{
new AutoClosingMessageBox(text, caption, timeout, efb);
return dialogResult_;
}
void OnTimerElapsed(object state)
{
IntPtr mbWnd = FindWindow("#32770", _caption);
if (mbWnd != IntPtr.Zero)
{
SendMessage(mbWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
_timeoutTimer.Dispose();
}
dialogResult_ = null;
}
const int WM_CLOSE = 0x0010;
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
MessageBox を作成するには、Show 関数を呼び出すだけです。
AutoClosingMessageBox.Show("Show me sth", "capt", 3000, MessageBoxButtons.AbortRetryIgnore);
このアプローチは、ユーザーが MessageBox 内のボタンをクリックすると dialogResult_ 値を返しますが、WM_Close メッセージはタイムアウト時間後に MessageBox を閉じません。
これは、MessageBox がまだ Dialog Result を待っているためですか? はいの場合、どうすれば回避できますか? 新しいスレッドでメッセージ ボックスを開始したり、スレッドを強制終了したりする必要がないようにしたいと考えています。