2013年11月8日 星期五

C# 用API 控制滑鼠

From: http://www.dotblogs.com.tw/optimist9266/archive/2011/06/07/27309.aspx
From:http://www.dotblogs.com.tw/yc421206/archive/2011/01/24/20971.aspx
From:http://www.dotblogs.com.tw/sam319/archive/2009/12/24/12643.aspx


以下控制滑鼠的動作不限於在Form裡

控制滑鼠移動到某個位置
這個不需要呼叫API
而且即使Form不是作用中視窗
仍然可以控制滑鼠位置
Cursor.Position = new Point(x, y);

控制滑鼠點擊就需要呼叫API了
在適當的地方加入以下宣告
using System.Threading;
using System.Runtime.InteropServices;

static public class Mouse
{
    [DllImport("user32.dll", SetLastError = true)]
    public static extern Int32 SendInput(Int32 cInputs, ref INPUT pInputs, Int32 cbSize);

    [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 28)]
    public struct INPUT
    {
        [FieldOffset(0)]
        public INPUTTYPE dwType;
        [FieldOffset(4)]
        public MOUSEINPUT mi;
        [FieldOffset(4)]
        public KEYBOARDINPUT ki;
        [FieldOffset(4)]
        public HARDWAREINPUT hi;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct MOUSEINPUT
    {
        public Int32 dx;
        public Int32 dy;
        public Int32 mouseData;
        public MOUSEFLAG dwFlags;
        public Int32 time;
        public IntPtr dwExtraInfo;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct KEYBOARDINPUT
    {
        public Int16 wVk;
        public Int16 wScan;
        public KEYBOARDFLAG dwFlags;
        public Int32 time;
        public IntPtr dwExtraInfo;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct HARDWAREINPUT
    {
        public Int32 uMsg;
        public Int16 wParamL;
        public Int16 wParamH;
    }

    public enum INPUTTYPE : int
    {
        Mouse = 0,
        Keyboard = 1,
        Hardware = 2
    }

    [Flags()]
    public enum MOUSEFLAG : int
    {
        MOVE = 0x1,
        LEFTDOWN = 0x2,
        LEFTUP = 0x4,
        RIGHTDOWN = 0x8,
        RIGHTUP = 0x10,
        MIDDLEDOWN = 0x20,
        MIDDLEUP = 0x40,
        XDOWN = 0x80,
        XUP = 0x100,
        VIRTUALDESK = 0x400,
        WHEEL = 0x800,
        ABSOLUTE = 0x8000
    }

    [Flags()]
    public enum KEYBOARDFLAG : int
    {
        EXTENDEDKEY = 1,
        KEYUP = 2,
        UNICODE = 4,
        SCANCODE = 8
    }
}

控制滑鼠左鍵按下
static public void LeftDown()
{
    INPUT leftdown = new INPUT();

    leftdown.dwType = 0;
    leftdown.mi = new MOUSEINPUT();
    leftdown.mi.dwExtraInfo = IntPtr.Zero;
    leftdown.mi.dx = 0;
    leftdown.mi.dy = 0;
    leftdown.mi.time = 0;
    leftdown.mi.mouseData = 0;
    leftdown.mi.dwFlags = MOUSEFLAG.LEFTDOWN;

    SendInput(1, ref leftdown, Marshal.SizeOf(typeof(INPUT)));
}

控制滑鼠左鍵放開
static public void LeftUp()
{
    INPUT leftup = new INPUT();

    leftup.dwType = 0;
    leftup.mi = new MOUSEINPUT();
    leftup.mi.dwExtraInfo = IntPtr.Zero;
    leftup.mi.dx = 0;
    leftup.mi.dy = 0;
    leftup.mi.time = 0;
    leftup.mi.mouseData = 0;
    leftup.mi.dwFlags = MOUSEFLAG.LEFTUP;

    SendInput(1, ref leftup, Marshal.SizeOf(typeof(INPUT)));
}

控制滑鼠右鍵/中鍵,只要改一下MOUSEFLAG就可以了

有了左鍵按下和左鍵放開的方法
就可以模擬滑鼠左鍵的動作了
點一下(Click)
static public void LeftClick()
{
    LeftDown();
    Thread.Sleep(20);
    LeftUp();
}

連點兩下
static public void LeftDoubleClick()
{
    LeftClick();
    Thread.Sleep(50);
    LeftClick();
}

拖曳
static public void DragTo(int sor_X, int sor_Y, int des_X, int des_Y)
{
    Cursor.Position = new Point(sor_X, sor_Y); //在來源按下左鍵
    LeftDown();
    Thread.Sleep(200);
    Cursor.Position = new Point(des_X, des_Y); //到目的放開左鍵
    LeftUp();
}

這邊要注意的是滑鼠點下跟放開的中間
最好加點延遲時間
不然有時候會莫名的失效沒有作用

參考資料:
pinvoke.net: SendInput (user32)

0 意見:

張貼留言

 

MangoHost Copyright © 2009 Cookiez is Designed by Ipietoon for Free Blogger Template