misu – Blame information for rev 8

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
2 using System.ComponentModel;
7 office 3 using System.Configuration;
1 office 4 using System.Drawing;
5 using System.Linq;
6 using System.Threading.Tasks.Dataflow;
7 using System.Windows.Forms;
6 office 8 using AutoUpdaterDotNET;
1 office 9 using Gma.System.MouseKeyHook;
7 office 10 using misu.Properties;
1 office 11  
12 namespace misu
13 {
3 office 14 public partial class MisuMainForm : Form
1 office 15 {
16 #region Private Delegates, Events, Enums, Properties, Indexers and Fields
17  
18 private BufferBlock<KeyEventArgs> PressedKeysBufferBlock { get; }
19  
20 private IKeyboardMouseEvents GlobalHook { get; }
21  
22 private AboutForm AboutForm { get; set; }
23  
24 private BindKeyForm BindKeyForm { get; set; }
25  
26 private volatile bool _lock;
27  
28 #endregion
29  
30 #region Constructors, Destructors and Finalizers
31  
3 office 32 public MisuMainForm()
1 office 33 {
34 InitializeComponent();
6 office 35 AutoUpdater.Start("http://misu.grimore.org/update/update.xml");
1 office 36  
7 office 37 // Upgrade settings if required.
38 if (!ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).HasFile)
1 office 39 {
7 office 40 Settings.Default.Upgrade();
1 office 41 }
42  
7 office 43 // Bind to settings changed event.
44 Settings.Default.SettingsLoaded += Default_SettingsLoaded;
45 Settings.Default.SettingsSaving += Default_SettingsSaving;
46 Settings.Default.PropertyChanged += Default_PropertyChanged;
1 office 47  
7 office 48 PressedKeysBufferBlock = new BufferBlock<KeyEventArgs>(new DataflowBlockOptions {EnsureOrdered = true});
49  
1 office 50 // Hook to global events.
51 GlobalHook = Hook.GlobalEvents();
52  
53 // Bind to receive keyboard presses.
54 GlobalHook.KeyDown += GlobalHook_KeyDown;
55 GlobalHook.KeyUp += GlobalHook_KeyUp;
3 office 56  
57 GlobalHook.MouseUpExt += GlobalHook_BlockMouse;
58 GlobalHook.MouseDragFinishedExt += GlobalHook_BlockMouse;
59 GlobalHook.MouseDragStartedExt += GlobalHook_BlockMouse;
60 GlobalHook.MouseWheelExt += GlobalHook_BlockMouse;
61 GlobalHook.MouseMoveExt += GlobalHook_BlockMouse;
62 GlobalHook.MouseDownExt += GlobalHook_BlockMouse;
63  
7 office 64 if (Settings.Default.Keys != null)
3 office 65 {
5 office 66 Notify("Shortcut is bound.",
7 office 67 $"Press {string.Join(" ", Settings.Default.Keys.OfType<string>())} to toggle locking.");
3 office 68 }
1 office 69 }
70  
71 #endregion
72  
73 #region Event Handlers
74  
7 office 75 private static void Default_SettingsSaving(object sender, CancelEventArgs e)
1 office 76 {
3 office 77 }
78  
7 office 79 private static void Default_PropertyChanged(object sender, PropertyChangedEventArgs e)
80 {
81 Settings.Default.Save();
82 }
83  
84 private static void Default_SettingsLoaded(object sender, SettingsLoadedEventArgs e)
85 {
86 }
87  
3 office 88 private void GlobalHook_BlockMouse(object sender, MouseEventExtArgs e)
89 {
90 // Do not perform any operations while the binding form is visible.
91 if (BindKeyForm != null && BindKeyForm.Visible)
1 office 92 {
3 office 93 return;
1 office 94 }
3 office 95  
7 office 96 if (_lock && Settings.Default.Mouse)
3 office 97 {
98 e.Handled = true;
99 }
1 office 100 }
101  
102 private void GlobalHook_KeyUp(object sender, KeyEventArgs e)
103 {
3 office 104 // Do not perform any operations while the binding form is visible.
105 if (BindKeyForm != null && BindKeyForm.Visible)
1 office 106 {
107 return;
108 }
109  
110 if (!PressedKeysBufferBlock.TryReceiveAll(out var keys))
111 {
112 return;
113 }
114  
7 office 115 if (Settings.Default.Keys == null)
3 office 116 {
117 return;
118 }
119  
7 office 120 if (!Settings.Default.Keys.OfType<string>().SequenceEqual(keys.Select(key => key.KeyCode.ToString())))
1 office 121 {
7 office 122 return;
123 }
1 office 124  
7 office 125 _lock = !_lock;
1 office 126  
7 office 127 // Lock the cursor in position.
128 switch (_lock)
129 {
130 case true:
131 Cursor.Clip = new Rectangle(Cursor.Position, new Size(1, 1));
132 break;
133 default:
134 Cursor.Clip = Screen.PrimaryScreen.Bounds;
135 break;
136 }
1 office 137  
7 office 138 // Dismiss the current keypress to avoid typing the key.
139 e.Handled = true;
140 e.SuppressKeyPress = true;
141  
142 Notify($"Mouse and Keyboard are {(_lock ? "locked" : "unlocked")}.",
143 $"Press {string.Join(" ", Settings.Default.Keys.OfType<string>())} to toggle mouse and keyboard locking.");
1 office 144 }
145  
146 private async void GlobalHook_KeyDown(object sender, KeyEventArgs e)
147 {
3 office 148 // Do not perform any operations while the binding form is visible.
149 if (BindKeyForm != null && BindKeyForm.Visible)
150 {
151 return;
152 }
153  
7 office 154 if (_lock && Settings.Default.Keyboard)
1 office 155 {
156 e.SuppressKeyPress = true;
157 e.Handled = true;
158 }
159  
160 await PressedKeysBufferBlock.SendAsync(e);
161 }
162  
163 private void OnContextMenuAboutClick(object sender, EventArgs e)
164 {
165 // Show the about form.
166 AboutForm = new AboutForm();
167 AboutForm.Show();
168 }
169  
170 private void OnContextMenuQuitClick(object sender, EventArgs e)
171 {
8 office 172 Close();
173  
174 Environment.Exit(0);
1 office 175 }
176  
177 private void OnContextMenuLaunchOnBootChanged(object sender, EventArgs e)
178 {
7 office 179 Settings.Default.LaunchOnBoot = ((ToolStripMenuItem) sender).Checked;
1 office 180  
7 office 181 Utilities.LaunchOnBootSet(Settings.Default.LaunchOnBoot);
1 office 182 }
183  
184 private void OnContextMenuBindKeyClick(object sender, EventArgs e)
185 {
7 office 186 BindKeyForm = new BindKeyForm(GlobalHook);
1 office 187 BindKeyForm.KeyBound += BindKeyForm_KeyBound;
188 BindKeyForm.Closing += BindKeyForm_Closing;
189 BindKeyForm.Show();
190 }
191  
192 private void BindKeyForm_Closing(object sender, CancelEventArgs e)
193 {
194 BindKeyForm.KeyBound -= BindKeyForm_KeyBound;
195 BindKeyForm.Closing -= BindKeyForm_Closing;
196 }
197  
3 office 198 private async void BindKeyForm_KeyBound(object sender, KeyBoundEventArgs e)
1 office 199 {
3 office 200 Notify("Shortcut key is bound.",
7 office 201 $"Press {string.Join(" ", Settings.Default.Keys.OfType<string>())} to toggle between locked and unlocked keyboard and mouse.");
1 office 202 }
203  
204 private void KeyboardToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
205 {
206 var item = (ToolStripMenuItem) sender;
207  
7 office 208 Settings.Default.Keyboard = item.Checked;
1 office 209 }
210  
211 private void MouseToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
212 {
213 var item = (ToolStripMenuItem) sender;
214  
7 office 215 Settings.Default.Mouse = item.Checked;
1 office 216 }
217  
218 private void ContextMenuStrip_Opening(object sender, CancelEventArgs e)
219 {
220 // Apply the settings to the menu items.
7 office 221 launchOnBootToolStripMenuItem.Checked = Settings.Default.LaunchOnBoot;
222 Utilities.LaunchOnBootSet(Settings.Default.LaunchOnBoot);
1 office 223  
7 office 224 mouseToolStripMenuItem.Checked = Settings.Default.Mouse;
225 keyboardToolStripMenuItem.Checked = Settings.Default.Keyboard;
1 office 226 }
227  
228 #endregion
229  
230 #region Private Methods
231  
232 private void Notify(string title, string message, int timeout = 10000)
233 {
3 office 234 misuNotificationIcon.BalloonTipTitle = title;
235 misuNotificationIcon.BalloonTipText = message;
1 office 236 // the timeout parameter is not used for Windows Vista and up
3 office 237 misuNotificationIcon.ShowBalloonTip(timeout);
1 office 238 }
239  
240 #endregion
241 }
242 }