PInvokeStackImbalance при использовании GetAsyncKeyState в VB.NET 2010 - PullRequest
0 голосов
/ 21 декабря 2011

Я пытаюсь отследить нажатие клавиш 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 Ответ

1 голос
/ 21 декабря 2011

Ошибка дисбаланса стека почти всегда означает, что ваша подпись определения P / Invoke неверна. Первое, что нужно сделать, - это тщательно проверить все ваши типы и убедиться, что они соответствуют документированной подписи для нативной функции. В этом случае выглядит хорошо.

За исключением того, что вы установили PreserveSig на False, и я не совсем уверен, почему. Как указывает документация для этого поля, оно предназначено для использования с неуправляемыми методами, которые возвращают код ошибки (например, код 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. В частности, раздел о возвращаемых значениях:

Если функция завершается успешно, возвращаемое значение указывает, была ли клавиша нажата с момента последнего вызова GetAsyncKeyState, и в данный момент клавиша вверх или вниз. Если задан старший значащий бит, клавиша нажата, а если задан младший значащий бит, клавиша была нажата после предыдущего вызова GetAsyncKeyState. Тем не менее, вы не должны полагаться на это последнее поведение; для получения дополнительной информации см. примечания.

Возвращаемое значение равно нулю в следующих случаях:

  • Текущий рабочий стол не является активным рабочим столом
  • Поток переднего плана принадлежит другому процессу, а рабочий стол не допускает перехват или запись журнала.
...