【问题标题】:How to run an application inside wpf application?如何在 wpf 应用程序中运行应用程序?
【发布时间】:2011-06-25 12:56:41
【问题描述】:

我的问题是如何在 WPF 应用程序中运行应用程序(.exe)。 我的意思是在应用程序的窗口内运行,而不是在外部运行应用程序。

提前致谢:D

【问题讨论】:

  • 您为什么可能需要这样做?只需正常启动应用程序即可。我无法想象它需要在 inside 另一个应用程序的窗口中运行的任何可能原因。
  • 感谢您的回复:) 只是我想在我的 WPF 应用程序中使用诸如记事本之类的应用程序。我已经为我的问题找到了解决方案,但它是 WinForm 的一个示例。我不知道如何为 WPF 编写它。任何想法都会被考虑:)
  • 你为什么要这样做?
  • 您正在寻找一个编辑控件。这就是记事本的全部组成部分。在 WinForms 中,这称为TextBox 控件。我不确定它在 WPF 中叫什么。如果您想要更多功能(如写字板),您可以使用RichTextBox 控件(同样,不确定 WPF 将其称为什么)。您根本不需要在窗口中托管其他应用程序。
  • '为什么你可能需要这样做' 这种类型的答案应该被禁止。请回答问题,而不是就“做”和“不做”向人们讲课。你想要一个理由,我给你一个理由:在我的视频监控软件中,我有摄像头矩阵监控一个站点,但我想将一个矩阵的一个单元(WPF Grid)专用于托管一个第 3 方 Windows 应用程序例如,允许控制我正在监控的站点的供暖和通风。

标签: wpf


【解决方案1】:

您想要做的是完全可能的,但它确实存在一些错误,所以不要指望一帆风顺。您需要做的是创建一个继承自HwndHost 并覆盖BuildWindowCore() 方法的类。请参阅 Microsoft 的示例,地址为 http://msdn.microsoft.com/en-us/library/ms752055.aspx

在上面的示例中,它们为您提供了能够在 WPF 表单中放置 Win32 控件的概念,但您可以使用相同的体系结构将您创建的记事本进程的 MainWindowhandle 加载到边框的子进程中.像这样:

protected override HandleRef BuildWindowCore(HandleRef hwndParent)
    {
        ProcessStartInfo psi = new ProcessStartInfo("notepad.exe");
        psi.WindowStyle = ProcessWindowStyle.Minimized;
        _process = Process.Start(psi);
        _process.WaitForInputIdle();

        // The main window handle may be unavailable for a while, just wait for it
        while (_process.MainWindowHandle == IntPtr.Zero)
        {
            Thread.Yield();
        }

        IntPtr notepadHandle = _process.MainWindowHandle;

        int style = GetWindowLong(notepadHandle, GWL_STYLE);
        style = style & ~((int)WS_CAPTION) & ~((int)WS_THICKFRAME); // Removes Caption bar and the sizing border
        style |= ((int)WS_CHILD); // Must be a child window to be hosted

        SetWindowLong(notepadHandle, GWL_STYLE, style);
        SetParent(notepadHandle, hwndParent.Handle);

        this.InvalidateVisual();

        HandleRef hwnd = new HandleRef(this, notepadHandle);
        return hwnd;
    }

请记住,您需要从 User32.dll 中导入一些函数才能设置窗口样式和设置父窗口句柄:

[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);

[DllImport("user32")]
private static extern IntPtr SetParent(IntPtr hWnd, IntPtr hWndParent);

还要确保您包括:

using System.Windows.Interop;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

这是我在论坛上的第一个答案,所以如果它需要一些工作,请告诉我。也可以参考Hosting external app in WPF window,但不要担心 DwayneNeed 的东西。正如您在上面的代码中看到的那样,只需使用 SetParent() 即可。如果您尝试将应用程序嵌入标签页中,请小心。在那里你会遇到一些乐趣。

【讨论】:

  • 谢谢。我有一个问题:我有一个主窗口打开另一个显示托管窗口的窗口。我的问题是我的主窗口冻结了,因为它看起来卡在 while 循环中......它不适用于我的示例应用程序,但它可以用于记事本。
  • 常量定义在哪里?
  • 这个答案中的BuildWindowCore方法似乎取自答案here;该链接具有完整的类,但继承自 HwndHostEx 而不是 HwndHost
猜你喜欢
  • 1970-01-01
  • 2017-06-04
  • 2014-10-12
  • 1970-01-01
  • 1970-01-01
  • 2011-02-20
  • 1970-01-01
  • 1970-01-01
  • 2018-02-01
相关资源
最近更新 更多