Skip to content

Commit

Permalink
Improve detection of RA3 and be faster
Browse files Browse the repository at this point in the history
  • Loading branch information
zokker13 committed Nov 29, 2017
1 parent e5a6f14 commit 6dd6290
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 107 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# RatherWeird Changelog

## ??
### Changed
* Improved RA3 detection - if you restart RA3 or start the tool after RA3, RA3 will be detected faster and work directly.

## 0.4.0 [2017-11-12]
### Added
* Support to disable Windows Keys (left and right).
Expand Down
32 changes: 27 additions & 5 deletions RatherWeird/RatherWeird/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace RatherWeird
/// </summary>
public partial class MainWindow : Window
{
private readonly ForegroundWatcher _foregroundWatcher = new ForegroundWatcher();
private readonly SystemWatcher _systemWatcher = new SystemWatcher();
private readonly KeyboardWatcher _keyboardWatcher = new KeyboardWatcher();
private readonly MemoryManipulator _memoryManipulator = new MemoryManipulator();

Expand Down Expand Up @@ -64,7 +64,7 @@ public MainWindow()
InitializeComponent();
}

private void ForegroundWatcher_ForegroundChanged(object sender, ForegroundArgs e)
private void SystemWatcherSystemChanged(object sender, ProcessArgs e)
{
if (e.Process.ProcessName!= Constants.Ra3ProcessName)
return;
Expand Down Expand Up @@ -121,18 +121,40 @@ private void Window_Loaded(object sender, RoutedEventArgs e)
settings = Preferences.Load();
SetupControls();

_foregroundWatcher.HookForeground();
_systemWatcher.Hook();
_keyboardWatcher.HookKeyboard();

_foregroundWatcher.ForegroundChanged += ForegroundWatcher_ForegroundChanged;
_systemWatcher.ForegroundChanged += SystemWatcherSystemChanged;
_systemWatcher.ShowWindow += SystemWatcherOnShowWindow;
_systemWatcher.HideWindow += SystemWatcherOnHideWindow;
_keyboardWatcher.KeyboardInputChanged += _keyboardWatcher_KeyboardInputChanged;

var ra3Procs = Process.GetProcessesByName(Constants.Ra3ProcessName);
if (ra3Procs.Length > 0)
{
LatestRa3 = ra3Procs[0];
}


DispatcherTimer tmr = new DispatcherTimer();
tmr.Tick += Tmr_Tick;
tmr.Interval = new TimeSpan(0, 0, 0, 1);
tmr.Start();
}

private void SystemWatcherOnHideWindow(object sender, ProcessArgs e)
{
// :( ??
}

private void SystemWatcherOnShowWindow(object sender, ProcessArgs e)
{
if (e.Process.ProcessName != Constants.Ra3ProcessName)
return;

LatestRa3 = e.Process;
}

