Skip to content

Instantly share code, notes, and snippets.

@lhecker

lhecker/main.cpp Secret

Last active November 20, 2023 14:26
Show Gist options
  • Save lhecker/43e562d5a1370d2582bb5d6eed4e4f3e to your computer and use it in GitHub Desktop.
Save lhecker/43e562d5a1370d2582bb5d6eed4e4f3e to your computer and use it in GitHub Desktop.
print INPUT_RECORD
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <cstdio>
// wprintf() in the uCRT prints every single wchar_t individually and thus breaks surrogate
// pairs apart which Windows Terminal treats as invalid input and replaces it with U+FFFD.
static void printfUTF16(const _In_z_ _Printf_format_string_ wchar_t* const format, ...) {
wchar_t buffer[512];
va_list args;
va_start(args, format);
const auto length = _vsnwprintf_s(&buffer[0], 512, _TRUNCATE, format, args);
va_end(args);
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), &buffer[0], length, nullptr, nullptr);
}
static wchar_t visualize(wchar_t ch) {
if (ch < 0x20) {
ch += 0x2400;
} else if (ch == 0x20) {
ch = 0x2423; // ␣
} else if (ch == 0x7f) {
ch = 0x2421; // ␡
}
return ch;
}
static void printInputRecord(const INPUT_RECORD& r) noexcept {
switch (r.EventType) {
case KEY_EVENT:
printfUTF16(
L"{\n"
" .EventType = KEY_EVENT,\n"
" .Event = {\n"
" .KeyEvent = {\n"
" .bKeyDown = %d,\n"
" .wRepeatCount = %d,\n"
" .wVirtualKeyCode = %d,\n"
" .wVirtualScanCode = %d,\n"
" .uChar.UnicodeChar = %04x, // %c\n"
" .dwControlKeyState = %d,\n"
" },\n"
" },\n"
"}\n",
r.Event.KeyEvent.bKeyDown,
r.Event.KeyEvent.wRepeatCount,
r.Event.KeyEvent.wVirtualKeyCode,
r.Event.KeyEvent.wVirtualScanCode,
r.Event.KeyEvent.uChar.UnicodeChar,
visualize(r.Event.KeyEvent.uChar.UnicodeChar),
r.Event.KeyEvent.dwControlKeyState
);
break;
case MOUSE_EVENT:
printfUTF16(
L"{\n"
" .EventType = MOUSE_EVENT,\n"
" .Event = {\n"
" .MouseEvent = {\n"
" .dwMousePosition = { .X = %d, .Y = %d },\n"
" .dwButtonState = %d,\n"
" .dwControlKeyState = %d,\n"
" .dwEventFlags = %d,\n"
" },\n"
" },\n"
"}\n",
r.Event.MouseEvent.dwMousePosition.X,
r.Event.MouseEvent.dwMousePosition.Y,
r.Event.MouseEvent.dwButtonState,
r.Event.MouseEvent.dwControlKeyState,
r.Event.MouseEvent.dwEventFlags
);
break;
case WINDOW_BUFFER_SIZE_EVENT:
printfUTF16(
L"{\n"
" .EventType = WINDOW_BUFFER_SIZE_EVENT,\n"
" .Event = {\n"
" .WindowBufferSizeEvent = {\n"
" .dwSize = { .X = %d, .Y = %d },\n"
" },\n"
" },\n"
"}\n",
r.Event.WindowBufferSizeEvent.dwSize.X,
r.Event.WindowBufferSizeEvent.dwSize.Y
);
break;
case MENU_EVENT:
printfUTF16(
L"{\n"
" .EventType = MENU_EVENT,\n"
" .Event = {\n"
" .MenuEvent = {\n"
" .dwCommandId = %d,\n"
" },\n"
" },\n"
"}\n",
r.Event.MenuEvent.dwCommandId
);
break;
case FOCUS_EVENT:
printfUTF16(
L"{\n"
" .EventType = FOCUS_EVENT,\n"
" .Event = {\n"
" .FocusEvent = {\n"
" .bSetFocus = %d,\n"
" },\n"
" },\n"
"}\n",
r.Event.FocusEvent.bSetFocus
);
break;
default:
printfUTF16(
L"{\n"
" .EventType = %d,\n"
" .Event = ?,\n"
"}\n",
r.EventType
);
break;
}
}
int main() {
for (;;) {
INPUT_RECORD records[16];
DWORD read = 0;
if (!ReadConsoleInputW(GetStdHandle(STD_INPUT_HANDLE), &records[0], 16, &read) || !read) {
break;
}
for (DWORD i = 0; i < read; ++i) {
printInputRecord(records[i]);
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment