说明
双11又来了,又到抢红包的时候了。每到这个时候,我喜欢写个小东西晚上睡觉挂着自动抢,每次也都还是有点收获的。标题中提到的初级是纯鼠标键盘操作,想当年顶红包的时候,还做过直接操作页面元素提交请求的,那个效率要高的多。今天早上打开电脑发现天猫已经在抢红包了,我忙完了手中的事就来敲瞧代码,代码还没敲完,才发现这个抢红包是有次数限制的,一下没多少兴趣再写下去了,而且天猫的kiss次数和抢到的几率没有关联,你kiss10多次和kiss100多次说不定,kiss10次的那个有红包,100多的没有,这是亲身经历。既然次数是有限制的,大家还是选择自己喜欢的品牌去kiss吧,没必要做成全程自动,本程序就提供一个空格键自动按,或者鼠标的自动点击。本文的中心思想是回顾一下c#操作鼠标键盘的方法,末尾我会附上源代码和生成的程序。最后说一下:在下是新人,我这个人不太会说话,你要是看到我凌乱的代码和混乱的布局非常不爽的话,你他妈来打我啊!
方法的说明与实现
c#要操作鼠标键盘的话,除了使用System.Windows.Forms.SendKeys这个类,其他就要调用系统的api函数了。本程序实现的有鼠标相关操作、键盘相关操作以及快捷键的系统注册等。这每一个功能想了解非常详细的话,都可以大作文章。本文呢,抛砖引玉,大家看到具体实现想了解原理的可以去google相关资料。先附上代码:
class="code_img_closed" src="/Upload/Images/2013110213/0015B68B3C38AA5B.gif" alt="" />logs_code_hide('b8cb7b59-3bc0-40aa-b52c-e8583943cdc9',event)" src="/Upload/Images/2013110213/2B1B950FA3DF188F.gif" alt="" />using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Threading; namespace MouseDome { public enum KeyModifiers //组合键枚举 { None = 0, Alt = 1, Control = 2, Shift = 4, Windows = 8 } public partial class Form1 : Form { /// <summary> /// 鼠标控制参数 /// </summary> const int MOUSEEVENTF_LEFTDOWN = 0x2; const int MOUSEEVENTF_LEFTUP = 0x4; const int MOUSEEVENTF_MIDDLEDOWN = 0x20; const int MOUSEEVENTF_MIDDLEUP = 0x40; const int MOUSEEVENTF_MOVE = 0x1; const int MOUSEEVENTF_ABSOLUTE = 0x8000; const int MOUSEEVENTF_RIGHTDOWN = 0x8; const int MOUSEEVENTF_RIGHTUP = 0x10; /// <summary> /// 鼠标的位置 /// </summary> public struct PONITAPI { public int x, y; } #region 声明一些API函数 [DllImport("user32.dll")]//声明API函数 public static extern int GetCursorPos(ref PONITAPI p); [DllImport("user32.dll")]//声明API函数 public static extern int SetCursorPos(int x, int y); [DllImport("user32.dll")]//声明API函数 public static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo); //[DllImport("user32.dll")] //static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo); //[DllImport("user32.dll")] //static extern byte MapVirtualKey(byte wCode, int wMap); [System.Runtime.InteropServices.DllImport("user32.dll")] //申明API函数 public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, Keys vk); [System.Runtime.InteropServices.DllImport("user32.dll")] //申明API函数 public static extern bool UnregisterHotKey(IntPtr hWnd, int id); #endregion #region 声明一些变量 public delegate void go(); public delegate void mousemsg(); int time; int time1; int time2; int time3; private System.Timers.Timer t = null; //private System.Timers.Timer l = null; PONITAPI p1 = new PONITAPI();//亲品牌点击坐标 PONITAPI p2 = new PONITAPI();//结果页叉叉点击坐标 #endregion public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { RegisterHotKey(Handle, 100, (uint)KeyModifiers.Control, Keys.F1); System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false; mousemsg msg = new mousemsg(ShowMouse);//鼠标显示当时坐标的委托 msg.BeginInvoke(null,null); } /// <summary> /// 显示鼠标当前坐标 /// </summary> private void ShowMouse() { PONITAPI p = new PONITAPI(); while (true) { GetCursorPos(ref p); label4.Text = "X:" + p.x + ",Y:" + p.y; } } /// <summary> /// 按下设定的键时调用该方法 /// </summary> /// <param name="m"></param> private void ProcessHotkey(Message m) { IntPtr id = m.WParam; //IntPtr用于表示指针或句柄的平台特定类型 string sid = id.ToString(); switch (sid) { case "100": Application.Exit(); break; } } /// <summary> /// 监视Windows消息方法重载 /// </summary> /// <param name="m"></param> protected override void WndProc(ref Message m) { //如果m.Msg的值为0x0312那么表示用户按下了热键 const int WM_HOTKEY = 0x0312; switch (m.Msg) { case WM_HOTKEY: ProcessHotkey(m);//按下热键时调用ProcessHotkey()函数 break; } base.WndProc(ref m); //将系统消息传递自父类的WndProc } //开始事件 private void button1_Click(object sender, EventArgs e) { if (button1.Text == "开始") { button1.Text = "停止"; if (!string.IsNullOrEmpty(txtXPoint.Text) && !string.IsNullOrEmpty(txtYPoint.Text) && !string.IsNullOrEmpty(txtYPoint1.Text) && !string.IsNullOrEmpty(txtYPoint1.Text)) { p1.x = Convert.ToInt32(txtXPoint.Text); p1.y = Convert.ToInt32(txtYPoint.Text); p2.x = Convert.ToInt32(txtXPoint1.Text); p2.y = Convert.ToInt32(txtYPoint1.Text); } else { p1.x = 680; p1.y = 660; p2.x = 123; p2.y = 123; } time = Convert.ToInt32(numericUpDown1.Value); time1 = Convert.ToInt32(numericUpDown2.Value); time2 = Convert.ToInt32(numericUpDown3.Value); time3 = Convert.ToInt32(numericUpDown4.Value); Thread.Sleep(time); t = new System.Timers.Timer(time3);//实例化Timer类,设置间隔时间,毫秒; t.Elapsed += new System.Timers.ElapsedEventHandler(theout);//到达时间的时候执行事件; t.AutoReset = true;//设置是执行一次(false)还是一直执行(true); t.Enabled = true;//是否执行System.Timers.Timer.Elapsed事件; //l = new System.Timers.Timer(time1);//实例化Timer类,设置间隔时间,毫秒; //l.Elapsed += new System.Timers.ElapsedEventHandler(start);//到达时间的时候执行事件; //l.AutoReset = true;//设置是执行一次(false)还是一直执行(true); //l.Enabled = true;//是否执行System.Timers.Timer.Elapsed事件; } else { //l.Close(); t.Close(); button1.Text = "开始"; } } ///// <summary> ///// 鼠标点击方法 ///// </summary> //public void start(object source, System.Timers.ElapsedEventArgs e) //{ // //SetCursorPos(p1.x, p1.y); // mouse_event(MOUSEEVENTF_LEFTDOWN, p1.x, p1.y, 0, 0); // mouse_event(MOUSEEVENTF_LEFTUP, p1.x, p1.y, 0, 0); // Thread.Sleep(time2); // mouse_event(MOUSEEVENTF_LEFTDOWN, p2.x, p2.y, 0, 0); // mouse_event(MOUSEEVENTF_LEFTUP, p2.x, p2.y, 0, 0); //} /// <summary> /// 空格按键方法 /// </summary> public void theout(object source, System.Timers.ElapsedEventArgs e) { SendKeys.SendWait(" ");//还得靠模拟键盘的SendKeys.SendWait方法才行 } } }View Code
这是一个winfrom程序的后端代码。前面的几个声明都可以见名知意,鼠标显示当前坐标的方法用到一个委托把线程分开。后面空格的按键操作放在System.Timers.Timer事件里面,可以通过开始按钮来控制开始和停止。由于开始还想到操作鼠标去全自动化抢红包(这个是可行的,我试过),后来发现抢的次数有限,就没必要再写下去了,有一个demo的代码就行。所以我注册了一个ctrl+F1的快捷键,只要按这个快捷键,程序就会关闭。释放鼠标操作,不然控制不了你的鼠标。好像功能就说完了,毕竟花费的时间比较少,比较忙。
后记
本文提供了一些可用的示例代码意在抛砖引玉,大家根据代码去了解相关知识吧,遇到不懂的可以留言,自己去搜索相关资料学习一下。最后本文旨在服务一些新手老鸟可以直接无视(问:看完了才说老鸟可以无视?答:对,是的,你不爽的话,你T......啊!)
源码及程序下载:http://url.cn/NAwwhI