Skip to content

Instantly share code, notes, and snippets.

@rzhw
Created December 13, 2011 02:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rzhw/1470282 to your computer and use it in GitHub Desktop.
Save rzhw/1470282 to your computer and use it in GitHub Desktop.
Hotkey input box for WinForms
// 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