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

Commit

Permalink
Small refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
erryox committed Aug 22, 2021
1 parent 0699e9c commit e2b17c8
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 59 deletions.
10 changes: 5 additions & 5 deletions Switchy/Switchy.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,26 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
Expand Down Expand Up @@ -132,7 +132,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="main.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
Expand Down
2 changes: 1 addition & 1 deletion Switchy/Switchy.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<ClCompile Include="main.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
Expand Down
127 changes: 74 additions & 53 deletions Switchy/main.cpp → Switchy/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,67 @@

typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);

typedef struct {
BOOL popup;
BYTE modifier;
} Settings;

void ShowError(LPCSTR message);
DWORD GetOSVersion();
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);


HHOOK hHook;
bool popup;
bool modifier;
bool wasPressed = false;
bool modifierPressed = false;
BOOL modifier;
BOOL processed = FALSE;
BOOL winPressed = FALSE;

Settings settings = {
.popup = FALSE,
.modifier = VK_LSHIFT
};


int main(int argc, char** argv) {
if (argc > 1 && argv[1] == "nopopup") {
settings.popup = FALSE;
} else {
settings.popup = GetOSVersion() >= 10;
}

HANDLE hMutex = CreateMutex(0, 0, "Switchy");
if (GetLastError() == ERROR_ALREADY_EXISTS) {
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\"");
return 1;
}

void ShowError(LPCSTR s) {
MessageBox(NULL, s, "Error", MB_OK | MB_ICONERROR);
MSG messages;
while (GetMessage(&messages, NULL, 0, 0)) {
TranslateMessage(&messages);
DispatchMessage(&messages);
}

return 0;
}


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


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

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

if (p) {
osvi.dwOSVersionInfoSize = sizeof(osvi);
Expand All @@ -28,75 +73,51 @@ DWORD GetOSVersion() {
return osvi.dwMajorVersion;
}


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

if (p->vkCode == VK_CAPITAL) {
if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) {
if (GetKeyState(VK_LSHIFT) & 0x8000) {
if (key->vkCode == VK_CAPITAL) {
if (wParam == WM_KEYDOWN) {
if (GetKeyState(settings.modifier)) {
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;
}
else if (!processed) {
processed = TRUE;

if (!wasPressed) {
wasPressed = true;

if (popup) {
if (settings.popup) {
keybd_event(VK_LWIN, 0x3a, 0, 0);
keybd_event(VK_SPACE, 0x3a, 0, 0);
} else {
keybd_event(VK_SPACE, 0x3a, KEYEVENTF_KEYUP, 0);
winPressed = TRUE;
}
else {
HWND hWnd = GetForegroundWindow();
if (hWnd) {
hWnd = GetAncestor(hWnd, GA_ROOTOWNER);
PostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST, 0, (LPARAM)HKL_NEXT);
}
}

return 1;
}
}
else if (wParam == WM_KEYUP) {
processed = FALSE;

if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP) {
wasPressed = false;

if (popup) {
if (winPressed) {
keybd_event(VK_LWIN, 0x3a, KEYEVENTF_KEYUP, 0);
keybd_event(VK_SPACE, 0x3a, KEYEVENTF_KEYUP, 0);
}
}

return 1;
return 1;
}
}
}

return CallNextHookEx(hHook, nCode, wParam, lParam);
}

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

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

hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, 0, 0);
if (hHook == nullptr) {
ShowError("Error with \"SetWindowsHookEx\"");
return 1;
}

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

return 0;
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}

0 comments on commit e2b17c8

Please sign in to comment.