WPF嵌入外部exe应用程序-去除子窗体边框样式
- 去除子窗体边框样式
- 导入winodows API
- 使用API去除边框
- 报错:
- 解决
- 实现效果
- 完整实现代码
接着上一篇WPF嵌入外部exe应用程序-实现基本的嵌入,解决子窗体边框样式问题,去掉子窗体样式,让其融为一体,更像一个整体的软件。。。
去除子窗体边框样式
导入winodows API
设置窗体样式需要用到Windows APIGetWindowLong
和SetWindowLong
,函数原型如下:
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中用到的常量字段:
/// <summary>
/// GetWindowLong中表示获得窗口样式
/// SetWindowLong中表示设定一个新的窗口风格。
/// </summary>
const int GWL_STYLE = (-16);
/// <summary>
/// 窗口具有标题栏
/// </summary>
const int WS_CAPTION = 0x00C00000;
/// <summary>
/// 窗口具有调整大小边框。
/// </summary>
const int WS_THICKFRAME = 0x00040000;
更多的窗口样式常量可以看官网
窗口样式-https://learn.microsoft.com/zh-cn/windows/win32/winmsg/window-styles
报错:
这里有个坑,根据函数原型实现类型用long,但是win32中long类型也是32位,而C#中long是64位的所以会导致报错
解决
将上述加载的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);
实现效果
成功去除边框
完整实现代码
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);
/// <summary>
/// GetWindowLong中表示获得窗口样式
/// SetWindowLong中表示设定一个新的窗口风格。
/// </summary>
const int GWL_STYLE = (-16);
/// <summary>
/// 窗口具有标题栏
/// </summary>
const int WS_CAPTION = 0x00C00000;
/// <summary>
/// 窗口具有调整大小边框。
/// </summary>
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);
}
}