我有一个
WPF应用程序,我想看起来它托管在另一个 – 非WPF – 应用程序.在现实生活中,这个非WPF应用程序是Internet Explorer中的ActiveX,但为了说明问题,我使用了一个简单的
Windows窗体应用程序.
我使用Windows API函数SetParent,已经有几十个线程.但是,我找不到任何关于我的确切问题的内容:WPF应用程序右侧和底部的一个小区域没有在非WPF应用程序窗口内绘制.
WPF窗口自行运行:
使用WinForm应用程序窗口作为父级的WPF窗口:
如果将WPF应用程序与WinForms应用程序或普通Win32应用程序(如记事本)交换,我不会遇到此问题.
WinForm代码如下所示:
private void Form1_Load(object sender,EventArgs e) { // Start process var psi = new ProcessStartInfo("c:\\wpfapp\\wpfapp\\bin\\Debug\\wpfapp.exe"); psi.WindowStyle = ProcessWindowStyle.Normal; _process = Process.Start(psi); // Sleep until new process is ready Thread.Sleep(1000); // Set new process's parent to this window SetParent(_process.MainWindowHandle,this.Handle); // Remove WS_POPUP and add WS_CHILD window style to child window const int GWL_STYLE = -16; const long WS_POPUP = 0x80000000; const long WS_CHILD = 0x40000000; long style = GetWindowLong(_process.MainWindowHandle,GWL_STYLE); style = (style & ~(WS_POPUP)) | WS_CHILD; SetWindowLong(_process.MainWindowHandle,GWL_STYLE,style); // Move and resize child window to fit into parent's MoveWindow(_process.MainWindowHandle,this.Width,this.Height,true); }
注意:我知道这个使用SetParent不一定是推荐的做法,但我想并且需要找到如何这样做,所以请让我:)
我找到了一个相当好的解决方法:在SetParent之前调用MoveWindow:
原文链接:https://www.f2er.com/windows/365230.htmlprivate void Form1_Load(object sender,EventArgs e) { // Start process var psi = new ProcessStartInfo("C:\\WpfApp\\WpfApp.exe"); psi.WindowStyle = ProcessWindowStyle.Normal; _process = Process.Start(psi); // Sleep until new process is ready Thread.Sleep(3000); // Move and resize child window to fit into parent's Rectangle rect; GetClientRect(this.Handle,out rect); MoveWindow(_process.MainWindowHandle,rect.Right - rect.Left,rect.Bottom - rect.Top,true); // Set new process's parent to this window SetParent(_process.MainWindowHandle,this.Handle); // Remove WS_POPUP and add WS_CHILD window style to child window long style = GetWindowLong(_process.MainWindowHandle,GWL_STYLE); style = (style & ~(WS_POPUP) & ~(WS_CAPTION)) & ~(WS_THICKFRAME) | WS_CHILD; SetWindowLong(_process.MainWindowHandle,style); }
在SizeChanged事件处理程序中,我将子项从父项中取出,调用MoveWindow并将其移回父项.为了减少闪烁,我在执行这些操作时隐藏了窗口:
private void Form1_SizeChanged(object sender,EventArgs e) { ShowWindow(_process.MainWindowHandle,SW_HIDE); var ptr = new IntPtr(); SetParent(_process.MainWindowHandle,ptr); Rectangle rect; GetClientRect(this.Handle,out rect); MoveWindow(_process.MainWindowHandle,true); SetParent(_process.MainWindowHandle,this.Handle); ShowWindow(_process.MainWindowHandle,SW_SHOW); }
它没有解释为什么MoveWindow在SetParent之后不起作用,但它解决了我的问题,所以我将此标记为答案,除非出现更好的东西.