BOB/ProcessManager/WindowEmbedHelper.cs
2025-12-02 15:43:08 +08:00

94 lines
3.0 KiB
C#

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using System.Windows.Interop;
namespace ProcessManager.Helpers
{
public static class WindowEmbedHelper
{
private const int GWL_STYLE = -16;
private const long WS_CAPTION = 0x00C00000;
private const long WS_THICKFRAME = 0x00040000;
private const long WS_CHILD = 0x40000000;
public static void FindAndEmbedWindow(string windowTitle, System.Windows.Forms.Panel panel, int timeoutMs = 10000)
{
Task.Run(async () =>
{
IntPtr hWnd = IntPtr.Zero;
int elapsed = 0;
while (elapsed < timeoutMs)
{
hWnd = FindWindow(null, windowTitle);
if (hWnd != IntPtr.Zero)
break;
await Task.Delay(200);
elapsed += 200;
}
if (hWnd == IntPtr.Zero)
{
Application.Current.Dispatcher.Invoke(() =>
{
MessageBox.Show($"在 {timeoutMs / 1000.0}s 内未找到窗口:{windowTitle}");
});
return;
}
Application.Current.Dispatcher.Invoke(() =>
{
EmbedWindow(hWnd, panel);
});
});
}
public static void EmbedWindow(IntPtr childHwnd, System.Windows.Forms.Panel panel)
{
IntPtr parentHwnd = panel.Handle;
// 设定父窗口
SetParent(childHwnd, parentHwnd);
// 去掉标题栏
long style = GetWindowLong(childHwnd, GWL_STYLE);
style &= ~WS_CAPTION;
style &= ~WS_THICKFRAME;
style |= WS_CHILD;
SetWindowLong(childHwnd, GWL_STYLE, style);
ResizeEmbeddedWindow(childHwnd, panel);
// 自动resize
panel.Resize -= (s, e) => ResizeEmbeddedWindow(childHwnd, panel);
panel.Resize += (s, e) => ResizeEmbeddedWindow(childHwnd, panel);
}
public static void ResizeEmbeddedWindow(IntPtr hWnd, System.Windows.Forms.Panel panel)
{
MoveWindow(hWnd, 0, 0, panel.Width, panel.Height, true);
}
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string? lpClassName, string? lpWindowName);
[DllImport("user32.dll")]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int W, int H, bool repaint);
[DllImport("user32.dll")]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll")]
public static extern long GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
public static extern long SetWindowLong(IntPtr hWnd, int nIndex, long dwNewLong);
}
}