在WPF的程序中,嵌入其他进程的窗体

这篇具有很好参考价值的文章主要介绍了在WPF的程序中,嵌入其他进程的窗体。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

我最近遇到了这样一个问题,就是我的WPF程序中,需要用到32位的COM组件。所以我的WPF程序也是要32位的。但是32的程序的逻辑内存最多只有2G,因此,当这个COM组件比较吃内存的时候,程序就会出现内存不够的情况,就会出现异常。因此,我的解决方案是使用winform来调用这个COM组件。然后WPF程序再调用winform。这样,就把内存分配到了多个进程当中,就不会出现一个进程使用太多内存的情况。

下面是WPF实现此功能的简单代码

窗体XAML代码

<Window x:Class="WPF_Open_Exe.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:WPF_Open_Exe"
        mc:Ignorable="d"
        Loaded="Window_Loaded"
         Title="Window1" Height="450" Width="800">
    <Grid>
        <WindowsFormsHost x:Name="WindowsFormsHost1" Background="Red" VerticalAlignment="Top" HorizontalAlignment="Left" Height="450" Width="800">
        </WindowsFormsHost>
    </Grid>
</Window>

页面的逻辑代码:

    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

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


        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);

        Process _process;
        System.Windows.Forms.Panel _hostPanel;

        public bool StartAndEmbedProcess(string processPath)
        {
            bool isStartAndEmbedSuccess = false;


            if (WindowsFormsHost1 != null)
            {
                _hostPanel = new System.Windows.Forms.Panel();
                WindowsFormsHost1.Child = _hostPanel;
            }

            _process = System.Diagnostics.Process.Start(processPath);

            //确保可获取到句柄
            Thread thread = new Thread(new ThreadStart(() =>
            {
                while (true)
                {
                    if (_process.MainWindowHandle != (IntPtr)0)
                    {
                        break;
                    }
                    Thread.Sleep(10);
                }
            }));
            thread.Start();

            Thread.Sleep(1000);
            isStartAndEmbedSuccess = EmbedApp(_process);
            if (!isStartAndEmbedSuccess)
            {
                CloseApp(_process);
            }
            return isStartAndEmbedSuccess;
        }

        public bool EmbedExistProcess(Process process)
        {
            _process = process;
            return EmbedApp(process);
        }

        /// <summary>
        /// 将外进程嵌入到当前程序
        /// </summary>
        /// <param name="process"></param>
        private bool EmbedApp(Process process)
        {
            //是否嵌入成功标志,用作返回值
            bool isEmbedSuccess = false;
            //外进程句柄
            IntPtr processHwnd = process.MainWindowHandle;
            //容器句柄
            IntPtr panelHwnd = _hostPanel.Handle;

            if (processHwnd != (IntPtr)0 && panelHwnd != (IntPtr)0)
            {
                //把本窗口句柄与目标窗口句柄关联起来
                int setTime = 0;
                while (!isEmbedSuccess && setTime < 10)
                {
                    isEmbedSuccess = (SetParent(processHwnd, panelHwnd) != 0);
                    Thread.Sleep(100);
                    setTime++;
                }
                //设置初始尺寸和位置
                MoveWindow(_process.MainWindowHandle, 0, 0, (int)ActualWidth, (int)ActualHeight, true);
            }

            if (isEmbedSuccess)
            {
                //_embededWindowHandle = _process.MainWindowHandle;
            }

            return isEmbedSuccess;
        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            if (_process != null)
            {
                MoveWindow(_process.MainWindowHandle, 0, 0, (int)ActualWidth, (int)ActualHeight, true);
            }
            base.OnRender(drawingContext);
        }

        protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
        {
            if (_hostPanel != null)
            {
                _hostPanel.Width = (int)this.Width;
                _hostPanel.Height = (int)this.Height;

                WindowsFormsHost1.Width = (int)this.Width;
                WindowsFormsHost1.Height = (int)this.Height;
            }

            this.InvalidateVisual();
            base.OnRenderSizeChanged(sizeInfo);
        }

        /// <summary>
        /// 关闭进程
        /// </summary>
        /// <param name="process"></param>
        private void CloseApp(Process process)
        {
            if (process != null && !process.HasExited)
            {
                process.Kill();
            }
        }

        public void CloseProcess()
        {
            CloseApp(_process);
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            StartAndEmbedProcess(@"C:\Windows\system32\mspaint.exe");
        }
    }

在WPF的程序中,嵌入其他进程的窗体

运行后的效果图,这里是把系统的画图程序调进来了,调用其他的程序也是可以的,亲测有效。

代码链接:链接:https://pan.baidu.com/s/1BO7DLC0uy6pka8cjsaTUDA 
提取码:zxhe 
--来自百度网盘超级会员V3的分享 文章来源地址https://www.toymoban.com/news/detail-502387.html

