mirror of
https://github.com/hawkeye-stan/msfs-popout-panel-manager.git
synced 2024-12-28 07:11:59 +00:00
Merge RSG GTN750 refocus fix
This commit is contained in:
commit
023a474fda
7 changed files with 151 additions and 35 deletions
|
@ -4,6 +4,8 @@ using MSFSPopoutPanelManager.WindowsAgent;
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MSFSPopoutPanelManager.Orchestration
|
||||
{
|
||||
|
@ -14,6 +16,11 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
private Rectangle _lastWindowRectangle;
|
||||
private IntPtr _panelHandleDisableRefresh = IntPtr.Zero;
|
||||
|
||||
private uint _prevWinEvent = PInvokeConstant.EVENT_SYSTEM_CAPTUREEND;
|
||||
private int _winEventClickLock = 0;
|
||||
private object _hookLock = new object();
|
||||
private bool _isHookMouseDown = false;
|
||||
|
||||
public PanelConfigurationOrchestrator()
|
||||
{
|
||||
_winEvent = new PInvoke.WinEventProc(EventCallback);
|
||||
|
@ -199,7 +206,10 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
return;
|
||||
|
||||
// Setup panel config event hooks
|
||||
_winEventHook = PInvoke.SetWinEventHook(PInvokeConstant.EVENT_SYSTEM_MOVESIZEEND, PInvokeConstant.EVENT_OBJECT_LOCATIONCHANGE, IntPtr.Zero, _winEvent, 0, 0, PInvokeConstant.WINEVENT_OUTOFCONTEXT);
|
||||
if (!ActiveProfile.RealSimGearGTN750Gen1Override)
|
||||
_winEventHook = PInvoke.SetWinEventHook(PInvokeConstant.EVENT_SYSTEM_MOVESIZEEND, PInvokeConstant.EVENT_OBJECT_LOCATIONCHANGE, IntPtr.Zero, _winEvent, 0, 0, PInvokeConstant.WINEVENT_OUTOFCONTEXT);
|
||||
else
|
||||
_winEventHook = PInvoke.SetWinEventHook(PInvokeConstant.EVENT_SYSTEM_CAPTURESTART, PInvokeConstant.EVENT_OBJECT_LOCATIONCHANGE, IntPtr.Zero, _winEvent, 0, 0, PInvokeConstant.WINEVENT_OUTOFCONTEXT);
|
||||
}
|
||||
|
||||
private void UnhookWinEvent()
|
||||
|
@ -214,6 +224,8 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
{
|
||||
case PInvokeConstant.EVENT_OBJECT_LOCATIONCHANGE:
|
||||
case PInvokeConstant.EVENT_SYSTEM_MOVESIZEEND:
|
||||
case PInvokeConstant.EVENT_SYSTEM_CAPTURESTART:
|
||||
case PInvokeConstant.EVENT_SYSTEM_CAPTUREEND:
|
||||
// check by priority to speed up comparing of escaping constraints
|
||||
if (hwnd == IntPtr.Zero || idObject != 0 || hWinEventHook != _winEventHook || !AllowEdit)
|
||||
return;
|
||||
|
@ -253,6 +265,17 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
PInvoke.ShowWindow(hwnd, PInvokeConstant.SW_RESTORE);
|
||||
}
|
||||
break;
|
||||
case PInvokeConstant.EVENT_SYSTEM_CAPTURESTART:
|
||||
if (!panelConfig.HasTouchableEvent || _prevWinEvent == PInvokeConstant.EVENT_SYSTEM_CAPTURESTART)
|
||||
break;
|
||||
|
||||
HandleTouchDownEvent(panelConfig);
|
||||
break;
|
||||
case PInvokeConstant.EVENT_SYSTEM_CAPTUREEND:
|
||||
if (!panelConfig.TouchEnabled || _prevWinEvent == PInvokeConstant.EVENT_OBJECT_LOCATIONCHANGE)
|
||||
break;
|
||||
HandleTouchUpEvent(panelConfig);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -301,6 +324,75 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
case PInvokeConstant.EVENT_SYSTEM_MOVESIZEEND:
|
||||
ProfileData.WriteProfiles();
|
||||
break;
|
||||
case PInvokeConstant.EVENT_SYSTEM_CAPTURESTART:
|
||||
if (!panelConfig.HasTouchableEvent || _prevWinEvent == PInvokeConstant.EVENT_SYSTEM_CAPTURESTART)
|
||||
break;
|
||||
|
||||
HandleTouchDownEvent(panelConfig);
|
||||
break;
|
||||
case PInvokeConstant.EVENT_SYSTEM_CAPTUREEND:
|
||||
if (!panelConfig.TouchEnabled || _prevWinEvent == PInvokeConstant.EVENT_OBJECT_LOCATIONCHANGE)
|
||||
break;
|
||||
HandleTouchUpEvent(panelConfig);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleTouchDownEvent(PanelConfig panelConfig)
|
||||
{
|
||||
if (!_isHookMouseDown)
|
||||
{
|
||||
lock (_hookLock)
|
||||
{
|
||||
Point point;
|
||||
PInvoke.GetCursorPos(out point);
|
||||
|
||||
// Disable left clicking if user is touching the title bar area
|
||||
if (point.Y - panelConfig.Top > (panelConfig.HideTitlebar ? 5 : 31))
|
||||
_isHookMouseDown = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void HandleTouchUpEvent(PanelConfig panelConfig)
|
||||
{
|
||||
if (_isHookMouseDown)
|
||||
{
|
||||
Thread.Sleep(AppSettingData.AppSetting.TouchScreenSettings.TouchDownUpDelay);
|
||||
|
||||
lock (_hookLock)
|
||||
{
|
||||
_isHookMouseDown = false;
|
||||
|
||||
Point point;
|
||||
PInvoke.GetCursorPos(out point);
|
||||
|
||||
// Disable left clicking if user is touching the title bar area
|
||||
if (point.Y - panelConfig.Top > (panelConfig.HideTitlebar ? 5 : 31))
|
||||
{
|
||||
var prevWinEventClickLock = ++_winEventClickLock;
|
||||
|
||||
if (prevWinEventClickLock == _winEventClickLock && AppSettingData.AppSetting.TouchScreenSettings.RefocusGameWindow)
|
||||
{
|
||||
Task.Run(() => RefocusMsfs(panelConfig.PanelHandle, prevWinEventClickLock));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RefocusMsfs(IntPtr panelConfigHandle, int prevWinEventClickLock)
|
||||
{
|
||||
Thread.Sleep(AppSettingData.AppSetting.TouchScreenSettings.RefocusGameWindowDelay);
|
||||
|
||||
if (prevWinEventClickLock == _winEventClickLock)
|
||||
{
|
||||
if (!_isHookMouseDown)
|
||||
{
|
||||
var rectangle = WindowActionManager.GetWindowRect(panelConfigHandle);
|
||||
PInvoke.SetCursorPos(rectangle.X - 5, rectangle.Y + 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,6 +140,7 @@ namespace MSFSPopoutPanelManager.UserDataAgent
|
|||
TouchDownUpDelay = 0;
|
||||
RefocusGameWindow = true;
|
||||
RefocusGameWindowDelay = 500;
|
||||
RealSimGearGTN750Gen1Override = false;
|
||||
}
|
||||
|
||||
public int TouchDownUpDelay { get; set; }
|
||||
|
@ -147,6 +148,8 @@ namespace MSFSPopoutPanelManager.UserDataAgent
|
|||
public bool RefocusGameWindow { get; set; }
|
||||
|
||||
public int RefocusGameWindowDelay { get; set; }
|
||||
|
||||
public bool RealSimGearGTN750Gen1Override { get; set; }
|
||||
}
|
||||
|
||||
public class TouchPanelSettings : ObservableObject
|
||||
|
|
|
@ -16,6 +16,7 @@ namespace MSFSPopoutPanelManager.UserDataAgent
|
|||
IsLocked = false;
|
||||
PowerOnRequiredForColdStart = false;
|
||||
IncludeInGamePanels = false;
|
||||
RealSimGearGTN750Gen1Override = false;
|
||||
|
||||
MsfsGameWindowConfig = new MsfsGameWindowConfig();
|
||||
|
||||
|
@ -46,6 +47,8 @@ namespace MSFSPopoutPanelManager.UserDataAgent
|
|||
|
||||
public bool IncludeInGamePanels { get; set; }
|
||||
|
||||
public bool RealSimGearGTN750Gen1Override { get; set; }
|
||||
|
||||
public MsfsGameWindowConfig MsfsGameWindowConfig { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
|
|
|
@ -16,6 +16,9 @@ namespace MSFSPopoutPanelManager.WindowsAgent
|
|||
public const int SW_MINIMIZE = 6;
|
||||
public const int SW_RESTORE = 9;
|
||||
|
||||
public const uint EVENT_SYSTEM_CAPTURESTART = 0x0008;
|
||||
public const uint EVENT_SYSTEM_CAPTUREEND = 0x0009;
|
||||
public const uint EVENT_SYSTEM_MOVESIZESTART = 0x000A;
|
||||
public const uint EVENT_SYSTEM_MOVESIZEEND = 0x000B;
|
||||
public const uint EVENT_OBJECT_LOCATIONCHANGE = 0x800B;
|
||||
|
||||
|
|
|
@ -15,10 +15,9 @@ namespace MSFSPopoutPanelManager.WindowsAgent
|
|||
private static PInvoke.WindowsHookExProc callbackDelegate = HookCallBack;
|
||||
private static bool _isTouchDown;
|
||||
private static int _mouseMoveCount;
|
||||
private static bool _isMouseMoveBlock = false;
|
||||
private static object _mouseTouchLock = new object();
|
||||
private static bool _isDragged = false;
|
||||
private static bool _refocused = true;
|
||||
private static int _refocusedTaskIndex = 0;
|
||||
|
||||
private const int PANEL_MENUBAR_HEIGHT = 31;
|
||||
private const uint TOUCH_FLAG = 0xFF515700;
|
||||
|
@ -37,18 +36,30 @@ namespace MSFSPopoutPanelManager.WindowsAgent
|
|||
|
||||
public static void Hook()
|
||||
{
|
||||
// If using RSG GT750 Gen 1, disable touch support
|
||||
if (ActiveProfile != null && ActiveProfile.RealSimGearGTN750Gen1Override)
|
||||
return;
|
||||
|
||||
_simulatorProcess = WindowProcessManager.GetSimulatorProcess();
|
||||
|
||||
Process curProcess = Process.GetCurrentProcess();
|
||||
ProcessModule curModule = curProcess.MainModule;
|
||||
var hookWindowPtr = PInvoke.GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);
|
||||
|
||||
_hHook = PInvoke.SetWindowsHookEx(HookType.WH_MOUSE_LL, callbackDelegate, hookWindowPtr, 0);
|
||||
}
|
||||
|
||||
public static void UnHook()
|
||||
{
|
||||
PInvoke.UnhookWindowsHookEx(_hHook);
|
||||
_hHook = IntPtr.Zero;
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsHooked { get { return _hHook != IntPtr.Zero; } }
|
||||
|
@ -58,7 +69,6 @@ namespace MSFSPopoutPanelManager.WindowsAgent
|
|||
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;
|
||||
|
@ -104,9 +114,7 @@ namespace MSFSPopoutPanelManager.WindowsAgent
|
|||
case WM_LBUTTONDOWN:
|
||||
if (!_isTouchDown)
|
||||
{
|
||||
_refocused = false;
|
||||
_isTouchDown = true;
|
||||
_isMouseMoveBlock = true;
|
||||
|
||||
lock (_mouseTouchLock)
|
||||
{
|
||||
|
@ -121,7 +129,6 @@ namespace MSFSPopoutPanelManager.WindowsAgent
|
|||
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);
|
||||
_isMouseMoveBlock = false;
|
||||
_isTouchDown = false;
|
||||
});
|
||||
}
|
||||
|
@ -142,11 +149,25 @@ namespace MSFSPopoutPanelManager.WindowsAgent
|
|||
_isDragged = false;
|
||||
}
|
||||
_mouseMoveCount = 0;
|
||||
RefocusMsfsGameWindow(panelConfig);
|
||||
|
||||
// Refocus game window
|
||||
if (AppSetting.TouchScreenSettings.RefocusGameWindow && !panelConfig.DisableGameRefocus)
|
||||
{
|
||||
_refocusedTaskIndex++;
|
||||
var currentRefocusIndex = _refocusedTaskIndex;
|
||||
|
||||
Thread.Sleep(AppSetting.TouchScreenSettings.RefocusGameWindowDelay);
|
||||
|
||||
if (currentRefocusIndex == _refocusedTaskIndex)
|
||||
{
|
||||
var rectangle = WindowActionManager.GetWindowRect(panelConfig.PanelHandle);
|
||||
PInvoke.SetCursorPos(rectangle.X - 5, rectangle.Y + 5);
|
||||
}
|
||||
}
|
||||
});
|
||||
return 1;
|
||||
case WM_MOUSEMOVE:
|
||||
if (_isMouseMoveBlock)
|
||||
if (_isTouchDown)
|
||||
return 1;
|
||||
|
||||
_mouseMoveCount++;
|
||||
|
@ -156,19 +177,5 @@ namespace MSFSPopoutPanelManager.WindowsAgent
|
|||
return PInvoke.CallNextHookEx(_hHook, code, wParam, lParam);
|
||||
|
||||
}
|
||||
|
||||
private static void RefocusMsfsGameWindow(PanelConfig panelConfig)
|
||||
{
|
||||
Thread.Sleep(AppSetting.TouchScreenSettings.RefocusGameWindowDelay);
|
||||
|
||||
if (!_refocused && !_isTouchDown && AppSetting.TouchScreenSettings.RefocusGameWindow && !panelConfig.DisableGameRefocus)
|
||||
{
|
||||
_refocused = true;
|
||||
var rectangle = WindowActionManager.GetWindowRect(_simulatorProcess.Handle);
|
||||
var clientRectangle = WindowActionManager.GetClientRect(_simulatorProcess.Handle);
|
||||
|
||||
PInvoke.SetCursorPos(rectangle.X + clientRectangle.Width / 2, rectangle.Y + clientRectangle.Height / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -262,17 +262,22 @@
|
|||
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<WrapPanel Orientation="Vertical" Visibility="{Binding TouchSettingsVisible, Converter={StaticResource VisibleIfTrueConverter}, Mode=OneWay}">
|
||||
<WrapPanel Orientation="Vertical" Margin="0,0,20,20">
|
||||
<TextBlock Style="{StaticResource TextBlockHeading}">Refocus Game Window</TextBlock>
|
||||
<Line Stretch="Fill" Stroke="Gray" X2="1"/>
|
||||
<CheckBox IsChecked="{Binding AppSettingData.AppSetting.TouchScreenSettings.RefocusGameWindow, Mode=TwoWay}" >
|
||||
<AccessText TextWrapping="Wrap">Automactically set focus back to game window after a period of inactivity on touch enabled panel. This will give your flight control back when using pop out panel.</AccessText>
|
||||
</CheckBox>
|
||||
<WrapPanel Margin="0,10,0,0">
|
||||
<mah:NumericUpDown Width="100" Minimum="500" Maximum="2000" Interval="500" FontSize="16" Height="32" Value="{Binding AppSettingData.AppSetting.TouchScreenSettings.RefocusGameWindowDelay, Mode=TwoWay}"></mah:NumericUpDown>
|
||||
<AccessText Margin="10,0,0,0" Width="490">Amount of time in milliseconds to wait for touch inactivity before input focus goes back to game window.</AccessText>
|
||||
<WrapPanel Orientation="Vertical" Margin="0,0,20,20">
|
||||
<TextBlock Style="{StaticResource TextBlockHeading}">Refocus Game Window</TextBlock>
|
||||
<Line Stretch="Fill" Stroke="Gray" X2="1"/>
|
||||
<CheckBox IsChecked="{Binding AppSettingData.AppSetting.TouchScreenSettings.RefocusGameWindow, Mode=TwoWay}" >
|
||||
<AccessText TextWrapping="Wrap">Automactically set focus back to game window after a period of inactivity on touch enabled panel. This will give your flight control back when using pop out panel.</AccessText>
|
||||
</CheckBox>
|
||||
<WrapPanel Margin="0,10,0,0">
|
||||
<mah:NumericUpDown Width="100" Minimum="500" Maximum="10000" Interval="500" FontSize="16" Height="32" Value="{Binding AppSettingData.AppSetting.TouchScreenSettings.RefocusGameWindowDelay, Mode=TwoWay}"></mah:NumericUpDown>
|
||||
<AccessText Margin="10,0,0,0" Width="490">Amount of time in milliseconds to wait for touch inactivity before input focus goes back to game window.</AccessText>
|
||||
</WrapPanel>
|
||||
<WrapPanel Margin="0,10,0,0">
|
||||
<CheckBox IsChecked="{Binding AppSettingData.AppSetting.TouchScreenSettings.RealSimGearGTN750Gen1Override, Mode=TwoWay}" >
|
||||
<AccessText Margin="10,0,0,0" Width="490">Use custom refocus logic for RealSimGear GTN750 Gen1.</AccessText>
|
||||
</CheckBox>
|
||||
</WrapPanel>
|
||||
</WrapPanel>
|
||||
</WrapPanel>
|
||||
<WrapPanel Orientation="Vertical" Margin="0,0,20,20">
|
||||
<TextBlock Style="{StaticResource TextBlockHeading}">Touch Down Touch Up Delay</TextBlock>
|
||||
<Line Stretch="Fill" Stroke="Gray" X2="1"/>
|
||||
|
|
|
@ -78,6 +78,9 @@
|
|||
</WrapPanel>
|
||||
<CheckBox Margin="10,5,0,0" Content="Power on required to pop out panels on cold start (G1000 / NXi Only)" IsChecked="{Binding ProfileData.ActiveProfile.PowerOnRequiredForColdStart}" Command="{Binding SetPowerOnRequiredCommand}" />
|
||||
<CheckBox Margin="10,5,0,0" Content="Include in-game menu bar panels (VFR Map, Checklist, ATC, etc)" IsChecked="{Binding ProfileData.ActiveProfile.IncludeInGamePanels}" Command="{Binding SetIncludeInGamePanelsCommand}" />
|
||||
<WrapPanel Orientation="Horizontal" Visibility="{Binding AppSettingData.AppSetting.TouchScreenSettings.RealSimGearGTN750Gen1Override, Converter={StaticResource VisibleIfTrueConverter}, Mode=OneWay}" >
|
||||
<CheckBox Margin="10,5,0,0" Content="RealSimGear GTN750 Gen1" IsChecked="{Binding ProfileData.ActiveProfile.RealSimGearGTN750Gen1Override}" Command="{Binding SetIncludeInGamePanelsCommand}" />
|
||||
</WrapPanel>
|
||||
<WrapPanel Name="TouchPanelConfigurationPanel" Orientation="Horizontal" Margin="0,10,0,0" Visibility="{Binding AppSettingData.AppSetting.IsEnabledTouchPanelServer, Converter={StaticResource VisibleIfTrueConverter}, Mode=OneWay}" >
|
||||
<Label Content="Open MSFS touch panel when flight session starts" Margin="5,0,0,0" />
|
||||
<Button Content="+" ToolTip="Add Binding" Margin="94,0,0,0" Width="40" Command="{Binding OpenTouchPanelBindingCommand}"/>
|
||||
|
|
Loading…
Reference in a new issue