Reputation: 3168
What I'm trying to do is tracing Ctrl+Tab keypress on my main form using following code
<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
But while calling the property CtrlPressed
I'm getting PInvokeStackImbalance
error. I'm sure with declaration of GetAsyncKeyState
and also have imported InteropServices
but the CtrlPressed
property has something syntactically wrong. How can I solve this issue?
Thanks
Upvotes: 0
Views: 2047
Reputation: 244752
A stack imbalance error almost always means that your P/Invoke definition signature is wrong. The first thing to do is check carefully all of your types and make sure that they match the documented signature for the native function. In this case, it looks good.
Except that you've set PreserveSig
to False
, and I'm not really sure why. As the documentation for that field indicates, it is designed for use with unmanaged methods that return an error code (for example, an HRESULT
code). It instructs the runtime to automatically convert those error codes into exceptions. But the GetAsyncKeyState
method doesn't return an error code, so enabling this option doesn't make a lot of sense.
The following code works fine for me:
<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
Make sure that you've paid close attention to the documentation for the GetAsyncKeyState
function. Specifically, the section on return values:
If the function succeeds, the return value specifies whether the key was pressed since the last call to
GetAsyncKeyState
, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call toGetAsyncKeyState
. However, you should not rely on this last behavior; for more information, see the Remarks.The return value is zero for the following cases:
- The current desktop is not the active desktop
- The foreground thread belongs to another process and the desktop does not allow the hook or the journal record.
Upvotes: 1