Low-level Windows rapid-fire input simulator written in C++17.
A C++ rewrite of the Python HyperClicker. Sends keyboard / mouse input via
SendInput using hardware scan codes only (KEYEVENTF_SCANCODE,
wVk = 0), which is the closest software approximation to real keyboard
hardware that user-mode code can produce. Most games and applications that
filter "high-level" key events accept it.
- Two independent build targets:
HyperClickerGUI.exe— native Win32 dark-themed GUI (default).HyperClickerCPP.exe— line-based console for headless / scripted use.
- Per-key threads — each bound key gets its own firing loop, so binds fire genuinely in parallel (hold Shift + Left-Click both bound and they rapid-fire independently).
- Decoupled press / release timing — separate sliders for "how long the key is held down" and "the gap between presses". CPS shown as a derived value. Useful when a game samples input at 60 Hz and needs a longer press to register.
- Random ±5 % jitter on each press and release.
- Persistence —
hyperclicker.cfgnext to the .exe. Saved on every bind change, slider drag, hotkey change, and on exit. - Global toggle hotkey (default F6, configurable).
- Clean shutdown — Ctrl+C, window-close, X-button, log-off, and shutdown all release any held keys before the process dies.
- Static CRT — single .exe, no MSVC redistributable required.
┌────────────────────────────────────────────────────────────────────┐
│ main.cpp / gui_main.cpp console & native Win32 GUI │
└──────┬─────────────────────────────────────────────────────────────┘
│
┌──────▼──────────┐ ┌───────────────────┐ ┌─────────────┐
│ MacroEngine │───▶│ HookManager │───▶│ Win32 hooks│
│ per-key threads│ │ WH_KEYBOARD_LL │ │ │
│ jitter, toggle │ │ WH_MOUSE_LL │ └─────────────┘
└──────┬──────────┘ └───────────────────┘
│
┌──────▼──────────┐ ┌─────────────┐ ┌─────────────────┐
│ InputSimulator │───▶│ SendInput │ │ ConfigManager │
│ scan-code only │ │ │ │ load / save │
└─────────────────┘ └─────────────┘ └─────────────────┘
| File | Role |
|---|---|
src/main.cpp |
Console UI, Ctrl-handler, lifecycle. |
src/gui_main.cpp |
Win32 GUI. Custom-painted dark theme, sliders, key list. |
src/MacroEngine.* |
Bind tracking, per-key firing threads, capture mode. |
src/HookManager.* |
Owns the WH_KEYBOARD_LL / WH_MOUSE_LL hooks. |
src/InputSimulator.* |
Wraps SendInput with scan-code-only keyboard events. |
src/KeyMap.* |
VK ↔ scan-code, extended-key set, display names. |
src/ConfigManager.* |
Load / save plain-text settings file. |
Three choices that matter:
-
wVk = 0+KEYEVENTF_SCANCODE— tells Windows "I'm giving you a raw hardware scan code, not a virtual key. Translate it like the keyboard driver would." The resultingWM_KEYDOWN/WM_KEYUPcarries a real scan code inlParambits 16–23; DirectInput-based games read that directly. -
MapVirtualKeyW(vk, MAPVK_VK_TO_VSC_EX)instead of the legacyMAPVK_VK_TO_VSC. The_EXvariant preserves the left/right distinction for modifier keys (Right-Shift =0x36, not generic Shift =0x2A). -
KEYEVENTF_EXTENDEDKEYfor the keys whose scan codes are prefixed with0xE0on a real PS/2 keyboard: arrow block, Right-Ctrl, Right-Alt, Win keys, Apps key, Numpad-/, NumLock, ScrollLock, PrintScreen. Without this flag, e.g. an Up-Arrow would be indistinguishable from Numpad-8 in scan-code mode.
// InputSimulator.cpp – the entire keyboard send path.
INPUT in = {};
in.type = INPUT_KEYBOARD;
in.ki.wVk = 0; // MUST be 0 with SCANCODE
in.ki.wScan = scanCode;
in.ki.dwFlags = KEYEVENTF_SCANCODE;
if (extended) in.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
if (!keyDown) in.ki.dwFlags |= KEYEVENTF_KEYUP;
SendInput(1, &in, sizeof(INPUT));Anti-cheat systems that look at the LLKHF_INJECTED bit in the low-level
hook data may detect this as injected input — that bit is set by
Windows itself the moment a SendInput call enters the input queue,
regardless of how cleanly the event is constructed.
In practice the scan-code path passes through far more games than the high-level (virtual-key) path does — confirmed working against Notepad, Firefox, Geometry Dash, and Roblox. Anything stricter than that needs a kernel driver or external HID hardware.
See BUILD.md for the exact CMake commands.
Quick version (from a Developer-Tools-aware shell at the repo root):
cmake -S . -B build -G "Visual Studio 17 2022" -A x64
cmake --build build --config ReleaseOutputs:
build\bin\HyperClickerGUI.exe
build\bin\HyperClickerCPP.exe
- Run
build\bin\HyperClickerGUI.exe. - The window starts with SPACE pre-bound. Press F6 → status badge flips to ON. Hold SPACE — Notepad fills with spaces.
- Click
+ Add Mouse → Left Clickto also rapid-fire left-click while the left button is held. - Drag the Press and Release sliders to tune timing. The
~CPSreadout updates live. Saves to disk on release. - Close the window — keys are released, settings are persisted.
help Show command list
status Show current state
list List bound keys
on / off Manually enable / disable
cps <1-1000> Splits press/release evenly to that rate
press <1-500> Override press duration (ms)
release <1-500> Override release gap (ms)
add Add a keyboard bind (then press a key)
addmouse <l|r|m> Add Left / Right / Middle mouse bind
remove <id> Remove a bind (e.g. `remove kb:32`)
toggle Change toggle hotkey
save Save settings to hyperclicker.cfg
quit / exit Clean shutdown (also auto-saves)
MIT.