如何判断INS键状态

How to determine INS key state

我正在维护一个显示 Caps LockNum LockInsert[ 键状态的应用程序=28=]键。我一直在使用 user32.dll 方法 GetKeyState() 来完成这个:

Public Declare Function GetKeyState Lib "user32" Alias "GetKeyState" (ByVal nVirtKey As Long) As Integer

Public Sub CheckKeys()
    lblCaps.ForeColor = CType(IIf(GetKeyState(Keys.CapsLock) <> 0, Color.Black, Color.Gray), System.Drawing.Color)
    lblIns.ForeColor = CType(IIf(GetKeyState(Keys.Insert) <> 0, Color.Black, Color.Gray), System.Drawing.Color)
    lblNum.ForeColor = CType(IIf(GetKeyState(Keys.NumLock) <> 0, Color.Black, Color.Gray), System.Drawing.Color)
End Sub

工作正常,但现在将目标框架升级到 .NET 4.0 后,托管调试助手出现错误:

A call to PInvoke function '[application]::GetKeyState' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

我知道我可以使用 My.Computer.Keyboard.CapsLock 和 [=14 获取 Caps LockNum Lock 键的状态=] 布尔值,但是是否有类似的方法来获取 Insert 键的状态?

您的P/Invoke签名有误:

Public Declare Function GetKeyState Lib "user32" Alias "GetKeyState" (ByVal nVirtKey As Long) As Short

MSDN statesGetKeyStatenVirtKey参数是int类型,return类型是short,即一个分别为 32 位有符号和 16 位整数值。在 VB.NET 中,Long 类型是 Int64,因此您正在覆盖堆栈。

在 VB6 中,Long 是 32 位有符号值,Integer 是 16 位有符号值,并且 Short 不是关键字,所以 VB.NET' s 更改正在中断。

将参数更改为 ByVal nVirtKey As Integer,将 return 类型更改为 As Short

我注意到 Insert 键与 Caps-Lock 和 Num-Lock 不同,它没有系统范围的状态,它因应用程序甚至控件而异。我相信(尽管不确定)维护 Insert 键的状态是您的责任,并且 GetKeyState 不会像您希望的那样工作,尤其是 Insert 键。