将两个不同进程的窗口设置为父子关系

来源:转载


今天用WPF程序给一个第三方程序做插件,该程序支持通过菜单扩展的方式集成第三方程序,看起来像是弹出一个对话框。

但是,由于新写的WPF程序和原程序是没有任何关系的, 一旦原程序重新获取焦点时,新弹出的WPF程序窗口就会切换到后台,看起来就不像子窗口了。看了一下之前的人们的做法,大多是将新蹦出来的窗口设置为TopMost,但这样就又引入了改窗口不能切换到后台隐藏的问题。

在网上搜了一下,找到了如下解决方法: http://stackoverflow.com/questions/2599053/how-to-set-win32-window-as-owner-of-wpf-window。具体就是通过WindowInteropHelper将外部窗口设置为Owner。

var helper = new WindowInteropHelper (myWpfChildWindow); helper-> Owner = mainWindowHWND;

这样做确实解决问题了,但反过来一想,如果要让外部窗口作为WPF的子窗口,就无法用这个方法了。由于WPF程序本身就是调用的WindowsAPI,肯定WindowsAPI是支持两个不相干的窗口的父子关系设置的,便在 referencesource上看了一下其源码,用的是如下代码:

UnsafeNativeMethods.SetWindowLong(new HandleRef(null, CriticalHandle),

NativeMethods. GWL_HWNDPARENT,

_ownerHandle

);

也就是说,它调用的是API SetWindowLong:

LONG WINAPI SetWindowLong( _In_ HWND hWnd, _In_ int nIndex, _In_ LONG dwNewLong );

它有三个参数,第一个参数传入子窗口Handle, 第二个参数传入GWL_HWNDPARENT,第三个传入父窗口Handle。不过,MSDN上同时写着不建议使用这种方式设置父子关系,而需要用SetParent。我试了一下,用这种方式可以,反而用SetParent不行,既然微软自己都在用,暂且先用着,后续发现有问题再补充说明。



分享给朋友:
您可能感兴趣的文章:
随机阅读: