WPF嵌套外部exe程序并消除白边框

 class NestedHelper : HwndHost, IKeyboardInputSink
    {
        [DllImport("user32.dll")]
        private static extern int SetParent(IntPtr hWndChild, IntPtr hWndParent);
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern uint SetWindowLong(IntPtr hwnd, int nIndex, uint newLong);
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern uint GetWindowLong(IntPtr hwnd, int nIndex);
        [DllImport("user32.dll")]
        private static extern int EnumWindows(CallBackPtr callPtr, ref WindowInfo WndInfoRef);
        [DllImport("User32.dll")]
        static extern int GetWindowText(IntPtr handle, StringBuilder text, int MaxLen);
        [DllImport("user32.dll")]
        public static extern int GetWindowRect(IntPtr hwnd, ref RECT rc);
        [DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern int SendMessage(IntPtr hwnd, uint wMsg, int wParam, int lParam); //对外部软件窗口发送一些消息(如 窗口最大化、最小化等)
        internal const int
            GWL_WNDPROC = (-4),
            GWL_HINSTANCE = (-6),
            GWL_HWNDPARENT = (-8),
            GWL_STYLE = (-16),
            GWL_EXSTYLE = (-20),
            GWL_USERDATA = (-21),
            GWL_ID = (-12);
        internal const uint
              WS_CHILD = 0x40000000,
              WS_VISIBLE = 0x10000000,
              LBS_NOTIFY = 0x00000001,
              HOST_ID = 0x00000002,
              LISTBOX_ID = 0x00000001,
              WS_VSCROLL = 0x00200000,
              WS_BORDER = 0x00800000,
              WS_POPUP = 0x80000000;
        public const long WS_CATION = 0x00C00000L;
        public const long WS_CATION_2 = 0x00C0000L;
        private const int HWND_TOP = 0x0;
        private const int WM_COMMAND = 0x0112;
        private const int WM_QT_PAINT = 0xC2DC;
        private const int WM_PAINT = 0x000F;
        private const int WM_SIZE = 0x0005;
        private const int SWP_FRAMECHANGED = 0x0020;
        private const int WM_SYSCOMMAND = 0x0112;
        private const int SC_CLOSE = 0xF060;
        private const int SC_MINIMIZE = 0xF020;
        private const int SC_MAXIMIZE = 0xF030;
        private const uint WM_LBUTTONDOWN = 0x0201;
        private const uint WM_LBUTTONUP = 0x0202;
        private const int BM_CLICK = 0xF5;

        private Border WndHoster;
        private double screenW, screenH;
        private Process appProc;
        private uint oldStyle;
        public IntPtr hwndHost;
        private String appPath;
        private String arguments;

        public NestedHelper(Border b, String p, String args, String f)
        {
            WndHoster = b;
            appPath = p;
            WinInfo = new WindowInfo();
            WinInfo.winTitle = f;
            this.arguments = args;
        }


        protected override HandleRef BuildWindowCore(HandleRef hwndParent)
        {
            hwndHost = FindTheWindow();
            appProc = new Process();
            ProcessStartInfo info = new ProcessStartInfo(appPath)
            {
                UseShellExecute = true,
                WindowStyle = ProcessWindowStyle.Minimized,
                Arguments = arguments
            };
            appProc.StartInfo = info;
            appProc.Start();
            hwndHost = appProc.MainWindowHandle;
            while (hwndHost.ToInt32() == 0)
            {
                Thread.Sleep(1000);
                hwndHost = appProc.MainWindowHandle;
            }
            SendMessage(hwndHost, WM_SYSCOMMAND, SC_MINIMIZE, 0);
            // 嵌入在HwnHost中的窗口必须要 设置为WS_CHILD风格    
            oldStyle = GetWindowLong(hwndHost, GWL_STYLE);
            uint newStyle = (uint)(oldStyle & (~(WS_CATION | WS_CATION_2)));//消除白边框
            //WS_CHILD和WS_POPUP不能同时存在。   
            newStyle |= WS_CHILD;
            newStyle &= ~WS_POPUP;
            newStyle &= ~WS_BORDER;
            SetWindowLong(hwndHost, GWL_STYLE, newStyle);
            //将窗口居中,实际上是将窗口的容器居中   
            // RePosWindow(WndHoster, WndHoster.Width, WndHoster.Height);
            //将netterm的父窗口设置为HwndHost    
            SetParent(hwndHost, hwndParent.Handle);
            return new HandleRef(this, hwndHost);
        }
        protected override void DestroyWindowCore(System.Runtime.InteropServices.HandleRef hwnd)
        {
            SetWindowLong(hwndHost, GWL_STYLE, oldStyle);
            SetParent(hwndHost, (IntPtr)0);
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct WindowInfo
        {
            public String winTitle;
            public RECT r;
            public IntPtr hwnd;
        }
        public delegate bool CallBackPtr(IntPtr hwnd, ref WindowInfo WndInfoRef);
        private static CallBackPtr callBackPtr;
        private WindowInfo WinInfo;
        public static bool CallBackProc(IntPtr hwnd, ref WindowInfo WndInfoRef)
        {
            StringBuilder str = new StringBuilder(512);
            GetWindowText(hwnd, str, str.Capacity);
            Console.WriteLine(str.ToString());
            if (str.ToString().IndexOf(WndInfoRef.winTitle, 0) >= 0)
            {
                WndInfoRef.hwnd = hwnd;
                GetWindowRect(hwnd, ref (WndInfoRef.r));
            }
            return true;
        }
        public IntPtr FindTheWindow()
        {
            callBackPtr = new CallBackPtr(CallBackProc);
            EnumWindows(callBackPtr, ref WinInfo);
            return WinInfo.hwnd;
        }
        public void RePosWindow(Border b, double w, double h)
        {
            double width = WinInfo.r.right - WinInfo.r.left;
            double height = WinInfo.r.bottom - WinInfo.r.top;

            double left = (w - screenW) / 2;
            double right = (w - screenW) / 2;
            double top = (h - screenH) / 2;
            double bottom = (h - screenH) / 2;

            b.Margin = new Thickness(0, 0, 0, 0);
        }
    }
//自定义UserControl容器 
<UserControl x:Class="WpfTest.Godot3dGraph"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfTest"
             mc:Ignorable="d" 
             d:DesignHeight="600" d:DesignWidth="600" Loaded="UserControl_Loaded">
    <Border x:Name="GodotControl">
            
    </Border>
</UserControl>

 /// </summary>
    public partial class Godot3dGraph : UserControl
    {
        public Godot3dGraph(string TAG)
        {
            InitializeComponent();
            string path = @"D:\...\xxx.exe";
            //通过ProcessStartInfo传递参数给exe程序,随自己定义
            string args = string.Format("--Params={0};{1};{2}", xxxx, TAG, 1001);
            NestedHelper ea = new NestedHelper(this.GodotControl, path, args, "Godot3D");
            GodotControl.Child = ea;
           // WebSocketHelper.Instance.Start(12333);
        }
    }

主窗口 MainWindow 
<Window
        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:WpfTest" x:Class="WpfTest.MainWindow"
        mc:Ignorable="d"
        Title="MainWindow" Height="420" Width="800">
    <StackPanel Orientation="Horizontal" x:Name="border" Margin="0,0,0,0" >
        <!-- 可以xaml添加子控件嵌套
        <local:Godot3dGraph Width="400" Height="400" />
        <local:Godot3dGraph Width="400" Height="400" />
        -->
    </StackPanel>
</Window>

 public MainWindow()
        {
            InitializeComponent();
            this.WindowState = WindowState.Normal;
           // this.ResizeMode = ResizeMode.NoResize;
           // this.Topmost = true;
            this.Left = 0.0;
            this.Top = 0.0;
            this.Width = SystemParameters.WorkArea.Width;
            this.Height = SystemParameters.WorkArea.Height;
            this.Closing += MainWindow_Closing;
            //this.WindowStyle = WindowStyle.None;
            // AllowsTransparency = true;
            //也可以 代码添加子控件嵌入
            Godot3dGraph godot = new Godot3dGraph("LEFT");
            godot.Width = this.Width / 2;
            this.border.Children.Add(godot);
            Godot3dGraph godot2 = new Godot3dGraph("RIGHT");
            godot2.Width = this.Width / 2;
            this.border.Children.Add(godot2);
            WSClientHelper.Instance.OpenWS();
        }

NestedHelper是参考几个大佬文章写的,也忘了是谁的,如有侵权可联系删除。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值