Find all our projects in development below.
All source code is GNU General Public License (GPL)
Browsing ctrlHotkey.cs (11.18 KB)
using System;
using System.Collections;
using System.Windows.Forms;
//
// Hotkey selection control, written by serenity@exscape.org, 2006-08-03
// Please mail me if you find a bug.
//
// '' <summary>
// '' A simple control that allows the user to select pretty much any valid hotkey combination
// '' </summary>
namespace NvCplAdjust
{
public partial class ctrlHotkey : TextBox
{
// These variables store the current hotkey and modifier(s)
private Keys _hotkey = Keys.None;
private Keys _modifiers = Keys.None;
// ArrayLists used to enforce the use of proper modifiers.
// Shift+A isn't a valid hotkey, for instance, as it would screw up when the user is typing.
private ArrayList needNonShiftModifier = null;
private ArrayList needNonAltGrModifier = null;
private ContextMenu dummy = new ContextMenu();
// '' <summary>
// '' Used to make sure that there is no right-click menu available
// '' </summary>
public override ContextMenu ContextMenu
{
get
{
return dummy;
}
set
{
base.ContextMenu = dummy;
}
}
public override bool Multiline
{
get
{
return base.Multiline;
}
set
{
// Ignore what the user wants; force Multiline to false
base.Multiline = false;
}
}
public ctrlHotkey()
{
this.ContextMenu = dummy;
// Disable right-clicking
this.Text = "None";
this.KeyPress += new KeyPressEventHandler(this.HotkeyControl_KeyPress);
this.KeyUp += new KeyEventHandler(this.HotkeyControl_KeyUp);
this.KeyDown += new KeyEventHandler(this.HotkeyControl_KeyDown);
// Fill the ArrayLists that contain all invalid hotkey combinations
needNonShiftModifier = new ArrayList();
needNonAltGrModifier = new ArrayList();
// PopulateModifierLists()
}
// '' <summary>
// '' Populates the ArrayLists specifying disallowed hotkeys
// '' such as Shift+A, Ctrl+Alt+4 (would produce a dollar sign) etc
// '' </summary>
private void PopulateModifierLists()
{
// Shift + 0 - 9, A - Z
for (Keys k = Keys.D0; (k <= Keys.Z); k++)
{
needNonShiftModifier.Add(((int)(k)));
}
// Shift + Numpad keys
for (Keys k = Keys.NumPad0; (k <= Keys.NumPad9); k++)
{
needNonShiftModifier.Add(((int)(k)));
}
// Shift + Misc (,;<./ etc)
for (Keys k = Keys.Oem1; (k <= Keys.OemBackslash); k++)
{
needNonShiftModifier.Add(((int)(k)));
}
// Shift + Space, PgUp, PgDn, End, Home
for (Keys k = Keys.Space; (k <= Keys.Home); k++)
{
needNonShiftModifier.Add(((int)(k)));
}
// Misc keys that we can't loop through
needNonShiftModifier.Add(((int)(Keys.Insert)));
needNonShiftModifier.Add(((int)(Keys.Help)));
needNonShiftModifier.Add(((int)(Keys.Multiply)));
needNonShiftModifier.Add(((int)(Keys.Add)));
needNonShiftModifier.Add(((int)(Keys.Subtract)));
needNonShiftModifier.Add(((int)(Keys.Divide)));
needNonShiftModifier.Add(((int)(Keys.Decimal)));
needNonShiftModifier.Add(((int)(Keys.Return)));
needNonShiftModifier.Add(((int)(Keys.Escape)));
needNonShiftModifier.Add(((int)(Keys.NumLock)));
needNonShiftModifier.Add(((int)(Keys.Scroll)));
needNonShiftModifier.Add(((int)(Keys.Pause)));
// Ctrl+Alt + 0 - 9
for (Keys k = Keys.D0; (k <= Keys.D9); k++)
{
needNonAltGrModifier.Add(((int)(k)));
}
}
// '' <summary>
// '' Resets this hotkey control to None
// '' </summary>
public new void Clear()
{
this.Hotkey = Keys.None;
this.HotkeyModifiers = Keys.None;
}
// '' <summary>
// '' Fires when a key is pushed down. Here, we'll want to update the text in the box
// '' to notify the user what combination is currently pressed.
// '' </summary>
private void HotkeyControl_KeyDown(object sender, KeyEventArgs e)
{
// Clear the current hotkey
if (((e.KeyCode == Keys.Back)
|| (e.KeyCode == Keys.Delete)))
{
this.ResetHotkey();
}
else
{
this._modifiers = e.Modifiers;
this._hotkey = e.KeyCode;
this.Redraw();
}
}
// '' <summary>
// '' Fires when all keys are released. If the current hotkey isn't valid, reset it.
// '' Otherwise, do nothing and keep the text and hotkey as it was.
// '' </summary>
private void HotkeyControl_KeyUp(object sender, KeyEventArgs e)
{
if ((((this._hotkey == Keys.None)
&& (Control.ModifierKeys == Keys.None))
|| ((this._hotkey == Keys.None)
&& (Control.ModifierKeys != Keys.None))))
{
this.ResetHotkey();
}
}
// '' <summary>
// '' Prevents the letter/whatever entered to show up in the TextBox
// '' Without this, a "A" key press would appear as "aControl, Alt + A"
// '' </summary>
private void HotkeyControl_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = true;
}
// '' <summary>
// '' Handles some misc keys, such as Ctrl+Delete and Shift+Insert
// '' </summary>
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (((keyData == Keys.Delete) || (keyData == (Keys.Control | Keys.Delete))))
{
this.ResetHotkey();
return true;
}
if ((keyData == (Keys.Shift | Keys.Insert)))
{
return true;
}
// Don't allow
// Allow the rest
return base.ProcessCmdKey(ref msg, keyData);
}
// '' <summary>
// '' Clears the current hotkey and resets the TextBox
// '' </summary>
public void ResetHotkey()
{
this._hotkey = Keys.None;
this._modifiers = Keys.None;
this.Redraw();
}
// '' <summary>
// '' Used to get/set the hotkey (e.g. Keys.A)
// '' </summary>
public Keys Hotkey
{
get
{
return this._hotkey;
}
set
{
this._hotkey = value;
this.Redraw(true);
}
}
public Keys HotkeyModifiers
{
get
{
return this._modifiers;
}
set
{
this._modifiers = value;
this.Redraw(true);
}
}
private void Redraw()
{
this.Redraw(false);
}
// '' <summary>
// '' Redraws the TextBox when necessary.
// '' </summary>
// '' <param name="bCalledProgramatically">Specifies whether this function was called by the Hotkey/HotkeyModifiers properties or by the user.</param>
private void Redraw(bool bCalledProgramatically)
{
// No hotkey set
if ((this._hotkey == Keys.None))
{
this.Text = "None";
return;
}
// LWin/RWin doesn't work as hotkeys (neither do they work as modifier keys in .NET 2.0)
if (((this._hotkey == Keys.LWin) || (this._hotkey == Keys.RWin)))
{
this.Text = "None";
return;
}
// Only validate input if it comes from the user
if ((bCalledProgramatically == false))
{
// No modifier or shift only, AND a hotkey that needs another modifier
if ((((this._modifiers == Keys.Shift) || (this._modifiers == Keys.None)) && this.needNonShiftModifier.Contains(((int)(this._hotkey)))))
{
if ((this._modifiers == Keys.None))
{
// Set Ctrl+Alt as the modifier unless Ctrl+Alt+<key> won't work...
if ((needNonAltGrModifier.Contains(((int)(this._hotkey))) == false))
{
this._modifiers = (Keys.Alt | Keys.Control);
}
else
{
this._modifiers = (Keys.Alt | Keys.Shift);
}
}
else
{
// User pressed Shift and an invalid key (e.g. a letter or a number),
// that needs another set of modifier keys
this._hotkey = Keys.None;
this.Text = (this._modifiers.ToString() + " + Invalid key");
return;
}
}
// Check all Ctrl+Alt keys
if (((this._modifiers == (Keys.Alt | Keys.Control)) && this.needNonAltGrModifier.Contains(((int)(this._hotkey)))))
{
// Ctrl+Alt+4 etc won't work; reset hotkey and tell the user
this._hotkey = Keys.None;
this.Text = (this._modifiers.ToString() + " + Invalid key");
return;
}
}
if ((this._modifiers == Keys.None))
{
if ((this._hotkey == Keys.None))
{
this.Text = "None";
return;
}
else
{
// We get here if we've got a hotkey that is valid without a modifier,
// like F1-F12, Media-keys etc.
this.Text = this._hotkey.ToString();
return;
}
}
// I have no idea why this is needed, but it is. Without this code, pressing only Ctrl
// will show up as "Control + ControlKey", etc.
if (((this._hotkey == Keys.Menu) || ((this._hotkey == Keys.ShiftKey) || (this._hotkey == Keys.ControlKey))))
{
this._hotkey = Keys.None;
}
this.Text = this._modifiers.ToString() + " + " + this._hotkey.ToString();
}
}
}