WPF 中的 WindowsFormsHost 不显示托管应用程序

WindowsFormsHost in WPF Not Displaying Hosted Application

在我的 WPF 中,我有一个包含 WindowsFormsHost 的网格,它将承载一个 .exe。 我的 .xaml 代码是:

<Window x:Class="PracticeWPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:PracticeWPF"
        mc:Ignorable="d"
        Title="MainWindow" Height="800" Width="1300">
    <Grid x:Name="grid">

        <Button x:Name="BtnRun" Content="Run" 
                HorizontalAlignment="Left" Margin="10,10,0,0"
                VerticalAlignment="Top" Click="BtnRun_Click"/>

        <WindowsFormsHost x:Name="formshost" Margin="0,39,0,0"
            Height="720" Width="1280"/>

    </Grid>
</Window>

还有我的cs:

namespace PracticeWPF
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        [DllImport("user32.dll")]
        public static extern int SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        private void BtnRun_Click(object sender, EventArgs e)
        {
            Process proc = Process.Start("notepad.exe"); 
            proc.WaitForInputIdle();

            while (proc.MainWindowHandle == IntPtr.Zero)
            {
                Thread.Sleep(100);
                proc.Refresh();
            }
            SetParent(proc.MainWindowHandle, formshost.Handle);
        }    
    }
}

当我使用 WinForm 时一切正常,但是当我在 WPF 中使用 WindowsFormsHosting 时,.exe 不可见。 任何帮助将不胜感激。 谢谢。

恐怕 WindowsFormsHost 无法在另一个应用程序中托管整个 Windows Forms 应用程序。

它用于在 WPF 视图中托管一个单独的 Windows 表单 控件

如果您想获取 WPF window 的句柄,请尝试:

new System.Windows.Interop.WindowInteropHelper(this).Handle

您想使用此句柄而不是 formshost.Handle

在此linkDocking Window inside another Window我想你的答案。我把它和你的代码匹配了

xaml

<Window x:Class="PracticeWPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"  
        xmlns:local="clr-namespace:PracticeWPF"
        mc:Ignorable="d"
        Title="MainWindow" Height="800" Width="1300">
    <Grid x:Name="grid">

        <Button x:Name="BtnRun" Content="Run" 
                HorizontalAlignment="Left" Margin="10,10,0,0"
                VerticalAlignment="Top" Click="BtnRun_Click"/>

        <WindowsFormsHost x:Name="formshost" Margin="0,39,0,0"
            Height="720" Width="1280">
             <wf:Button Text="by button" Visible="False"></wf:Button>
        </WindowsFormsHost>
    </Grid>
</Window>

mainwindow.cs

namespace PracticeWPF
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void BtnRun_Click(object sender, EventArgs e)
        {
            //Process proc = Process.Start("notepad.exe");
           //proc.WaitForInputIdle();

            //while (proc.MainWindowHandle == IntPtr.Zero)
            //{
            //    Thread.Sleep(100);
            //    proc.Refresh();
            //}
            this.Width = formshost.Width;
            this.Height = formshost.Height;
            dockIt();
        }


        [DllImport("user32.dll")]
        public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        private Process pDocked;
        private IntPtr hWndOriginalParent;
        private IntPtr hWndDocked;

        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);


        private void dockIt()
        {
            if (hWndDocked != IntPtr.Zero) //don't do anything if there's already a window docked.
                return;
            IntPtr hWndParent = IntPtr.Zero;

            pDocked = Process.Start(@"notepad");
            while (hWndDocked == IntPtr.Zero)
            {
                pDocked.WaitForInputIdle(1000); //wait for the window to be ready for input;
                pDocked.Refresh();              //update process info
                if (pDocked.HasExited)
                {
                    return; //abort if the process finished before we got a handle.
                }
                hWndDocked = pDocked.MainWindowHandle;  //cache the window handle
            }
            //Windows API call to change the parent of the target window.
            //It returns the hWnd of the window's parent prior to this call.
            hWndOriginalParent = SetParent(hWndDocked, formshost.Handle);

            //Wire up the event to keep the window sized to match the control
            formshost.SizeChanged += new SizeChangedEventHandler(Panel1_Resize);
            //Perform an initial call to set the size.
            Panel1_Resize(new Object(), new EventArgs());
        }

        private void undockIt()
        {
            //Restores the application to it's original parent.
            SetParent(hWndDocked, hWndOriginalParent);
        }

        private void Panel1_Resize(object sender, EventArgs e)
        {
            //Change the docked windows size to match its parent's size. 
            MoveWindow(hWndDocked, 0, 0, (int)formshost.Width, (int)formshost.Height, true);
        }
    }
}