Win32
マウスやキーボードを自動で動かす


HomeProgramming TipsWin32SDK Tips[SDK-002]

マウスを動かすには mouse_event() 関数を使います。
キーボードを動かすには keybd_event() 関数を使います。
マウスの座標系は 0〜65535 に正規化されていますので変換が必要です。
面倒なのでマクロ登録すると良いかもしれません。

■ mouse_event() 実行例

#define MOUSE_EVENT_X(x)    ((DWORD)x * WORD(-1) / ::GetSystemMetrics(SM_CXSCREEN))
#define MOUSE_EVENT_Y(y)    ((DWORD)y * WORD(-1) / ::GetSystemMetrics(SM_CYSCREEN))

    // マウスの移動
    mouse_event(
        MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE,
        MOUSE_EVENT_X(nPosX), MOUSE_EVENT_X(nPosY),
        0, 0
    );

    // マウスの左クリック
    mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
    Sleep(10);
    mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);


本当は、SendInput() のほうが Microsoft の推奨らしいです。
理由は mouse_event() と mouse_event() の間に他のアプリが発行した mouse_event() 等が割り込む可能性があるからです。
確実な連続動作をさせるなら SendInput を使います。
まず以下の宣言をします。MFC の場合は、 stdafx.h に記載済みですので書き換えます。


#define _WIN32_WINNT 0x0500



この指定をしなければ使えないということは、Windows2000 以降という事になります。
さて、まずは動作するサンプルを見てもらいましょうか。
連続で入力を指定するなら、SendInput でもシンプルな記述となります。

■ SendInput 実行例


    INPUT input[] = {
        { INPUT_MOUSE, 0, 65535, 0, MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, 0, 0 },
        { INPUT_MOUSE, 0, 0, 0, MOUSEEVENTF_RIGHTDOWN, 0, 0, },
        { INPUT_MOUSE, 0, 0, 0, MOUSEEVENTF_RIGHTUP,   0, 0, },
        { INPUT_MOUSE, 0, 0, 0, MOUSEEVENTF_LEFTDOWN,  0, 0, },
        { INPUT_MOUSE, 0, 0, 0, MOUSEEVENTF_LEFTUP,    0, 0, },
    };
    ::SendInput(5, input, sizeof(INPUT));



イベントの指定には INPUT 構造体を使います。
この INPUT 構造体は以下のメンバを持ちます。


typedef struct tagINPUT { 
    DWORD type;             // 入力タイプ
    union {
        MOUSEINPUT    mi;   // マウスイベント用データ
        KEYBOARDINPUT ki;   // キーボードイベント用データ
        HARDWAREINPUT hi;   // ハードウェアイベント用データ(詳細不明)
    };
} INPUT, *PINPUT;



■ 入力タイプ

INPUT_MOUSE     マウスイベントを発生させます
INPUT_KEYBOARD  キーボードイベントを発生させます
INPUT_HARDWARE  ハードウェアイベントを発生させます(詳細不明)



さて、入力タイプ別に指定するデータ構造体が変わります。
マウスイベントには MOUSEINPUT 構造体を、キーボードイベントには KEYBDINPUT 構造体を使うことになります。

■ マウスイベント
mouse_event 関数で指定する内容と殆ど同じです。

typedef struct tagMOUSEINPUT {
    LONG dx;                // マウスの絶対/相対座標(dwFlags で変化)
    LONG dy;
    DWORD mouseData;        // ホイールの移動(dwFlags = MOUSEEVENTF_WHEEL の時)
    DWORD dwFlags;          // マウスの動作を指定するフラグ
    DWORD time;             // タイムスタンプ。単位は ms (詳細不明)
    ULONG_PTR dwExtraInfo;  // 32 ビットの追加情報
} MOUSEINPUT, *PMOUSEINPUT;


■ キーボードイベント
keybd_event 関数で指定する内容と殆ど同じです。
ハードウェアスキャンコードは MapVirtualKey 関数を使って作成します。

typedef struct tagKEYBDINPUT {
    WORD wVk;               // 仮想キーコード
    WORD wScan;             // ハードウェアスキャンコード
    DWORD dwFlags;          // キーボードの動作を指定するフラグ
    DWORD time;             // タイムスタンプ。単位は ms (詳細不明)
    ULONG_PTR dwExtraInfo;  // 32 ビットの追加情報
} KEYBDINPUT, *PKEYBDINPUT;




 Copyright 2005 VALGUS. All Rights Reserved.