在 VB.NET 2010 中使用 GetAsyncKeyState 时的 PInvokeStackImbalance
Posted
技术标签:
【中文标题】在 VB.NET 2010 中使用 GetAsyncKeyState 时的 PInvokeStackImbalance【英文标题】:PInvokeStackImbalance when using GetAsyncKeyState in VB.NET 2010 【发布时间】:2012-01-25 03:57:10 【问题描述】:我正在尝试使用以下代码在我的主窗体上跟踪 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
属性在语法上有些错误。我该如何解决这个问题?
谢谢
【问题讨论】:
【参考方案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
确保您已密切关注 documentation 的 GetAsyncKeyState
函数。具体来说,返回值部分:
如果函数成功,则返回值指定自上次调用
GetAsyncKeyState
以来是否按下了键,以及该键当前是向上还是向下。如果设置了最高有效位,则按键按下,如果设置了最低有效位,则在上一次调用GetAsyncKeyState
之后按下了按键。但是,您不应该依赖最后一种行为;有关详细信息,请参阅备注。以下情况返回值为零:
当前桌面不是活动桌面 前台线程属于另一个进程,桌面不允许挂钩或日志记录。
【讨论】:
以上是关于在 VB.NET 2010 中使用 GetAsyncKeyState 时的 PInvokeStackImbalance的主要内容,如果未能解决你的问题,请参考以下文章
在 Visual Basic VB.Net 2010 中使用 System.DateTime 类型作为可选参数
如何在 vb.net 2010 的我的文档/屏幕截图中保存 jpg 文件