嵌套了两个Unity程序,修复焦点丢失的问题,本文代码只演示嵌套一个,如果需要两个复制代码即可。
前端代码:
winform端直接用panel即可
wpf用法如下
<WindowsFormsHost Grid.Row="1">
<form:Panel x:Name="left_unityHost" Resize="left_unityHost_Resize" AutoSizeMode="GrowAndShrink"></form:Panel>
</WindowsFormsHost>
后端核心代码
主要功能:
打开程序、设置大小位置、设置焦点
/// <summary>
/// 开启
/// </summary>
void left_Start()
{
KillProcess(left_exeName);
left_process = new Process();
left_process.StartInfo.FileName = left_ExePath;
left_process.StartInfo.Arguments = "-parentHWND " + left_unityHost.Handle.ToInt32() + " " + Environment.CommandLine;
left_process.StartInfo.UseShellExecute = true;
left_process.StartInfo.CreateNoWindow = true;
left_process.Start();
left_process.WaitForInputIdle();
EnumChildWindows(left_unityHost.Handle, left_WindowEnum, IntPtr.Zero);
}
private int left_WindowEnum(IntPtr hwnd, IntPtr lparam)
{
left_unityHWND = hwnd;
ActivateUnityWindow(hwnd);
return 0;
}
private void left_unityHost_Resize(object sender, EventArgs e)
{
MoveWindow(left_unityHWND, 0, 0, left_unityHost.Width, left_unityHost.Height, true);
}
private void ActivateUnityWindow(IntPtr hwnd)
{
SendMessage(hwnd, WM_ACTIVATE, WA_ACTIVE, IntPtr.Zero);
}
用到的api
#region win接口
[DllImport("User32.dll")]
static extern bool MoveWindow(IntPtr handle, int x, int y, int width, int height, bool redraw);
internal delegate int WindowEnumProc(IntPtr hwnd, IntPtr lparam);
[DllImport("user32.dll")]
internal static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc func, IntPtr lParam);
[DllImport("user32.dll")]
static extern int SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
private const int WM_ACTIVATE = 0x0006;
private readonly IntPtr WA_ACTIVE = new IntPtr(1);
private readonly IntPtr WA_INACTIVE = new IntPtr(0);
/// <summary>
/// 获取鼠标的坐标
/// </summary>
/// <param name="lpPoint">传址参数,坐标point类型</param>
/// <returns>获取成功返回真</returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool GetCursorPos(out System.Drawing.Point pt);
[DllImport("User32", EntryPoint = "ClientToScreen", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool ClientToScreen(IntPtr hWnd, ref System.Drawing.Point pt);
const int leftDown = 0x0001;
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern short GetKeyState(int vKey);
#endregion
修复鼠标焦点丢失
private async void Update()
{
while (true)
{
short val = GetKeyState(leftDown);
if (val < 0 || val == -127 || val == -128)
{
System.Drawing.Point mouse_point;
GetCursorPos(out mouse_point);
Point mousePoint = new Point(mouse_point.X, mouse_point.Y);
System.Drawing.Point left_point = new System.Drawing.Point();
ClientToScreen(left_unityHWND, ref left_point);
Size left_size = new Size(left_unityHost.Width, left_unityHost.Height);
Rect left_rect = new Rect(new Point(left_point.X, left_point.Y), left_size);
System.Drawing.Point right_point = new System.Drawing.Point();
ClientToScreen(right_unityHWND, ref right_point);
Size right_size = new Size(right_unityHost.Width, right_unityHost.Height);
Rect right_rect = new Rect(new Point(right_point.X, right_point.Y), right_size);
if (left_rect.Contains(mousePoint))
{
//left_log.Text = "鼠标在左侧";
ActivateUnityWindow(left_unityHWND);
}
if (right_rect.Contains(mousePoint))
{
//left_log.Text = "鼠标在右侧";
ActivateUnityWindow(right_unityHWND);
}
}
await Task.Delay(10);
}
}