C#によるキーボード擬似操作について

APIのSendInput関数を使ってキーボード擬似操作を行なうサンプルです。KEYBDINPUTという構造体を定義し、dwFlagsフラグへ「ボタンを押した」、「ボタンを離した」などのフラグを設定します。

キーボード擬似操作のサンプルソース

using System;
using System.Reflection;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class SendInput
{
  /// 
  /// アプリケーションのメイン エントリ ポイントです。
  /// 
  [STAThread]
  static void Main()
  {
    Application.Run(new MainForm());
  }
}

class MainForm : Form
{
    // マウスイベント(mouse_eventの引数と同様のデータ)
    [StructLayout(LayoutKind.Sequential)]
    private struct MOUSEINPUT
    {
        public int dx;
        public int dy;
        public int mouseData;
        public int dwFlags;
        public int time;
        public int dwExtraInfo;
    };

    // キーボードイベント(keybd_eventの引数と同様のデータ)
    [StructLayout(LayoutKind.Sequential)]
    private struct KEYBDINPUT
    {
        public short wVk;
        public short wScan;
        public int dwFlags;
        public int time;
        public int dwExtraInfo;
    };

    // ハードウェアイベント
    [StructLayout(LayoutKind.Sequential)]
    private struct HARDWAREINPUT
    {
        public int uMsg;
        public short wParamL;
        public short wParamH;
    };

    // 各種イベント(SendInputの引数データ)
    [StructLayout(LayoutKind.Explicit)]
    private struct INPUT
    {
        [FieldOffset(0)] public int type;
        [FieldOffset(4)] public MOUSEINPUT mi;
        [FieldOffset(4)] public KEYBDINPUT ki;
        [FieldOffset(4)] public HARDWAREINPUT hi;
    };

    // キー操作、マウス操作をシミュレート(擬似的に操作する)
    [DllImport("user32.dll")]
    private extern static void SendInput(
        int nInputs, ref INPUT pInputs, int cbsize);

    // 仮想キーコードをスキャンコードに変換
    [DllImport("user32.dll", EntryPoint = "MapVirtualKeyA")]
    private extern static int MapVirtualKey(
        int wCode, int wMapType);

    private const int INPUT_MOUSE = 0;                  // マウスイベント
    private const int INPUT_KEYBOARD = 1;               // キーボードイベント
    private const int INPUT_HARDWARE = 2;               // ハードウェアイベント

    private const int MOUSEEVENTF_MOVE = 0x1;           // マウスを移動する
    private const int MOUSEEVENTF_ABSOLUTE = 0x8000;    // 絶対座標指定
    private const int MOUSEEVENTF_LEFTDOWN = 0x2;       // 左 ボタンを押す
    private const int MOUSEEVENTF_LEFTUP = 0x4;         // 左 ボタンを離す
    private const int MOUSEEVENTF_RIGHTDOWN = 0x8;      // 右 ボタンを押す
    private const int MOUSEEVENTF_RIGHTUP = 0x10;       // 右 ボタンを離す
    private const int MOUSEEVENTF_MIDDLEDOWN = 0x20;    // 中央ボタンを押す
    private const int MOUSEEVENTF_MIDDLEUP = 0x40;      // 中央ボタンを離す
    private const int MOUSEEVENTF_WHEEL = 0x800;        // ホイールを回転する
    private const int WHEEL_DELTA = 120;                // ホイール回転値

    private const int KEYEVENTF_KEYDOWN = 0x0;          // キーを押す
    private const int KEYEVENTF_KEYUP = 0x2;            // キーを離す
    private const int KEYEVENTF_EXTENDEDKEY = 0x1;      // 拡張コード
    private const int VK_SHIFT = 0x10;                  // SHIFTキー

  private Button button1 = new Button();// ボタンコントロール
  public MainForm()
  {
    this.Width = 200;
    this.Height = 100;
    this.Text = "キー入力送信";
    
    this.button1.Location = new Point(50, 20);
    this.button1.Size = new Size(100, 30);
    this.button1.Text = "送信";
    this.button1.Click += new EventHandler(this.Button1_Click);
    this.Controls.Add(this.button1);
  }
  /// 
  /// 「送信」ボタン処理
  /// 
  /// オブジェクト
  /// イベント
  private void Button1_Click(object sender, EventArgs e)
  {
        // 自ウインドウを非表示(キーボード操作対象のウィンドウへフォーカスを移動するため)
        this.Visible = false;

        // キーボード操作実行用のデータ
        const int num = 4;
        INPUT[] inp = new INPUT[num];

        // (1)キーボード(SHIFT)を押す
        inp[0].type = INPUT_KEYBOARD;
        inp[0].ki.wVk = VK_SHIFT;
        inp[0].ki.wScan = (short)MapVirtualKey(inp[0].ki.wVk, 0);
        inp[0].ki.dwFlags = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYDOWN;
        inp[0].ki.dwExtraInfo = 0;
        inp[0].ki.time = 0;

        // (2)キーボード(A)を押す
        inp[1].type = INPUT_KEYBOARD;
        inp[1].ki.wVk = (short)Keys.A;
        inp[1].ki.wScan = (short)MapVirtualKey(inp[1].ki.wVk, 0);
        inp[1].ki.dwFlags = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYDOWN;
        inp[1].ki.dwExtraInfo = 0;
        inp[1].ki.time = 0;

        // (3)キーボード(A)を離す
        inp[2].type = INPUT_KEYBOARD;
        inp[2].ki.wVk = (short)Keys.A;
        inp[2].ki.wScan = (short)MapVirtualKey(inp[2].ki.wVk, 0);
        inp[2].ki.dwFlags = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP;
        inp[2].ki.dwExtraInfo = 0;
        inp[2].ki.time = 0;

        // (4)キーボード(SHIFT)を離す
        inp[3].type = INPUT_KEYBOARD;
        inp[3].ki.wVk = VK_SHIFT;
        inp[3].ki.wScan = (short)MapVirtualKey(inp[3].ki.wVk, 0);
        inp[3].ki.dwFlags = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP;
        inp[3].ki.dwExtraInfo = 0;
        inp[3].ki.time = 0;

        // キーボード操作実行
        SendInput(num, ref inp[0], Marshal.SizeOf(inp[0]));

        // 1000ミリ秒スリープ
        System.Threading.Thread.Sleep(1000);

        // 自ウインドウを表示
        this.Visible = true;
  }
}

inserted by FC2 system