为了解释我的问题,我会尝试将其截图,以便我可以将我的信息传达给每个人。在图片上,我有一个主项目,即MainWinForm和解决方案文件夹,其中包含两个Windows项目,即FirstWinFormApp和SecondWinFormApp。
以下是截图:
MainWinForm项目包含一个Form1.cs,它是一个设置为true的MDI容器。我正在尝试使用按钮单击事件处理程序从FirstWinFormApp项目启动表单(First.cs)。
一切都应该正常。我可以在Form1的MDI容器中启动First.cs表单。
现在这里是棘手的部分,我想运行FirstWinFormApp的Program.cs而不是MainWinForm的Program.cs。这背后的原因是我对我的项目(程序集,连接等)的要求。
当我启动应用程序时,会触发MainWinForm项目的Program.cs。当我调用子应用程序时,它的Program.cs不再被调用。即使已经调用了MainWinForm项目的Program.cs,我是否可以调用子应用程序的Program.cs(FirstWinFormApp)?
答案 0 :(得分:3)
我认为MDI容器和子窗口属于不同的可执行文件(不同的项目和所有)。首先不建议这样做,但可以这样做。基本上你需要搞乱Windows API而不使用Framework管理方法。
您肯定需要SetParent API - 即使父窗口不是MDI容器,也可以将窗口放在另一个窗口中。但是,您需要某种方式来传递父窗口的Handle属性,并且这些方法要么不稳定(将指针写入两个进程都可以访问的位置)或者不必要地复杂化(需要进程间通信)。
最简单的是,您可以使用FindWindow通过标题找到孩子的主窗口。如果另一个程序与MDI窗口具有相同的标题,则会失败。
以下代码未经测试,但您需要在子窗口的Program.cs中使用它:
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
private static extern IntPtr FindWindow(IntPtr className, string lpWindowName);
并在您孩子的程序中使用Main()
var hwnd = FindWindow(IntPtr.Zero, "My MDI Title");
SetParent(childWindow.Handle, hwnd);
在你的情况下,这将是
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
private static extern IntPtr FindWindow(IntPtr className, string lpWindowName);
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var formObj = new First();
var hwnd = FindWindow(IntPtr.Zero, "My MDI Title");
SetParent(formObj.Handle, hwnd);
Application.Run(formObj);
}
请务必将MDI表单的标题更改为“我的MDI标题”。 在下面的测试应用中,我正在反向执行 - 在Form1中放置一个记事本窗口,但您可以按照自己喜欢的方式进行操作。