关于如何让不同进程之间的窗体成为父子级关系
背景
我的公司在做项目的时候,通过进程打开的方式来其他公司平台的软件。由于我们的平台是主平台,而其他平台就被看做是逻辑上的子平台而被打开。所以需要其他平台所打开的窗体,隶属于我的平台软件窗体,即做为子窗体存在。
大家都知道,在同一个项目(进程)中,可以通过form.Show(parentForm.Handle)或者通过form.ShowDialog(parentForm.Handle)来强制性的指定一个窗体为另一个窗体的子窗体。
那么对于不同程序集之间(不同项目之间、不同进程之间)的程序,可不可以同样的确定两个窗体之间的父子级的关系?答案当然是肯定的。
思路
我们可以观察Show()和ShowDialg()的函数原型:
- public DialogResult ShowDialog(IWin32Window owner);
- public void Show(IWin32Window owner);
他们的参数都是一个实现IWin32Window的对象
我们再看IWin32Window接口
//
// 摘要:
// 提供一个用于公开 Win32 HWND 句柄的接口。
[ComVisible(true)]
[Guid("458AB8A2-A1EA-4d7b-8EBE-DEE5D3D9442C")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IWin32Window
{
//
// 摘要:
// 获取由实施者表示的窗口句柄。
//
// 返回结果:
// 由实施者表示的窗口句柄。
IntPtr Handle { get; }
}
观察上面函数,发现只要在一个对象内部实现获取一个窗口句柄属性方法的对象都以做为传值。那么我们可以想到,我们只要通过一个对象,里面放入某一个进程窗体的句柄,让然后实现这个属性获取该进程窗体的句柄,是不是就可以将这个进程的窗体做为父窗体传入Show或者ShowDialog了。
代码
代码如下:
public class FormHandle : IWin32Window
{
private IntPtr _handle = IntPtr.Zero;
public FormHandle(int handleNum)
{
this._handle = new IntPtr(handleNum);
}
public IntPtr Handle
{
get
{
return this._handle;
}
}
}
上端条用,如已知另一个项目(进程)窗体的句柄的方法为GetOtherProcessWinForm,那么代码为:
//ShowDialog
SonFrm sonFrm = new SonFrm();
sonFrm.ShowDialog(new FormHandle(GetOtherProcessWinForm()));
//Show
SonFrm sonFrm = new SonFrm();
sonFrm.Show(new FormHandle(GetOtherProcessWinForm()));