在我的应用程序中,我允许用户使用ProcessCmdKey
按住右箭头键来滚动电影。现在我想让用户能够在需要时提高滚动速度。理想情况下,用户应该能够按住右箭头键,然后当他决定提高速度时,不释放右箭头键,同时按住 Shift键当他决定回到正常速度时,他应该简单地释放 Shift键。因此,滚动速度的差异应仅从 Shift键修饰符给出,该修饰符应添加或移除到右箭头键压力。
我尝试了这样的代码,但没有成功(我在这个测试示例中的表单中有一个简单的标签):
int count = 0;
bool keyRightDown = false;
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Right)
{
keyRightDown = true;
count++;
label.Text = "count = " + count.ToString();
return true;
}
if (keyData == (Keys.Shift | Keys.ShiftKey) && keyRightDown)
{
count += 10;
label.Text = "count = " + count.ToString();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
protected override bool ProcessKeyMessage(ref Message m)
{
if ((Keys)m.WParam == Keys.Right)
{
if (m.Msg == 0x101) // KEYUP
{
keyDown = false;
return true;
}
}
return base.ProcessKeyMessage(ref m);
}
当用户将 Shift键添加到右箭头时,keyData
不包含(Keys.Shift | Keys.Right)
,正如我期望的那样{{1} }}。但是,这个问题仍然可以通过布尔值(Keys.Shift | Keys.ShiftKey)
来解决。主要问题是当用户通过此时仅释放右箭头来释放 Shift键时,没有其他人同时调用keyRightDown
和{ {1}}被触发。我怎样才能实现目标?
答案 0 :(得分:2)
我找到的唯一方法是使用调用GetKeyState
API函数(user32.dll)和Timer
的组合。这是适用于测试应用程序:
System.Windows.Forms.Timer keyManagerTimer = new System.Windows.Forms.Timer();
int count = 0;
public Form1()
{
InitializeComponent();
this.keyManagerTimer.Tick += (s, e) => ProcessKeys();
this.keyManagerTimer.Interval = 25;
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if ((keyData & Keys.Right) != 0)
{
keyManagerTimer.Enabled = true;
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
private void ProcessKeys()
{
bool isShiftKeyPressed = IsKeyPressed(Keys.ShiftKey);
bool isRightKeyPressed = IsKeyPressed(Keys.Right);
if (isRightKeyPressed && !isShiftKeyPressed)
{
count++;
}
else if (isRightKeyPressed && isShiftKeyPressed)
{
count += 10;
}
label.Text = "count = " + count.ToString();
}
public static bool IsKeyPressed(Keys key)
{
return BitConverter.GetBytes(GetKeyState((int)key))[1] > 0;
}
[DllImport("user32")]
private static extern short GetKeyState(int vKey);
在我的真实代码中,我停用Timer
Leave
上我有视频的Control
事件的{{1}}。可能另一种解决方案可能是使用IMessageFilter(参见here)。
答案 1 :(得分:0)
一种可能的解决方案是将所有可能的按键存储在bool数组中,然后检查bool数组是否为某些值。在按住按钮的情况下,您将按钮键设置为true,并在释放按键时将其设置为false。当我需要检查多次按键时,这是一个我通常会使用的选项。