Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Windows.Forms;
- using System.ComponentModel;
- using System.Xml.Serialization;
- using System.Runtime.InteropServices;
- namespace MovablePython
- {
- public class Hotkey : IMessageFilter
- {
- #region Interop
- [DllImport("user32.dll", SetLastError = true)]
- private static extern int RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, Keys vk);
- [DllImport("user32.dll", SetLastError=true)]
- private static extern int UnregisterHotKey(IntPtr hWnd, int id);
- private const uint WM_HOTKEY = 0x312;
- private const uint MOD_ALT = 0x1;
- private const uint MOD_CONTROL = 0x2;
- private const uint MOD_SHIFT = 0x4;
- private const uint MOD_WIN = 0x8;
- private const uint ERROR_HOTKEY_ALREADY_REGISTERED = 1409;
- #endregion
- private static int currentID;
- private const int maximumID = 0xBFFF;
- private Keys keyCode;
- private bool shift;
- private bool control;
- private bool alt;
- private bool windows;
- [XmlIgnore]
- private int id;
- [XmlIgnore]
- private bool registered;
- [XmlIgnore]
- private Control windowControl;
- public event HandledEventHandler Pressed;
- public Hotkey() : this(Keys.None, false, false, false, false)
- {
- // No work done here!
- }
- public Hotkey(Keys keyCode, bool shift, bool control, bool alt, bool windows)
- {
- // Assign properties
- this.KeyCode = keyCode;
- this.Shift = shift;
- this.Control = control;
- this.Alt = alt;
- this.Windows = windows;
- // Register us as a message filter
- Application.AddMessageFilter(this);
- }
- ~Hotkey()
- {
- // Unregister the hotkey if necessary
- if (this.Registered)
- { this.Unregister(); }
- }
- public Hotkey Clone()
- {
- // Clone the whole object
- return new Hotkey(this.keyCode, this.shift, this.control, this.alt, this.windows);
- }
- public bool GetCanRegister(Control windowControl)
- {
- // Handle any exceptions: they mean "no, you can't register" :)
- try
- {
- // Attempt to register
- if (!this.Register(windowControl))
- { return false; }
- // Unregister and say we managed it
- this.Unregister();
- return true;
- }
- catch (Win32Exception)
- { return false; }
- catch (NotSupportedException)
- { return false; }
- }
- public bool Register(Control windowControl)
- {
- // Check that we have not registered
- if (this.registered)
- { throw new NotSupportedException("You cannot register a hotkey that is already registered"); }
- // We can't register an empty hotkey
- if (this.Empty)
- { throw new NotSupportedException("You cannot register an empty hotkey"); }
- // Get an ID for the hotkey and increase current ID
- this.id = Hotkey.currentID;
- Hotkey.currentID = Hotkey.currentID + 1 % Hotkey.maximumID;
- // Translate modifier keys into unmanaged version
- uint modifiers = (this.Alt ? Hotkey.MOD_ALT : 0) | (this.Control ? Hotkey.MOD_CONTROL : 0) |
- (this.Shift ? Hotkey.MOD_SHIFT : 0) | (this.Windows ? Hotkey.MOD_WIN : 0);
- // Register the hotkey
- if (Hotkey.RegisterHotKey(windowControl.Handle, this.id, modifiers, keyCode) == 0)
- {
- // Is the error that the hotkey is registered?
- if (Marshal.GetLastWin32Error() == ERROR_HOTKEY_ALREADY_REGISTERED)
- { return false; }
- else
- { throw new Win32Exception(); }
- }
- // Save the control reference and register state
- this.registered = true;
- this.windowControl = windowControl;
- // We successfully registered
- return true;
- }
- public void Unregister()
- {
- // Check that we have registered
- if (!this.registered)
- { throw new NotSupportedException("You cannot unregister a hotkey that is not registered"); }
- // It's possible that the control itself has died: in that case, no need to unregister!
- if (!this.windowControl.IsDisposed)
- {
- // Clean up after ourselves
- if (Hotkey.UnregisterHotKey(this.windowControl.Handle, this.id) == 0)
- { throw new Win32Exception(); }
- }
- // Clear the control reference and register state
- this.registered = false;
- this.windowControl = null;
- }
- private void Reregister()
- {
- // Only do something if the key is already registered
- if (!this.registered)
- { return; }
- // Save control reference
- Control windowControl = this.windowControl;
- // Unregister and then reregister again
- this.Unregister();
- this.Register(windowControl);
- }
- public bool PreFilterMessage(ref Message message)
- {
- // Only process WM_HOTKEY messages
- if (message.Msg != Hotkey.WM_HOTKEY)
- { return false; }
- // Check that the ID is our key and we are registerd
- if (this.registered && (message.WParam.ToInt32() == this.id))
- {
- // Fire the event and pass on the event if our handlers didn't handle it
- return this.OnPressed();
- }
- else
- { return false; }
- }
- private bool OnPressed()
- {
- // Fire the event if we can
- HandledEventArgs handledEventArgs = new HandledEventArgs(false);
- if (this.Pressed != null)
- { this.Pressed(this, handledEventArgs); }
- // Return whether we handled the event or not
- return handledEventArgs.Handled;
- }
- public override string ToString()
- {
- // We can be empty
- if (this.Empty)
- { return "(none)"; }
- // Build key name
- string keyName = Enum.GetName(typeof(Keys), this.keyCode);;
- switch (this.keyCode)
- {
- case Keys.D0:
- case Keys.D1:
- case Keys.D2:
- case Keys.D3:
- case Keys.D4:
- case Keys.D5:
- case Keys.D6:
- case Keys.D7:
- case Keys.D8:
- case Keys.D9:
- // Strip the first character
- keyName = keyName.Substring(1);
- break;
- default:
- // Leave everything alone
- break;
- }
- // Build modifiers
- string modifiers = "";
- if (this.shift)
- { modifiers += "Shift+"; }
- if (this.control)
- { modifiers += "Control+"; }
- if (this.alt)
- { modifiers += "Alt+"; }
- if (this.windows)
- { modifiers += "Windows+"; }
- // Return result
- return modifiers + keyName;
- }
- public bool Empty
- {
- get { return this.keyCode == Keys.None; }
- }
- public bool Registered
- {
- get { return this.registered; }
- }
- public Keys KeyCode
- {
- get { return this.keyCode; }
- set
- {
- // Save and reregister
- this.keyCode = value;
- this.Reregister();
- }
- }
- public bool Shift
- {
- get { return this.shift; }
- set
- {
- // Save and reregister
- this.shift = value;
- this.Reregister();
- }
- }
- public bool Control
- {
- get { return this.control; }
- set
- {
- // Save and reregister
- this.control = value;
- this.Reregister();
- }
- }
- public bool Alt
- {
- get { return this.alt; }
- set
- {
- // Save and reregister
- this.alt = value;
- this.Reregister();
- }
- }
- public bool Windows
- {
- get { return this.windows; }
- set
- {
- // Save and reregister
- this.windows = value;
- this.Reregister();
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement