2022-01-27 13:40:04 +00:00
|
|
|
|
using System;
|
|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
const uint MOUSEEVENTF_LEFTDOWN = 0x02;
|
|
|
|
|
const uint MOUSEEVENTF_LEFTUP = 0x04;
|
|
|
|
|
const uint KEYEVENTF_EXTENDEDKEY = 0x01;
|
|
|
|
|
const uint KEYEVENTF_KEYDOWN = 0x0;
|
|
|
|
|
const uint KEYEVENTF_KEYUP = 0x2;
|
|
|
|
|
const uint VK_RMENU = 0xA5;
|
|
|
|
|
const uint VK_LMENU = 0xA4;
|
|
|
|
|
const uint VK_LCONTROL = 0xA2;
|
2022-08-01 23:21:42 +00:00
|
|
|
|
const uint VK_RCONTROL = 0xA3;
|
2021-12-14 05:40:07 +00:00
|
|
|
|
const uint VK_SPACE = 0x20;
|
2022-04-18 19:52:39 +00:00
|
|
|
|
const uint VK_ENT = 0x0D;
|
2021-12-14 05:40:07 +00:00
|
|
|
|
const uint KEY_0 = 0x30;
|
|
|
|
|
|
2022-07-23 20:04:06 +00:00
|
|
|
|
private static InputSimulator InputSimulator = new InputSimulator();
|
2022-07-23 19:23:32 +00:00
|
|
|
|
|
|
|
|
|
public static void LeftClickGameWindow()
|
|
|
|
|
{
|
|
|
|
|
var simualatorProcess = WindowProcessManager.GetSimulatorProcess();
|
|
|
|
|
if (simualatorProcess == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Rectangle rectangle;
|
|
|
|
|
PInvoke.GetWindowRect(simualatorProcess.Handle, out rectangle);
|
|
|
|
|
|
|
|
|
|
Rectangle clientRectangle;
|
|
|
|
|
PInvoke.GetClientRect(simualatorProcess.Handle, out clientRectangle);
|
|
|
|
|
|
|
|
|
|
var x = Convert.ToInt32(rectangle.X + (clientRectangle.Width) * 0.5);
|
|
|
|
|
var y = Convert.ToInt32(rectangle.Y + (clientRectangle.Height) * 0.5);
|
|
|
|
|
|
|
|
|
|
LeftClick(x, y);
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-14 05:40:07 +00:00
|
|
|
|
public static void LeftClick(int x, int y)
|
|
|
|
|
{
|
2022-09-06 04:07:03 +00:00
|
|
|
|
PInvoke.SetCursorPos(x, y); // Need to do this twice to overcome MSFS bug for separating pop out panels
|
2021-12-14 05:40:07 +00:00
|
|
|
|
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);
|
2022-09-06 04:07:03 +00:00
|
|
|
|
|
|
|
|
|
PInvoke.SetCursorPos(x + 5, y);
|
2021-12-14 05:40:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-13 03:49:56 +00:00
|
|
|
|
public static void LeftClickFast(int x, int y)
|
|
|
|
|
{
|
|
|
|
|
PInvoke.mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, 0, 0);
|
|
|
|
|
Thread.Sleep(50);
|
|
|
|
|
PInvoke.mouse_event(MOUSEEVENTF_LEFTUP, x, y, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-23 19:23:32 +00:00
|
|
|
|
public static void LeftClickMouseDown(int x, int y)
|
|
|
|
|
{
|
|
|
|
|
PInvoke.mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void LeftClickMouseUp(int x, int y)
|
|
|
|
|
{
|
2022-07-23 20:04:06 +00:00
|
|
|
|
InputSimulator.Mouse.LeftButtonUp();
|
2022-07-23 19:23:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-08-18 14:20:12 +00:00
|
|
|
|
public static void PopOutPanel(int x, int y, bool useSecondaryKeys)
|
2021-12-14 05:40:07 +00:00
|
|
|
|
{
|
2022-02-07 03:05:05 +00:00
|
|
|
|
LeftClick(x, y);
|
|
|
|
|
Thread.Sleep(300);
|
|
|
|
|
|
2022-07-10 23:58:54 +00:00
|
|
|
|
PInvoke.SetCursorPos(x, y);
|
2021-12-14 05:40:07 +00:00
|
|
|
|
PInvoke.SetCursorPos(x, y);
|
|
|
|
|
Thread.Sleep(300);
|
|
|
|
|
|
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);
|
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);
|
2022-07-23 20:04:06 +00:00
|
|
|
|
InputSimulator.Keyboard.KeyUp(WindowsInput.Native.VirtualKeyCode.RCONTROL);
|
|
|
|
|
InputSimulator.Keyboard.KeyUp(WindowsInput.Native.VirtualKeyCode.LCONTROL);
|
2022-07-23 19:23:32 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
PInvoke.keybd_event(Convert.ToByte(VK_RMENU), 0, KEYEVENTF_EXTENDEDKEY, 0);
|
|
|
|
|
PInvoke.mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, 0, 0);
|
|
|
|
|
Thread.Sleep(200);
|
|
|
|
|
PInvoke.mouse_event(MOUSEEVENTF_LEFTUP, x, y, 0, 0);
|
|
|
|
|
PInvoke.keybd_event(Convert.ToByte(VK_RMENU), 0, KEYEVENTF_KEYUP, 0);
|
|
|
|
|
}
|
2021-12-14 05:40:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-23 19:23:32 +00:00
|
|
|
|
public static void CenterView()
|
2021-12-14 05:40:07 +00:00
|
|
|
|
{
|
2022-07-23 19:23:32 +00:00
|
|
|
|
var simualatorProcess = WindowProcessManager.GetSimulatorProcess();
|
|
|
|
|
if (simualatorProcess == null)
|
|
|
|
|
return;
|
|
|
|
|
|
2022-08-01 23:21:42 +00:00
|
|
|
|
CenterView(simualatorProcess);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void CenterView(WindowProcess simualatorProcess)
|
|
|
|
|
{
|
2022-05-31 15:45:35 +00:00
|
|
|
|
Rectangle rectangle;
|
2022-07-23 19:23:32 +00:00
|
|
|
|
PInvoke.GetWindowRect(simualatorProcess.Handle, out rectangle);
|
2022-05-31 15:45:35 +00:00
|
|
|
|
|
|
|
|
|
Rectangle clientRectangle;
|
2022-07-23 19:23:32 +00:00
|
|
|
|
PInvoke.GetClientRect(simualatorProcess.Handle, out clientRectangle);
|
2022-05-31 15:45:35 +00:00
|
|
|
|
|
2022-06-30 23:53:08 +00:00
|
|
|
|
var x = Convert.ToInt32(rectangle.X + (clientRectangle.Width) * 0.5);
|
2022-05-31 15:45:35 +00:00
|
|
|
|
var y = Convert.ToInt32(rectangle.Y + (clientRectangle.Height) * 0.5);
|
|
|
|
|
|
2022-07-23 19:23:32 +00:00
|
|
|
|
PInvoke.SetForegroundWindow(simualatorProcess.Handle);
|
2022-01-27 13:40:04 +00:00
|
|
|
|
LeftClick(x, y);
|
2021-12-14 05:40:07 +00:00
|
|
|
|
|
|
|
|
|
// First center view using Ctrl-Space
|
2022-08-01 23:21:42 +00:00
|
|
|
|
PInvoke.keybd_event(Convert.ToByte(VK_RCONTROL), 0, KEYEVENTF_KEYDOWN, 0);
|
2021-12-14 05:40:07 +00:00
|
|
|
|
PInvoke.keybd_event(Convert.ToByte(VK_SPACE), 0, KEYEVENTF_KEYDOWN, 0);
|
|
|
|
|
Thread.Sleep(200);
|
|
|
|
|
PInvoke.keybd_event(Convert.ToByte(VK_SPACE), 0, KEYEVENTF_KEYUP, 0);
|
2022-08-01 23:21:42 +00:00
|
|
|
|
PInvoke.keybd_event(Convert.ToByte(VK_RCONTROL), 0, KEYEVENTF_KEYUP, 0);
|
2021-12-14 05:40:07 +00:00
|
|
|
|
Thread.Sleep(200);
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-23 19:23:32 +00:00
|
|
|
|
public static void SaveCustomView(string keybinding)
|
2021-12-14 05:40:07 +00:00
|
|
|
|
{
|
2022-07-23 19:23:32 +00:00
|
|
|
|
var simualatorProcess = WindowProcessManager.GetSimulatorProcess();
|
|
|
|
|
if (simualatorProcess == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
var hwnd = simualatorProcess.Handle;
|
2022-06-30 23:53:08 +00:00
|
|
|
|
uint customViewKey = (uint)(Convert.ToInt32(keybinding) + KEY_0);
|
2022-04-18 03:38:33 +00:00
|
|
|
|
|
2021-12-14 05:40:07 +00:00
|
|
|
|
PInvoke.SetForegroundWindow(hwnd);
|
|
|
|
|
Thread.Sleep(500);
|
|
|
|
|
|
|
|
|
|
PInvoke.SetFocus(hwnd);
|
|
|
|
|
Thread.Sleep(300);
|
|
|
|
|
|
|
|
|
|
// 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);
|
2022-07-23 19:23:32 +00:00
|
|
|
|
|
2021-12-14 05:40:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-06 18:09:10 +00:00
|
|
|
|
public static void LoadCustomView(string keybinding)
|
2021-12-14 05:40:07 +00:00
|
|
|
|
{
|
2022-07-23 19:23:32 +00:00
|
|
|
|
var simualatorProcess = WindowProcessManager.GetSimulatorProcess();
|
|
|
|
|
if (simualatorProcess == null)
|
|
|
|
|
return;
|
2021-12-14 05:40:07 +00:00
|
|
|
|
|
2022-07-23 19:23:32 +00:00
|
|
|
|
// First center view to make sure recalling custom camera works on the first press
|
|
|
|
|
InputEmulationManager.CenterView();
|
2022-07-30 02:29:20 +00:00
|
|
|
|
Thread.Sleep(500);
|
2021-12-14 05:40:07 +00:00
|
|
|
|
|
2022-07-23 19:23:32 +00:00
|
|
|
|
uint 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);
|
2022-07-06 18:09:10 +00:00
|
|
|
|
|
2022-07-23 19:23:32 +00:00
|
|
|
|
Thread.Sleep(500);
|
2021-12-14 05:40:07 +00:00
|
|
|
|
}
|
2022-01-27 13:40:04 +00:00
|
|
|
|
|
2022-04-18 19:52:39 +00:00
|
|
|
|
public static void ToggleFullScreenPanel(IntPtr hwnd)
|
|
|
|
|
{
|
|
|
|
|
PInvoke.SetForegroundWindow(hwnd);
|
|
|
|
|
Thread.Sleep(500);
|
|
|
|
|
|
|
|
|
|
PInvoke.SetFocus(hwnd);
|
|
|
|
|
Thread.Sleep(300);
|
|
|
|
|
|
|
|
|
|
PInvoke.keybd_event(Convert.ToByte(VK_RMENU), 0, KEYEVENTF_KEYDOWN, 0);
|
|
|
|
|
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);
|
|
|
|
|
PInvoke.keybd_event(Convert.ToByte(VK_RMENU), 0, KEYEVENTF_KEYUP, 0);
|
|
|
|
|
}
|
2022-08-08 06:07:24 +00:00
|
|
|
|
|
|
|
|
|
public static void RefocusGameWindow()
|
|
|
|
|
{
|
|
|
|
|
var simualatorProcess = WindowProcessManager.GetSimulatorProcess();
|
|
|
|
|
if (simualatorProcess == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
var rectangle = WindowActionManager.GetWindowRect(simualatorProcess.Handle);
|
|
|
|
|
var clientRectangle = WindowActionManager.GetClientRect(simualatorProcess.Handle);
|
|
|
|
|
|
|
|
|
|
PInvoke.SetCursorPos(rectangle.X + clientRectangle.Width / 2, rectangle.Y + clientRectangle.Height / 2);
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-14 05:40:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|