misu – Rev 1
?pathlinks?
using System;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks.Dataflow;
using System.Windows.Forms;
using Configuration;
using Gma.System.MouseKeyHook;
namespace misu
{
public partial class Form1 : Form
{
#region Public Enums, Properties and Fields
public Settings Settings { get; set; }
public Point LockedCursorPosition { get; set; }
#endregion
#region Private Delegates, Events, Enums, Properties, Indexers and Fields
private BufferBlock<KeyEventArgs> PressedKeysBufferBlock { get; }
private IKeyboardMouseEvents GlobalHook { get; }
private AboutForm AboutForm { get; set; }
private BindKeyForm BindKeyForm { get; set; }
private volatile bool _lock;
#endregion
#region Constructors, Destructors and Finalizers
public Form1()
{
InitializeComponent();
PressedKeysBufferBlock = new BufferBlock<KeyEventArgs>(new DataflowBlockOptions {EnsureOrdered = true});
// Load the settings.
var serialization = Serialization.Deserialize(@"Settings.xml");
switch (serialization)
{
case SerializationSuccess<Settings> serializationSuccess:
Settings = serializationSuccess.Result;
break;
case SerializationFailure _:
Settings = new Settings();
break;
}
Settings.PropertyChanged += Settings_PropertyChanged;
// Hook to global events.
GlobalHook = Hook.GlobalEvents();
// Bind to receive keyboard presses.
GlobalHook.KeyDown += GlobalHook_KeyDown;
GlobalHook.KeyUp += GlobalHook_KeyUp;
GlobalHook.MouseMove += GlobalHook_MouseMove;
}
#endregion
#region Event Handlers
private void GlobalHook_MouseMove(object sender, MouseEventArgs e)
{
if (Settings.Mouse)
{
switch (_lock)
{
case true:
Cursor.Clip = new Rectangle(LockedCursorPosition, new Size(1, 1));
break;
default:
Cursor.Clip = Screen.PrimaryScreen.Bounds;
break;
}
}
}
private async void Settings_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
// Serialize the settings to the configuration file on form closing.
await Settings.Serialize(@"Settings.xml");
}
private void GlobalHook_KeyUp(object sender, KeyEventArgs e)
{
if (Settings.Binding == null)
{
return;
}
if (!PressedKeysBufferBlock.TryReceiveAll(out var keys))
{
return;
}
if (Settings.Binding.Keys.SequenceContains(keys.Select(key => key.KeyCode)))
{
_lock = !_lock;
// Save the cursor position in order to lock the mouse.
LockedCursorPosition = Cursor.Position;
// Dismiss the current keypress to avoid typing the key.
e.Handled = true;
e.SuppressKeyPress = true;
Notify($"Input is {(_lock ? "locked" : "unlocked")}", "Press the keyboard shortcut to toggle locking.");
}
}
private async void GlobalHook_KeyDown(object sender, KeyEventArgs e)
{
if (_lock && Settings.Keyboard)
{
e.SuppressKeyPress = true;
e.Handled = true;
}
await PressedKeysBufferBlock.SendAsync(e);
}
private void OnContextMenuAboutClick(object sender, EventArgs e)
{
// Show the about form.
AboutForm = new AboutForm();
AboutForm.Show();
}
private void OnContextMenuQuitClick(object sender, EventArgs e)
{
Application.Exit();
}
private void OnContextMenuLaunchOnBootChanged(object sender, EventArgs e)
{
Settings.LaunchOnBoot = ((ToolStripMenuItem) sender).Checked;
Utilities.LaunchOnBootSet(Settings.LaunchOnBoot);
}
private void OnContextMenuBindKeyClick(object sender, EventArgs e)
{
BindKeyForm = new BindKeyForm(GlobalHook, Settings);
BindKeyForm.KeyBound += BindKeyForm_KeyBound;
BindKeyForm.Closing += BindKeyForm_Closing;
BindKeyForm.Show();
}
private void BindKeyForm_Closing(object sender, CancelEventArgs e)
{
BindKeyForm.KeyBound -= BindKeyForm_KeyBound;
BindKeyForm.Closing -= BindKeyForm_Closing;
}
private void BindKeyForm_KeyBound(object sender, KeyBoundEventArgs e)
{
Notify("Keys bound", "Press to toggle between locked and unlocked states.");
Settings.Binding = e.Binding;
}
private void KeyboardToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
{
var item = (ToolStripMenuItem) sender;
Settings.Keyboard = item.Checked;
}
private void MouseToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
{
var item = (ToolStripMenuItem) sender;
Settings.Mouse = item.Checked;
}
private void ContextMenuStrip_Opening(object sender, CancelEventArgs e)
{
// Apply the settings to the menu items.
launchOnBootToolStripMenuItem.Checked = Settings.LaunchOnBoot;
Utilities.LaunchOnBootSet(Settings.LaunchOnBoot);
mouseToolStripMenuItem.Checked = Settings.Mouse;
keyboardToolStripMenuItem.Checked = Settings.Keyboard;
}
#endregion
#region Private Methods
private void Notify(string title, string message, int timeout = 10000)
{
notifyIcon1.BalloonTipTitle = title;
notifyIcon1.BalloonTipText = message;
// the timeout parameter is not used for Windows Vista and up
notifyIcon1.ShowBalloonTip(timeout);
}
#endregion
}
}
Generated by GNU Enscript 1.6.5.90.