This tool will listen for ASUS notebook's FN keystrokes. And it will map ROG key to Scroll Lock and Fan key to Num Lock. (Ctrl + Num Lock = Pause key).
$ clang main.cpp -o rog.exe && rog.exe
// Introduce some shit (a.k.a. winapi) | |
#define UNICODE | |
#include <windows.h> | |
#pragma comment(lib, "user32") | |
// #include <fcntl.h> | |
#define _O_U16TEXT 0x00020000 | |
#define _O_U8TEXT 0x00040000 | |
#include <io.h> | |
#include <stdio.h> | |
enum ASUSKEYS : UINT { | |
ROG_KEY = 56, | |
FN_F10 = 107, | |
MUTE = 124, | |
FN_V = 138, | |
FN_C = 158, | |
FN_F5 = 174, | |
FN_LEFT = 178, | |
FN_RIGHT = 179, | |
FN_UP = 196, | |
FN_DOWN = 197, | |
// Aliases | |
FAN_KEY = FN_F5, | |
}; | |
const wchar_t pClassName[] = L"ROGKeyRebind"; | |
const wchar_t pWindowName[] = L"ROGKeyRebind"; | |
UINT pAPCI = RegisterWindowMessageW(L"ACPI Notification through ATKHotkey from BIOS"); | |
void SendScanCode(WORD scancode) { | |
INPUT ip; | |
ip.type = INPUT_KEYBOARD; | |
ip.ki.time = 0; | |
ip.ki.wVk = 0; | |
ip.ki.dwExtraInfo = 0; | |
ip.ki.dwFlags = KEYEVENTF_SCANCODE; | |
ip.ki.wScan = scancode; | |
SendInput(1, &ip, sizeof(INPUT)); | |
ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP; | |
SendInput(1, &ip, sizeof(INPUT)); | |
return; | |
} | |
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { | |
if (uMsg == pAPCI) { | |
switch (wParam) { | |
case ASUSKEYS::MUTE: | |
wprintf(L"Mute key\n"); | |
break; | |
case ASUSKEYS::FAN_KEY: | |
wprintf(L"Fan key\n"); | |
SendScanCode(0x45); // Send NumLock | |
break; | |
case ASUSKEYS::ROG_KEY: | |
wprintf(L"ROG key\n"); | |
SendScanCode(0x46); // Send ScrollLock | |
break; | |
case ASUSKEYS::FN_F10: | |
wprintf(L"Fn + 10 key\n"); | |
break; | |
case ASUSKEYS::FN_C: | |
wprintf(L"Fn + C key\n"); | |
break; | |
case ASUSKEYS::FN_V: | |
wprintf(L"Fn + V key\n"); | |
break; | |
case ASUSKEYS::FN_UP: | |
wprintf(L"Fn + Up Arrow key\n"); | |
break; | |
case ASUSKEYS::FN_LEFT: | |
wprintf(L"Fn + Left Arrow key\n"); | |
break; | |
case ASUSKEYS::FN_DOWN: | |
wprintf(L"Fn + Down Arrow key\n"); | |
break; | |
case ASUSKEYS::FN_RIGHT: | |
wprintf(L"Fn + Right Arrow key\n"); | |
break; | |
default: | |
wprintf(L"Unknown key: %d\n", wParam); | |
break; | |
} | |
} else { | |
switch (uMsg) { | |
case WM_DESTROY: | |
wprintf(L"Error window destroyed. Shutting down.\n"); | |
PostQuitMessage(0); | |
ExitProcess(4); | |
break; | |
default: | |
break; | |
} | |
} | |
return DefWindowProcW(hWnd, uMsg, wParam, lParam); | |
} | |
int main() { | |
_setmode(_fileno(stdout), _O_U16TEXT); | |
HMODULE hInst = GetModuleHandleW(nullptr); | |
if (hInst == 0) { | |
wprintf(L"Error getting module.\n"); | |
return 2; | |
} | |
WNDCLASSEXW wc = {}; | |
wc.lpfnWndProc = MainWndProc; | |
wc.hInstance = hInst; | |
wc.lpszClassName = pWindowName; | |
wc.cbSize = sizeof(wc); | |
RegisterClassEx(&wc); | |
HWND hWnd = CreateWindowExW( | |
0, | |
wc.lpszClassName, | |
pWindowName, | |
WS_VISIBLE, | |
-1, -1, 1, 1, | |
nullptr, | |
nullptr, | |
hInst, | |
nullptr | |
); | |
if (hWnd == 0) { | |
wprintf(L"Error spawning window.\n"); | |
return 3; | |
} | |
ShowWindow(hWnd, SW_HIDE); | |
ChangeWindowMessageFilterEx( | |
hWnd, | |
pAPCI, | |
MSGFLT_ALLOW, | |
nullptr | |
); | |
wprintf(L"Listening for keys.\n"); | |
MSG msg; | |
int bRet = -1; | |
while ((bRet = GetMessageW(&msg, hWnd, 0, 0)) != 0) { | |
if (bRet < 0) { | |
wprintf(L"Unknown error while getting message."); | |
return 1; | |
} else { | |
TranslateMessage(&msg); | |
DispatchMessage(&msg); | |
} | |
} | |
wprintf(L"Shutting down.\n"); | |
return 0; | |
} |