Advertisement
Guest User

Untitled

a guest
May 7th, 2015
356
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.23 KB | None | 0 0
  1. using System;
  2. using System.Windows.Forms;
  3. using System.ComponentModel;
  4. using System.Xml.Serialization;
  5. using System.Runtime.InteropServices;
  6.  
  7. namespace MovablePython
  8. {
  9.     public class Hotkey : IMessageFilter
  10.     {
  11.         #region Interop
  12.  
  13.         [DllImport("user32.dll", SetLastError = true)]
  14.         private static extern int RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, Keys vk);
  15.  
  16.         [DllImport("user32.dll", SetLastError=true)]
  17.         private static extern int UnregisterHotKey(IntPtr hWnd, int id);
  18.  
  19.         private const uint WM_HOTKEY = 0x312;
  20.  
  21.         private const uint MOD_ALT = 0x1;
  22.         private const uint MOD_CONTROL = 0x2;
  23.         private const uint MOD_SHIFT = 0x4;
  24.         private const uint MOD_WIN = 0x8;
  25.  
  26.         private const uint ERROR_HOTKEY_ALREADY_REGISTERED = 1409;
  27.  
  28.         #endregion
  29.  
  30.         private static int currentID;
  31.         private const int maximumID = 0xBFFF;
  32.        
  33.         private Keys keyCode;
  34.         private bool shift;
  35.         private bool control;
  36.         private bool alt;
  37.         private bool windows;
  38.  
  39.         [XmlIgnore]
  40.         private int id;
  41.         [XmlIgnore]
  42.         private bool registered;
  43.         [XmlIgnore]
  44.         private Control windowControl;
  45.  
  46.         public event HandledEventHandler Pressed;
  47.  
  48.         public Hotkey() : this(Keys.None, false, false, false, false)
  49.         {
  50.             // No work done here!
  51.         }
  52.        
  53.         public Hotkey(Keys keyCode, bool shift, bool control, bool alt, bool windows)
  54.         {
  55.             // Assign properties
  56.             this.KeyCode = keyCode;
  57.             this.Shift = shift;
  58.             this.Control = control;
  59.             this.Alt = alt;
  60.             this.Windows = windows;
  61.  
  62.             // Register us as a message filter
  63.             Application.AddMessageFilter(this);
  64.         }
  65.  
  66.         ~Hotkey()
  67.         {
  68.             // Unregister the hotkey if necessary
  69.             if (this.Registered)
  70.             { this.Unregister(); }
  71.         }
  72.  
  73.         public Hotkey Clone()
  74.         {
  75.             // Clone the whole object
  76.             return new Hotkey(this.keyCode, this.shift, this.control, this.alt, this.windows);
  77.         }
  78.  
  79.         public bool GetCanRegister(Control windowControl)
  80.         {
  81.             // Handle any exceptions: they mean "no, you can't register" :)
  82.             try
  83.             {
  84.                 // Attempt to register
  85.                 if (!this.Register(windowControl))
  86.                 { return false; }
  87.  
  88.                 // Unregister and say we managed it
  89.                 this.Unregister();
  90.                 return true;
  91.             }
  92.             catch (Win32Exception)
  93.             { return false; }
  94.             catch (NotSupportedException)
  95.             { return false; }
  96.         }
  97.  
  98.         public bool Register(Control windowControl)
  99.         {
  100.             // Check that we have not registered
  101.             if (this.registered)
  102.             { throw new NotSupportedException("You cannot register a hotkey that is already registered"); }
  103.        
  104.             // We can't register an empty hotkey
  105.             if (this.Empty)
  106.             { throw new NotSupportedException("You cannot register an empty hotkey"); }
  107.  
  108.             // Get an ID for the hotkey and increase current ID
  109.             this.id = Hotkey.currentID;
  110.             Hotkey.currentID = Hotkey.currentID + 1 % Hotkey.maximumID;
  111.  
  112.             // Translate modifier keys into unmanaged version
  113.             uint modifiers = (this.Alt ? Hotkey.MOD_ALT : 0) | (this.Control ? Hotkey.MOD_CONTROL : 0) |
  114.                             (this.Shift ? Hotkey.MOD_SHIFT : 0) | (this.Windows ? Hotkey.MOD_WIN : 0);
  115.  
  116.             // Register the hotkey
  117.             if (Hotkey.RegisterHotKey(windowControl.Handle, this.id, modifiers, keyCode) == 0)
  118.             {
  119.                 // Is the error that the hotkey is registered?
  120.                 if (Marshal.GetLastWin32Error() == ERROR_HOTKEY_ALREADY_REGISTERED)
  121.                 { return false; }
  122.                 else
  123.                 { throw new Win32Exception(); }
  124.             }
  125.  
  126.             // Save the control reference and register state
  127.             this.registered = true;
  128.             this.windowControl = windowControl;
  129.  
  130.             // We successfully registered
  131.             return true;
  132.         }
  133.  
  134.         public void Unregister()
  135.         {
  136.             // Check that we have registered
  137.             if (!this.registered)
  138.             { throw new NotSupportedException("You cannot unregister a hotkey that is not registered"); }
  139.        
  140.             // It's possible that the control itself has died: in that case, no need to unregister!
  141.             if (!this.windowControl.IsDisposed)
  142.             {
  143.                 // Clean up after ourselves
  144.                 if (Hotkey.UnregisterHotKey(this.windowControl.Handle, this.id) == 0)
  145.                 { throw new Win32Exception(); }
  146.             }
  147.  
  148.             // Clear the control reference and register state
  149.             this.registered = false;
  150.             this.windowControl = null;
  151.         }
  152.  
  153.         private void Reregister()
  154.         {
  155.             // Only do something if the key is already registered
  156.             if (!this.registered)
  157.             { return; }
  158.  
  159.             // Save control reference
  160.             Control windowControl = this.windowControl;
  161.  
  162.             // Unregister and then reregister again
  163.             this.Unregister();
  164.             this.Register(windowControl);
  165.         }
  166.  
  167.         public bool PreFilterMessage(ref Message message)
  168.         {
  169.             // Only process WM_HOTKEY messages
  170.             if (message.Msg != Hotkey.WM_HOTKEY)
  171.             { return false; }
  172.  
  173.             // Check that the ID is our key and we are registerd
  174.             if (this.registered && (message.WParam.ToInt32() == this.id))
  175.             {
  176.                 // Fire the event and pass on the event if our handlers didn't handle it
  177.                 return this.OnPressed();
  178.             }
  179.             else
  180.             { return false; }
  181.         }
  182.  
  183.         private bool OnPressed()
  184.         {
  185.             // Fire the event if we can
  186.             HandledEventArgs handledEventArgs = new HandledEventArgs(false);
  187.             if (this.Pressed != null)
  188.             { this.Pressed(this, handledEventArgs); }
  189.  
  190.             // Return whether we handled the event or not
  191.             return handledEventArgs.Handled;
  192.         }
  193.  
  194.         public override string ToString()
  195.         {
  196.             // We can be empty
  197.             if (this.Empty)
  198.             { return "(none)"; }
  199.  
  200.             // Build key name
  201.             string keyName = Enum.GetName(typeof(Keys), this.keyCode);;
  202.             switch (this.keyCode)
  203.             {
  204.                 case Keys.D0:
  205.                 case Keys.D1:
  206.                 case Keys.D2:
  207.                 case Keys.D3:
  208.                 case Keys.D4:
  209.                 case Keys.D5:
  210.                 case Keys.D6:
  211.                 case Keys.D7:
  212.                 case Keys.D8:
  213.                 case Keys.D9:
  214.                     // Strip the first character
  215.                     keyName = keyName.Substring(1);
  216.                     break;
  217.                 default:
  218.                     // Leave everything alone
  219.                     break;
  220.             }
  221.  
  222.             // Build modifiers
  223.             string modifiers = "";
  224.             if (this.shift)
  225.             { modifiers += "Shift+"; }
  226.             if (this.control)
  227.             { modifiers += "Control+"; }
  228.             if (this.alt)
  229.             { modifiers += "Alt+"; }
  230.             if (this.windows)
  231.             { modifiers += "Windows+"; }
  232.  
  233.             // Return result
  234.             return modifiers + keyName;
  235.         }
  236.  
  237.         public bool Empty
  238.         {
  239.             get { return this.keyCode == Keys.None; }
  240.         }
  241.  
  242.         public bool Registered
  243.         {
  244.             get { return this.registered; }
  245.         }
  246.  
  247.         public Keys KeyCode
  248.         {
  249.             get { return this.keyCode; }
  250.             set
  251.             {
  252.                 // Save and reregister
  253.                 this.keyCode = value;
  254.                 this.Reregister();
  255.             }
  256.         }
  257.  
  258.         public bool Shift
  259.         {
  260.             get { return this.shift; }
  261.             set
  262.             {
  263.                 // Save and reregister
  264.                 this.shift = value;
  265.                 this.Reregister();
  266.             }
  267.         }
  268.  
  269.         public bool Control
  270.         {
  271.             get { return this.control; }
  272.             set
  273.             {
  274.                 // Save and reregister
  275.                 this.control = value;
  276.                 this.Reregister();
  277.             }
  278.         }
  279.  
  280.         public bool Alt
  281.         {
  282.             get { return this.alt; }
  283.             set
  284.             {
  285.                 // Save and reregister
  286.                 this.alt = value;
  287.                 this.Reregister();
  288.             }
  289.         }
  290.  
  291.         public bool Windows
  292.         {
  293.             get { return this.windows; }
  294.             set
  295.             {
  296.                 // Save and reregister
  297.                 this.windows = value;
  298.                 this.Reregister();
  299.             }
  300.         }
  301.     }
  302. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement