11

キーボードのキー「A」を押すことをエミュレートする C++ コードを書きたかったのです。

// Set up a generic keyboard event.
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0; // hardware scan code for key
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;

// Press the "..." key
ip.ki.wVk = code; // virtual-key code for the "a" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));

// Release the "..." key
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));

他のプログラムを起動してプログラムの実行を待つと、「A」がクリックされ、最初のプログラムがそれに反応します。しかし、他のアプリケーションでは、私のアクションが何らかの形で妨げられていることがわかりました (キーボードで手動で「A」を押すことはできますが、プログラムを使用してもアクションは発生しません)。

では、プログラムから「A」を押すことを、手動で「A」を押すのと同じにするために何ができますか(そのため、2 番目のプログラムはプログラムから呼び出されたことを認識しません)。

2 番目のプログラムのソース コードがなく、「A」が手動で押されていないことをどのように認識するのかわかりません。

コードに反応したいウィンドウがフォアグラウンドであり、キーを受け取ってブロックしていると確信しています(したがって、イベントがユーザーからではなくプログラムから来ていると判断できます)。

4

3 に答える 3

26

SendInput() を使用してハードウェア スキャン コードを送信することもできます (DirectInput が無視する仮想スキャン コードとは対照的に)。文書化が不十分ですが、 SendInput() は実際に DirectInput をバイパスできます。Eric の解決策がうまくいかなかった理由は、彼がハードウェア スキャン コードを設定したのに、(dwFlags を 0 に、wVk を 0 以外に設定することによって) 仮想スキャン コードを使用することになったためです。

基本的に、設定したいキーを押すには:

ip.ki.dwFlags = KEYEVENTF_SCANCODE;

キーリリースを行うには、次のように設定します。

ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;

完全な作業サンプルが以下にあり、文字「a」が出力されます。その他のスキャン コードはこちらで確認できます。

#define WINVER 0x0500
#include <windows.h>

using namespace std;

int main()
{

    //Structure for the keyboard event
    INPUT ip;

    Sleep(5000);

    //Set up the INPUT structure
    ip.type = INPUT_KEYBOARD;
    ip.ki.time = 0;
    ip.ki.wVk = 0; //We're doing scan codes instead
    ip.ki.dwExtraInfo = 0;

    //This let's you do a hardware scan instead of a virtual keypress
    ip.ki.dwFlags = KEYEVENTF_SCANCODE;
    ip.ki.wScan = 0x1E;  //Set a unicode character to use (A)

    //Send the press
    SendInput(1, &ip, sizeof(INPUT));

    //Prepare a keyup event
    ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
    SendInput(1, &ip, sizeof(INPUT));



    return 0;
}

注: SendInput() に INPUT 構造体の配列を渡すことで、キープレス (A の Shift + a など) を組み合わせることができます。

于 2013-09-17T15:55:08.737 に答える
4

多くの場合、スキャン コードを設定する必要があります。

// Set up a generic keyboard event.
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = MapVirtualKey(code, MAPVK_VK_TO_VSC); // hardware scan code for key
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;

// Press the "..." key
ip.ki.wVk = code; // virtual-key code for the "a" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));

また、IInspectable が示唆するように配列を構築することも、間違いなく進むべき道です。

于 2013-09-06T06:35:23.747 に答える