0

私がやろうとしているのは、次のコードを使用してメインフォームで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

しかし、プロパティを呼び出しているときCtrlPressedPInvokeStackImbalanceエラーが発生します。の宣言とGetAsyncKeyStateインポートも確実ですInteropServicesが、CtrlPressedプロパティの構文が間違っています。この問題を解決するにはどうすればよいですか?

ありがとう

4

1 に答える 1

1

スタックの不均衡エラーは、ほとんどの場合、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。ただし、この最後の動作に依存しないでください。詳細については、備考を参照してください。

次の場合、戻り値はゼロです。

  • 現在のデスクトップはアクティブデスクトップではありません
  • フォアグラウンドスレッドは別のプロセスに属しており、デスクトップはフックまたはジャーナルレコードを許可していません。
于 2011-12-21T10:30:48.093 に答える