WPF嵌入外部exe应用程序-去除子窗体边框样式

WPF嵌入外部exe应用程序-去除子窗体边框样式

  • 去除子窗体边框样式
    • 导入winodows API
    • 使用API去除边框
    • 报错:
    • 解决
    • 实现效果
  • 完整实现代码

接着上一篇WPF嵌入外部exe应用程序-实现基本的嵌入,解决子窗体边框样式问题,去掉子窗体样式,让其融为一体,更像一个整体的软件。。。

去除子窗体边框样式

导入winodows API

设置窗体样式需要用到Windows APIGetWindowLongSetWindowLong,函数原型如下:
WPF嵌入外部exe应用程序-去除子窗体边框样式_第1张图片
在这里插入图片描述

C#中DllImport加载静态方法


[DllImport("user32.dll", EntryPoint = "GetWindowLongA", SetLastError = true)]
public static extern long GetWindowLong(IntPtr hwnd, int nIndex);

[DllImport("user32.dll", EntryPoint = "SetWindowLongA", SetLastError = true)]
public static extern long SetWindowLong(IntPtr hwnd, int nIndex, long dwNewLong);

使用API去除边框

//appWin为子窗体句柄
var style = GetWindowLong(appWin, GWL_STYLE); 
SetWindowLong(appWin, GWL_STYLE, style  &~WS_CAPTION & ~WS_THICKFRAME);

API中用到的常量字段:

        /// 
        /// GetWindowLong中表示获得窗口样式
        /// SetWindowLong中表示设定一个新的窗口风格。
        /// 
        const int GWL_STYLE = (-16);
        /// 
        /// 窗口具有标题栏
        /// 
        const int WS_CAPTION = 0x00C00000;
        /// 
        /// 窗口具有调整大小边框。
        /// 
        const int WS_THICKFRAME = 0x00040000;

更多的窗口样式常量可以看官网
窗口样式-https://learn.microsoft.com/zh-cn/windows/win32/winmsg/window-styles

报错:

这里有个坑,根据函数原型实现类型用long,但是win32中long类型也是32位,而C#中long是64位的所以会导致报错
WPF嵌入外部exe应用程序-去除子窗体边框样式_第2张图片

解决

将上述加载的windowsAPI的long类型都改成int,改完之后能正常执行

        [DllImport("user32.dll", EntryPoint = "GetWindowLongA", SetLastError = true)]
        public static extern int GetWindowLong(IntPtr hwnd, int nIndex);

        [DllImport("user32.dll", EntryPoint = "SetWindowLongA", SetLastError = true)]
        public static extern int SetWindowLong(IntPtr hwnd, int nIndex, int dwNewLong);

实现效果

成功去除边框

WPF嵌入外部exe应用程序-去除子窗体边框样式_第3张图片

完整实现代码

    public partial class MainWindow : Window
    {
        [DllImport("user32.dll", SetLastError = true)]
        public static extern long 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);


        [DllImport("user32.dll", EntryPoint = "GetWindowLongA", SetLastError = true)]
        private static extern int GetWindowLong(IntPtr hwnd, int nIndex);

        [DllImport("user32.dll", EntryPoint = "SetWindowLongA", SetLastError = true)]
        private static extern int SetWindowLong(IntPtr hwnd, int nIndex, int dwNewLong);

        /// 
        /// GetWindowLong中表示获得窗口样式
        /// SetWindowLong中表示设定一个新的窗口风格。
        /// 
        const int GWL_STYLE = (-16);
        /// 
        /// 窗口具有标题栏
        /// 
        const int WS_CAPTION = 0x00C00000;
        /// 
        /// 窗口具有调整大小边框。
        /// 
        const int WS_THICKFRAME = 0x00040000;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
           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 = new WindowInteropHelper(this).Handle;//当前窗体(主程序)句柄
           //设置父窗体(实现窗体嵌入)
            SetParent(appWin, hwnd);
            //设置窗体样式
            var style = GetWindowLong(appWin, GWL_STYLE);
            SetWindowLong(appWin, GWL_STYLE, style & ~WS_CAPTION & ~WS_THICKFRAME);

            //设置窗体位置和大小
            MoveWindow(appWin, 0, 0, 500, 400, true);
           
        }
    }

你可能感兴趣的:(WPF,wpf)