我目前正在开发一个应用程序,根据用户是否按下右移位键或左移键(RShiftKey,LShiftKey)需要不同的行为,但是当按下这些键中的任何一个时,我只看到ShiftKey |移。
我的键盘有问题吗? (笔记本电脑)我需要一个新的键盘驱动程序/键盘,以便发送不同的键命令...
目前这是一个相当大的问题,因为没有办法测试代码的工作原理(除了单元测试)。任何人都有不同的shift / alt / ctrl键的经验吗?
答案 0 :(得分:6)
查看GetAsyncKeyState Win32方法。您可以使用以下命令向其添加pInvoke调用:
[DllImport("user32.dll")]
private static extern short GetAsyncKeyState(Keys key);
然后处理表单上的KeyDown
事件:
private void MyForm_KeyDown(object sender, KeyEventArgs e)
{
Console.WriteLine("Left Shift : " + (GetAsyncKeyState(Keys.LShiftKey) < 0));
Console.WriteLine("Right Shift: " + (GetAsyncKeyState(Keys.RShiftKey) < 0));
}
答案 1 :(得分:5)
我不知道这篇文章是否对您有所帮助,但看起来您可能不得不使用InteropServices和Diagnostics:
MSDN Forum: How to send Left/Right shift key
编辑:我终于想出了如何使GetAsyncKeyState()正常工作,正如adrianbanks所揭示的那样。
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern short GetAsyncKeyState(Keys vKey);
private void theForm_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.ShiftKey)
{
if (Convert.ToBoolean(GetAsyncKeyState(Keys.LShiftKey)))
{
Console.WriteLine("Left");
}
if (Convert.ToBoolean(GetAsyncKeyState(Keys.RShiftKey)))
{
Console.WriteLine("Right");
}
}
}
答案 2 :(得分:3)
谢谢你们,那里有很好的解决方案。同时,这是我自己的“hacky”方式,通过重写ProcessCmdKey来做到这一点:
public override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (msg.LParam.ToInt32() == 0x2a0001)
LastShiftKey = ShiftKeys.NumericShift;
else if (msg.LParam.ToInt32() == 0x360001)
LastShiftKey = ShiftKeys.AlphaShift;
etc....
}
答案 3 :(得分:2)
我有类似的需要来区分左右移位和控制键。这是我相当长的但可能更好的解决方案。如果你想要捕获alt键,你需要覆盖其他一些东西,以防止它们激活任何菜单。 ((int)m.LParam & 0xFFFF)
应该重复计数,但它似乎永远不会超过2。
protected override bool ProcessKeyMessage(ref Message m)
{
if ((m.Msg == WM_KEYDOWN || m.Msg == WM_KEYUP) && ((int)m.WParam == VK_CONTROL || (int)m.WParam == VK_SHIFT))
{
KeyEventArgs e = new KeyEventArgs(Keys.None);
switch ((OemScanCode)(((int)m.LParam >> 16) & 0x1FF))
{
case OemScanCode.LControl:
e = new KeyEventArgs(Keys.LControlKey);
break;
case OemScanCode.RControl:
e = new KeyEventArgs(Keys.RControlKey);
break;
case OemScanCode.LShift:
e = new KeyEventArgs(Keys.LShiftKey);
break;
case OemScanCode.RShift:
e = new KeyEventArgs(Keys.RShiftKey);
break;
default:
if ((int)m.WParam == VK_SHIFT)
e = new KeyEventArgs(Keys.ShiftKey);
else if ((int)m.WParam == VK_CONTROL)
e = new KeyEventArgs(Keys.ControlKey);
break;
}
if (e.KeyData != Keys.None)
{
if (m.Msg == WM_KEYDOWN)
OnKeyDown(e);
else
OnKeyUp(e);
return true;
}
}
return base.ProcessKeyMessage(ref m);
}
#region Scan code & window message stuff
const int WM_KEYDOWN = 0x100;
const int WM_KEYUP = 0x101;
const int VK_SHIFT = 0x10;
const int VK_CONTROL = 0x11;
/// <summary>
/// Alt key
/// </summary>
const int VK_MENU = 0x12;
/// <summary>
/// List of scan codes for standard 104-key keyboard US English keyboard
/// </summary>
enum OemScanCode
{
/// <summary>
/// ` ~
/// </summary>
BacktickTilde = 0x29,
/// <summary>
/// 1 !
/// </summary>
N1 = 2,
/// <summary>
/// 2 @
/// </summary>
N2 = 3,
/// <summary>
/// 3 #
/// </summary>
N3 = 4,
/// <summary>
/// 4 $
/// </summary>
N4 = 5,
/// <summary>
/// 5 %
/// </summary>
N5 = 6,
/// <summary>
/// 6 ^
/// </summary>
N6 = 7,
/// <summary>
/// 7 &
/// </summary>
N7 = 8,
/// <summary>
/// 8 *
/// </summary>
N8 = 9,
/// <summary>
/// 9 (
/// </summary>
N9 = 0x0A,
/// <summary>
/// 0 )
/// </summary>
N0 = 0x0B,
/// <summary>
/// - _
/// </summary>
MinusDash = 0x0C,
/// <summary>
/// = +
/// </summary>
Equals = 0x0D,
Backspace = 0x0E,
Tab = 0x0F,
Q = 0x10,
W = 0x11,
E = 0x12,
R = 0x13,
T = 0x14,
Y = 0x15,
U = 0x16,
I = 0x17,
O = 0x18,
P = 0x19,
/// <summary>
/// [ {
/// </summary>
LBracket = 0x1A,
/// <summary>
/// ] }
/// </summary>
RBracket = 0x1B,
/// <summary>
/// | \ (same as pipe)
/// </summary>
VerticalBar = 0x2B,
/// <summary>
/// | \ (same as vertical bar)
/// </summary>
Pipe = 0x2B,
CapsLock = 0x3A,
A = 0x1E,
S = 0x1F,
D = 0x20,
F = 0x21,
G = 0x22,
H = 0x23,
J = 0x24,
K = 0x25,
L = 0x26,
/// <summary>
/// ; :
/// </summary>
SemiColon = 0x27,
/// <summary>
/// ' "
/// </summary>
Quotes = 0x28,
// Unused
Enter = 0x1C,
LShift = 0x2A,
Z = 0x2C,
X = 0x2D,
C = 0x2E,
V = 0x2F,
B = 0x30,
N = 0x31,
M = 0x32,
/// <summary>
/// , <
/// </summary>
Comma = 0x33,
/// <summary>
/// . >
/// </summary>
Period = 0x34,
/// <summary>
/// / ?
/// </summary>
Slash = 0x35,
RShift = 0x36,
LControl = 0x1D,
LAlternate = 0x38,
SpaceBar = 0x39,
RAlternate = 0x138,
RControl = 0x11D,
/// <summary>
/// The menu key thingy
/// </summary>
Application = 0x15D,
Insert = 0x152,
Delete = 0x153,
Home = 0x147,
End = 0x14F,
PageUp = 0x149,
PageDown = 0x151,
UpArrow = 0x148,
DownArrow = 0x150,
LeftArrow = 0x14B,
RightArrow = 0x14D,
NumLock = 0x145,
NumPad0 = 0x52,
NumPad1 = 0x4F,
NumPad2 = 0x50,
NumPad3 = 0x51,
NumPad4 = 0x4B,
NumPad5 = 0x4C,
NumPad6 = 0x4D,
NumPad7 = 0x47,
NumPad8 = 0x48,
NumPad9 = 0x49,
NumPadDecimal = 0x53,
NumPadEnter = 0x11C,
NumPadPlus = 0x4E,
NumPadMinus = 0x4A,
NumPadAsterisk = 0x37,
NumPadSlash = 0x135,
Escape = 1,
PrintScreen = 0x137,
ScrollLock = 0x46,
PauseBreak = 0x45,
LeftWindows = 0x15B,
RightWindows = 0x15C,
F1 = 0x3B,
F2 = 0x3C,
F3 = 0x3D,
F4 = 0x3E,
F5 = 0x3F,
F6 = 0x40,
F7 = 0x41,
F8 = 0x42,
F9 = 0x43,
F10 = 0x44,
F11 = 0x57,
F12 = 0x58,
}
#endregion