WPF如何在窗口中打开exe程序?

7

不确定是否有可能,但是否有一种方法可以在WPF窗口的容器中打开另一个程序(例如记事本),类似于使用WebBrowser控件打开网页?

基本上,我想打开记事本或其他exe文件,但使用xaml/c#代码将其约束在WPF窗口容器内。不确定是否可能?

3个回答

6

是的,这是可能的。

您需要做的是:

  1. 创建一个WindowsFormsHost并将其添加到UI中的面板中
  2. 使用Process.Start启动进程(例如Notepad)
  3. 调用process.WaitForInputIdle
  4. 使用process.MainWindowHandle获取窗口句柄
  5. 调用SetWindowPos将进程的窗口设置为HwndHost窗口的坐标和Z顺序
  6. 钩住HwndHost和process.MainWindowHandle以检测大小更改并重复步骤5。

这些都非常简单。 效果是整个Notepad窗口(或您启动的任何应用程序)看起来和表现得就像它是您的WPF应用程序的一部分。


WaitForInputIdle等待任何线程变得空闲,而不仅仅是GUI线程。 - Sheng Jiang 蒋晟
@Sheng: 很好的观点。以上适用于像记事本这样简单的应用程序,但对于更复杂的应用程序,可能需要将步骤4替换为定期使用EnumWindows搜索具有与从GetWindowThreadProcessId返回的匹配值的窗口,该窗口可见且没有父级的代码。无论如何,仍然可以使用XAML/C#实现。 - Ray Burns

2

使用SetParent方法成功实现了这一点。

[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetParent(IntPtr hwc, IntPtr hwp);

通过获取WPF窗口的句柄,然后获取exe窗口的句柄,我能够将WPF窗口设置为父窗口,从而模拟嵌入式效果(还关闭了标题栏等)。

从这里得到了帮助:http://channel9.msdn.com/forums/TechOff/250417-Hide-window-caption-in-c/


很高兴这对你有用。但是它确实有两个限制,你应该知道:1. 标题栏、关闭按钮等不会显示,因此它看起来不像一个窗口;2. 它会导致依赖于NC_事件、在非客户区绘制或扫描其窗口树以查找根窗口的应用程序失败。另一种技术则更少侵入性和更普遍,并且还提供了隐藏非客户区域的能力(如果需要)。 - Ray Burns

-1

你不能这样做。

你能够浏览网页的原因是因为IE是使用允许它的架构设计的 - 渲染引擎实际上不是IE可执行文件的一部分,而是一个公开组件的DLL。

通用的可执行文件不是这样工作的,你不能将它们嵌入到你的应用程序中。


1
但是你可以这样做。请看我的回答。 - Ray Burns

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接