Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Toggle Function #63

Merged
merged 12 commits into from
Feb 17, 2022
1 change: 1 addition & 0 deletions AutoClicker/AutoClicker.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
<Compile Include="Models\AutoClickerSettings.cs" />
<Compile Include="Models\HotkeySettings.cs" />
<Compile Include="Models\SystemTrayMenuActionEventArgs.cs" />
<Compile Include="Utils\GlobalMouseHook.cs" />
<Compile Include="Utils\JsonUtils.cs" />
<Compile Include="Utils\KeyMappingUtils.cs" />
<Compile Include="Models\ApplicationSettings.cs" />
Expand Down
3 changes: 3 additions & 0 deletions AutoClicker/Commands/MainWindowCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ public static class MainWindowCommands

public static readonly RoutedUICommand Stop =
AssemblyUtils.CreateCommand(typeof(MainWindowCommands), nameof(Stop));

public static readonly RoutedUICommand Toggle =
AssemblyUtils.CreateCommand(typeof(MainWindowCommands), nameof(Toggle));

public static readonly RoutedUICommand SaveSettings =
AssemblyUtils.CreateCommand(typeof(MainWindowCommands), nameof(SaveSettings));
Expand Down
10 changes: 9 additions & 1 deletion AutoClicker/Enums/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ public enum LocationMode
public enum Operation
{
Start = 0,
Stop = 1
Stop = 1,
Toggle = 2
}

public enum SystemTrayMenuAction
Expand All @@ -37,4 +38,11 @@ public enum SystemTrayMenuAction
Hide = 1,
Exit = 2
}

public enum ToleranceMode
{
Absolute = 0,
Relative = 1,
Intelligent = 2
}
}
6 changes: 6 additions & 0 deletions AutoClicker/Models/AutoClickerSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,11 @@ public class AutoClickerSettings
public int PickedYValue { get; set; }

public int SelectedTimesToRepeat { get; set; }

public bool StopOnMouseMove { get; set; }

public int MouseMoveTolerance { get; set; }

public ToleranceMode ToleranceMode { get; set; }
}
}
3 changes: 3 additions & 0 deletions AutoClicker/Models/HotkeySettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ public class HotkeySettings
public static readonly KeyMapping defaultStartKeyMapping = KeyMappingUtils.GetKeyMappingByCode(Constants.DEFAULT_START_HOTKEY);

public static readonly KeyMapping defaultStopKeyMapping = KeyMappingUtils.GetKeyMappingByCode(Constants.DEFAULT_STOP_HOTKEY);
public static readonly KeyMapping defaultToggleKeyMapping = KeyMappingUtils.GetKeyMappingByCode(Constants.DEFAULT_TOGGLE_HOTKEY);

public KeyMapping StartHotkey { get; set; } = defaultStartKeyMapping;

public KeyMapping StopHotkey { get; set; } = defaultStopKeyMapping;

public KeyMapping ToggleHotkey { get; set; } = defaultToggleKeyMapping;
}
}
7 changes: 7 additions & 0 deletions AutoClicker/Resources/MainWindowResources.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,11 @@
<x:Type TypeName="enums:LocationMode"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ObjectDataProvider x:Key="toleranceModeValues"
MethodName="GetValues"
ObjectType="{x:Type system:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="enums:ToleranceMode"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</ResourceDictionary>
5 changes: 5 additions & 0 deletions AutoClicker/Utils/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public static class Constants
public const string MAIN_WINDOW_TITLE_DEFAULT = "AutoClicker";
public const string MAIN_WINDOW_TITLE_RUNNING = " - Running...";
public const string MAIN_WINDOW_START_BUTTON_CONTENT = "Start";
public const string MAIN_WINDOW_TOGGLE_BUTTON_CONTENT = "Toggle";
public const string MAIN_WINDOW_STOP_BUTTON_CONTENT = "Stop";

public const string ABOUT_WINDOW_TITLE = "About";
Expand All @@ -30,9 +31,13 @@ public static class Constants
public const int MOD_NONE = 0x0;
public const int START_HOTKEY_ID = 9000;
public const int STOP_HOTKEY_ID = 9001;
public const int TOGGLE_HOTKEY_ID = 9002;
public const int WM_HOTKEY = 0x0312;

public const int DEFAULT_START_HOTKEY = 0x75;
public const int DEFAULT_STOP_HOTKEY = 0x76;
public const int DEFAULT_TOGGLE_HOTKEY = 0x77;

