В настоящее время у меня есть программа Unity3D, встроенная в страницу WPF с помощью WindowsFormsHost. Тем не менее, когда бы ни выполнялась прокрутка на странице, когда она не сфокусирована на приложении для единства, исполняемый файл по-прежнему фиксирует этот ввод и выполняет то, что предполагается сделать в исполняемом Unity. Есть ли какой-нибудь способ отличить то, что от того, когда Unity сфокусирован, а когда нет?
Я пытался заглянуть в класс process
, чтобы увидеть, есть ли какие-либо методы или свойства, связанные с фокусом, но безрезультатно. Я также попытался заглянуть в нативные классы Unity, чтобы проверить фокус на приложении, прежде чем принимать ввод, опять же безрезультатно.
Вот как я встраиваю приложение в WPF
[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 Process process;
private IntPtr unityHWND = IntPtr.Zero;
private const int WM_ACTIVATE = 0x0006;
private readonly IntPtr WA_ACTIVE = new IntPtr(1);
private readonly IntPtr WA_INACTIVE = new IntPtr(0);
private bool hasStartedOnce = false;
public UnityUserControl()
{
InitializeComponent();
try
{
StartProgram(this.Panel1.Handle.ToInt32());
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
public void StopUnity()
{
process.Kill();
this.Refresh();
}
public Int32 GetPanelHandle()
{
return this.Panel1.Handle.ToInt32();
}
public void StartProgram(Int32 panelHandleInt)
{
try
{
if (File.Exists("SamMaintenanceRackRobot.exe"))
{
process = new Process();
process.StartInfo.FileName = "SamMaintenanceRackRobot.exe";
process.StartInfo.Arguments =
"-parentHWND " + panelHandleInt + " " + Environment.CommandLine;
process.StartInfo.UseShellExecute = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
process.WaitForInputIdle();
Thread.Sleep(1000);
EnumChildWindows(Panel1.Handle, WindowEnum, IntPtr.Zero);
this.Load += UserControl1_Loaded;
hasStartedOnce = true;
}
}
void UserControl1_Loaded(object sender, EventArgs e)
{
Window window = Application.Current.MainWindow;
window.Closing += window_Closing;
}
void window_Closing(object sender, global::System.ComponentModel.CancelEventArgs e)
{
DeactivateUnityWindow();
}
private void ActivateUnityWindow()
{
SendMessage(unityHWND, WM_ACTIVATE, WA_ACTIVE, IntPtr.Zero);
}
private void DeactivateUnityWindow()
{
SendMessage(unityHWND, WM_ACTIVATE, WA_INACTIVE, IntPtr.Zero);
}
private int WindowEnum(IntPtr hwnd, IntPtr lparam)
{
unityHWND = hwnd;
ActivateUnityWindow();
return 0;
}
private void panel1_Resize(object sender, EventArgs e)
{
MoveWindow(unityHWND, 0, 0, Panel1.Width, Panel1.Height, true);
ActivateUnityWindow();
}