mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2024-12-30 07:40:13 +01:00
446 lines
21 KiB
C#
446 lines
21 KiB
C#
|
/* Copyright (c) Citrix Systems Inc.
|
|||
|
* All rights reserved.
|
|||
|
*
|
|||
|
* Redistribution and use in source and binary forms,
|
|||
|
* with or without modification, are permitted provided
|
|||
|
* that the following conditions are met:
|
|||
|
*
|
|||
|
* * Redistributions of source code must retain the above
|
|||
|
* copyright notice, this list of conditions and the
|
|||
|
* following disclaimer.
|
|||
|
* * Redistributions in binary form must reproduce the above
|
|||
|
* copyright notice, this list of conditions and the
|
|||
|
* following disclaimer in the documentation and/or other
|
|||
|
* materials provided with the distribution.
|
|||
|
*
|
|||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|||
|
* SUCH DAMAGE.
|
|||
|
*/
|
|||
|
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Windows.Forms;
|
|||
|
using XenAdmin.Core;
|
|||
|
|
|||
|
namespace XenAdmin.ConsoleView
|
|||
|
{
|
|||
|
public enum ConsoleShortcutKey
|
|||
|
{
|
|||
|
CTRL_ALT,
|
|||
|
CTRL_ALT_F,
|
|||
|
F12,
|
|||
|
CTRL_ENTER,
|
|||
|
ALT_SHIFT_U,
|
|||
|
F11,
|
|||
|
RIGHT_CTRL,
|
|||
|
LEFT_ALT,
|
|||
|
CTRL_ALT_INS
|
|||
|
}
|
|||
|
|
|||
|
public class ConsoleKeyHandler
|
|||
|
{
|
|||
|
public const int CTRL_SCAN = 29;
|
|||
|
public const int ALT_SCAN = 56;
|
|||
|
|
|||
|
public const int CTRL2_SCAN = 157;
|
|||
|
public const int ALT2_SCAN = 184;
|
|||
|
public const int GR_SCAN = 541;
|
|||
|
|
|||
|
public const int DEL_SCAN = 211;
|
|||
|
public const int INS_SCAN = 210;
|
|||
|
public const int L_SHIFT_SCAN = 0x2A;
|
|||
|
public const int R_SHIFT_SCAN = 0x36;
|
|||
|
|
|||
|
public const int F11_SCAN = 87;
|
|||
|
public const int F12_SCAN = 88;
|
|||
|
public const int F_SCAN = 33;
|
|||
|
|
|||
|
public const int U_SCAN = 22;
|
|||
|
public const int ENTER_SCAN = 28;
|
|||
|
|
|||
|
internal List<int> ModifierScans = new List<int>()
|
|||
|
{
|
|||
|
CTRL_SCAN,
|
|||
|
CTRL2_SCAN,
|
|||
|
L_SHIFT_SCAN,
|
|||
|
R_SHIFT_SCAN,
|
|||
|
ALT_SCAN,
|
|||
|
ALT2_SCAN,
|
|||
|
GR_SCAN
|
|||
|
};
|
|||
|
|
|||
|
internal List<Keys> ModifierKeys = new List<Keys>()
|
|||
|
{
|
|||
|
Keys.ControlKey,
|
|||
|
Keys.RControlKey,
|
|||
|
Keys.LControlKey,
|
|||
|
Keys.ShiftKey,
|
|||
|
Keys.RShiftKey,
|
|||
|
Keys.LShiftKey,
|
|||
|
Keys.Menu,
|
|||
|
Keys.RMenu,
|
|||
|
Keys.LMenu
|
|||
|
};
|
|||
|
|
|||
|
internal Dictionary<Set<int>, MethodInvoker> ExtraScans = new Dictionary<Set<int>, MethodInvoker>();
|
|||
|
internal Dictionary<Set<Keys>, MethodInvoker> ExtraKeys = new Dictionary<Set<Keys>, MethodInvoker>();
|
|||
|
|
|||
|
internal void AddKeyHandler(ConsoleShortcutKey shortcutKey, MethodInvoker methodInvoker)
|
|||
|
{
|
|||
|
Program.AssertOnEventThread();
|
|||
|
|
|||
|
switch (shortcutKey)
|
|||
|
{
|
|||
|
case ConsoleShortcutKey.CTRL_ALT:
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.ControlKey, Keys.Menu), methodInvoker);
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.LControlKey, Keys.LMenu), methodInvoker);
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.LControlKey, Keys.RMenu), methodInvoker);
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.RControlKey, Keys.LMenu), methodInvoker);
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.RControlKey, Keys.RMenu), methodInvoker);
|
|||
|
|
|||
|
AddKeyHandler(new Set<int>(CTRL_SCAN, ALT_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(CTRL2_SCAN, ALT2_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(CTRL2_SCAN, ALT2_SCAN, GR_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(CTRL2_SCAN, ALT_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(CTRL_SCAN, ALT2_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(CTRL_SCAN, ALT2_SCAN, GR_SCAN), methodInvoker);
|
|||
|
break;
|
|||
|
case ConsoleShortcutKey.CTRL_ALT_F:
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.ControlKey, Keys.Menu, Keys.F), methodInvoker);
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.LControlKey, Keys.LMenu, Keys.F), methodInvoker);
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.LControlKey, Keys.RMenu, Keys.F), methodInvoker);
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.RControlKey, Keys.LMenu, Keys.F), methodInvoker);
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.RControlKey, Keys.RMenu, Keys.F), methodInvoker);
|
|||
|
|
|||
|
AddKeyHandler(new Set<int>(CTRL_SCAN, ALT_SCAN, F_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(CTRL2_SCAN, ALT2_SCAN, F_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(CTRL2_SCAN, ALT2_SCAN, GR_SCAN, F_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(CTRL2_SCAN, ALT_SCAN, F_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(CTRL_SCAN, ALT2_SCAN, F_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(CTRL_SCAN, ALT2_SCAN, GR_SCAN, F_SCAN), methodInvoker);
|
|||
|
break;
|
|||
|
case ConsoleShortcutKey.F12:
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.F12), methodInvoker);
|
|||
|
|
|||
|
AddKeyHandler(new Set<int>(F12_SCAN), methodInvoker);
|
|||
|
break;
|
|||
|
case ConsoleShortcutKey.CTRL_ENTER:
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.ControlKey, Keys.Enter), methodInvoker);
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.LControlKey, Keys.Enter), methodInvoker);
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.RControlKey, Keys.Enter), methodInvoker);
|
|||
|
|
|||
|
AddKeyHandler(new Set<int>(CTRL_SCAN, ENTER_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(CTRL2_SCAN, ENTER_SCAN), methodInvoker);
|
|||
|
break;
|
|||
|
case ConsoleShortcutKey.ALT_SHIFT_U:
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.Menu, Keys.ShiftKey, Keys.U), methodInvoker);
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.LMenu, Keys.LShiftKey, Keys.U), methodInvoker);
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.LMenu, Keys.RShiftKey, Keys.U), methodInvoker);
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.RMenu, Keys.LShiftKey, Keys.U), methodInvoker);
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.RMenu, Keys.RShiftKey, Keys.U), methodInvoker);
|
|||
|
|
|||
|
AddKeyHandler(new Set<int>(ALT_SCAN, L_SHIFT_SCAN, U_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(ALT2_SCAN, L_SHIFT_SCAN, U_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(ALT_SCAN, R_SHIFT_SCAN, U_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(ALT2_SCAN, R_SHIFT_SCAN, U_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(ALT2_SCAN, R_SHIFT_SCAN, GR_SCAN, U_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(ALT2_SCAN, L_SHIFT_SCAN, GR_SCAN, U_SCAN), methodInvoker);
|
|||
|
break;
|
|||
|
case ConsoleShortcutKey.F11:
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.F11), methodInvoker);
|
|||
|
|
|||
|
AddKeyHandler(new Set<int>(F11_SCAN), methodInvoker);
|
|||
|
break;
|
|||
|
case ConsoleShortcutKey.RIGHT_CTRL:
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.RControlKey), methodInvoker);
|
|||
|
|
|||
|
AddKeyHandler(new Set<int>(CTRL2_SCAN), methodInvoker);
|
|||
|
break;
|
|||
|
case ConsoleShortcutKey.LEFT_ALT:
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.LMenu), methodInvoker);
|
|||
|
|
|||
|
AddKeyHandler(new Set<int>(ALT_SCAN), methodInvoker);
|
|||
|
break;
|
|||
|
case ConsoleShortcutKey.CTRL_ALT_INS:
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.ControlKey, Keys.Menu, Keys.Insert), methodInvoker);
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.LControlKey, Keys.LMenu, Keys.Insert), methodInvoker);
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.LControlKey, Keys.RMenu, Keys.Insert), methodInvoker);
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.RControlKey, Keys.LMenu, Keys.Insert), methodInvoker);
|
|||
|
AddKeyHandler(new Set<Keys>(Keys.RControlKey, Keys.RMenu, Keys.Insert), methodInvoker);
|
|||
|
|
|||
|
AddKeyHandler(new Set<int>(CTRL_SCAN, ALT_SCAN, INS_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(CTRL2_SCAN, ALT2_SCAN, INS_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(CTRL2_SCAN, ALT2_SCAN, GR_SCAN, INS_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(CTRL_SCAN, ALT2_SCAN, INS_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(CTRL2_SCAN, ALT_SCAN, INS_SCAN), methodInvoker);
|
|||
|
AddKeyHandler(new Set<int>(CTRL_SCAN, ALT2_SCAN, GR_SCAN, INS_SCAN), methodInvoker);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
internal void AddKeyHandler(Set<Keys> keySet, MethodInvoker methodInvoker)
|
|||
|
{
|
|||
|
Program.AssertOnEventThread();
|
|||
|
|
|||
|
if (ExtraKeys.ContainsKey(keySet))
|
|||
|
ExtraKeys.Remove(keySet);
|
|||
|
|
|||
|
ExtraKeys.Add(keySet, methodInvoker);
|
|||
|
}
|
|||
|
|
|||
|
internal void AddKeyHandler(Set<int> keySet, MethodInvoker methodInvoker)
|
|||
|
{
|
|||
|
Program.AssertOnEventThread();
|
|||
|
|
|||
|
if (ExtraScans.ContainsKey(keySet))
|
|||
|
ExtraScans.Remove(keySet);
|
|||
|
|
|||
|
ExtraScans.Add(keySet, methodInvoker);
|
|||
|
}
|
|||
|
|
|||
|
internal void RemoveKeyHandler(ConsoleShortcutKey shortcutKey)
|
|||
|
{
|
|||
|
Program.AssertOnEventThread();
|
|||
|
|
|||
|
switch (shortcutKey)
|
|||
|
{
|
|||
|
case ConsoleShortcutKey.CTRL_ALT:
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.ControlKey, Keys.Menu));
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.LControlKey, Keys.LMenu));
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.LControlKey, Keys.RMenu));
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.RControlKey, Keys.LMenu));
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.RControlKey, Keys.RMenu));
|
|||
|
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL_SCAN, ALT_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL2_SCAN, ALT2_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL2_SCAN, ALT2_SCAN, GR_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL2_SCAN, ALT_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL_SCAN, ALT2_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL_SCAN, ALT2_SCAN, GR_SCAN));
|
|||
|
break;
|
|||
|
case ConsoleShortcutKey.CTRL_ALT_F:
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.ControlKey, Keys.Menu, Keys.F));
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.LControlKey, Keys.LMenu, Keys.F));
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.LControlKey, Keys.RMenu, Keys.F));
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.RControlKey, Keys.LMenu, Keys.F));
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.RControlKey, Keys.RMenu, Keys.F));
|
|||
|
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL_SCAN, ALT_SCAN, F_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL2_SCAN, ALT2_SCAN, F_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL2_SCAN, ALT2_SCAN, GR_SCAN, F_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL2_SCAN, ALT_SCAN, F_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL_SCAN, ALT2_SCAN, F_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL_SCAN, ALT2_SCAN, GR_SCAN, F_SCAN));
|
|||
|
break;
|
|||
|
case ConsoleShortcutKey.F12:
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.F12));
|
|||
|
|
|||
|
RemoveKeyHandler(new Set<int>(F12_SCAN));
|
|||
|
break;
|
|||
|
case ConsoleShortcutKey.CTRL_ENTER:
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.ControlKey, Keys.Enter));
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.LControlKey, Keys.Enter));
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.RControlKey, Keys.Enter));
|
|||
|
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL_SCAN, ENTER_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL2_SCAN, ENTER_SCAN));
|
|||
|
break;
|
|||
|
case ConsoleShortcutKey.ALT_SHIFT_U:
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.Menu, Keys.ShiftKey, Keys.U));
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.LMenu, Keys.LShiftKey, Keys.U));
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.LMenu, Keys.RShiftKey, Keys.U));
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.RMenu, Keys.LShiftKey, Keys.U));
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.RMenu, Keys.RShiftKey, Keys.U));
|
|||
|
|
|||
|
RemoveKeyHandler(new Set<int>(ALT_SCAN, L_SHIFT_SCAN, U_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(ALT2_SCAN, L_SHIFT_SCAN, U_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(ALT_SCAN, R_SHIFT_SCAN, U_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(ALT2_SCAN, R_SHIFT_SCAN, U_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(ALT2_SCAN, R_SHIFT_SCAN, GR_SCAN, U_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(ALT2_SCAN, L_SHIFT_SCAN, GR_SCAN, U_SCAN));
|
|||
|
break;
|
|||
|
case ConsoleShortcutKey.F11:
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.F11));
|
|||
|
|
|||
|
RemoveKeyHandler(new Set<int>(F11_SCAN));
|
|||
|
break;
|
|||
|
case ConsoleShortcutKey.RIGHT_CTRL:
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.RControlKey));
|
|||
|
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL2_SCAN));
|
|||
|
break;
|
|||
|
case ConsoleShortcutKey.LEFT_ALT:
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.LMenu));
|
|||
|
|
|||
|
RemoveKeyHandler(new Set<int>(ALT_SCAN));
|
|||
|
break;
|
|||
|
case ConsoleShortcutKey.CTRL_ALT_INS:
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.ControlKey, Keys.Menu, Keys.Insert));
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.LControlKey, Keys.LMenu, Keys.Insert));
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.LControlKey, Keys.RMenu, Keys.Insert));
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.RControlKey, Keys.LMenu, Keys.Insert));
|
|||
|
RemoveKeyHandler(new Set<Keys>(Keys.RControlKey, Keys.RMenu, Keys.Insert));
|
|||
|
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL_SCAN, ALT_SCAN, INS_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL2_SCAN, ALT2_SCAN, INS_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL2_SCAN, ALT2_SCAN, GR_SCAN, INS_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL_SCAN, ALT2_SCAN, INS_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL2_SCAN, ALT_SCAN, INS_SCAN));
|
|||
|
RemoveKeyHandler(new Set<int>(CTRL_SCAN, ALT2_SCAN, GR_SCAN, INS_SCAN));
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
internal void RemoveKeyHandler(Set<Keys> keySet)
|
|||
|
{
|
|||
|
Program.AssertOnEventThread();
|
|||
|
|
|||
|
if (ExtraKeys.ContainsKey(keySet))
|
|||
|
ExtraKeys.Remove(keySet);
|
|||
|
}
|
|||
|
|
|||
|
internal void RemoveKeyHandler(Set<int> keySet)
|
|||
|
{
|
|||
|
Program.AssertOnEventThread();
|
|||
|
|
|||
|
if (ExtraScans.ContainsKey(keySet))
|
|||
|
ExtraScans.Remove(keySet);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Generic function to handle key tracking and event firing
|
|||
|
/// </summary>
|
|||
|
/// <typeparam name="T">either int or Keys</typeparam>
|
|||
|
/// <param name="pressed"></param>
|
|||
|
/// <param name="depressed"></param>
|
|||
|
/// <param name="methods"></param>
|
|||
|
/// <param name="key"></param>
|
|||
|
/// <param name="modifierKeyPressedAlone"></param>
|
|||
|
/// <param name="modifierKeys"></param>
|
|||
|
/// <returns>Handled or not</returns>
|
|||
|
public bool handleExtras<T>(bool pressed, Set<T> depressed, Dictionary<Set<T>, MethodInvoker> methods, T key, List<T> modifierKeys, ref bool modifierKeyPressedAlone) where T : IComparable
|
|||
|
{
|
|||
|
if (pressed)
|
|||
|
{
|
|||
|
depressed.Add(key);
|
|||
|
if (modifierKeyPressedAlone)
|
|||
|
modifierKeyPressedAlone = false;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (modifierKeyPressedAlone && methods.ContainsKey(depressed) && depressed.Count == 1)
|
|||
|
{
|
|||
|
methods[depressed]();
|
|||
|
depressed.Clear();
|
|||
|
return true;
|
|||
|
}
|
|||
|
depressed.Remove(key);
|
|||
|
}
|
|||
|
|
|||
|
if (pressed && methods.ContainsKey(depressed))
|
|||
|
{
|
|||
|
if (depressed.Count == 1 && modifierKeys.Contains(key)) //single modifier keys are processed when the key is released
|
|||
|
{
|
|||
|
modifierKeyPressedAlone = true;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
methods[depressed]();
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
internal static Keys TranslateKeyMessage(Message msg)
|
|||
|
{
|
|||
|
// Determine the virtual key code.
|
|||
|
int virtualKeyCode = (int)msg.WParam;
|
|||
|
|
|||
|
// Determine whether the key is an extended key, e.g. a right hand Alt, Ctrl or Shift.
|
|||
|
int lParam = (int)msg.LParam;
|
|||
|
bool extended = (lParam & (1 << 24)) != 0;
|
|||
|
|
|||
|
// Left Alt or Right Alt
|
|||
|
if (virtualKeyCode == 18)
|
|||
|
return extended ? Keys.RMenu : Keys.LMenu;
|
|||
|
|
|||
|
// Left Ctrl or Right Ctrl
|
|||
|
if (virtualKeyCode == 17)
|
|||
|
return extended ? Keys.RControlKey : Keys.LControlKey;
|
|||
|
|
|||
|
// Left Shift or Right Shift
|
|||
|
if (virtualKeyCode == 16)
|
|||
|
return extended ? Keys.RShiftKey : Keys.LShiftKey;
|
|||
|
|
|||
|
// Default
|
|||
|
return (Keys)msg.WParam;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Given a modifier key (Ctrl, Shift or Alt), it builds a list of extended (Left and Right) keys.
|
|||
|
/// For example, if ControlKey is passed in, the result will be [RControlKey, LControlKey].
|
|||
|
/// </summary>
|
|||
|
/// <param name="key"></param>
|
|||
|
/// <returns></returns>
|
|||
|
internal static List<Keys> GetExtendedKeys(Keys key)
|
|||
|
{
|
|||
|
List<Keys> list = new List<Keys>();
|
|||
|
if (key == Keys.ControlKey)
|
|||
|
{
|
|||
|
list.Add(Keys.RControlKey);
|
|||
|
list.Add(Keys.LControlKey);
|
|||
|
}
|
|||
|
|
|||
|
if (key == Keys.ShiftKey)
|
|||
|
{
|
|||
|
list.Add(Keys.RShiftKey);
|
|||
|
list.Add(Keys.LShiftKey);
|
|||
|
}
|
|||
|
|
|||
|
if (key == Keys.Menu)
|
|||
|
{
|
|||
|
list.Add(Keys.RMenu);
|
|||
|
list.Add(Keys.LMenu);
|
|||
|
}
|
|||
|
return list;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Translates Left and Right modifier keys into simple keys, like ControlKey, ShiftKey and Menu.
|
|||
|
/// </summary>
|
|||
|
/// <param name="key"></param>
|
|||
|
/// <returns></returns>
|
|||
|
internal static Keys GetSimpleKey(Keys key)
|
|||
|
{
|
|||
|
switch (key)
|
|||
|
{
|
|||
|
case Keys.LControlKey:
|
|||
|
case Keys.RControlKey:
|
|||
|
return Keys.ControlKey;
|
|||
|
case Keys.LShiftKey:
|
|||
|
case Keys.RShiftKey:
|
|||
|
return Keys.ShiftKey;
|
|||
|
case Keys.LMenu:
|
|||
|
case Keys.RMenu:
|
|||
|
return Keys.Menu;
|
|||
|
default:
|
|||
|
return key;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|