private void _keyboardWatcher_KeyboardInputChanged(object sender, KeyboardInputArgs e)
{
HookNumpadEnter(e);
Expand Down Expand Up @@ -174,7 +196,7 @@ private void Tmr_Tick(object sender, EventArgs e)

private void Window_Closed(object sender, EventArgs e)
{
_foregroundWatcher.Unhook();
_systemWatcher.Unhook();
_keyboardWatcher.UnhookKeyboard();
_memoryManipulator.LockProcess();

Expand Down
101 changes: 0 additions & 101 deletions RatherWeird/WindowHook/ForegroundWatcher.cs

This file was deleted.

193 changes: 193 additions & 0 deletions RatherWeird/WindowHook/SystemWatcher.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace WindowHook
{
public class SystemWatcher
{
#region DllImport

[DllImport("user32.dll")]
static extern IntPtr SetWinEventHook(
SystemEvents eventMin
, SystemEvents eventMax
, IntPtr hmodWinEventProc
, WinEventDelegate lpfnWinEventProc
, uint idProcess
, uint idThread
, uint dwFlags
);

[DllImport("user32.dll")]
static extern bool UnhookWinEvent(IntPtr hWinEventHook);

[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

#endregion

public enum SystemEvents
{
EventMin = 0x00000001, // EVENT_MIN
SystemSound = 0x0001, // EVENT_SYSTEM_SOUND
SystemAlert = 0x0002, // EVENT_SYSTEM_ALERT
SystemForeground = 0x0003, // EVENT_SYSTEM_FOREGROUND
SystemMenuStart = 0x0004, // EVENT_SYSTEM_MENUSTART
SystemMenuEnd = 0x0005, // EVENT_SYSTEM_MENUEND
SystemMenuPopupStart = 0x0006, // EVENT_SYSTEM_MENUPOPUPSTART
SystemMenuPopupEnd = 0x0007, // EVENT_SYSTEM_MENUPOPUPEND
SystemCaptureStart = 0x0008, // EVENT_SYSTEM_CAPTURESTART
SystemCaptureEnd = 0x0009, // EVENT_SYSTEM_CAPTUREEND
SystemMoveSizeStart = 0x000A, // EVENT_SYSTEM_MOVESIZESTART
SystemMoveSizeEnd = 0x000B, // EVENT_SYSTEM_MOVESIZEEND
SystemContextHelpStart = 0x000C, // EVENT_SYSTEM_CONTEXTHELPSTART
SystemContextHelpEnd = 0x000D, // EVENT_SYSTEM_CONTEXTHELPEND
SystemDragStart = 0x000E, // EVENT_SYSTEM_DRAGDROPSTART
SystemDragEnd = 0x000F, // EVENT_SYSTEM_DRAGDROPEND
SystemDialogStart = 0x0010, // EVENT_SYSTEM_DIALOGSTART
SystemDialogEnd = 0x0011, // EVENT_SYSTEM_DIALOGEND
SystemScrollingStart = 0x0012, // EVENT_SYSTEM_SCROLLINGSTART
SystemScrollingEnd = 0x0013, // EVENT_SYSTEM_SCROLLINGEND
SystemSwitchStart = 0x0014, // EVENT_SYSTEM_SWITCHSTART
SystemSwitchEnd = 0x0015, // EVENT_SYSTEM_SWITCHEND
SystemMinimizeStart = 0x0016, // EVENT_SYSTEM_MINIMIZESTART
SystemMinimizeEnd = 0x0017, // EVENT_SYSTEM_MINIMIZEEND
ObjectCreate = 0x8000, // EVENT_OBJECT_CREATE
ObjectDestroy = 0x8001, // EVENT_OBJECT_DESTROY
ObjectShow = 0x8002, // EVENT_OBJECT_SHOW
ObjectHide = 0x8003, // EVENT_OBJECT_HIDE
ObjectReorder = 0x8004, // EVENT_OBJECT_REORDER
ObjectFocus = 0x8005, // EVENT_OBJECT_FOCUS
ObjectSelection = 0x8006, // EVENT_OBJECT_SELECTION
ObjectSelectionAdd = 0x8007, // EVENT_OBJECT_SELECTIONADD
ObjectSelectionRemove = 0x8008, // EVENT_OBJECT_SELECTIONREMOVE
ObjectSelectionWithin = 0x8009, // EVENT_OBJECT_SELECTIONWITHIN
ObjectStateChange = 0x800A, // EVENT_OBJECT_STATECHANGE
ObjectLocationChange = 0x800B, // EVENT_OBJECT_LOCATIONCHANGE
ObjectNameChange = 0x800C, // EVENT_OBJECT_NAMECHANGE
ObjectDescriptionChange = 0x800D, // EVENT_OBJECT_DESCRIPTIONCHANGE
ObjectValueChange = 0x800E, // EVENT_OBJECT_VALUECHANGE
ObjectParentChange = 0x800F, // EVENT_OBJECT_PARENTCHANGE
ObjectHelpChange = 0x8010, // EVENT_OBJECT_HELPCHANGE
ObjectDefactionChange = 0x8011, // EVENT_OBJECT_DEFACTIONCHANGE
ObjectAcceleratorChange = 0x8012, // EVENT_OBJECT_ACCELERATORCHANGE
EventMax = 0x7FFFFFFF, // EVENT_MAX

// Vista or later.
ObjectContentScrolled = 0x8015, // EVENT_OBJECT_CONTENTSCROLLED
ObjectTextSelectionChanged = 0x8014, // EVENT_OBJECT_TEXTSELECTIONCHANGED
ObjectInvoked = 0x8013, // EVENT_OBJECT_INVOKED
SystemDesktopSwitch = 0x00000020, // EVENT_SYSTEM_DESKTOPSWITCH
}

private const uint WINEVENT_OUTOFCONTEXT = 0x0000; // Events are ASYNC

public event ForegroundChangeHandler ForegroundChanged;
public event ShowWindowHandler ShowWindow;
public event HideWindowHandler HideWindow;

private readonly List<IntPtr> _wndHooks = new List<IntPtr>();

private WinEventDelegate _del;

private delegate void WinEventDelegate(
IntPtr hWinEventHook
, SystemEvents eventType
, IntPtr hwnd
, int idObject
, int idChild
, uint dwEventThread
, uint dwmsEventTime
);

public void Hook()
{
_del = (hWinEventHook, eventType, hwnd, idObject, idChild, dwEventThread, dwmsEventTime) =>
{
switch (eventType)
{
case SystemEvents.SystemForeground:
OnForegroundChange(this, new ProcessArgs(AquireProcessFromHandle(hwnd)));
break;
case SystemEvents.ObjectShow:
OnShowWindow(this, new ProcessArgs(AquireProcessFromHandle(hwnd)));
break;
case SystemEvents.ObjectHide:
OnHideWindow(this, new ProcessArgs(AquireProcessFromHandle(hwnd)));
break;
}
};

_wndHooks.Add(
SetWinEventHook(
SystemEvents.SystemForeground
, SystemEvents.SystemForeground
, IntPtr.Zero
, _del
, 0
, 0
, WINEVENT_OUTOFCONTEXT
)
);

_wndHooks.Add(
SetWinEventHook(
SystemEvents.ObjectShow
, SystemEvents.ObjectHide
, IntPtr.Zero
, _del
, 0
, 0
, WINEVENT_OUTOFCONTEXT
)
);
}

private Process AquireProcessFromHandle(IntPtr hwnd)
{
GetWindowThreadProcessId(hwnd, out var processId);
return Process.GetProcessById((int)processId);
}

public void Unhook()
{
foreach (var wndHook in _wndHooks)
{
UnhookWinEvent(wndHook);
}
}

private void OnForegroundChange(object o, ProcessArgs e)
{
ForegroundChanged?.Invoke(o, e);
}

private void OnShowWindow(object o, ProcessArgs e)
{
ShowWindow?.Invoke(o, e);
}

private void OnHideWindow(object o, ProcessArgs e)
{
HideWindow?.Invoke(o, e);
}
}

public delegate void ForegroundChangeHandler(object sender, ProcessArgs e);
public delegate void ShowWindowHandler(object sender, ProcessArgs e);
public delegate void HideWindowHandler(object sender, ProcessArgs e);

public class ProcessArgs : EventArgs
{
public Process Process { get; }
public ProcessArgs(Process process)
{
Process = process;
}
}
}
2 changes: 1 addition & 1 deletion RatherWeird/WindowHook/WindowHook.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ForegroundWatcher.cs" />
<Compile Include="SystemWatcher.cs" />
<Compile Include="KeyboardWatcher.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
Expand Down

0 comments on commit 6dd6290

Please sign in to comment.