如果我在另一个进程上显示一个MessageBox作为窗口的模态,只要我的程序仍然响应,它就可以正常工作。如果它在MessageBox显示时被关闭或终止,那么收到MessageBox的窗口将被锁定(但仍然响应),并且必须通过任务管理器完成。
以下示例代码用于演示:
using System;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
namespace TestMessageBox
{
class Program
{
private WindowWrapper notepad;
Program(IntPtr handle)
{
notepad = new WindowWrapper(handle);
}
static void Main(string[] args)
{
Process[] procs = Process.GetProcessesByName("notepad");
if (procs.Length > 0)
{
Console.WriteLine("Notepad detected...");
Program program = new Program(procs[0].MainWindowHandle);
Thread thread = new Thread(new ThreadStart(program.ShowMessage));
thread.IsBackground = true;
thread.Start();
Console.Write("Press any key to end the program and lock notepad...");
Console.ReadKey();
}
}
void ShowMessage()
{
MessageBox.Show(notepad, "If this is open when the program ends\nit will lock up notepad...");
}
}
/// <summary>
/// Wrapper class so that we can return an IWin32Window given a hwnd
/// </summary>
public class WindowWrapper : System.Windows.Forms.IWin32Window
{
public WindowWrapper(IntPtr handle)
{
_hwnd = handle;
}
public IntPtr Handle
{
get { return _hwnd; }
}
private IntPtr _hwnd;
}
}
如何避免?
答案 0 :(得分:1)
显示模式对话框的行为会禁用对话框的父窗口(示例中的记事本窗口)。关闭模态对话框后,将重新启用父窗口。
如果你的程序在重新启用窗口之前就会死掉,那么该窗口将永远不会重新启用 - 这取决于显示对话框的线程,以重新启用父窗口。 (在您的示例中,在用户单击“确定”或其他任何内容后,它会在MessageBox.Show()
内发生。)
实现这项工作的唯一方法就是有一个第二个过程,如果创建模态对话框的过程过早死亡,那么它应该把事情放回去,但这太可怕了。并且它仍然没有防弹 - 如果观察者进程也死了怎么办?