到了这里,关于在WPF的程序中,嵌入其他进程的窗体的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

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

    首先要解决在WPF中如何使用Winfom控件的问题,官方对此有支持的方式。 在引用管理器中添加winfrom相关的程序集 System.Windows.Forms 和 WindowsFormsIntegration 。 然后使用winform的控件,得在外面套一层WindowsFormsHost(好像添加了WindowsFormsIntegration,不使用wfi:也能使用) 这样就可以在WPF中使

    2024年02月17日
    浏览(66)
  • WPF 异步加载数据,窗体事件

    加载WPF界面时,需要获取数据,而数据返回的时间比较长,这个时候可以异步加载数据到界面。   1、首先在XAML中触发窗口载入事件  2、在后台代码中处理窗口载入事件 (1)找到主窗口类   (2)在MainWindow类中添加 XAML中加入的窗口载入事件   这个事件中可以放置各种界面

    2024年02月05日
    浏览(44)
  • Simple WPF:实现一个透明、无边框、鼠标穿透的WPF窗体

    一个自定义WPF窗体的解决方案,借鉴了吕毅老师的WPF制作高性能的透明背景的异形窗口一文,并在此基础上增加了鼠标穿透的功能。可以使得透明窗体的鼠标事件穿透到下层,在下层窗体中响应。这一功能在开发一些截图工具,直播、会议标注工具的时候会有比较多的应用,

    2024年02月09日
    浏览(99)
  • wpf中窗体的移动通用解决方法

    需求背景:设置了不允许改变窗口大小(在Window标签中设置ResizeMode为NoResize),之后窗口无法被拖动 1.在Window标签中添加’MouseLeftButtonDown‘,并且生成事件处理程序 2.到后台的相应事件处理程序中添加

    2024年02月16日
    浏览(39)
  • WPF使用Prism新开窗体regionManager处理

    如果我们需要使用prism弹出一个新的提示窗体可以这样写 但是这样写新窗体注入的regionManager还是原来父窗体的regionManager对象。利用这个对象进行视图注入也可以操作,但是会导致一些奇怪的问题,比如在regionManager.Regions里找不到新加的Region。 此处新窗体的构造函数需要做如

    2024年02月12日
    浏览(40)
  • 在delphi Form窗体的panel 中嵌入 Fmx窗体

    1.创建2个工程,一个是window application ,一个bpl 工程(multi-device Forml),创建方式见: 在delphi Form窗体调用Fmx窗体_zjg076000的博客-CSDN博客(这里不再重复) 2.调整一下windows应用的界面,放入panel 来嵌入fmx窗体 3.编写代码   unit Unit2; interface uses   Winapi.Windows, Winapi.Messages, System.

    2024年02月09日
    浏览(35)
  • 微信小程序web-view嵌入uni-app H5页面,通过H5页面跳转其他小程序如何操作?

     微信小程序appId查看方法: 1)有后台登录权限的情况下:登录微信公众平台后, 微信公众平台 微信公众平台,给个人、企业和组织提供业务服务与用户管理能力的全新服务平台。 https://mp.weixin.qq.com/ 点击右上角logo,在“帐号信息”中找到AppID(小程序ID) 2)没有后台登录权

    2024年02月11日
    浏览(81)
  • WPF 设置窗体 Window的 WindowStyle=“None“ 上方有白条问题

    WPF 重写Window窗体的样式为None,上方有一条白条线,如下图: 解决方案: Window窗体属性设置:ResizeMode=“CanMinimize” 解决之后显示如下: 整体代码参考如下: 备注:如果添加WindowStyle=“None” 和ResizeMode=\\\"CanMinimize\\\"同时设置,就不会显示横向导航条

    2024年02月16日
    浏览(37)
  • WPF中使用TabControl为每个页签添加不同窗体的方法。

    注:每一个页签添加不同窗体,其实不能叫是窗体,只能叫做控件。我这么起标题主要是方便一些新手来搜索答案。 项目需求: 对于一些上位机控制程序来说,一个窗体根本放不下所有的功能,所以我们通常会使用TabControl控件来进行分类布局。通过选择分类选项卡,来展示

    2024年02月12日
    浏览(42)
  • C# Winform 多进程窗体间传值->SendMessage()

    在 C# 的 Windows Forms 中,使用 Windows API 的 SendMessage 方法可以实现窗口间的消息通传递,当然也可以在不同的进程之间发送消息。接下来,我将为您提供一个基本的示例,演示如何使用 SendMessage 以及如何重写 WndProc 方法来接收并处理消息。 首先,你需要添加对Windows API的引用:

    2024年02月14日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包