前台模拟可以使用 SendInput 函数实现(可以实现 DirectX 级别的窗口模拟)
后台模拟使用 SendMessage 发送消息实现(适合部分窗口)
代码已经充分考虑过各个参数的构造,确保模拟的仿真性,复制粘贴即可使用:
// 构建 LParam 参数
int MakeKeyParam(int vk, int msg, int ext)
{
int iBit0_15 = 1;
int iBit16_23 = MapVirtualKey(vk, 0) << 16;
int iBit24 = ext ? 0x1000000 : 0;
int iBit25_31;
if ( msg == WM_KEYDOWN ) { iBit25_31 = 0x0; }
if ( msg == WM_KEYUP ) { iBit25_31 = 0xC0000000; }
if ( msg == WM_CHAR ) { iBit25_31 = 0x20000000; }
if ( msg == WM_SYSKEYDOWN ) { iBit25_31 = 0x20000000; }
if ( msg == WM_SYSKEYUP ) { iBit25_31 = 0xE0000000; }
if ( msg == WM_SYSCHAR ) { iBit25_31 = 0xE0000000; }
return iBit0_15 | iBit16_23 | iBit24 | iBit25_31;
}
void Key_Down(HWND hWin, int vKey)
{
if ( hWin ) {
SendMessage(hWin, WM_KEYDOWN, vKey, MakeKeyParam(vKey, WM_KEYDOWN, FALSE));
} else {
INPUT ti[1];
memset(ti, 0, sizeof(ti));
ti[0].type = INPUT_KEYBOARD;
ti[0].ki.dwFlags = 0;
ti[0].ki.wVk = vKey;
ti[0].ki.wScan = MapVirtualKey(vKey, 0);
ti[0].ki.time = GetTickCount();
ti[0].ki.dwExtraInfo = GetMessageExtraInfo();
SendInput(1, ti, sizeof(INPUT));
}
}
void Key_Up(HWND hWin, int vKey)
{
if ( hWin ) {
SendMessage(hWin, WM_KEYUP, vKey, MakeKeyParam(vKey, WM_KEYUP, FALSE));
} else {
INPUT ti[1];
memset(ti, 0, sizeof(ti));
ti[0].type = INPUT_KEYBOARD;
ti[0].ki.dwFlags = KEYEVENTF_KEYUP;
ti[0].ki.wVk = vKey;
ti[0].ki.wScan = MapVirtualKey(vKey, 0);
ti[0].ki.time = GetTickCount();
ti[0].ki.dwExtraInfo = GetMessageExtraInfo();
SendInput(1, ti, sizeof(INPUT));
}
}
void Key_Press(HWND hWin, int vKey)
{
if ( hWin ) {
SendMessage(hWin, WM_KEYDOWN, vKey, MakeKeyParam(vKey, WM_KEYDOWN, FALSE));
SendMessage(hWin, WM_KEYUP, vKey, MakeKeyParam(vKey, WM_KEYUP, FALSE));
} else {
INPUT ti[2];
memset(ti, 0, sizeof(ti));
ti[0].type = INPUT_KEYBOARD;
ti[0].ki.dwFlags = 0;
ti[0].ki.wVk = vKey;
ti[0].ki.wScan = MapVirtualKey(vKey, 0);
ti[0].ki.time = GetTickCount();
ti[0].ki.dwExtraInfo = GetMessageExtraInfo();
ti[1].type = INPUT_KEYBOARD;
ti[1].ki.dwFlags = KEYEVENTF_KEYUP;
ti[1].ki.wVk = vKey;
ti[1].ki.wScan = MapVirtualKey(vKey, 0);
ti[1].ki.time = GetTickCount();
ti[1].ki.dwExtraInfo = GetMessageExtraInfo();
SendInput(2, ti, sizeof(INPUT));
}
}
void Mouse_Move(HWND hWin, int x, int y)
{
if ( hWin ) {
SendMessage(hWin, WM_MOUSEMOVE, 0, MAKELONG(x, y));
} else {
INPUT ti[1];
memset(ti, 0, sizeof(ti));
ti[0].type = INPUT_MOUSE;
ti[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
ti[0].mi.dx = ((0xFFFF / (GetSystemMetrics(SM_CXSCREEN) - 1)) * x);
ti[0].mi.dy = ((0xFFFF / (GetSystemMetrics(SM_CYSCREEN) - 1)) * y);
ti[0].mi.time = GetTickCount();
ti[0].mi.dwExtraInfo = GetMessageExtraInfo();
SendInput(1, ti, sizeof(INPUT));
}
}
void Mouse_Whell(HWND hWin, int iVal)
{
if ( hWin ) {
SendMessage(hWin, WM_MOUSEWHEEL, MAKELONG(0, iVal), MAKELONG(0, 0));
} else {
INPUT ti[1];
memset(ti, 0, sizeof(ti));
ti[0].type = INPUT_MOUSE;
ti[0].mi.dwFlags = MOUSEEVENTF_WHEEL;
ti[0].mi.mouseData = iVal;
ti[0].mi.time = GetTickCount();
ti[0].mi.dwExtraInfo = GetMessageExtraInfo();
SendInput(1, ti, sizeof(INPUT));
}
}
void Mouse_Down(HWND hWin, int x, int y, int iBtn)
{
if ( hWin ) {
if ( iBtn == 1 ) {
SendMessage(hWin, WM_RBUTTONDOWN, 0, MAKELONG(x, y));
} else if ( iBtn == 2 ) {
SendMessage(hWin, WM_MBUTTONDOWN, 0, MAKELONG(x, y));
} else {
SendMessage(hWin, WM_LBUTTONDOWN, 0, MAKELONG(x, y));
}
} else {
Mouse_Move(NULL, x, y);
INPUT ti[1];
memset(ti, 0, sizeof(ti));
ti[0].type = INPUT_MOUSE;
if ( iBtn == 1 ) {
ti[0].mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;
} else if ( iBtn == 2 ) {
ti[0].mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;
} else {
ti[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
}
ti[0].mi.time = GetTickCount();
ti[0].mi.dwExtraInfo = GetMessageExtraInfo();
SendInput(1, ti, sizeof(INPUT));
}
}
void Mouse_Up(HWND hWin, int x, int y, int iBtn)
{
if ( hWin ) {
if ( iBtn == 1 ) {
SendMessage(hWin, WM_RBUTTONUP, 0, MAKELONG(x, y));
} else if ( iBtn == 2 ) {
SendMessage(hWin, WM_MBUTTONUP, 0, MAKELONG(x, y));
} else {
SendMessage(hWin, WM_LBUTTONUP, 0, MAKELONG(x, y));
}
} else {
Mouse_Move(NULL, x, y);
INPUT ti[1];
memset(ti, 0, sizeof(ti));
ti[0].type = INPUT_MOUSE;
if ( iBtn == 1 ) {
ti[0].mi.dwFlags = MOUSEEVENTF_RIGHTUP;
} else if ( iBtn == 2 ) {
ti[0].mi.dwFlags = MOUSEEVENTF_MIDDLEUP;
} else {
ti[0].mi.dwFlags = MOUSEEVENTF_LEFTUP;
}
ti[0].mi.time = GetTickCount();
ti[0].mi.dwExtraInfo = GetMessageExtraInfo();
SendInput(1, ti, sizeof(INPUT));
}
}
void Mouse_Click(HWND hWin, int x, int y, int iBtn)
{
if ( hWin ) {
if ( iBtn == 1 ) {
SendMessage(hWin, WM_RBUTTONDOWN, 0, MAKELONG(x, y));
SendMessage(hWin, WM_RBUTTONUP, 0, MAKELONG(x, y));
} else if ( iBtn == 2 ) {
SendMessage(hWin, WM_MBUTTONDOWN, 0, MAKELONG(x, y));
SendMessage(hWin, WM_MBUTTONUP, 0, MAKELONG(x, y));
} else {
SendMessage(hWin, WM_LBUTTONDOWN, 0, MAKELONG(x, y));
SendMessage(hWin, WM_LBUTTONUP, 0, MAKELONG(x, y));
}
} else {
Mouse_Move(NULL, x, y);
INPUT ti[2];
memset(ti, 0, sizeof(ti));
ti[0].type = INPUT_MOUSE;
ti[1].type = INPUT_MOUSE;
if ( iBtn == 1 ) {
ti[0].mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;
ti[1].mi.dwFlags = MOUSEEVENTF_RIGHTUP;
} else if ( iBtn == 2 ) {
ti[0].mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;
ti[1].mi.dwFlags = MOUSEEVENTF_MIDDLEUP;
} else {
ti[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
ti[1].mi.dwFlags = MOUSEEVENTF_LEFTUP;
}
ti[0].mi.time = GetTickCount();
ti[1].mi.time = GetTickCount();
ti[0].mi.dwExtraInfo = GetMessageExtraInfo();
ti[1].mi.dwExtraInfo = GetMessageExtraInfo();
SendInput(2, ti, sizeof(INPUT));
}
}