public const int MOUSE_HOOK_MIN_EVENT_DELTA_MILIS = 30;
}
}
149 changes: 149 additions & 0 deletions AutoClicker/Utils/GlobalMouseHook.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Drawing;
using Serilog;

namespace AutoClicker.Utils
{

/// <summary>
/// This class has been copied from StackOverflow where the OP copied it form somewhere else...
/// </summary>
public static class GlobalMouseHook
{
public static bool IsActive { get; private set; }

public static event EventHandler MouseAction = delegate { };

public static int MilisBetweenEvents { get; private set; }

public static void Start(int milisBetweenEvents)
{
Start();
MilisBetweenEvents = milisBetweenEvents;
_timer = new Stopwatch();
_timer.Start();
}
public static void Start()
{
_hookID = SetHook(_proc);
IsActive = true;
Log.Information("GloablMouseHook started");
}
public static void stop()
{
UnhookWindowsHookEx(_hookID);
IsActive = false;
if (MilisBetweenEvents > 0)
_timer.Stop();
Log.Information("GloablMouseHook stopped");
}

private static LowLevelMouseProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
private static Stopwatch _timer = new Stopwatch();

private static IntPtr SetHook(LowLevelMouseProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
IntPtr hook = SetWindowsHookEx(WH_MOUSE_LL, proc, GetModuleHandle("user32"), 0);
if (hook == IntPtr.Zero)
{
throw new System.ComponentModel.Win32Exception();
}
return hook;
}
}

private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && MouseMessages.WM_MOUSEMOVE == (MouseMessages)wParam)
{
MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
if (MilisBetweenEvents > 0)
{
if (_timer.ElapsedMilliseconds > MilisBetweenEvents)
{
_timer.Restart();
MouseAction(null, new EventArgs());
}
}
else
MouseAction(null, new EventArgs());
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}

private const int WH_MOUSE_LL = 14;

private enum MouseMessages
{
WM_LBUTTONDOWN = 0x0201,
WM_LBUTTONUP = 0x0202,
WM_MOUSEMOVE = 0x0200,
WM_MOUSEWHEEL = 0x020A,
WM_RBUTTONDOWN = 0x0204,
WM_RBUTTONUP = 0x0205
}

/// <summary>
/// Struct representing a point.
/// Thanks StackOverflow again :)
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;

public static implicit operator Point(POINT point)
{
return new Point(point.X, point.Y);
}
}

[StructLayout(LayoutKind.Sequential)]
private struct MSLLHOOKSTRUCT
{
public POINT pt;
public uint mouseData, flags, time;
public IntPtr dwExtraInfo;
}

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);

/// <summary>
/// Retrieves the cursor's position, in screen coordinates.
/// </summary>
/// <see>See MSDN documentation for further information.</see>
[DllImport("user32.dll")]
public static extern bool GetCursorPos(out POINT lpPoint);

public static Point GetCursorPosition()
{
POINT lpPoint;
GetCursorPos(out lpPoint);
// NOTE: If you need error handling
// bool success = GetCursorPos(out lpPoint);
// if (!success)

return lpPoint;
}
}
}
8 changes: 8 additions & 0 deletions AutoClicker/Utils/SettingsUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ public static void SetStopHotKey(KeyMapping key)
CurrentSettings.HotkeySettings.StopHotkey = key;
NotifyChanges(CurrentSettings.HotkeySettings.StopHotkey, Operation.Stop);
}
public static void SetToggleHotKey(KeyMapping key)
{
CurrentSettings.HotkeySettings.ToggleHotkey = key;
NotifyChanges(CurrentSettings.HotkeySettings.ToggleHotkey, Operation.Toggle);
}

