你的位置:首页 > ASP.net教程

[ASP.net教程]C#实现自动单击


最新玩了一下上学时候玩的游戏,但游戏里面变化太多了,进去后等级就很高,要不停地点击鼠标加技能。

所以利用工作中常用的C#调用 API不停地点击鼠标。

如图:

 

为方便在基础上修改,我把整个解决方案放到百度云盘。以下为链接:

链接: http://pan.baidu.com/s/1o7t80bS 密码: pehi

 

先将用到的公用方法贴上来:

 1 using System; 2 using System.Collections.Generic; 3 using System.Diagnostics; 4 using System.Runtime.InteropServices; 5 using System.Text; 6 using System.Windows.Forms; 7  8 namespace AutoKeyTool 9 { 10   public class KeyboardHook 11   { 12     int hHook; 13     Win32Api.HookProc KeyboardHookDelegate; 14     public event KeyEventHandler OnKeyDownEvent; 15     public event KeyEventHandler OnKeyUpEvent; 16     public event KeyPressEventHandler OnKeyPressEvent; 17  18     public KeyboardHook() { } 19     public void SetHook() 20     { 21       KeyboardHookDelegate = new Win32Api.HookProc(KeyboardHookProc); 22       Process cProcess = Process.GetCurrentProcess(); 23       ProcessModule cModule = cProcess.MainModule; 24       var mh = Win32Api.GetModuleHandle(cModule.ModuleName); 25       hHook = Win32Api.SetWindowsHookEx(Win32Api.WH_KEYBOARD_LL, KeyboardHookDelegate, mh, 0); 26     } 27  28     public void UnHook() 29     { 30       Win32Api.UnhookWindowsHookEx(hHook); 31     } 32  33     private List<Keys> preKeysList = new List<Keys>();//存放被按下的控制键,用来生成具体的键 34     private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam) 35     { 36       //如果该消息被丢弃(nCode<0)或者没有事件绑定处理程序则不会触发事件 37       if ((nCode >= 0) && (OnKeyDownEvent != null || OnKeyUpEvent != null || OnKeyPressEvent != null)) 38       { 39         Win32Api.KeyboardHookStruct KeyDataFromHook = (Win32Api.KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(Win32Api.KeyboardHookStruct)); 40         Keys keyData = (Keys)KeyDataFromHook.vkCode; 41         //按下控制键 42         if ((OnKeyDownEvent != null || OnKeyPressEvent != null) && (wParam == Win32Api.WM_KEYDOWN || wParam == Win32Api.WM_SYSKEYDOWN)) 43         { 44           if (IsCtrlAltShiftKeys(keyData) && preKeysList.IndexOf(keyData) == -1) 45           { 46             preKeysList.Add(keyData); 47           } 48         } 49         //WM_KEYDOWN和WM_SYSKEYDOWN消息,将会引发OnKeyDownEvent事件 50         if (OnKeyDownEvent != null && (wParam == Win32Api.WM_KEYDOWN || wParam == Win32Api.WM_SYSKEYDOWN)) 51         { 52           KeyEventArgs e = new KeyEventArgs(GetDownKeys(keyData)); 53           OnKeyDownEvent(this, e); 54         } 55  56         //WM_KEYDOWN消息将引发OnKeyPressEvent  57  58         if (OnKeyPressEvent != null && wParam == Win32Api.WM_KEYDOWN) 59         { 60           byte[] keyState = new byte[256]; 61           Win32Api.GetKeyboardState(keyState); 62           byte[] inBuffer = new byte[2]; 63           if (Win32Api.ToAscii(KeyDataFromHook.vkCode, KeyDataFromHook.scanCode, keyState, inBuffer, KeyDataFromHook.flags) == 1) 64           { 65             KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]); 66             OnKeyPressEvent(this, e); 67           } 68         } 69  70         //松开控制键 71         if ((OnKeyDownEvent != null || OnKeyPressEvent != null) && (wParam == Win32Api.WM_KEYUP || wParam == Win32Api.WM_SYSKEYUP)) 72         { 73           if (IsCtrlAltShiftKeys(keyData)) 74           { 75             for (int i = preKeysList.Count - 1; i >= 0; i--) 76             { 77               if (preKeysList[i] == keyData) { preKeysList.RemoveAt(i); } 78             } 79           } 80         } 81  82         //WM_KEYUP和WM_SYSKEYUP消息,将引发OnKeyUpEvent事件  83         if (OnKeyUpEvent != null && (wParam == Win32Api.WM_KEYUP || wParam == Win32Api.WM_SYSKEYUP)) 84         { 85           KeyEventArgs e = new KeyEventArgs(GetDownKeys(keyData)); 86           OnKeyUpEvent(this, e); 87         } 88       } 89       return Win32Api.CallNextHookEx(hHook, nCode, wParam, lParam); 90  91     } 92  93     //根据已经按下的控制键生成key 94     private Keys GetDownKeys(Keys key) 95     { 96       Keys rtnKey = Keys.None; 97       foreach (Keys i in preKeysList) 98       { 99         if (i == Keys.LControlKey || i == Keys.RControlKey) { rtnKey = rtnKey | Keys.Control; }100         if (i == Keys.LMenu || i == Keys.RMenu) { rtnKey = rtnKey | Keys.Alt; }101         if (i == Keys.LShiftKey || i == Keys.RShiftKey) { rtnKey = rtnKey | Keys.Shift; }102       }103       return rtnKey | key;104     }105     private Boolean IsCtrlAltShiftKeys(Keys key)106     {107       if (key == Keys.LControlKey || key == Keys.RControlKey || key == Keys.LMenu || key == Keys.RMenu || key == Keys.LShiftKey || key == Keys.RShiftKey) { return true; }108       return false;109     }110   }111 }

 1 using System; 2 using System.Collections.Generic; 3 using System.Runtime.InteropServices; 4 using System.Text; 5  6 namespace AutoKeyTool 7 { 8   public class MouseHook 9   {10     //结构体布局 本机位置11     [StructLayout(LayoutKind.Sequential)]12     struct NativeRECT13     {14       public int left;15       public int top;16       public int right;17       public int bottom;18     }19 20     //将枚举作为位域处理21     [Flags]22     enum MouseEventFlag : uint //设置鼠标动作的键值23     {24       Move = 0x0001,        //发生移动25       LeftDown = 0x0002,      //鼠标按下左键26       LeftUp = 0x0004,       //鼠标松开左键27       RightDown = 0x0008,     //鼠标按下右键28       RightUp = 0x0010,      //鼠标松开右键29       MiddleDown = 0x0020,     //鼠标按下中键30       MiddleUp = 0x0040,      //鼠标松开中键31       XDown = 0x0080,32       XUp = 0x0100,33       Wheel = 0x0800,       //鼠标轮被移动34       VirtualDesk = 0x4000,    //虚拟桌面35       Absolute = 0x800036     }37     //设置鼠标位置38     [DllImport("user32.dll")]39     static extern bool SetCursorPos(int X, int Y);40 41     //设置鼠标按键和动作42     [DllImport("user32.dll")]43     static extern void mouse_event(MouseEventFlag flags, int dx, int dy,uint data, UIntPtr extraInfo); //UIntPtr指针多句柄类型44 45     [DllImport("user32.dll")]46     static extern IntPtr FindWindow(string strClass, string strWindow);47 48     //该函数获取一个窗口句柄,该窗口雷鸣和窗口名与给定字符串匹配 hwnParent=Null从桌面窗口查找49     [DllImport("user32.dll")]50     static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string strClass, string strWindow);51 52     [DllImport("user32.dll")]53     static extern bool GetWindowRect(HandleRef hwnd, out NativeRECT rect);54 55 56     public static void MouseClick()57     {58       mouse_event(MouseEventFlag.LeftDown, 0, 0, 0, UIntPtr.Zero);59       mouse_event(MouseEventFlag.LeftUp, 0, 0, 0, UIntPtr.Zero);60     }61   }62 }

using System;using System.Collections.Generic;using System.Runtime.InteropServices;using System.Text;namespace AutoKeyTool{  public class Win32Api  {    #region 常数和结构    public const int WM_KEYDOWN = 0x100;    public const int WM_KEYUP = 0x101;    public const int WM_SYSKEYDOWN = 0x104;    public const int WM_SYSKEYUP = 0x105;    public const int WH_KEYBOARD_LL = 13;    [StructLayout(LayoutKind.Sequential)] //声明键盘钩子的封送结构类型     public class KeyboardHookStruct    {      public int vkCode; //表示一个在1到254间的虚似键盘码       public int scanCode; //表示硬件扫描码       public int flags;      public int time;      public int dwExtraInfo;    }    #endregion    #region Api    public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);    //安装钩子的函数     [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]    public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);    //卸下钩子的函数     [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]    public static extern bool UnhookWindowsHookEx(int idHook);    //下一个钩挂的函数     [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]    public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);    [DllImport("user32")]    public static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState);    [DllImport("user32")]    public static extern int GetKeyboardState(byte[] pbKeyState);    [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]    public static extern IntPtr GetModuleHandle(string lpModuleName);    #endregion  }}

调用放在winform窗体里面了,如果需要可下载源码:链接: http://pan.baidu.com/s/1jGO85Xc 密码: jk37