我要做的是使用以下代码在我的主窗体上跟踪Ctrl + Tab按键
<DllImport("user32.dll", PreserveSig:=False)>
Private Shared Function GetAsyncKeyState(ByVal vKey As System.Windows.Forms.Keys) As Short
End Function
Private ReadOnly Property CtrlPressed As Boolean
Get
Dim keyval As Integer
keyval = GetAsyncKeyState(Keys.ControlKey)
If keyval = 0 Then
CtrlPressed = False
Else
CtrlPressed = True
End If
End Get
End Property
但是在调用属性CtrlPressed
时,我收到PInvokeStackImbalance
错误。我确定声明了GetAsyncKeyState
并且还导入了InteropServices
,但CtrlPressed
属性在语法上有错误。我该如何解决这个问题?
由于
答案 0 :(得分:1)
堆栈不平衡错误几乎总是意味着您的P / Invoke定义签名错误。要做的第一件事就是仔细检查所有类型,并确保它们与本机函数的文档签名相匹配。在这种情况下,它看起来不错。
除非您将PreserveSig
设置为False
,否则我不确定原因。正如该字段的documentation所示,它设计用于返回错误代码的非托管方法(例如,HRESULT
代码)。它指示运行时自动将这些错误代码转换为异常。但GetAsyncKeyState
方法不会返回错误代码,因此启用此选项并没有多大意义。
以下代码适用于我:
<DllImport("user32.dll")> _
Private Shared Function GetAsyncKeyState(ByVal vKey As Keys) As Short
End Function
Private ReadOnly Property IsCtrlPressed As Boolean
Get
Dim isPressed As Short = GetAsyncKeyState(Keys.ControlKey)
Return (isPressed & &H8000) != 0
End Get
End Property
确保您已密切关注GetAsyncKeyState
功能的documentation。具体来说,关于返回值的部分:
如果函数成功,则返回值指定自上次调用
GetAsyncKeyState
以来是否按下了键,以及该键当前是向上还是向下。如果设置了最高有效位,则键为关闭,如果设置了最低有效位,则在上一次调用GetAsyncKeyState
后按下该键。但是,你不应该依赖这最后的行为;有关更多信息,请参阅备注。以下情况的返回值为零:
- 当前桌面不是活动桌面
- 前台线程属于另一个进程,桌面不允许挂钩或日志记录。