有没有办法取消MessageBox.Show()
显示的消息框?
我在想通过向本机win32消息队列发送一个关闭的“消息”(WM_?)是可能的吗?究竟是怎么回事?
答案 0 :(得分:2)
使用WinApi的最简单的解决方案是:
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
private const int WM_CLOSE = 0x10;
private const string MessageBoxTitle = "UniqueTitle123";
void CloseMessageBox()
{
var hwnd = FindWindow(null, MessageBoxTitle);
if (hwnd != IntPtr.Zero)
{
PostMessage(hwnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}
}
您需要使用MessageBoxTitle调用messagebox:
MessageBox.Show("This gonna close itself", MessageBoxTitle);
然后在某处:
CloseMessageBox();
示例用例:
Task.Run(async () =>
{
await Task.Delay(2000).ConfigureAwait(false);
CloseMessageBox();
});
MessageBox.Show("This closes in 2 seconds", MessageBoxTitle);
请注意,如果存在与消息框具有相同标题的不同窗口,则调用CloseMessageBox()将关闭该窗口而不是消息框。解决方案很简单,但选择你的msgbox标题的方式是,与系统f.ex中的其他窗口名称冲突的可能性非常小。 YourAppName-51245
应该没问题。
答案 1 :(得分:0)
我以为我会发布一个' windows hook'解决这个问题,因为我认为这是最好的方法。上面的答案是脆弱的。我已经在本机C ++中提供了代码,因为我缺乏在C#中回答的.net技能。也许拥有这些技能的人会翻译。注意,代码不是线程安全的。如果你在多个线程上创建消息框,那么你必须更聪明一点。
static HHOOK my_hook;
static HWND message_box_hwnd;
// Hook proc
LRESULT CALLBACK MyHookProc (int code, WPARAM wParam, LPARAM lParam)
{
if (code < 0)
return CallNextHookEx (tdata->tcpHook, code, wParam, lParam);
CWPSTRUCT *msg = (CWPSTRUCT *) lParam;
LRESULT result = CallNextHookEx (tdata->tcpHook, code, wParam, lParam);
if (msg->message == WM_INITDIALOG)
{
message_box_hwnd = msg->hwnd;
UnhookWindowsHookEx (my_hook);
my_hook = NULL;
}
return result;
}
my_hook = SetWindowsHookEx (WH_CALLWNDPROC, MyHookProc, NULL, GetCurrentThreadId ());
MessageBox (...);
当然,在你的计时器过程中或其他任何事情:
PostMessage (message_box_hwnd, WM_CLOSE, 0, 0);
或(说):
PostMessage (message_box_hwnd, WM_COMMAND, IDCANCEL, 0);
真的没那么多。