public static void Reset()
{
Expand Down Expand Up @@ -94,6 +99,9 @@ public static void SetApplicationSettings(AutoClickerSettings settings)
CurrentSettings.AutoClickerSettings.SelectedMouseButton = settings.SelectedMouseButton;
CurrentSettings.AutoClickerSettings.SelectedRepeatMode = settings.SelectedRepeatMode;
CurrentSettings.AutoClickerSettings.SelectedTimesToRepeat = settings.SelectedTimesToRepeat;
CurrentSettings.AutoClickerSettings.StopOnMouseMove = settings.StopOnMouseMove;
CurrentSettings.AutoClickerSettings.MouseMoveTolerance = settings.MouseMoveTolerance;
CurrentSettings.AutoClickerSettings.ToleranceMode = settings.ToleranceMode;

SaveSettingsToFile();
}
Expand Down
50 changes: 48 additions & 2 deletions AutoClicker/Views/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
xmlns:commands="clr-namespace:AutoClicker.Commands"
xmlns:enums="clr-namespace:AutoClicker.Enums"
ResizeMode="CanMinimize"
Height="320" Width="450">
Height="370" Width="450">
<Window.Resources>
<ResourceDictionary Source="../Resources/MainWindowResources.xaml"/>
</Window.Resources>
Expand All @@ -14,6 +14,8 @@
Executed="StartCommand_Execute" CanExecute="StartCommand_CanExecute"/>
<CommandBinding Command="commands:MainWindowCommands.Stop"
Executed="StopCommand_Execute" CanExecute="StopCommand_CanExecute"/>
<CommandBinding Command="commands:MainWindowCommands.Toggle"
Executed="ToggleCommand_Execute" CanExecute="ToggleCommand_CanExecute"/>
<CommandBinding Command="commands:MainWindowCommands.SaveSettings"
Executed="SaveSettingsCommand_Execute"/>
<CommandBinding Command="commands:MainWindowCommands.HotkeySettings"
Expand Down Expand Up @@ -50,6 +52,7 @@
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
Expand Down Expand Up @@ -175,14 +178,57 @@
</UniformGrid>
</GroupBox>

<GroupBox Name="behaviourOptionsGroupBox"
Header="Behaviour" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="4">
<Grid Name="behaviourOptionsGrid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<CheckBox Grid.Row="0" Grid.Column="0" Margin="0, 5, 5, 5"
Content="Stop on mouse move"
VerticalContentAlignment="Center"
IsChecked="{Binding AutoClickerSettings.StopOnMouseMove}"/>

<TextBlock Grid.Row="0" Grid.Column="1" Text="Tolerance (px)" HorizontalAlignment="Right"
Margin="5, 5, 5, 5"
ToolTip="If the mouse cursor is less pixels away from the start position of "/>
<TextBox Margin="5,3,5,3" Grid.Row="0" Grid.Column="2" IsEnabled="{Binding AutoClickerSettings.StopOnMouseMove}"
Text="{Binding AutoClickerSettings.MouseMoveTolerance, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>

<TextBlock Grid.Row="1" Grid.Column="0" Text="Tolerance Mode"
Margin="5, 5, 5, 5" VerticalAlignment="Center" TextAlignment="Center"/>
<ComboBox Grid.Row="1" Grid.Column="1" Margin="5, 5, 5, 5" IsEnabled="{Binding AutoClickerSettings.StopOnMouseMove}"
ItemsSource="{Binding Source={StaticResource toleranceModeValues}}"
SelectedIndex="0" SelectedItem="{Binding AutoClickerSettings.ToleranceMode}" HorizontalAlignment="Stretch">
<ComboBox.ToolTip>
<TextBlock>
<Bold>Absolute:</Bold> The distance in pixel from the point where the autoclicker was started <LineBreak/>
<Bold>Relative:</Bold> How many pixel lay between the current and last mouse position <LineBreak/>
<Bold>Inteligent:</Bold> Is a mix from both. The absolute "home" slowly moves to the mouse cursor <LineBreak/>
but if the mouse suddenly moves by a lot it will stop
</TextBlock>
</ComboBox.ToolTip>
</ComboBox>
</Grid>
</GroupBox>

<UniformGrid Name="buttonsGrid"
Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="4" Rows="2" Columns="2">
Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="4" Rows="2" Columns="3">
<Button Name="startButton"
Grid.Row="0" Grid.Column="0" Margin="5"
Content="Start (F6)" Command="commands:MainWindowCommands.Start"/>
<Button Name="stopButton"
Grid.Row="0" Grid.Column="1" Margin="5"
Content="Stop (F7)" Command="commands:MainWindowCommands.Stop"/>
<Button Name="toggleButton"
Grid.Row="0" Grid.Column="1" Margin="5"
Content="Toggle (F8)" Command="commands:MainWindowCommands.Toggle"/>
<Button Name="saveSettingsButton"
Grid.Row="1" Grid.Column="0" Margin="5"
Content="Save Settings" Command="commands:MainWindowCommands.SaveSettings"/>
Expand Down
Loading