如何确定INS键状态

时间:2015-10-12 21:54:00

标签: vb.net keyboard-events

我正在维护一个显示 Caps Lock Num Lock Insert 键的键状态的应用程序。我一直在使用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后,我从托管调试助手收到错误:

  

调用PInvoke函数&#39; [application] :: GetKeyState&#39;堆栈不平衡。这很可能是因为托管PInvoke签名与非托管目标签名不匹配。检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。

我知道我可以分别使用My.Computer.Keyboard.CapsLockMy.Computer.Keyboard.NumLock布尔值来获取 Caps Lock Num Lock 键的状态,但是是否有类似的方法来获取插入键的状态?

1 个答案:

答案 0 :(得分:1)

您的P / Invoke签名错误:

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

MSDN states GetKeyState&#39; nVirtKey参数的类型为int,返回类型为short,即32位分别为带符号和16位整数值。在VB.NET中,Long类型为Int64,因此您将覆盖堆栈。

在VB6中,Long为32位有符号且Integer为16位有符号值且Short不是关键字,因此VB.NET&#39; s变化正在破灭。

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

我注意到,与Caps-Lock和Num-Lock不同, Insert 键没有系统范围的状态,并且每个应用程序甚至每个控件都有所不同。我相信(尽管不确定)保持Insert键的状态是你的责任,并且GetKeyState将无法正常工作,特别是你想要使用Insert键。