如果使用GetAsyncKeyState()识别按下的热键,则仅在调用一次之前返回正确的结果

时间:2019-02-11 11:33:38

标签: c# winapi hotkeys

我对此很困惑。我有一种方法可以检查是否按下了热键(使用RegisterHotkey)。 我在热键上调用GetAsyncKeyState(vKey),它的修饰符用来确定哪个已注册热键被调用。

    public bool IsPressed()
    {
         // Checks if the key and any (but not all) required modifiers are pressed
        // Int16.MinValue indicates that a key is pressed - 0 indicates it isn't - Keys.None cannot be used
        return GetAsyncKeyState(Key) == Int16.MinValue && (Modifier == ModifierKeys.None ||
            (Modifier == ModifierKeys.Shift && GetAsyncKeyState(Keys.ShiftKey) == Int16.MinValue) ||
            (Modifier == ModifierKeys.Alt && GetAsyncKeyState(Keys.Alt) == Int16.MinValue) ||
            (Modifier == ModifierKeys.Control && GetAsyncKeyState(Keys.ControlKey) == Int16.MinValue) ||
            (Modifier == ModifierKeys.Windows && (GetAsyncKeyState(Keys.LWin) == Int16.MinValue || GetAsyncKeyState(Keys.RWin) == Int16.MinValue))
            );
    }

以上返回false。因此,我尝试单独添加语句以查看问题所在:

public bool IsPressed()
{

var keything =  GetAsyncKeyState(Key);

bool a = GetAsyncKeyState(Key) == Int16.MinValue && (Modifier == ModifierKeys.None);
bool b = (Modifier == ModifierKeys.Shift && GetAsyncKeyState(Keys.ShiftKey) == Int16.MinValue);
bool c = (Modifier == ModifierKeys.Alt && GetAsyncKeyState(Keys.Alt) == Int16.MinValue);
bool d = (Modifier == ModifierKeys.Control && GetAsyncKeyState(Keys.ControlKey) == Int16.MinValue);
bool e = (Modifier == ModifierKeys.Windows && (GetAsyncKeyState(Keys.LWin) == Int16.MinValue || GetAsyncKeyState(Keys.RWin) == Int16.MinValue));
bool f = GetAsyncKeyState(Key) == Int16.MinValue && (Modifier == ModifierKeys.None ||
    (Modifier == ModifierKeys.Shift && GetAsyncKeyState(Keys.ShiftKey) == Int16.MinValue) ||
    (Modifier == ModifierKeys.Alt && GetAsyncKeyState(Keys.Alt) == Int16.MinValue) ||
    (Modifier == ModifierKeys.Control && GetAsyncKeyState(Keys.ControlKey) == Int16.MinValue) ||
    (Modifier == ModifierKeys.Windows && (GetAsyncKeyState(Keys.LWin) == Int16.MinValue || GetAsyncKeyState(Keys.RWin) == Int16.MinValue))
    );


// Checks if the key and any (but not all) required modifiers are pressed
// Int16.MinValue indicates that a key is pressed - 0 indicates it isn't - Keys.None cannot be used
return GetAsyncKeyState(Key) == Int16.MinValue && (Modifier == ModifierKeys.None ||
    (Modifier == ModifierKeys.Shift && GetAsyncKeyState(Keys.ShiftKey) == Int16.MinValue) ||
    (Modifier == ModifierKeys.Alt && GetAsyncKeyState(Keys.Alt) == Int16.MinValue) ||
    (Modifier == ModifierKeys.Control && GetAsyncKeyState(Keys.ControlKey) == Int16.MinValue) ||
    (Modifier == ModifierKeys.Windows && (GetAsyncKeyState(Keys.LWin) == Int16.MinValue || GetAsyncKeyState(Keys.RWin) == Int16.MinValue))
    );
}

A和F返回true-应当正确(F也是所返回语句的副本)... 但是,我没想到的是该方法本身也返回true。

因此,在实际查询之前添加对GetAsyncKeyState()的调用会使其正常工作。 为什么会这样?解决此问题的最佳方法是什么(除了对函数的死调用)

1 个答案:

答案 0 :(得分:0)

除了使用GetAsyncKeyState()而不是建议的HotKey.IsPressed()之外,您还可以像这样从侦听器的lParam确定热键:

在热键类中的

IsPressed看起来像这样:

public bool IsPressed(IntPtr lParam)
{
    uint param = (uint)lParam.ToInt64();
    var inputKey = (Keys)((param & 0xffff0000) >> 16);
    var inputModifier = (ModifierKeys)(param & 0x0000ffff);

    return inputKey == this.Key && inputModifier == this.Modifier;
}

或者使用不需要在每个IsPressed调用上进行计算的变量。