プログラミング素人のはてなブログ

プログラミングも電気回路も専門外の技術屋の末端が勉強したことや作品をアウトプットするブログ。コードに間違いなど見つけられたら、気軽にコメントください。 C#、Python3、ラズパイなど。

マウス自動化ツール

マウス操作をC# で自動化するツールを作ってみました。

使うだけであれば、ぐぐるといろいろ出てきますのであってアイデア自体は昔からあるものです。
マウス自動化 - Google 検索

↓のサイトを参考にプログラミングしてみました。
whoopsidaisies.hatenablog.com

目標はスクレイピングでは対応しきれない(自分の技術力的に)部分をマウスエミュレーションで解決することです。

◆目指す機能
マウスで座標をもとにブラウザ上のLinkをたどって目的のWeb Pageへ
そのために、クリックすべき座標を記録する。
記録した座標をもとにWeb Pageをたどる

using System.Runtime.InteropServices;
  public partial class Form1 : Form
    {

        int interval = 2000;
        private const int MOUSEEVENTF_LEFTDOWN = 0x2;
        private const int MOUSEEVENTF_LEFTUP = 0x4;
        private const int MOUSEEVENTF_RIGHTTDOWN = 0x8;
        private const int MOUSEEVENTF_RIGHTUP = 0x10;
        [DllImport("USER32.dll", CallingConvention = CallingConvention.StdCall)]
        static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
        int[] cursorLogX = new int[10] { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
        int[] cursorLogY = new int[10] { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
        int n = 0;

        private void Form1_Load(object sender, EventArgs e)
        {
            this.KeyPreview = true;   
            comboBoxInterval.Items.Add("2000");
            comboBoxInterval.Text = "2000";
        }
}

Using System.Runtime.InteropServices;の宣言を追加し、Classの直下に
[DllImport("USER32.dll", CallingConvention = CallingConvention.StdCall)]
を追加します。
これが、マウス操作のためのRuntimeのようです。(詳細はよくわかってない)
MOUSEEVENTF_LEFTDOWN …などの変数を設定します。
この16進数で示された値を渡すことでマウスを操作します。
x,yの座標を最大10個記憶するため、配列を持たせます。(必要に応じて配列の大きさは変更可能)
座標は0以上の整数として入ってくるので、"-1"で初期化するとことで、呼び出された座標が"-1"であれば座標が記録されていないということになります。

  private void Form1_Load(object sender, EventArgs e)
        {
      this.KeyPreview = true;  
    }

これで、キー操作を受け取るようになります。

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        { 
           if ((e.Modifiers & Keys.Alt) == Keys.Alt)
            {                
                //マウスポインタのX座標を取得する
                int x = System.Windows.Forms.Cursor.Position.X;
                //マウスポインタのY座標を取得する
                int y = System.Windows.Forms.Cursor.Position.Y;

                textBoxLog.AppendText( x.ToString()+" "+y.ToString()+ System.Environment.NewLine);
                cursorLogX[n] = x;
                cursorLogY[n] = y;
                n++;
            }

private void Form1_KeyDown( ~ という関数を作成し、ここでは「Alt」キーを押したときのマウス座標を記録します。

        private void button1_Click(object sender, EventArgs e)
        {
            interval = int.Parse(comboBoxInterval.Text);
            for (int m = 0; m < 10; m++)
            {
                if (cursorLogX[m] != -1)
                {
                    //マウスポインタの位置を画面左上基準の座標(x,y)にする
                    System.Windows.Forms.Cursor.Position = new System.Drawing.Point(cursorLogX[m], cursorLogY[m]);
                    mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);      
                      // マウスの左ボタンダウンイベントを発生させる             
                    mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);        
                      // マウスの左ボタンアップイベントを発生させる
                    System.Threading.Thread.Sleep(interval);
                }
                else
                {
                    break;
                }
            }
  
        }

ボタン1を押すと再現します。
webを扱うときには、読み込みにかかる時間を計算に入れておかないと、ItemがすべてDownloadされないうちに次のステップに進んでしまうと、座標とWeb Linkがずれてしまいます。のでここではIntervalとして、2000msほど入れています。