前台模拟可以使用 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)); } }