• wpf exe加载成控件


    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms.Integration;
    using System.Windows.Interop;
    
    namespace ClientHelper
    {
        public static class ExtentionMethods
        {
            #region 调用外部exe程序
            /// <summary>
            /// 在一个WPF控件Boder里显示一个exe程序,程序铺满窗口,但程序有标题栏,可以拖动
            /// </summary>
            /// <param name="border">border对象</param>
            /// <param name="exePath">exe程序路径</param>
            /// <param name="processName">exe进程名称</param>
            public static void ShowExeInBorder_Movable(this System.Windows.Controls.Border border, string exePath, string processName)
            {
                ExeHost e = new ExeHost(exePath, processName);
                border.Child = e;
            }
            /// <summary>
            /// 在一个WPF控件Boder里显示一个exe程序,程序铺满窗口,不可拖动
            /// </summary>
            /// <param name="border">border对象</param>
            /// <param name="exePath">exe程序路径</param>
            /// <param name="processName">exe进程名称</param>
            /// <param name="exeTitleBarHeight">exe程序标题栏高度</param>
            /// <param name="exeWidth">exe程序显示宽度</param>
            /// <param name="exeHeight">exe程序显示高度(包括标题栏高度)</param>
            public static void ShowExeInBorder_NoTitleBar(this System.Windows.Controls.Border border, string exePath, string processName, int exeTitleBarHeight, int exeWidth, int exeHeight)
            {
                border.Height = exeHeight - exeTitleBarHeight;
                border.Width = exeWidth;
                border.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
                border.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                WindowsFormsHost host = new WindowsFormsHost() { Width = border.Width, Height = border.Height };
    
                ExeHostUserControl uc = new ExeHostUserControl();
    
                InvalidataExeProcess(uc, exeHeight, exeWidth, exePath, processName);
    
                host.Child = uc;
    
                border.Loaded += new System.Windows.RoutedEventHandler((s, e) =>
                {
                    IntPtr notepadHandle = uc.EXEIntprt = uc._process.MainWindowHandle;
                    //强制使用样式,给exe程序设置父窗体
                    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, uc.Handle);
    
                    uc.Invalidate();
                    //移动exe程序的位置。
                    MoveWindow(uc.EXEIntprt, 0, exeTitleBarHeight * (-1), exeWidth, exeHeight, true);
                });
                border.Child = host;
                border.InvalidateVisual();
            }
            private static void InvalidataExeProcess(ExeHostUserControl uc, int exeHeight, int exeWidth, string exePath, string processName)
            {
                Process[] ps = Process.GetProcessesByName(processName);
                if (ps.Length > 0)
                {
                    var p = ps[0];
                    p.Kill();
                }
    
                ProcessStartInfo psi = new ProcessStartInfo(exePath);
                psi.WindowStyle = ProcessWindowStyle.Minimized;
                uc._process = Process.Start(psi);
                uc._process.WaitForInputIdle();
    
                uc.Size = new System.Drawing.Size(exeWidth, exeHeight);
    
    
                // The main window handle may be unavailable for a while, just wait for it
                while (uc._process.MainWindowHandle == IntPtr.Zero)
                {
                    Thread.Yield();
                }
    
                IntPtr notepadHandle = uc.EXEIntprt = uc._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, uc.Handle);
    
                uc.Invalidate();
            }
            [DllImport("user32.dll")]
            static extern bool MoveWindow(IntPtr Handle, int x, int y, int w, int h, bool repaint);
    
            #region win32
            [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);
    
            [DllImport("user32.dll", EntryPoint = "DestroyWindow", CharSet = CharSet.Unicode)]
            internal static extern bool DestroyWindow(IntPtr hwnd);
    
    
            private const int WS_CAPTION = 0x00C00000;
            private const int WS_THICKFRAME = 0x00040000;
            private const int GWL_STYLE = -16;
            private const int WS_CHILD = 0x40000000;
            #endregion
            #endregion
        }
    
        class ExeHost : HwndHost
        {
    
            public ExeHost(string exePath, string processName)
            {
                this._processName = processName;
                this._path = exePath;
            }
            private Process _process;
            protected override HandleRef BuildWindowCore(HandleRef hwndParent)
            {
    
                Process[] ps = Process.GetProcessesByName(_processName);
                if (ps.Length > 0)
                {
                    var p = ps[0];
                    p.Kill();
                }
                ProcessStartInfo psi = new ProcessStartInfo(_path);
                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;
            }
    
            protected override void DestroyWindowCore(HandleRef hwnd)
            {
                DestroyWindow(hwnd.Handle);
            }
    
            private const int GWL_STYLE = -16;
            private const int WS_CAPTION = 0x00C00000;
            private const int WS_THICKFRAME = 0x00040000;
            private const int WS_CHILD = 0x40000000;
            private string _path;
            private string _processName;
    
            [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);
    
            [DllImport("user32.dll", EntryPoint = "DestroyWindow", CharSet = CharSet.Unicode)]
            internal static extern bool DestroyWindow(IntPtr hwnd);
        }
    }
  • 相关阅读:
    【Express系列】第3篇——接入mysql
    【Express系列】第2篇——主程序的改造
    【Express系列】第1篇——项目创建
    AngularJS内置指令
    node服务端搭建学习笔记
    生成ssh key
    webstorm的常用操作
    VSCode 常用插件
    php集成包
    composer安装特别慢的解决方案
  • 原文地址:https://www.cnblogs.com/congqiandehoulai/p/12727887.html
Copyright © 2020-2023  润新知