WPF嵌入外部exe应用程序-使用Winfom控件承载外部程序

在WPF中使用Winfom控件

首先要解决在WPF中如何使用Winfom控件的问题,官方对此有支持的方式。

添加winform相关的程序集

在引用管理器中添加winfrom相关的程序集System.Windows.FormsWindowsFormsIntegration

在这里插入图片描述

在XAML头中加入对这两个程序集命名空间的引用

xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
xmlns:wfi ="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"

使用Winform控件

然后使用winform的控件,得在外面套一层WindowsFormsHost(好像添加了WindowsFormsIntegration,不使用wfi:也能使用)

<wfi:WindowsFormsHost Margin="0,0,400,73">
    <wf:TextBox />
</wfi:WindowsFormsHost>

在这里插入图片描述

效果:

这样就可以在WPF中使用Winform控件,但是不推荐,除非特殊情况。

在这里插入图片描述

问题

这种方式存在的问题:

  • WindowsFormsHost依旧是显示在最前,暂时没找到解决方法,尽量从设计上避免

  • 后台无法获取到WindowsFormsHost内部控件的名称,只能通过WindowsFormsHost获取内部控件的句柄。

在Winfom控件中嵌入exe程序

准备Winfrom控件

WindowsFormsHost中控件换成Panel

<wfi:WindowsFormsHost Name="WFHost" Margin="0,0,400,73">
    <wf:Panel  />
</wfi:WindowsFormsHost>

更换父窗体的句柄

将获取主窗体句柄换成获取Panel句柄,然后设置窗体大小跟WindowsFormsHost控件一样

   //当前窗体/容器(主程序)句柄
  IntPtr hwnd = WFHost.Child.Handle;
  //设置窗体位置和大小
  MoveWindow(appWin, 0, 0, (int)WFHost.ActualWidth, (int)WFHost.ActualHeight, true);

完整实现代码:

上述功能完整实现的代码如下
可以更新到上一篇的MainWindow的代码中去。

           var exeName = "C:\\WINDOWS\\system32\\mspaint";
            //使用Process运行程序
            Process p = new Process();
            p.StartInfo.FileName = exeName;
            p.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
            p.Start();
            //获取窗体句柄
            while (p.MainWindowHandle.ToInt32() == 0)
            {
    
    
                System.Threading.Thread.Sleep(100);
            }
            IntPtr appWin = p.MainWindowHandle;//子窗体(外部程序)句柄
            //当前窗体/容器(主程序)句柄
            IntPtr hwnd = WFHost.Child.Handle;
           //设置父窗体(实现窗体嵌入)
            SetParent(appWin, hwnd);
            //设置窗体样式
            var style = GetWindowLong(appWin, GWL_STYLE);
            SetWindowLong(appWin, GWL_STYLE, style & ~WS_CAPTION & ~WS_THICKFRAME);
            
            //设置窗体位置和大小
            MoveWindow(appWin, 0, 0, (int)WFHost.ActualWidth, (int)WFHost.ActualHeight, true);

实现效果:

在这里插入图片描述

搞个Grid分多行和列,进行拖动操作,可以看到子窗体显示区域限制在WindowsFormsHost 内部了,拖动变化子窗体不会超出显示区域。

效果

问题和后续更新

子窗体实现大小还是固定的,没有随着控件变化实时调整,需要窗体或者控件调整大小重绘时,使用MoveWindow刷新,以达到子窗体尺寸跟随控件尺寸的大小,实现更好的嵌入。

猜你喜欢

转载自blog.csdn.net/qq_39427511/article/details/131789993