You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#region Copyright
/* * Developer : Willy Kimura (WK). * Library : HotkeySelector. * License : MIT. * */
#endregion
usingSystem;usingSystem.Collections;usingSystem.Diagnostics;usingSystem.ComponentModel;usingSystem.Collections.Generic;usingSystem.Windows.Forms;usingSystem.Windows.Controls;namespaceWK.Libraries.HotkeyListenerNS{/// <summary>/// Provides support for enabling standard Windows controls /// and User controls to select hotkeys at runtime. /// Combined with the <see cref="HotkeyListener"/> class, /// you can easily enable the selection and registering of /// hotkeys for a seamless end-user experience./// </summary>//[DebuggerStepThrough][Description("Provides support for enabling standard Windows controls "+"and User controls to select hotkeys at runtime.")]publicpartialclassHotkeySelectorWPF:Component{
#region Constructor
/// <summary>/// Initializes a new instance of the <see cref="HotkeySelector"/> class./// </summary>publicHotkeySelectorWPF(){}/// <summary>/// Initializes a new instance of the <see cref="HotkeySelector"/> class./// </summary>publicHotkeySelectorWPF(IContainercontainer){container.Add(this);InitializeComponent();}
#endregion
#region Fields
// These variables store the selected hotkey and modifier key(s).privateKeys_hotkey=Keys.None;privateKeys_modifiers=Keys.None;// ArrayLists used to enforce the use of proper modifiers.// Shift+A isn't a valid hotkey, for instance.privateArrayList_needNonShiftModifier=null;privateArrayList_needNonAltGrModifier=null;// Stores the list of enabled hotkey selection controls.privateList<System.Windows.Controls.Control>_controls=newList<System.Windows.Controls.Control>();
#endregion
#region Properties
#region Public
/// <summary>/// Gets or sets the text to be displayed in a /// control when no hotkey has been set. /// (Preferred default text is "None")/// </summary>publicstringEmptyHotkeyText{get;set;}="None";/// <summary>/// Gets or sets the text to be displayed in a control /// when an invalid or unsupported hotkey is pressed./// (Preferred default text is "(Unsupported)")/// </summary>publicstringInvalidHotkeyText{get;set;}="Unsupported";
#endregion
#endregion
#region Methods
#region Public
/// <summary>/// Enables a control for hotkey selection and previewing./// This will make use of the control's Text property to /// preview the current hotkey selected./// </summary>/// <param name="control">The control to enable.</param>publicboolEnable(System.Windows.Controls.TextBoxcontrol){try{control.Text=EmptyHotkeyText;control.KeyDown+=newSystem.Windows.Input.KeyEventHandler(OnKeyDown);control.KeyUp+=newSystem.Windows.Input.KeyEventHandler(OnKeyUp);ResetModifiers();try{_controls.Add(control);}catch(Exception){}returntrue;}catch(Exception){returnfalse;}}/// <summary>/// Enables a control for hotkey selection and previewing./// This will make use of the control's Text property to /// preview the current hotkey selected./// </summary>/// <param name="control">The control to enable.</param>/// <param name="hotkey">Assign the default hotkey to be previewed in the control.</param>publicboolEnable(System.Windows.Controls.TextBoxcontrol,Hotkeyhotkey){try{Enable(control);_hotkey=hotkey.KeyCode;_modifiers=hotkey.Modifiers;Refresh(control);returntrue;}catch(Exception){returnfalse;}}/// <summary>/// Disables a control for hotkey selection and previewing./// </summary>/// <param name="control">The control to disable.</param>/// <param name="clearKeys">Clear the control's previewed keys?</param>publicboolDisable(System.Windows.Controls.TextBoxcontrol,boolclearKeys=true){try{control.KeyDown-=OnKeyDown;control.KeyUp-=OnKeyUp;if(clearKeys)control.Text=string.Empty;try{if(_controls.Contains(control))_controls.Remove(control);}catch(Exception){}returntrue;}catch(Exception){returnfalse;}}/// <summary>/// Gets a value indicating whether a specific /// control is enabled for hotkey selection./// </summary>/// <param name="control">The control to determine.</param>publicboolIsEnabled(System.Windows.Controls.TextBoxcontrol){if(_controls.Contains(control))returntrue;elsereturnfalse;}/// <summary>/// Sets a hotkey selection to be previewed in a control. /// Thsi does not automatically enable the control for /// hotkey selection. For this, please use the <see cref="Enable(Control)"/> method./// </summary>/// <param name="control">The control to set.</param>/// <param name="hotkey">Provide a standard key or key combination string.</param>publicboolSet(System.Windows.Controls.TextBoxcontrol,Hotkeyhotkey){try{Refresh(control);control.Text=Convert(hotkey);returntrue;}catch(Exception){returnfalse;}}/// <summary>/// Sets a hotkey selection to be previewed in a control. /// Thsi does not automatically enable the control for /// hotkey selection. For this, please use the <see cref="Enable(Control)"/> method./// </summary>/// <param name="control">The control to set.</param>/// <param name="key">Provide a standard key selection.</param>/// <param name="modifiers">Provide a modifier key selection.</param>publicboolSet(System.Windows.Controls.TextBoxcontrol,Keyskey,Keysmodifiers){try{_hotkey=key;_modifiers=modifiers;Refresh(control);returntrue;}catch(Exception){returnfalse;}}/// <summary>/// Clears the currently previewed hotkey /// selection displayed in a control./// </summary>publicvoidClear(System.Windows.Controls.TextBoxcontrol){this._hotkey=Keys.None;this._modifiers=Keys.None;Refresh(control);}/// <summary>/// (Variant of the <see cref="Clear(System.Windows.Controls.TextBox)"/> method) /// Clears the currently previewed hotkey /// selection displayed in a control./// </summary>publicvoidReset(System.Windows.Controls.TextBoxcontrol){this._hotkey=Keys.None;this._modifiers=Keys.None;Refresh(control);}/// <summary>/// [Helper] Converts keys or key combinations to their string types./// </summary>/// <param name="hotkey">The hotkey to convert.</param>publicstringConvert(Hotkeyhotkey){try{_hotkey=hotkey.KeyCode;_modifiers=hotkey.Modifiers;stringparsedHotkey=string.Empty;// No modifier or shift only, and a hotkey that needs another modifier.if((_modifiers==Keys.Shift||_modifiers==Keys.None)){if(_needNonShiftModifier!=null&&_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{// ...In that case, use Shift+Alt instead.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;}}}// Without this code, pressing only Ctrl // will show up as "Control + ControlKey", etc.if(this._hotkey==Keys.Menu||/* Alt */this._hotkey==Keys.ShiftKey||this._hotkey==Keys.ControlKey){this._hotkey=Keys.None;}if(this._modifiers==Keys.None){// LWin/RWin don't work as hotkeys...// (neither do they work as modifier keys in .NET 2.0).if(_hotkey==Keys.None||_hotkey==Keys.LWin||_hotkey==Keys.RWin){parsedHotkey=string.Empty;}else{parsedHotkey=this._hotkey.ToString();}}else{parsedHotkey=this._modifiers.ToString()+" + "+this._hotkey.ToString();}returnparsedHotkey;}catch(Exception){returnstring.Empty;}}
#endregion
#region Private
/// <summary>/// Resets the hotkey modifiers to their defaults./// </summary>privatevoidResetModifiers(){// Fill the ArrayLists that contain // all invalid hotkey combinations._needNonShiftModifier=newArrayList();_needNonAltGrModifier=newArrayList();PopulateModifierLists();}/// <summary>/// Populates the ArrayLists specifying disallowed Hotkeys /// such as Shift+A, Ctrl+Alt+4 (produces 'dollar' sign)./// </summary>privatevoidPopulateModifierLists(){// Shift + 0 - 9, A - Z.for(Keysk=Keys.D0;k<=Keys.Z;k++)_needNonShiftModifier.Add((int)k);// Shift + Numpad keys.for(Keysk=Keys.NumPad0;k<=Keys.NumPad9;k++)_needNonShiftModifier.Add((int)k);// Shift + Misc (,;<./ etc).for(Keysk=Keys.Oem1;k<=Keys.OemBackslash;k++)_needNonShiftModifier.Add((int)k);// Shift + Space, PgUp, PgDn, End, Home.for(Keysk=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(Keysk=Keys.D0;k<=Keys.D9;k++)_needNonAltGrModifier.Add((int)k);}/// <summary>/// Refreshes the previewed hotkey combination displayed in a control./// </summary>/// <param name="control">/// The control providing hotkey selection./// </param>privatevoidRefresh(System.Windows.Controls.TextBoxcontrol){Refresh(control,false);}/// <summary>/// Refreshes the previewed hotkey combination displayed in a control./// </summary>/// <param name="control">/// The control providing hotkey selection./// </param>/// <param name="internalCall">/// Specifies whether this function is /// called internally or by the user./// </param>privatevoidRefresh(System.Windows.Controls.TextBoxcontrol,boolinternalCall){try{stringparsedHotkey=string.Empty;// No hotkey set.if(this._hotkey==Keys.None&&this._modifiers==Keys.None){control.Text=EmptyHotkeyText;return;}// LWin/RWin don't work as hotkeys...// (neither do they work as modifier keys in .NET 2.0).if(this._hotkey==Keys.LWin||this._hotkey==Keys.RWin){control.Text=InvalidHotkeyText;return;}if(this._modifiers==Keys.None){if(this._hotkey==Keys.None){control.Text=EmptyHotkeyText;return;}else{// We get here if we've got a hotkey that is valid without a modifier,// like F1-F12, Media-keys etc.control.Text=this._hotkey.ToString();return;}}else{// Only validate input if it comes from the user.if(internalCall==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{// ...In that case, use Shift+Alt instead.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;control.Text=this._modifiers.ToString()+$" + {InvalidHotkeyText}";return;}}}}// Without this code, pressing only Ctrl // will show up as "Control + ControlKey", etc.if(this._hotkey==Keys.Menu||/* Alt */this._hotkey==Keys.ShiftKey||this._hotkey==Keys.Alt||this._hotkey==Keys.ControlKey||this._hotkey==Keys.LControlKey||this._hotkey==Keys.RControlKey||this._hotkey==Keys.LShiftKey||this._hotkey==Keys.RShiftKey){this._hotkey=Keys.None;}// A final compilation of the processed keys in string format.if(this._modifiers==Keys.None)parsedHotkey=this._hotkey.ToString();elseparsedHotkey=this._modifiers.ToString()+" + "+this._hotkey.ToString();control.Text=parsedHotkey;return;}catch(Exception){}}
#endregion
#endregion
#region Events
#region Private
/// <summary>/// Fires when a key is pressed down. Here, we'll want to update the Text /// property to notify the user what key combination is currently pressed./// </summary>privatevoidOnKeyDown(objectsender,System.Windows.Input.KeyEventArgse){if(e.Key==System.Windows.Input.Key.Delete||e.Key==(System.Windows.Input.Key.LeftCtrl|System.Windows.Input.Key.RightCtrl|System.Windows.Input.Key.Delete))Reset((System.Windows.Controls.TextBox)sender);if(e.Key==(System.Windows.Input.Key.LeftShift|System.Windows.Input.Key.RightShift|System.Windows.Input.Key.Insert)){this._modifiers=Keys.Shift;e.Handled=true;}// Clear the current hotkey.if(e.Key==System.Windows.Input.Key.Back||e.Key==System.Windows.Input.Key.Delete){Reset((System.Windows.Controls.TextBox)sender);return;}else{this._modifiers=ToWinforms(e.KeyboardDevice.Modifiers);this._hotkey=(Keys)System.Windows.Input.KeyInterop.VirtualKeyFromKey(e.Key);Refresh((System.Windows.Controls.TextBox)sender);}}/// <summary>/// Source: https://stackoverflow.com/questions/1153009/how-can-i-convert-system-windows-input-key-to-system-windows-forms-keys/// </summary>/// <param name="modifier"></param>/// <returns></returns>privateSystem.Windows.Forms.KeysToWinforms(System.Windows.Input.ModifierKeysmodifier){varretVal=System.Windows.Forms.Keys.None;if(modifier.HasFlag(System.Windows.Input.ModifierKeys.Alt)){retVal|=System.Windows.Forms.Keys.Alt;}if(modifier.HasFlag(System.Windows.Input.ModifierKeys.Control)){retVal|=System.Windows.Forms.Keys.Control;}if(modifier.HasFlag(System.Windows.Input.ModifierKeys.None)){// Pointless I knowretVal|=System.Windows.Forms.Keys.None;}if(modifier.HasFlag(System.Windows.Input.ModifierKeys.Shift)){retVal|=System.Windows.Forms.Keys.Shift;}if(modifier.HasFlag(System.Windows.Input.ModifierKeys.Windows)){// Not supported lel}returnretVal;}/// <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>privatevoidOnKeyUp(objectsender,System.Windows.Input.KeyEventArgse){if(this._hotkey==Keys.None&&e.KeyboardDevice.Modifiers==System.Windows.Input.ModifierKeys.None){Reset((System.Windows.Controls.TextBox)sender);return;}}
#endregion
#endregion
}}
The text was updated successfully, but these errors were encountered:
Hello, this project is awesome.
Do you have any plans to add WPF support for the HotkeySelector?
I have tried to make my own which does work.
It uses
System.Windows.Controls.TextBox
Add references to these (WPF) assemblies:
HotkeySelectorWPF.cs
The text was updated successfully, but these errors were encountered: