栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

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

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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

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

窗体XAML代码


    
        
        
    

页面的逻辑代码:

    /// 
    /// MainWindow.xaml 的交互逻辑
    /// 
    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);
        }

        /// 
        /// 将外进程嵌入到当前程序
        /// 
        /// 
        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);
        }

        /// 
        /// 关闭进程
        /// 
        /// 
        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:Windowssystem32mspaint.exe");
        }
    }

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

代码链接:链接:https://pan.baidu.com/s/1BO7DLC0uy6pka8cjsaTUDA 
提取码:zxhe 
--来自百度网盘超级会员V3的分享 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/906767.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号