1
0
Fork 0
mirror of https://github.com/hawkeye-stan/msfs-popout-panel-manager.git synced 2024-11-25 15:20:10 +00:00
msfs-popout-panel-manager/WindowsAgent/InputEmulationManager.cs

255 lines
9.4 KiB
C#
Raw Permalink Normal View History

2024-02-28 02:44:21 +00:00
using System;
2023-07-12 22:41:31 +00:00
using System.Diagnostics;
2022-01-27 13:40:04 +00:00
using System.Drawing;
2021-12-14 05:40:07 +00:00
using System.Threading;
2022-07-23 19:23:32 +00:00
using WindowsInput;
2021-12-14 05:40:07 +00:00
2022-07-23 19:23:32 +00:00
namespace MSFSPopoutPanelManager.WindowsAgent
2021-12-14 05:40:07 +00:00
{
public class InputEmulationManager
{
2024-02-28 02:44:21 +00:00
private const uint MOUSEEVENTF_LEFTDOWN = 0x02;
private const uint MOUSEEVENTF_LEFTUP = 0x04;
private const uint KEYEVENTF_KEYDOWN = 0x0;
private const uint KEYEVENTF_KEYUP = 0x2;
private const uint VK_LMENU = 0xA4;
private const uint VK_LCONTROL = 0xA2;
private const uint VK_ENT = 0x0D;
private const uint KEY_0 = 0x30;
private const uint NUMPAD_0 = 0x60;
private const uint NUMPAD_1 = 0x61;
private const uint NUMPAD_2 = 0x62;
private const uint NUMPAD_3 = 0x63;
private const uint NUMPAD_4 = 0x64;
private const uint NUMPAD_5 = 0x65;
private const uint NUMPAD_6 = 0x66;
private const uint NUMPAD_7 = 0x67;
private const uint NUMPAD_8 = 0x68;
private const uint NUMPAD_9 = 0x69;
private const uint NUMPAD_DECIMAL = 0x6E;
private const uint NUMPAD_ADD = 0x6B;
private const uint NUMPAD_SUBTRACT = 0x6D;
private const uint NUMPAD_DIVIDE = 0x6F;
private const uint NUMPAD_MULTIPLY = 0x6A;
private const uint NUMPAD_ENTER = 0x0D;
private const uint NUMPAD_TAB = 0x09;
private static readonly InputSimulator InputSimulator = new ();
2022-07-23 19:23:32 +00:00
2021-12-14 05:40:07 +00:00
public static void LeftClick(int x, int y)
{
PInvoke.SetCursorPos(x, y);
Thread.Sleep(300);
PInvoke.mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, 0, 0);
Thread.Sleep(200);
PInvoke.mouse_event(MOUSEEVENTF_LEFTUP, x, y, 0, 0);
2023-07-12 22:41:31 +00:00
Thread.Sleep(200);
2021-12-14 05:40:07 +00:00
}
2023-09-29 06:15:02 +00:00
public static void PrepareToPopOutPanel(int x, int y, bool isTurboMode)
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
PInvoke.SetForegroundWindow(WindowProcessManager.SimulatorProcess.Handle);
2023-09-29 06:15:02 +00:00
Thread.Sleep(isTurboMode ? 0 : 250);
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
MoveAppWindowFromLeftClickPoint(x, y);
2022-02-07 03:05:05 +00:00
2024-03-12 13:14:17 +00:00
LeftClick(x, y); // Left click outside the circle area to focus game window
2021-12-14 05:40:07 +00:00
2023-09-10 16:19:41 +00:00
// Force cursor reset and focus
PInvoke.SetCursorPos(x, y);
2023-09-29 06:15:02 +00:00
Thread.Sleep(isTurboMode ? 50 : 500);
2023-09-10 16:19:41 +00:00
}
2023-09-29 06:15:02 +00:00
public static void PopOutPanel(int x, int y, bool useSecondaryKeys, bool isTurbo)
2023-09-10 16:19:41 +00:00
{
2022-08-18 14:20:12 +00:00
if (useSecondaryKeys)
2022-07-23 19:23:32 +00:00
{
2022-07-23 20:04:06 +00:00
InputSimulator.Keyboard.KeyDown(WindowsInput.Native.VirtualKeyCode.LCONTROL);
InputSimulator.Keyboard.KeyDown(WindowsInput.Native.VirtualKeyCode.RCONTROL);
2023-09-29 06:15:02 +00:00
Thread.Sleep(isTurbo ? 0: 500);
2022-07-23 19:23:32 +00:00
PInvoke.mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, 0, 0);
Thread.Sleep(200);
PInvoke.mouse_event(MOUSEEVENTF_LEFTUP, x, y, 0, 0);
2023-09-29 06:15:02 +00:00
2022-07-23 20:04:06 +00:00
InputSimulator.Keyboard.KeyUp(WindowsInput.Native.VirtualKeyCode.RCONTROL);
InputSimulator.Keyboard.KeyUp(WindowsInput.Native.VirtualKeyCode.LCONTROL);
2023-07-12 22:41:31 +00:00
Thread.Sleep(100);
InputSimulator.Keyboard.KeyUp(WindowsInput.Native.VirtualKeyCode.RCONTROL); // resend to make sure Ctrl key is up
InputSimulator.Keyboard.KeyUp(WindowsInput.Native.VirtualKeyCode.LCONTROL);
2022-07-23 19:23:32 +00:00
}
else
{
2023-07-12 22:41:31 +00:00
InputSimulator.Keyboard.KeyDown(WindowsInput.Native.VirtualKeyCode.RMENU);
2023-09-29 06:15:02 +00:00
Thread.Sleep(isTurbo ? 0 : 500);
2022-07-23 19:23:32 +00:00
PInvoke.mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, 0, 0);
Thread.Sleep(200);
PInvoke.mouse_event(MOUSEEVENTF_LEFTUP, x, y, 0, 0);
2023-09-29 06:15:02 +00:00
2023-07-12 22:41:31 +00:00
InputSimulator.Keyboard.KeyUp(WindowsInput.Native.VirtualKeyCode.RMENU);
Thread.Sleep(100);
InputSimulator.Keyboard.KeyUp(WindowsInput.Native.VirtualKeyCode.RMENU); // resend to make sure Alt key is up
2022-07-23 19:23:32 +00:00
}
2021-12-14 05:40:07 +00:00
}
2024-02-28 02:44:21 +00:00
public static void SaveCustomView(string keyBinding)
2021-12-14 05:40:07 +00:00
{
2023-07-12 22:41:31 +00:00
Debug.WriteLine("Saving custom view...");
2022-07-23 19:23:32 +00:00
2024-02-28 02:44:21 +00:00
if (WindowProcessManager.SimulatorProcess == null)
return;
var hWnd = WindowProcessManager.SimulatorProcess.Handle;
var customViewKey = (uint)(Convert.ToInt32(keyBinding) + KEY_0);
2022-04-18 03:38:33 +00:00
2024-02-28 02:44:21 +00:00
PInvoke.SetForegroundWindow(hWnd);
2023-07-12 22:41:31 +00:00
Thread.Sleep(200);
2021-12-14 05:40:07 +00:00
2024-02-28 02:44:21 +00:00
PInvoke.SetFocus(hWnd);
2023-08-03 02:21:20 +00:00
Thread.Sleep(300);
2021-12-14 05:40:07 +00:00
// Set view using Ctrl-Alt-0
PInvoke.keybd_event(Convert.ToByte(VK_LCONTROL), 0, KEYEVENTF_KEYDOWN, 0);
PInvoke.keybd_event(Convert.ToByte(VK_LMENU), 0, KEYEVENTF_KEYDOWN, 0);
2022-04-18 03:38:33 +00:00
PInvoke.keybd_event(Convert.ToByte(customViewKey), 0, KEYEVENTF_KEYDOWN, 0);
2021-12-14 05:40:07 +00:00
Thread.Sleep(200);
2022-04-18 03:38:33 +00:00
PInvoke.keybd_event(Convert.ToByte(customViewKey), 0, KEYEVENTF_KEYUP, 0);
2021-12-14 05:40:07 +00:00
PInvoke.keybd_event(Convert.ToByte(VK_LMENU), 0, KEYEVENTF_KEYUP, 0);
PInvoke.keybd_event(Convert.ToByte(VK_LCONTROL), 0, KEYEVENTF_KEYUP, 0);
2023-07-12 22:41:31 +00:00
Thread.Sleep(200);
2021-12-14 05:40:07 +00:00
}
2024-02-28 02:44:21 +00:00
public static void LoadCustomView(string keyBinding)
2021-12-14 05:40:07 +00:00
{
2023-07-12 22:41:31 +00:00
Debug.WriteLine("Loading custom view...");
2021-12-14 05:40:07 +00:00
2024-02-28 02:44:21 +00:00
if (WindowProcessManager.SimulatorProcess == null)
return;
var hWnd = WindowProcessManager.SimulatorProcess.Handle;
PInvoke.SetForegroundWindow(hWnd);
2023-08-14 04:35:14 +00:00
Thread.Sleep(200);
2021-12-14 05:40:07 +00:00
2024-02-28 02:44:21 +00:00
var customViewKey = (uint)(Convert.ToInt32(keyBinding) + KEY_0);
2022-07-06 18:09:10 +00:00
2022-07-23 19:23:32 +00:00
// Then load view using Alt-0
PInvoke.keybd_event(Convert.ToByte(VK_LMENU), 0, KEYEVENTF_KEYDOWN, 0);
PInvoke.keybd_event(Convert.ToByte(customViewKey), 0, KEYEVENTF_KEYDOWN, 0);
Thread.Sleep(200);
PInvoke.keybd_event(Convert.ToByte(customViewKey), 0, KEYEVENTF_KEYUP, 0);
PInvoke.keybd_event(Convert.ToByte(VK_LMENU), 0, KEYEVENTF_KEYUP, 0);
2023-07-12 22:41:31 +00:00
Thread.Sleep(200);
2021-12-14 05:40:07 +00:00
}
2022-01-27 13:40:04 +00:00
2024-02-28 02:44:21 +00:00
public static void ToggleFullScreenPanel(IntPtr hWnd)
2022-04-18 19:52:39 +00:00
{
2024-02-28 02:44:21 +00:00
PInvoke.SetForegroundWindow(hWnd);
2023-07-26 20:22:44 +00:00
Thread.Sleep(200);
2022-04-18 19:52:39 +00:00
2024-02-28 02:44:21 +00:00
PInvoke.SetFocus(hWnd);
2023-08-03 02:21:20 +00:00
Thread.Sleep(300);
2023-08-05 03:40:29 +00:00
PInvoke.keybd_event(Convert.ToByte(VK_LMENU), 0, KEYEVENTF_KEYDOWN, 0);
2022-04-18 19:52:39 +00:00
PInvoke.keybd_event(Convert.ToByte(VK_ENT), 0, KEYEVENTF_KEYDOWN, 0);
Thread.Sleep(200);
PInvoke.keybd_event(Convert.ToByte(VK_ENT), 0, KEYEVENTF_KEYUP, 0);
2023-08-05 03:40:29 +00:00
PInvoke.keybd_event(Convert.ToByte(VK_LMENU), 0, KEYEVENTF_KEYUP, 0);
2023-07-12 22:41:31 +00:00
Thread.Sleep(200);
2022-04-18 19:52:39 +00:00
}
2022-08-08 06:07:24 +00:00
2024-02-28 02:44:21 +00:00
public static void NumPadClick(string numPadKey)
2023-07-12 22:41:31 +00:00
{
2024-02-28 02:44:21 +00:00
var hWnd = WindowProcessManager.SimulatorProcess.Handle;
PInvoke.SetForegroundWindow(hWnd);
Thread.Sleep(200);
2023-07-12 22:41:31 +00:00
2024-02-28 02:44:21 +00:00
var key = NUMPAD_DECIMAL;
2023-07-12 22:41:31 +00:00
2024-02-28 02:44:21 +00:00
switch (numPadKey.ToUpper())
{
case "0":
key = NUMPAD_0;
break;
case "1":
key = NUMPAD_1;
break;
case "2":
key = NUMPAD_2;
break;
case "3":
key = NUMPAD_3;
break;
case "4":
key = NUMPAD_4;
break;
case "5":
key = NUMPAD_5;
break;
case "6":
key = NUMPAD_6;
break;
case "7":
key = NUMPAD_7;
break;
case "8":
key = NUMPAD_8;
break;
case "9":
key = NUMPAD_9;
break;
case "DECIMAL":
key = NUMPAD_DECIMAL;
break;
case "ADD":
key = NUMPAD_ADD;
break;
case "SUBTRACT":
key = NUMPAD_SUBTRACT;
break;
case "DIVIDE":
key = NUMPAD_DIVIDE;
break;
case "MULTIPLY":
key = NUMPAD_MULTIPLY;
break;
case "TAB":
key = NUMPAD_TAB;
break;
case "ENTER":
key = NUMPAD_ENTER;
break;
}
2023-07-12 22:41:31 +00:00
2024-02-28 02:44:21 +00:00
PInvoke.keybd_event(Convert.ToByte(key), 0, KEYEVENTF_KEYDOWN, 0);
Thread.Sleep(200);
PInvoke.keybd_event(Convert.ToByte(key), 0, KEYEVENTF_KEYUP, 0);
2023-07-12 22:41:31 +00:00
}
private static void MoveAppWindowFromLeftClickPoint(int x, int y)
{
var appHandle = WindowProcessManager.GetApplicationProcess().Handle;
var applicationRectangle = WindowActionManager.GetWindowRectangle(appHandle);
if (IsPointWithinRectangle(x, y, applicationRectangle))
{
var top = y - applicationRectangle.Height - 50;
WindowActionManager.MoveWindow(appHandle, applicationRectangle.X, top, applicationRectangle.Width, applicationRectangle.Height);
2023-09-10 16:19:41 +00:00
Thread.Sleep(1000);
2023-07-12 22:41:31 +00:00
}
}
private static bool IsPointWithinRectangle(int x, int y, Rectangle rect)
{
var rightEdge = rect.X + rect.Width;
var bottomEdge = rect.Y + rect.Height;
return x >= rect.X && x <= rightEdge && y >= rect.Y && y <= bottomEdge;
}
2021-12-14 05:40:07 +00:00
}
}