Inertia – Rev 6
?pathlinks?
using System;
using System.ComponentModel;
using System.Configuration;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using WindowsInput;
using AutoUpdaterDotNET;
using Gma.System.MouseKeyHook;
using Inertia.Properties;
using Inertia.Utilities;
namespace Inertia
{
public partial class Form1 : Form
{
#region Static Fields and Constants
private static IKeyboardMouseEvents _globalMouseKeyHook;
private static InputSimulator _inputSimulator;
private static ScheduledContinuation _scrollUpContinuation;
private static long _upDelta;
private static long _downDelta;
private static ScheduledContinuation _scrollDownContinuation;
private static CancellationTokenSource _scrollCancellationTokenSource;
#endregion
#region Private Delegates, Events, Enums, Properties, Indexers and Fields
private AboutForm _aboutForm;
#endregion
#region Constructors, Destructors and Finalizers
public Form1()
{
InitializeComponent();
AutoUpdater.Start("http://inertia.grimore.org/update/update.xml");
// Upgrade settings if required.
if (!ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).HasFile)
{
Settings.Default.Upgrade();
}
// Bind to settings changed event.
Settings.Default.SettingsLoaded += DefaultOnSettingsLoaded;
Settings.Default.SettingsSaving += DefaultOnSettingsSaving;
Settings.Default.PropertyChanged += DefaultOnPropertyChanged;
_inputSimulator = new InputSimulator();
_scrollCancellationTokenSource = new CancellationTokenSource();
_globalMouseKeyHook = Hook.GlobalEvents();
_globalMouseKeyHook.MouseWheel += GlobalMouseKeyHookMouseWheel;
_scrollUpContinuation = new ScheduledContinuation();
_scrollDownContinuation = new ScheduledContinuation();
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && components != null)
{
_globalMouseKeyHook.MouseWheel -= GlobalMouseKeyHookMouseWheel;
_globalMouseKeyHook.Dispose();
components.Dispose();
}
base.Dispose(disposing);
}
#endregion
#region Event Handlers
private void DefaultOnSettingsSaving(object sender, CancelEventArgs e)
{
}
private void DefaultOnSettingsLoaded(object sender, SettingsLoadedEventArgs e)
{
}
private void DefaultOnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
Settings.Default.Save();
}
private static void GlobalMouseKeyHookMouseWheel(object sender, MouseEventArgs e)
{
var delta = Math.Abs(e.Delta);
switch (Math.Sign(e.Delta))
{
case 0:
break;
case 1: // up
Interlocked.Add(ref _upDelta, delta);
_scrollUpContinuation.Schedule(TimeSpan.FromMilliseconds(50), ScrollUp);
Debug.WriteLine($"Mouse wheel moved up by {e.Delta}.");
break;
case -1: // down
Interlocked.Add(ref _downDelta, delta);
_scrollDownContinuation.Schedule(TimeSpan.FromMilliseconds(50), ScrollDown);
Debug.WriteLine($"Mouse wheel moved down by {e.Delta}.");
break;
}
}
private void AboutToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_aboutForm != null)
{
return;
}
_aboutForm = new AboutForm();
_aboutForm.Closing += AboutForm_Closing;
_aboutForm.Show();
}
private void AboutForm_Closing(object sender, CancelEventArgs e)
{
if (_aboutForm == null)
{
return;
}
_aboutForm.Closing -= AboutForm_Closing;
_aboutForm.Dispose();
_aboutForm = null;
}
private void QuitToolStripMenuItem_Click(object sender, EventArgs e)
{
Close();
Environment.Exit(0);
}
private void LaunchOnBootToolStripMenuItem_Click(object sender, EventArgs e)
{
Settings.Default.LaunchOnBoot = ((ToolStripMenuItem) sender).Checked;
LaunchOnBoot.Set(Settings.Default.LaunchOnBoot);
}
#endregion
#region Private Methods
private static async void ScrollDown()
{
_scrollCancellationTokenSource.Cancel();
_scrollCancellationTokenSource = new CancellationTokenSource();
var cancellationToken = _scrollCancellationTokenSource.Token;
var downDelta = Interlocked.Read(ref _downDelta);
var delta = Math.Abs(downDelta / SystemInformation.MouseWheelScrollDelta);
Interlocked.Exchange(ref _downDelta, 0);
Debug.WriteLine($"Down event expired with delta {delta}");
_globalMouseKeyHook.MouseWheel -= GlobalMouseKeyHookMouseWheel;
try
{
await ScrollDown((int) delta, cancellationToken);
}
catch (TaskCanceledException)
{
// We do not care.
}
finally
{
_globalMouseKeyHook.MouseWheel += GlobalMouseKeyHookMouseWheel;
}
}
private static async void ScrollUp()
{
_scrollCancellationTokenSource.Cancel();
_scrollCancellationTokenSource = new CancellationTokenSource();
var cancellationToken = _scrollCancellationTokenSource.Token;
var upDelta = Interlocked.Read(ref _upDelta);
var delta = Math.Abs(upDelta / SystemInformation.MouseWheelScrollDelta);
Interlocked.Exchange(ref _upDelta, 0);
Debug.WriteLine($"Up event expired with delta {delta}");
_globalMouseKeyHook.MouseWheel -= GlobalMouseKeyHookMouseWheel;
try
{
await ScrollUp((int) delta, cancellationToken);
}
catch (TaskCanceledException)
{
// We do not care.
}
finally
{
_globalMouseKeyHook.MouseWheel += GlobalMouseKeyHookMouseWheel;
}
}
private static async Task ScrollUp(int delta, CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested && delta > 1)
{
_inputSimulator.Mouse.VerticalScroll(delta);
await Task.Delay(25 * delta, cancellationToken);
Debug.WriteLine($"Moving: {delta}");
delta = (int) Math.Log(delta, 2);
}
}
private static async Task ScrollDown(int delta, CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested && delta > 1)
{
_inputSimulator.Mouse.VerticalScroll(-delta);
await Task.Delay(25 * delta, cancellationToken);
Debug.WriteLine($"Moving: {delta}");
delta = (int) Math.Log(delta, 2);
}
}
#endregion
}
}
Generated by GNU Enscript 1.6.5.90.