2

誰かが助けてくれることを願っています。キーボード コマンドをシミュレートする SendInput コードの例を見つけようとしています。メモ帳ウィンドウを見つけて、テスト メッセージを入力したいと思います。

私は当初、現在取り組んでいるプロジェクトで SendKeys を使用していました。SendKeys 関数を使用すると、職場で使用している特注のソフトウェアにキーボード コマンドを転送できました。

誰かが助けてくれることを願っています.インターネット上の例はうまくいかないようです.

SendInput メソッドが侵入的であるかどうか、つまり、受信者ウィンドウに損傷を与えるかどうかについても、誰でもアドバイスできますか。

SendKey メソッドは機能しましたが、信頼性は非常に当たり外れがあるようです。

どうもありがとう

サラ

編集:

インターネットで次のコードを見つけました。これは SendInput メソッドですか? 「SendKey」という用語が使用されていることに気付きましたか?

Private Declare Function SendInput Lib "user32.dll" _
 (ByVal nInputs As Long, ByRef pInputs As Any, _
 ByVal cbSize As Long) As Long
Private Declare Function VkKeyScan Lib "user32" Alias "VkKeyScanA" _
 (ByVal cChar As Byte) As Integer

Private Type KeyboardInput      '   typedef struct tagINPUT {
 dwType As Long                '     DWORD type;
 wVK As Integer                '     union {MOUSEINPUT mi;
 wScan As Integer              '               KEYBDINPUT ki;
 dwFlags As Long               '               HARDWAREINPUT hi;
 dwTime As Long                '              };
 dwExtraInfo As Long           '     }INPUT, *PINPUT;
 dwPadding As Currency         '   8 extra bytes, because mouses take more.
End Type

Private Const INPUT_MOUSE As Long = 0
Private Const INPUT_KEYBOARD As Long = 1
Private Const KEYEVENTF_KEYUP As Long = 2
Private Const VK_LSHIFT = &HA0

Public Sub SendKey(ByVal Data As String)
Dim ki() As KeyboardInput
Dim i As Long
Dim o As Long ' output buffer position
Dim c As String ' character

ReDim ki(1 To Len(Data) * 4) As KeyboardInput
o = 1

For i = 1 To Len(Data)
 c = Mid$(Data, i, 1)
 Select Case c
   Case "A" To "Z": ' upper case
     ki(o).dwType = INPUT_KEYBOARD 'shift down
     ki(o).wVK = VK_LSHIFT
     ki(o + 1) = ki(o) ' key down
     ki(o + 1).wVK = VkKeyScan(Asc(c))
     ki(o + 2) = ki(o + 1) ' key up
     ki(o + 2).dwFlags = KEYEVENTF_KEYUP
     ki(o + 3) = ki(o) ' shift up
     ki(o + 3).dwFlags = KEYEVENTF_KEYUP
     o = o + 4
   Case Else: ' lower case
     ki(o).dwType = INPUT_KEYBOARD
     ki(o).wVK = VkKeyScan(Asc(c))
     ki(o + 1) = ki(o)
     ki(o + 1).dwFlags = KEYEVENTF_KEYUP
     o = o + 2
 End Select
Next i

Debug.Print SendInput(o - 1, ki(1), LenB(ki(1))),
Debug.Print Err.LastDllError
End Sub

Private Sub Command1_Click()
Text1.Text = ""
Text1.SetFocus
DoEvents
Call SendKey("This Is A Test")
End Sub
4

2 に答える 2

4

次のコードは VB.net 用ではなく VB/VBA 用です。sendkeys メソッドに似ていますが、ターゲット アプリケーションにキーを送信するため、おそらくもう少し信頼性が高くなります。(私が入手した投稿には、sendkeys メソッドも示されています)

Public Declare Function FindWindowX Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, _
ByVal hWnd2 As Long, ByVal lpsz1 As Long, ByVal lpsz2 As Long) As Long

Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, _
ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Integer) As Long

Private Const WM_KEYDOWN = &H100
Private Const WM_KEYUP = &H101

