相信经常上VS对战平台玩游戏的朋友都曾有过下面这样的经历

过程非常痛苦!!!怎么办?难道花钱充VIP?做个RMB玩家固然感觉非常好,但stalker还是个学生,没有收入,把父母的血汗钱花到游戏上,实在不忍心。
于是想到用按键精灵写一个脚本,虽然能代替手工操作,但生成小精灵广告频弹,非常不爽。stalker一直很讨厌广告,并不是因为广告烦人,而是因为自己没有钱购买广告中的商品
恰好最近正在学习C++程序设计,于是打算自己动手开发一个程序,取代那令人纠结的小精灵。
首先我设计了一个类,如下
//SimulatingActions.h
class SimulatingActions
{
public:
void MouseDown(bool bLeftRight);
void MouseUp(bool bLeftRight);
void MouseClick(bool bLeftRight);
void MouseDbClick(bool bLeftRight);
void KeyDown(char vKey);
void KeyUp(char vKey);
void KeyHit(char vKey);
};
前四个成员函数,分别模拟鼠标按键的按下,弹起,单击和双击动作,参数bLeftRight用于指示模拟左键还是右键动作(设计时没有考虑滚轮^_^)。
后三个成员函数,分别模拟键盘键的按下,弹起和击键动作(stalker对击键动作的定义是:键被按下并弹起),参数vKey用于指定具体的键。
设计完成之后,就剩下具体的实现,众所周知,模拟鼠标和键盘动作可以用Windows API mouse_event,keybd_event和SendInput。由于前面两个函数比较古老,stalker选择了二者功能兼备的SendInput。
具体代码如下,由于本人初学C++,编码可能有很多不好的地方,还希望大家能多指教!
//SimulatingActions.cpp
#define _WIN32_WINNT 0x0500
#include<windows.h>
#include"SimulatingActions.h"
void SimulatingActions::MouseDown(bool bLeftRight)
{
INPUT myinput;
MOUSEINPUT mymi;
POINT mypoint;
GetCursorPos(&mypoint);
mymi.dx = mypoint.x;
mymi.dy = mypoint.y;
mymi.mouseData = 0;
mymi.dwFlags = MOUSEEVENTF_LEFTDOWN;
mymi.time = 0;
mymi.dwExtraInfo = GetMessageExtraInfo();
if(bLeftRight)
mymi.dwFlags = MOUSEEVENTF_RIGHTDOWN;
myinput.type = INPUT_MOUSE;
myinput.mi = mymi;
SendInput(1,&myinput,sizeof(INPUT));
}
void SimulatingActions::MouseUp(bool bLeftRight)
{
INPUT myinput;
MOUSEINPUT mymi;
POINT mypoint;
GetCursorPos(&mypoint);
mymi.dx = mypoint.x;
mymi.dy = mypoint.y;
mymi.mouseData = 0;
mymi.dwFlags = MOUSEEVENTF_LEFTUP;
mymi.time = 0;
mymi.dwExtraInfo = GetMessageExtraInfo();
if(bLeftRight)
mymi.dwFlags = MOUSEEVENTF_RIGHTUP;
myinput.type = INPUT_MOUSE;
myinput.mi = mymi;
SendInput(1,&myinput,sizeof(INPUT));
}
void SimulatingActions::MouseClick(bool bLeftRight)
{
MouseDown(bLeftRight);
MouseUp(bLeftRight);
}
void SimulatingActions::MouseDbClick(bool bLeftRight)
{
MouseClick(bLeftRight);
MouseClick(bLeftRight);
}
void SimulatingActions::KeyDown(char vKey)
{
INPUT myinput;
KEYBDINPUT myki;
myki.wVk = vKey;
myki.wScan = MapVirtualKey(vKey,0);
myki.dwFlags = KEYEVENTF_EXTENDEDKEY;
myki.time = 0;
myki.dwExtraInfo = GetMessageExtraInfo();
myinput.type = INPUT_KEYBOARD;
myinput.ki = myki;
SendInput(1,&myinput,sizeof(INPUT));
}
void SimulatingActions::KeyUp(char vKey)
{
INPUT myinput;
KEYBDINPUT myki;
myki.wVk = vKey;
myki.wScan = MapVirtualKey(vKey,0);
myki.dwFlags = KEYEVENTF_KEYUP;
myki.time = 0;
myki.dwExtraInfo = GetMessageExtraInfo();
myinput.type = INPUT_KEYBOARD;
myinput.ki = myki;
SendInput(1,&myinput,sizeof(INPUT));
}
void SimulatingActions::KeyHit(char vKey)
{
KeyDown(vKey);
KeyUp(vKey);
}
关闭弹出来的人满对话框,有三种方法:
1.按ESC键
2.按ALT+F4组合键
3.移动鼠标点对话框右上角的X
其中方法3最难,我选择了最简单的方法1
最后的主程序如下
#include<windows.h>
#include"SimulatingActions.h"
DWORD WINAPI ThreadProc(LPVOID lpParameter);
int WINAPI WinMain(HINSTANCE a,HINSTANCE b,LPSTR c,int d)
{
bool bSwitch = true;
SHORT s1,s2,s3;
HANDLE hThread,hMutex;
//判断程序是否已经运行,如果已经运行则退出
CreateMutex(NULL,false,"specialmutexofstalker");
if(ERROR_ALREADY_EXISTS == GetLastError())
{
MessageBox(NULL,"Program already run!","Information",MB_ICONERROR);
ExitProcess(0);
}
while(true)
{
s1 = GetKeyState(VK_CONTROL);
s1 >>= (sizeof(SHORT)*8 - 1);
s2 = GetKeyState(VK_SHIFT);
s2 >>= (sizeof(SHORT)*8 - 1);
s3 = GetKeyState('Q');
s3 >>= (sizeof(SHORT)*8 - 1);
//Ctrl+Shift+Q被按下,则退出程序
if(s1&&s2&&s3)
ExitProcess(0);
s1 = GetKeyState(VK_CONTROL);
s2 = GetKeyState('P');
s1 >>= (sizeof(SHORT)*8 - 1);
s2 >>= (sizeof(SHORT)*8 - 1);
//Ctrl+P被按下,停止动作 ,并设置bSwitch为true,
//否则程序将不能再创建模拟动作线程
if(s1&&s2&&(!bSwitch))
{
TerminateThread(hThread,0);
bSwitch = true;
}
s1 = GetKeyState(VK_CONTROL);
s2 = GetKeyState('S');
s1 >>= (sizeof(SHORT)*8 - 1);
s2 >>= (sizeof(SHORT)*8 - 1);
//Ctrl+S被按下,开始动作,并设置bSwitch为false,
//防止程序创建多个线程
if(s1&&s2&&bSwitch)
{
hThread = CreateThread(NULL,0,&ThreadProc,NULL,0,NULL);
if(NULL != hThread)
bSwitch = false;
}
Sleep(100);
}
return 0;
}
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
SimulatingActions mySA;
while(true)
{
mySA.MouseDbClick(0);
Sleep(500);
mySA.KeyHit(VK_ESCAPE);
}
}

附件中有整个工程以及编译好的可执行文件
本程序使用Dev-C++开发




