1
0
Fork 0
mirror of https://github.com/hawkeye-stan/msfs-popout-panel-manager.git synced 2024-11-29 09:10:09 +00:00
msfs-popout-panel-manager/WindowsAgent/TouchEventManager.cs

183 lines
7.7 KiB
C#
Raw Normal View History

2022-07-25 12:40:21 +00:00
using MSFSPopoutPanelManager.UserDataAgent;
using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
namespace MSFSPopoutPanelManager.WindowsAgent
{
public class TouchEventManager
{
private static WindowProcess _simulatorProcess;
private static IntPtr _hHook = IntPtr.Zero;
private static PInvoke.WindowsHookExProc callbackDelegate = HookCallBack;
private static bool _isTouchDown;
2022-07-30 02:29:20 +00:00
private static int _mouseMoveCount;
2022-07-25 12:40:21 +00:00
private static object _mouseTouchLock = new object();
2022-07-30 02:29:20 +00:00
private static bool _isDragged = false;
2022-09-25 14:49:49 +00:00
private static int _refocusedTaskIndex = 0;
2022-07-25 12:40:21 +00:00
private const int PANEL_MENUBAR_HEIGHT = 31;
private const uint TOUCH_FLAG = 0xFF515700;
private const uint WM_MOUSEMOVE = 0x0200;
private const uint WM_LBUTTONDOWN = 0x0201;
private const uint WM_LBUTTONUP = 0x0202;
private const uint WM_RBUTTONDOWN = 0x0204;
private const uint WM_RBUTTONUP = 0x0205;
private const uint MOUSEEVENTF_LEFTDOWN = 0x0002;
private const uint MOUSEEVENTF_LEFTUP = 0x0004;
2022-07-30 02:29:20 +00:00
private const uint MOUSEEVENTF_MOVE = 0x0001;
2022-07-25 12:40:21 +00:00
public static Profile ActiveProfile { private get; set; }
public static AppSetting AppSetting { private get; set; }
public static void Hook()
{
2022-09-25 14:49:49 +00:00
// If using RSG GT750 Gen 1, disable touch support
if (ActiveProfile != null && ActiveProfile.RealSimGearGTN750Gen1Override)
return;
2022-07-25 12:40:21 +00:00
_simulatorProcess = WindowProcessManager.GetSimulatorProcess();
Process curProcess = Process.GetCurrentProcess();
ProcessModule curModule = curProcess.MainModule;
var hookWindowPtr = PInvoke.GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);
2022-09-25 14:49:49 +00:00
2022-07-25 12:40:21 +00:00
_hHook = PInvoke.SetWindowsHookEx(HookType.WH_MOUSE_LL, callbackDelegate, hookWindowPtr, 0);
}
public static void UnHook()
{
2022-09-25 14:49:49 +00:00
// If using RSG GT750 Gen 1, disable touch support
if (ActiveProfile != null && ActiveProfile.RealSimGearGTN750Gen1Override)
return;
if (_hHook != IntPtr.Zero)
{
PInvoke.UnhookWindowsHookEx(_hHook);
_hHook = IntPtr.Zero;
}
2022-07-25 12:40:21 +00:00
}
public static bool IsHooked { get { return _hHook != IntPtr.Zero; } }
private static int HookCallBack(int code, IntPtr wParam, IntPtr lParam)
{
if (code != 0)
return PInvoke.CallNextHookEx(_hHook, code, wParam, lParam);
var info = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
var extraInfo = (uint)info.dwExtraInfo;
var isTouched = (extraInfo & TOUCH_FLAG) == TOUCH_FLAG;
// Mouse Click
if (!isTouched)
{
switch ((uint)wParam)
{
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
if (_isTouchDown)
return 1;
break;
}
return PInvoke.CallNextHookEx(_hHook, code, wParam, lParam);
}
// If touch point is within pop out panel boundaries and have touch enabled
2022-09-11 13:50:04 +00:00
var panelConfig = ActiveProfile.PanelConfigs.FirstOrDefault(p => p.TouchEnabled &&
((!p.FullScreen &&
info.pt.X > p.Left
2022-07-25 12:40:21 +00:00
&& info.pt.X < p.Left + p.Width
2022-09-11 13:50:04 +00:00
&& info.pt.Y > p.Top + (p.HideTitlebar ? 5 : PANEL_MENUBAR_HEIGHT)
&& info.pt.Y < p.Top + p.Height) ||
(p.FullScreen &&
info.pt.X > p.FullScreenLeft
&& info.pt.X < p.FullScreenLeft + p.FullScreenWidth
&& info.pt.Y > p.FullScreenTop + 5
&& info.pt.Y < p.FullScreenTop + p.FullScreenHeight
)));
2022-07-30 02:29:20 +00:00
if (panelConfig == null)
2022-07-25 12:40:21 +00:00
return PInvoke.CallNextHookEx(_hHook, code, wParam, lParam);
switch ((uint)wParam)
{
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
return 1;
case WM_LBUTTONDOWN:
if (!_isTouchDown)
{
_isTouchDown = true;
lock (_mouseTouchLock)
{
Task.Run(() =>
{
2022-07-30 02:29:20 +00:00
if (_mouseMoveCount > 1)
2022-07-25 12:40:21 +00:00
{
2022-07-30 02:29:20 +00:00
PInvoke.mouse_event(MOUSEEVENTF_LEFTUP, info.pt.X, info.pt.Y, 0, 0);
_isDragged = true;
2022-07-25 12:40:21 +00:00
}
2022-07-30 02:29:20 +00:00
Thread.Sleep(AppSetting.TouchScreenSettings.TouchDownUpDelay + 25);
PInvoke.mouse_event(MOUSEEVENTF_LEFTDOWN, info.pt.X, info.pt.Y, 0, 0);
Thread.Sleep(AppSetting.TouchScreenSettings.TouchDownUpDelay + 50);
_isTouchDown = false;
2022-07-25 12:40:21 +00:00
});
}
}
2022-07-30 02:29:20 +00:00
return 1;
2022-07-25 12:40:21 +00:00
case WM_LBUTTONUP:
2022-07-30 02:29:20 +00:00
Task.Run(() =>
2022-07-25 12:40:21 +00:00
{
2022-07-30 02:29:20 +00:00
while (_isTouchDown) { }
PInvoke.mouse_event(MOUSEEVENTF_LEFTUP, info.pt.X, info.pt.Y, 0, 0);
if (_isDragged)
2022-07-25 12:40:21 +00:00
{
2022-07-30 02:29:20 +00:00
// Override GTN750 bug - must execute this to fix GTN750 cursor moving offscreen issue when doing touch and drag
Thread.Sleep(AppSetting.TouchScreenSettings.TouchDownUpDelay + 50);
PInvoke.SetCursorPos(info.pt.X, info.pt.Y);
Thread.Sleep(100);
InputEmulationManager.LeftClickFast(info.pt.X, info.pt.Y);
_isDragged = false;
2022-07-25 12:40:21 +00:00
}
2022-07-30 02:29:20 +00:00
_mouseMoveCount = 0;
2022-09-25 14:49:49 +00:00
// Refocus game window
if (AppSetting.TouchScreenSettings.RefocusGameWindow && !panelConfig.DisableGameRefocus)
{
_refocusedTaskIndex++;
var currentRefocusIndex = _refocusedTaskIndex;
Thread.Sleep(AppSetting.TouchScreenSettings.RefocusGameWindowDelay);
if (currentRefocusIndex == _refocusedTaskIndex)
{
2022-10-11 13:37:49 +00:00
var rectangle = WindowActionManager.GetWindowRect(_simulatorProcess.Handle);
var clientRectangle = WindowActionManager.GetClientRect(_simulatorProcess.Handle);
PInvoke.SetCursorPos(rectangle.X + clientRectangle.Width / 2, rectangle.Y + clientRectangle.Height / 2);
2022-09-25 14:49:49 +00:00
}
}
2022-07-30 02:29:20 +00:00
});
2022-07-25 12:40:21 +00:00
return 1;
case WM_MOUSEMOVE:
2022-09-25 14:49:49 +00:00
if (_isTouchDown)
2022-07-30 02:29:20 +00:00
return 1;
2022-07-25 12:40:21 +00:00
_mouseMoveCount++;
break;
}
return PInvoke.CallNextHookEx(_hHook, code, wParam, lParam);
}
}
}