Sub Three()
    hWind = FindWindow(vbNullString, "Untitled - Notepad")
    cWind = FindWindowX(hWind, 0, 0, 0)
    Debug.Print PostMessage(cWind, WM_KEYDOWN, vbKeyA, 0)
    Debug.Print PostMessage(cWind, WM_KEYDOWN, vbKeyB, 0)
    Debug.Print PostMessage(cWind, WM_KEYDOWN, vbKeyC, 0)
End Sub

このフォーラム投稿から取得したコード

これを Excel/VBA の新しいモジュールに貼り付け、メモ帳の新しいインスタンスを実行している場合、サブルーチンが実行されると、「abc」がメモ帳に表示されます。

これを使用する方法がわかりません。そうしないと、sendkeys メソッドがターゲット ウィンドウを「損傷」する可能性があります。メッセージのタイミングが適切である限り (大量の文字を同時にウィンドウに送信しない)、問題が発生することはありません。

于 2012-12-16T00:31:02.070 に答える
0

別の SendInput スクリプトをオンラインで見つけることができたので、興味のある人のために以下にコピーしました。

SendKeys を使用してスプレッドシートからデータをコピーし、職場のシステムに入力しています。これにより、入力する必要がある情報が膨大になるため、貴重な時間を節約できます。

SendKeys 関数は問題なく動作しました (ただし、信頼性の問題のため、代替手段を検討する必要がありました)。SendInput は、他のウィンドウに問題を引き起こしますか。つまり、キーボード ボタンをシミュレートする以外に、ターゲット ウィンドウの他の機能に干渉しますか?

Private Declare Function SendInput Lib "user32.dll" _
 (ByVal nInputs As Long, ByRef pInputs As Any, _
 ByVal cbSize As Long) As Long
Private Declare Function VkKeyScan Lib "user32" Alias "VkKeyScanA" _
 (ByVal cChar As Byte) As Integer

Private Type KeyboardInput      '   typedef struct tagINPUT {
 dwType As Long                '     DWORD type;
 wVK As Integer                '     union {MOUSEINPUT mi;
 wScan As Integer              '               KEYBDINPUT ki;
 dwFlags As Long               '               HARDWAREINPUT hi;
 dwTime As Long                '              };
 dwExtraInfo As Long           '     }INPUT, *PINPUT;
 dwPadding As Currency         '   8 extra bytes, because mouses take more.
End Type

Private Const INPUT_MOUSE As Long = 0
Private Const INPUT_KEYBOARD As Long = 1
Private Const KEYEVENTF_KEYUP As Long = 2
Private Const VK_LSHIFT = &HA0

Public Sub SendKey(ByVal Data As String)
Dim ki() As KeyboardInput
Dim i As Long
Dim o As Long ' output buffer position
Dim c As String ' character

ReDim ki(1 To Len(Data) * 4) As KeyboardInput
o = 1

For i = 1 To Len(Data)
 c = Mid$(Data, i, 1)
 Select Case c
   Case "A" To "Z": ' upper case
     ki(o).dwType = INPUT_KEYBOARD 'shift down
     ki(o).wVK = VK_LSHIFT
     ki(o + 1) = ki(o) ' key down
     ki(o + 1).wVK = VkKeyScan(Asc(c))
     ki(o + 2) = ki(o + 1) ' key up
     ki(o + 2).dwFlags = KEYEVENTF_KEYUP
     ki(o + 3) = ki(o) ' shift up
     ki(o + 3).dwFlags = KEYEVENTF_KEYUP
     o = o + 4
   Case Else: ' lower case
     ki(o).dwType = INPUT_KEYBOARD
     ki(o).wVK = VkKeyScan(Asc(c))
     ki(o + 1) = ki(o)
     ki(o + 1).dwFlags = KEYEVENTF_KEYUP
     o = o + 2
 End Select
Next i

Debug.Print SendInput(o - 1, ki(1), LenB(ki(1))),
'Debug.Print Err.LastDllError
End Sub

Private Sub Command1_Click()
Text1.Text = ""
Text1.SetFocus
DoEvents
Call SendKey("This Is A Test")
End Sub
于 2012-12-16T11:10:44.207 に答える