misu – Blame information for rev 8
?pathlinks?
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 | } |