C# API实现游戏自动登录
1。游戏自动登录,MousePosition.X获得系统鼠标位置的X坐标
第一种方法:指定文本框的坐标,适用于窗口最大化按钮不能用的,如QQ游戏
int x=500;
int y=300;
SendKeys.SendWait("274040246"); //输入游戏ID
SetCursorPos(x, y); //设置鼠标位置,x,y为账号框相对屏幕的位置
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
System.Threading.Thread.Sleep(500);//设置暂停时间,不然账号和密码会发在一个框中
SendKeys.SendWait("{Tab}");//发送Tab
SendKeys.SendWait("1111111111111"); //输入游戏密码
SendKeys.SendWait("{ENTER}");//输入回车键
第二种方法:
IntPtr myIntPtr = FindWindow(null, "QQ游戏");
IntPtr handle1 = FindWindowEx(myIntPtr, IntPtr.Zero, "ComboBox", null);//找账号输入框句柄
IntPtr handle2 = FindWindowEx(myIntPtr, handle1, "Edit", null);//找密码输入框句柄
if (handle1 != null && handle2 != null)
{
InputStr(handle1, "274040246"); //输入游戏ID
InputStr(handle2, "1111111111111"); //输入游戏密码
PostMessage(handle2, WM_KEYDOWN, 13, 0); //输入ENTER
PostMessage(handle2, WM_KEYUP, 13, 0);
}
/// <summary>
/// 发送一个字符串
/// </summary>
/// <param name="myIntPtr">窗口句柄</param>
/// <param name="Input">字符串</param>
public void InputStr(IntPtr myIntPtr, string Input)
{
byte[] ch = (ASCIIEncoding.ASCII.GetBytes(Input));
for (int i = 0; i < ch.Length; i++)
{
SendMessage(myIntPtr, WM_CHAR, ch[i], 0);
}
}
第三种:具有一定的通用性
IntPtr myIntPtr = FindWindow(null, "QQ游戏");
//获取当前活动窗口的线程句柄
IntPtr threadId1 = GetCurrentThreadId();
//获得指定句柄的线程句柄
IntPtr threadId2 = GetWindowThreadProcessId(myIntPtr, IntPtr.Zero);
//将两个线程的输入队列联系起来,只有这样,GetFocus函数才能获得其它线程中的焦点窗口
AttachThreadInput(threadId2, threadId1, 1);
//得到当前的具有输入焦点的子窗口(控件)的句柄
IntPtr getAccountTextBox = GetFocus();
//将连到一起的两个线程的输入队列分离
AttachThreadInput(threadId2, threadId1, 0);
if (getAccountTextBox != null)
{
Rectangle rc = new Rectangle();
GetWindowRect(getAccountTextBox.ToInt32(), ref rc);
InputStr(getAccountTextBox, "274040246"); //输入游戏ID
SetCursorPos(rc.X + 3, rc.Y + 32); //设置鼠标位置
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
System.Threading.Thread.Sleep(200);//如果账号和密码出现在一个文本框中,则此时间需要设置长
//再次查找拥有输入焦点的文本框句柄
AttachThreadInput(threadId2, threadId1, 1);
IntPtr getPwdTextBox = GetFocus();
AttachThreadInput(threadId2, threadId1, 0);
InputStr(getPwdTextBox, "1111111111111111"); //输入游戏密码
PostMessage(getPwdTextBox, WM_KEYDOWN, 13, 0); //输入ENTER
PostMessage(getPwdTextBox, WM_KEYUP, 13, 0);
}
2。魔兽自动登录一种实现,通过设置窗口大小及位置来做
//查找窗口
[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
//可将最小化窗口还原
[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
//将指定窗口激活
[DllImport("user32.dll ")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
//设置鼠标位置
[DllImport("user32.dll")]
private static extern bool SetCursorPos(int X, int Y);
//设置窗口位置和大小
[DllImport("user32.dll")]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndlnsertAfter, int X, int Y, int cx, int cy, uint Flags);
//模拟鼠标
[DllImport("user32.dll")]
private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
private const int SW_RESTORE = 9; //将窗口还原的参数
private const uint SWP_SHOWWINDOW = 0x0040; //设置窗口位置的参数
private const int MOUSEEVENTF_LEFTDOWN = 0x0002; //模拟鼠标左键按下
private const int MOUSEEVENTF_LEFTUP = 0x0004; //模拟鼠标左键抬起
IntPtr findPtr = FindWindow(null, "World of Warcraft");//World of Warcraft为游戏在任务栏的名称
ShowWindow(findPtr, SW_RESTORE); //将窗口还原
SetForegroundWindow(findPtr);//将指定窗口激活
if (findPtr.ToInt32() != 0)
{
SymmetricMethod sm = new SymmetricMethod();
SetWindowPos(findPtr, (IntPtr)(-1), 0, 0, 700, 550, SWP_SHOWWINDOW);
System.Threading.Thread.Sleep(500);
SetCursorPos(300, 300); //设置鼠标位置
mouse_event(0x0002, 0, 0, 0, 0); //模拟鼠标按下操作
mouse_event(0x0004, 0, 0, 0, 0); //模拟鼠标放开操作
System.Threading.Thread.Sleep(500);
SendKeys.Send(lvInfo.SelectedItems[0].SubItems[1].Text); //模拟键盘输入游戏ID
SendKeys.Send("{TAB}"); //模拟键盘输入TAB
SendKeys.Send(sm.Decrypto(lvInfo.SelectedItems[0].SubItems[2].Text)); //模拟键盘输入游戏密码
SendKeys.Send("{ENTER}"); //模拟键盘输入ENTER
}
else
{
MessageBox.Show("魔兽世界还没有打开!");
}
3。判断当前系统活动窗口是否是指定的窗口
//找到系统当前活动的窗口的句柄
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
//根据任务栏应用程序显示的名称找相应窗口的句柄
[DllImport("User32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
//获取指定句柄窗口的标题
[DllImport("User32.dll")]
static extern int GetWindowText(IntPtr handle, StringBuilder text, int MaxLen);
IntPtr findPtr = FindWindow(null, "QQ游戏");//QQ游戏为在任务栏的名称
StringBuilder text1 = new StringBuilder(50);//按要求找到的进程的标题
StringBuilder text2 = new StringBuilder(50);//当前活动进程的标题
GetWindowText(GetForegroundWindow(), text1, 50);
GetWindowText(findPtr, text2, 50);
if(text1.Equals(text2))
MessageBox.Show("当前活动窗口是指定窗口");
else
MessageBox.Show("当前活动窗口不是指定窗口");
4。设置指定窗口选中(激活)
private const int SW_RESTORE = 9;
[DllImport("user32.dll ")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
IntPtr findPtr = FindWindow(null, "AION Client");//AION Client为游戏在任务栏的名称
if (findPtr.ToInt32() != 0)
{
ShowWindow(findPtr, SW_RESTORE); //将窗口还原,如果不用此方法,缩小的窗口不能激活
SetForegroundWindow(findPtr);//将指定的窗口选中(激活)
}
5。获取指定窗口句柄相对屏幕中的位置
[DllImport("User32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("User32.dll")]
private static extern bool ClientToScreen(IntPtr hwnd, ref Point lpPoint);
IntPtr findPtr = FindWindow(null, "QQ游戏");
Point p = new Point (0);
ClientToScreen(findPtr, ref p);
MessageBox.Show(p.X+","+p.Y);
6。判断指定窗口是否是最大化
[DllImport("User32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
private static extern bool IsZoomed(IntPtr hWnd);
IntPtr findPtr = FindWindow(null, "QQ游戏");
if (IsZoomed(findPtr))
MessageBox.Show("最大化");
else
MessageBox.Show("最小化");
备注:程序中用到的
//设置鼠标位置
[DllImport("user32.dll")]
private static extern bool SetCursorPos(int X, int Y);
//模拟鼠标
[DllImport("user32.dll")]
private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
/// <summary>
/// 查找句柄
/// </summary>
[DllImport("User32.DLL")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
//发送按键消息必用PostMessage,SendMessage有时会不起作用
[DllImport("user32.dll", EntryPoint = "PostMessage", SetLastError = true)]
private extern static bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
//获取指定句柄的相对屏幕的位置和矩形区域
[DllImport("user32")]
public static extern int GetWindowRect(int hwnd, ref Rectangle lpRect);
[DllImport("kernel32")]
public static extern IntPtr GetCurrentThreadId();
[DllImport("user32.dll")]
private static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
[DllImport("user32.dll")]
private static extern IntPtr AttachThreadInput(IntPtr idAttach, IntPtr idAttachTo, int fAttach);
[DllImport("user32.dll")]
private static extern IntPtr GetFocus();
private const int MOUSEEVENTF_LEFTDOWN = 0x0002; //模拟鼠标左键按下参数
private const int MOUSEEVENTF_LEFTUP = 0x0004; //模拟鼠标左键抬起参数
//SendMessage参数
private const int WM_KEYDOWN = 0X100;
private const int WM_KEYUP = 0X101;
private const int WM_SYSCHAR = 0X106;
private const int WM_SYSKEYUP = 0X105;
private const int WM_SYSKEYDOWN = 0X104;
private const int WM_CHAR = 0X102;