Skip to content
This repository has been archived by the owner on Sep 3, 2024. It is now read-only.

Commit

Permalink
Change the CapsLock state by pressing Shift+CapsLock
Browse files Browse the repository at this point in the history
  • Loading branch information
erryox committed Jan 19, 2020
1 parent 099f575 commit cc86364
Showing 1 changed file with 33 additions and 36 deletions.
69 changes: 33 additions & 36 deletions Switchy/main.cpp
Original file line number Diff line number Diff line change
@@ -1,29 +1,51 @@
#include <iostream>
#include <Windows.h>

typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);

HHOOK hHook = 0;
bool showPopup = false;
HHOOK hHook;
bool popup;
bool modifier;
bool wasPressed = false;
bool modifierPressed = false;

void ShowError(LPCSTR s) {
MessageBox(NULL, s, "Error", MB_OK | MB_ICONERROR);
}

DWORD GetOSVersion() {
HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll");
RTL_OSVERSIONINFOW osvi = { 0 };

if (hMod) {
RtlGetVersionPtr p = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion");

if (p) {
osvi.dwOSVersionInfoSize = sizeof(osvi);
p(&osvi);
}
}

return osvi.dwMajorVersion;
}

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode == HC_ACTION) {
KBDLLHOOKSTRUCT* p = (KBDLLHOOKSTRUCT*)lParam;

if (p->vkCode == VK_CAPITAL) {
if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) {
if (GetKeyState(VK_CAPITAL)) {
if (GetKeyState(VK_LSHIFT) & 0x8000) {
UnhookWindowsHookEx(hHook);
keybd_event(VK_CAPITAL, 0x3a, 0, 0);
keybd_event(VK_CAPITAL, 0x3a, KEYEVENTF_KEYUP, 0);
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, 0, 0);
return 1;
}

if (!wasPressed) {
wasPressed = true;

if (showPopup) {
if (popup) {
keybd_event(VK_LWIN, 0x3a, 0, 0);
keybd_event(VK_SPACE, 0x3a, 0, 0);
} else {
Expand All @@ -39,7 +61,7 @@ LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP) {
wasPressed = false;

if (showPopup) {
if (popup) {
keybd_event(VK_LWIN, 0x3a, KEYEVENTF_KEYUP, 0);
keybd_event(VK_SPACE, 0x3a, KEYEVENTF_KEYUP, 0);
}
Expand All @@ -52,54 +74,29 @@ LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
return CallNextHookEx(hHook, nCode, wParam, lParam);
}

void ShowError(LPCSTR s) {
MessageBox(NULL, s, "Error", MB_OK | MB_ICONERROR);
}

DWORD GetOSVersion() {
HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll");
RTL_OSVERSIONINFOW osvi = { 0 };

if (hMod) {
RtlGetVersionPtr p = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion");

if (p) {
osvi.dwOSVersionInfoSize = sizeof(osvi);
p(&osvi);
}
}

return osvi.dwMajorVersion;
}

int main(int argc, char* argv[]) {
showPopup = GetOSVersion() >= 10;
popup = GetOSVersion() >= 10;
if (argc > 1) {
if (_stricmp("nopopup", argv[1]) == 0)
showPopup = false;
if (argv[1] != "nopopup") popup = false;
}

HANDLE hMutex = CreateMutex(0, 0, "Switchy");

if (GetLastError() == ERROR_ALREADY_EXISTS) {
ShowError("Another instance is already running!");
ShowError("Another instance of Switchy is already running!");
return 1;
}

hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, 0, 0);

if (hHook == NULL) {
ShowError("Error with SetWindowsHookEx()");
if (hHook == nullptr) {
ShowError("Error with \"SetWindowsHookEx\"");
return 1;
}

MSG messages;

while (GetMessage(&messages, NULL, 0, 0)) {
TranslateMessage(&messages);
DispatchMessage(&messages);
}

UnhookWindowsHookEx(hHook);
return 0;
}

0 comments on commit cc86364

Please sign in to comment.