Created
December 13, 2011 02:55
-
-
Save rzhw/1470282 to your computer and use it in GitHub Desktop.
Hotkey input box for WinForms
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// HotkeyInputBox 0.1 (c) 2011 Richard Z.H. Wang | |
// MIT licensed. | |
using System; | |
using System.Collections.Generic; | |
using System.ComponentModel; | |
using System.Linq; | |
using System.Text; | |
using System.Windows.Forms; | |
using System.Runtime.InteropServices; | |
namespace Uploadinator.Controls | |
{ | |
class HotkeyInputBox : TextBox | |
{ | |
public HotkeyInputBox() { } | |
#region Properties to hide from the designer | |
[Browsable(false)] | |
public new string[] Lines { get { return new string[] { Text }; } private set { base.Lines = value; } } | |
[Browsable(false)] | |
public override bool Multiline { get { return false; } } | |
[Browsable(false)] | |
public new char PasswordChar { get; set; } | |
[Browsable(false)] | |
public new ScrollBars ScrollBars { get; set; } | |
[Browsable(false)] | |
public override bool ShortcutsEnabled { get { return false; } } | |
[Browsable(false)] | |
public override string Text { get { return base.Text; } set { base.Text = value; } } | |
[Browsable(false)] | |
public new bool WordWrap { get; set; } | |
#endregion | |
#region Focus detection - use this to stop hotkeys being triggered in your code | |
private static Control FindFocusedControl(Control control) | |
{ | |
var container = control as ContainerControl; | |
while (container != null) | |
{ | |
control = container.ActiveControl; | |
container = control as ContainerControl; | |
} | |
return control; | |
} | |
public bool IsFocused { get { return FindFocusedControl(Form.ActiveForm) == this; } } | |
public static bool TypeIsFocused { get { return FindFocusedControl(Form.ActiveForm) is HotkeyInputBox; } } | |
#endregion | |
private Hotkey _hotkey = new Hotkey(); | |
public Keys KeyCode { get { return _hotkey.KeyCode; } set { _hotkey.KeyCode = value; } } | |
public bool Windows { get { return _hotkey.Windows; } set { _hotkey.Windows = value; } } | |
public bool Control { get { return _hotkey.Control; } set { _hotkey.Control = value; } } | |
public bool Alt { get { return _hotkey.Alt; } set { _hotkey.Alt = value; } } | |
public bool Shift { get { return _hotkey.Shift; } set { _hotkey.Shift = value; } } | |
public void SetHotkey(Hotkey hotkey) | |
{ | |
_hotkey = hotkey; | |
} | |
public void SetHotkey(string jsonSerializedHotkey) | |
{ | |
var s = new System.Web.Script.Serialization.JavaScriptSerializer(); | |
_hotkey = s.Deserialize<Hotkey>(jsonSerializedHotkey); | |
} | |
public Hotkey GetHotkey() | |
{ | |
return _hotkey.Clone(); | |
} | |
public string GetJsonHotkey() | |
{ | |
var s = new System.Web.Script.Serialization.JavaScriptSerializer(); | |
return s.Serialize(_hotkey); | |
} | |
public void Reset() | |
{ | |
KeyCode = Keys.None; | |
Windows = false; | |
Control = false; | |
Alt = false; | |
Shift = false; | |
} | |
private void RefreshText() | |
{ | |
Text = _hotkey.ToString(true); | |
Invalidate(); | |
} | |
protected override void OnPaint(PaintEventArgs e) | |
{ | |
RefreshText(); | |
base.OnPaint(e); | |
} | |
protected override void OnMouseMove(MouseEventArgs e) | |
{ | |
if (e.Button != System.Windows.Forms.MouseButtons.None) | |
SelectAll(); | |
base.OnMouseMove(e); | |
} | |
public event EventHandler HotkeyChanged; | |
protected virtual void OnHotkeyChanged(EventArgs e) | |
{ | |
if (HotkeyChanged != null) | |
HotkeyChanged(this, e); | |
} | |
const int WM_KEYDOWN = 0x100; | |
const int WM_KEYUP = 0x101; | |
const int WM_CHAR = 0x102; | |
const int WM_SYSCHAR = 0x106; | |
const int WM_SYSKEYDOWN = 0x104; | |
const int WM_SYSKEYUP = 0x105; | |
const int WM_IME_CHAR = 0x286; | |
private int _keysPressed = 0; | |
protected override bool ProcessKeyMessage(ref Message m) | |
{ | |
if (m.Msg == WM_KEYUP || m.Msg == WM_SYSKEYUP) | |
{ | |
_keysPressed--; | |
if (_keysPressed == 0) | |
OnHotkeyChanged(new EventArgs()); | |
} | |
if (m.Msg != WM_CHAR && m.Msg != WM_SYSCHAR && m.Msg != WM_IME_CHAR) | |
{ | |
KeyEventArgs e = new KeyEventArgs(((Keys)((int)((long)m.WParam))) | ModifierKeys); | |
if (e.KeyCode == Keys.Delete || e.KeyCode == Keys.Back) | |
this.Reset(); | |
else | |
{ | |
// Print Screen doesn't seem to be part of WM_KEYDOWN/WM_SYSKEYDOWN... | |
if (m.Msg == WM_KEYDOWN || m.Msg == WM_SYSKEYDOWN || e.KeyCode == Keys.PrintScreen) | |
{ | |
// Start over if we had no keys pressed, or have a selection (since it's always select all) | |
if (_keysPressed < 1 || SelectionLength > 0) | |
this.Reset(); | |
//if (e.KeyCode ) | |
// this.Windows = true; | |
this.Control = !(e.Shift && e.Alt && !e.Control); | |
this.Shift = e.Shift; | |
this.Alt = e.Alt || (this.Control && !e.Shift); // Ctrl + Alt as default | |
if (e.KeyCode != Keys.ShiftKey | |
&& e.KeyCode != Keys.ControlKey | |
&& e.KeyCode != Keys.Menu) | |
this.KeyCode = e.KeyCode; | |
_keysPressed++; | |
} | |
} | |
// Pretty readable output | |
RefreshText(); | |
// Select the end of our textbox | |
Select(TextLength, 0); | |
} | |
return true; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment