我有一个
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:
private 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之后不起作用,但它解决了我的问题,所以我将此标记为答案,除非出现更好的东西.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。