2

Windows 7 の user32.dll でマウスの動きとクリックをシミュレートして、ペイントに似たプログラムで自動的に描画しようとしています。

私が持っているものと使用方法は次のとおりです。

設定

    [DllImport("user32.dll")]
    static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);


    [Flags]
    public enum MouseEventFlags
    {
        LEFTDOWN = 0x00000002,
        LEFTUP = 0x00000004,
        MIDDLEDOWN = 0x00000020,
        MIDDLEUP = 0x00000040,
        MOVE = 0x00000001,
        ABSOLUTE = 0x00008000,
        RIGHTDOWN = 0x00000008,
        RIGHTUP = 0x00000010
    }

    public void LeftMouseDown()
    {
        mouse_event((int)(MouseEventFlags.LEFTDOWN), Cursor.Position.X, Cursor.Position.Y, 0, 0);
    }

    public void LeftMouseUp()
    {
        mouse_event((int)(MouseEventFlags.LEFTUP), Cursor.Position.X, Cursor.Position.Y, 0, 0);
    }

描画時

            foreach (var contour in contours)
            {
                LeftMouseDown();
                foreach (var point in contour)
                {
                    var x = point.X + offsetX;
                    var y = point.Y + offsetY;
                    Cursor.Position = new Point(x, y);
                    //LeftMouseDown();
                    System.Threading.Thread.Sleep(2);
                }
                LeftMouseUp();
            }

私がシミュレートしようとしているのは、マウスをクリックして保持し、それぞれのポイントの束contourに移動してから、次のポイントに移動する前に離すことcontourです。

問題は、これが最初の移動でマウス ボタンを押したままにしてから離すことです。

TL;DR

プログラムでマウスを動かしているときに、マウスの左クリックを押したままにするにはどうすればよいですか?

サードパーティのアプリで描画をシミュレートしようとしています。(Microsoft LINQ のホワイトボード、IM クライアント。)

4

2 に答える 2

2

コメント トレイルの要約: コードはマウスの動きではなくマウス クリックのみをシミュレートするため、これは期待される結果ではありません。Cursor.Position でカーソルを移動すると、Windows 入力イベント キューをバイパスして、カーソル位置が直接変更されます。そのため、フォーカスのあるウィンドウへの通知 (WM_MOUSEMOVE メッセージ) は生成されません。

MouseEventFlags.MOVE で mouse_event() を使用するヘルパー クラスに MouseMove() メソッドを追加して修正します。

于 2012-04-12T17:57:06.387 に答える
1

返事が遅くなりましたが、お電話の間違いだと思いますmouse_event。基本的に、相対的なマウスの動きをmouse_event報告します (なしの場合) が、絶対位置を渡すため、正しく動作しません。また、マウスダウンを行う前に、マウスボタンを押す位置にカーソルを移動してください。MOUSEEVENTF_ABSOLUTE

だからここに私の修正があります:

// I changed a bit of the method signature, but that doesn't really matter
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
static extern void mouse_event(MouseEventFlags flags, uint dx, uint dy, uint delta, IntPtr extraInfo);

[Flags]
enum MouseEventFlags : uint
{
    Absolute = 0x8000,
    LeftDown = 0x0002,
    LeftUp = 0x0004,
    MiddleDown = 0x0020,
    MiddleUp = 0x0040,
    Move = 0x0001,
    RightDown = 0x0008,
    RightUp = 0x0010,
    Wheel = 0x0800,
    XDown = 0x0080,
    XUp = 0x0100,
    HWheel = 0x1000,
}

public void LeftMouseDown()
{
    // Simulate left down, notice that RELATIVE movement is 0
    mouse_event(MouseEventFlags.LeftDown, 0, 0, 0, IntPtr.Zero);
}

public void LeftMouseUp()
{
    // Simulate left up, notice that RELATIVE movement is 0 too
    mouse_event(MouseEventFlags.LeftUp, 0, 0, 0, IntPtr.Zero);
}

そしてマウスを動かすと…

foreach (var contour in contours)
{
    // simulate mouse down AFTER cursor is moved to the first point (IMPORTANT!)
    var x = contour[0].X + offsetX;
    var y = contour[0].Y + offsetY;
    Cursor.Position = new Point(x, y);
    LeftMouseDown();
    foreach (var point in contour)
    {
        x = point.X + offsetX;
        y = point.Y + offsetY;
        Cursor.Position = new Point(x, y);
        System.Threading.Thread.Sleep(2);
    }
    // cursor is already at the final position
    LeftMouseUp();
}

補足として、いくつかの簡単なテストを通じて、設定Cursor.Position メッセージを生成しWM_MOUSEMOVEます。

于 2013-03-29T16:19:13.223 に答える