diff --git a/.github/workflows/snapkey.yml b/.github/workflows/snapkey.yml deleted file mode 100644 index 7a05ac3..0000000 --- a/.github/workflows/snapkey.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: C/C++ CI - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - -jobs: - build: - runs-on: windows-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Cache MinGW - uses: actions/cache@v3 - with: - path: C:\tools\mingw64 - key: mingw-${{ runner.os }}-${{ hashFiles('**/SnapKey.cpp', '**/resources.rc') }} - restore-keys: | - mingw-${{ runner.os }}- - - - name: Install MinGW - if: steps.cache.outputs.cache-hit != 'true' - run: choco install mingw - - - name: Add MinGW to Path - run: echo "C:\tools\mingw64\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding ascii -Append - - - name: Compile resource file - run: windres resources.rc -o resources.o - - - name: Compile the executable - run: g++ -o SnapKey SnapKey.cpp resources.o -mwindows -static -static-libgcc -static-libstdc++ - - - name: Upload executable - uses: actions/upload-artifact@v4 - with: - name: SnapKey-executable - path: SnapKey.exe - - - name: Run executable - run: .\SnapKey.exe - if: always() diff --git a/Build SnapKey/CMAKE-Build/CMake-Build.bat b/Build SnapKey/CMAKE-Build/CMake-Build.bat deleted file mode 100644 index def6cc2..0000000 --- a/Build SnapKey/CMAKE-Build/CMake-Build.bat +++ /dev/null @@ -1,14 +0,0 @@ -@echo off - -mkdir build > nul -cd build > nul -echo [+] Preparing files... -cmake .. > nul -echo [+] Compiling... -cmake --build . > nul -cd .. > nul -move "build\Debug\SnapKey.exe" "." > nul -echo [+] Done! -rmdir /s /q build > nul -echo [+] Press a key to exit... -pause > nul \ No newline at end of file diff --git a/Build SnapKey/CMAKE-Build/CMakeLists.txt b/Build SnapKey/CMAKE-Build/CMakeLists.txt deleted file mode 100644 index 4efd636..0000000 --- a/Build SnapKey/CMAKE-Build/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -cmake_minimum_required(VERSION 3.12) -project(SnapKey) - -# include_directories(${CMAKE_CURRENT_SOURCE_DIR}) --- unnecessary - -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") -set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT") -set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd") -set(BUILD_SHARED_LIBS OFF) - -add_executable(SnapKey SnapKey.cpp resources.rc) - -if (WIN32) - set_target_properties(SnapKey PROPERTIES - LINK_FLAGS "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup" - ) -endif() \ No newline at end of file diff --git a/Build SnapKey/CMAKE-Build/resources.rc b/Build SnapKey/CMAKE-Build/resources.rc deleted file mode 100644 index 24e6d51..0000000 --- a/Build SnapKey/CMAKE-Build/resources.rc +++ /dev/null @@ -1 +0,0 @@ -IDI_ICON1 ICON "snapkey.ico" \ No newline at end of file diff --git a/Build SnapKey/MSYS-Build/MSYS-Build.bat b/Build SnapKey/MSYS-Build/MSYS-Build.bat deleted file mode 100644 index bf1d02d..0000000 --- a/Build SnapKey/MSYS-Build/MSYS-Build.bat +++ /dev/null @@ -1,20 +0,0 @@ - -@echo off -setlocal - -echo Compiling SnapKey... - - -REM Get the directory of the batch file -set "SCRIPT_DIR=%~dp0" - -REM Set the path to your MSYS2 installation -set "MSYS2_PATH=C:\msys64\usr\bin\bash.exe" - -REM Run the MSYS2 shell to compile the program -"%MSYS2_PATH%" -c "cd '%SCRIPT_DIR%' && ./MSYS-Build.sh" - -REM Pause to keep the command window open -pause - -endlocal diff --git a/Build SnapKey/MSYS-Build/MSYS-Build.sh b/Build SnapKey/MSYS-Build/MSYS-Build.sh deleted file mode 100644 index 0c5496f..0000000 --- a/Build SnapKey/MSYS-Build/MSYS-Build.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -# MSYS path -export PATH="/mingw64/bin:$PATH" - -# resource file -windres -o resources.o resources.rc - -# compile src -g++ -o SnapKey SnapKey.cpp resources.o -mwindows -std=c++11 -static - -# success yes/no -if [ $? -eq 0 ]; then - echo "Compilation successful: SnapKey.exe created" -else - echo "Compilation failed." -fi diff --git a/Build SnapKey/MSYS-Build/resources.rc b/Build SnapKey/MSYS-Build/resources.rc deleted file mode 100644 index 88a5d99..0000000 --- a/Build SnapKey/MSYS-Build/resources.rc +++ /dev/null @@ -1,32 +0,0 @@ -#include - -// Icon resource -IDI_ICON1 ICON "snapkey.ico" - -// Version information -1 VERSIONINFO -FILEVERSION 0,0,0,0 -PRODUCTVERSION 0,0,0,0 -FILEOS 0x40004 -FILETYPE 0x1 -{ - BLOCK "StringFileInfo" - { - BLOCK "040904B0" - { - VALUE "FileDescription", "SnapKey" - VALUE "InternalName", "SnapKey.exe" - VALUE "OriginalFilename", "SnapKey.exe" - VALUE "CompanyName", "SnapKey" - VALUE "LegalCopyright", "" - VALUE "ProductName", "SnapKey" - VALUE "FileVersion", "0.0.0.0" - VALUE "ProductVersion", "0.0.0.0" - } - } - - BLOCK "VarFileInfo" - { - VALUE "Translation", 0x0409, 0x04B0 - } -} diff --git a/Build SnapKey/Setup-Build/setup.iss b/Build SnapKey/Setup-Build/setup.iss deleted file mode 100644 index 6163e64..0000000 --- a/Build SnapKey/Setup-Build/setup.iss +++ /dev/null @@ -1,60 +0,0 @@ -#define MyAppName "SnapKey" -#define MyAppVersion "1.2.9" -#define MyAppPublisher "cafali" -#define MyAppURL "https://github.com/cafali/SnapKey" -#define MyAppExeName "SnapKey.exe" -#define User "cafali" -#define Folder "SnapKeyDEV" - -[Setup] -AppId={{72AF690F-C35B-4E3F-B82B-8F75A06B960E} -AppName={#MyAppName} -AppVersion={#MyAppVersion} -AppVerName={#MyAppName} {#MyAppVersion} -AppPublisher={#MyAppPublisher} -AppPublisherURL={#MyAppURL} -AppSupportURL={#MyAppURL} -AppUpdatesURL={#MyAppURL} -DefaultDirName={localappdata}\{#MyAppName} -DisableDirPage=yes -UninstallDisplayIcon={app}\{#MyAppExeName} -UninstallDisplayName=SnapKey -ArchitecturesAllowed=x64compatible -ArchitecturesInstallIn64BitMode=x64compatible -DisableProgramGroupPage=yes -LicenseFile=C:\Users\{#User}\AppData\Local\{#Folder}\LICENSE -OutputDir=C:\Users\{#User}\Desktop -OutputBaseFilename={#MyAppName}-{#MyAppVersion}-Setup -SetupIconFile=Z:\dev\DEV SnapKey\snapkey.ico -SolidCompression=yes -WizardStyle=classic -WizardImageFile=Z:\dev\DEV SnapKey\wizard_large.bmp -WizardSmallImageFile=Z:\dev\DEV SnapKey\wizard_small.bmp -VersionInfoVersion={#MyAppVersion} - - -[Languages] -Name: "english"; MessagesFile: "compiler:Default.isl" - -[Tasks] -Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked - -[Files] -Source: "C:\Users\{#user}\AppData\Local\{#Folder}\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion -Source: "C:\Users\{#user}\AppData\Local\{#Folder}\config.cfg"; DestDir: "{app}"; Flags: ignoreversion -Source: "C:\Users\{#user}\AppData\Local\{#Folder}\icon.ico"; DestDir: "{app}"; Flags: ignoreversion -Source: "C:\Users\{#user}\AppData\Local\{#Folder}\icon_off.ico"; DestDir: "{app}"; Flags: ignoreversion -Source: "C:\Users\{#user}\AppData\Local\{#Folder}\LICENSE"; DestDir: "{app}"; Flags: ignoreversion -Source: "C:\Users\{#user}\AppData\Local\{#Folder}\README.pdf"; DestDir: "{app}"; Flags: ignoreversion -Source: "C:\Users\{#user}\AppData\Local\{#Folder}\SnapKey.exe"; DestDir: "{app}"; Flags: ignoreversion -Source: "C:\Users\{#user}\AppData\Local\{#Folder}\meta\*"; DestDir: "{app}\meta"; Flags: ignoreversion recursesubdirs createallsubdirs - -[Icons] -Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" -Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon -Name: "{group}\Uninstall SnapKey"; Filename: "{uninstallexe}" - - -[Run] -Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent - diff --git a/Build SnapKey/Setup-Build/wizard_large.bmp b/Build SnapKey/Setup-Build/wizard_large.bmp deleted file mode 100644 index 3fa8448..0000000 Binary files a/Build SnapKey/Setup-Build/wizard_large.bmp and /dev/null differ diff --git a/Build SnapKey/Setup-Build/wizard_large.xcf b/Build SnapKey/Setup-Build/wizard_large.xcf deleted file mode 100644 index b638009..0000000 Binary files a/Build SnapKey/Setup-Build/wizard_large.xcf and /dev/null differ diff --git a/Build SnapKey/Setup-Build/wizard_small.bmp b/Build SnapKey/Setup-Build/wizard_small.bmp deleted file mode 100644 index ab1aebc..0000000 Binary files a/Build SnapKey/Setup-Build/wizard_small.bmp and /dev/null differ diff --git a/Emitter.cpp b/Emitter.cpp new file mode 100644 index 0000000..aa2858e --- /dev/null +++ b/Emitter.cpp @@ -0,0 +1,10 @@ +#include +#include "InputState.h" + +void SendKey(WORD vk, bool down) { + INPUT input = {}; + input.type = INPUT_KEYBOARD; + input.ki.wVk = vk; + input.ki.dwFlags = down ? 0 : KEYEVENTF_KEYUP; + SendInput(1, &input, sizeof(INPUT)); +} diff --git a/Hooks.cpp b/Hooks.cpp new file mode 100644 index 0000000..138ab07 --- /dev/null +++ b/Hooks.cpp @@ -0,0 +1,99 @@ +#include +#include "InputState.h" + +HHOOK keyboardHook = NULL; +HHOOK mouseHook = NULL; + +/* ========================= + KEYBOARD HOOK + ========================= */ +LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { + if (nCode == HC_ACTION) { + KBDLLHOOKSTRUCT* k = (KBDLLHOOKSTRUCT*)lParam; + + // Ignore injected input + if (k->flags & LLKHF_INJECTED) { + return CallNextHookEx(NULL, nCode, wParam, lParam); + } + + bool isKeyDown = (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN); + bool isKeyUp = (wParam == WM_KEYUP || wParam == WM_SYSKEYUP); + + if (isKeyDown || isKeyUp) { + + switch (k->vkCode) { + + case 'A': + if (isKeyDown && !pA) { pA = true; lastH = 'A'; } + else if (isKeyUp) { pA = false; } + break; + + case 'D': + if (isKeyDown && !pD) { pD = true; lastH = 'D'; } + else if (isKeyUp) { pD = false; } + break; + + case 'W': + if (isKeyDown && !pW) { pW = true; lastV = 'W'; } + else if (isKeyUp) { pW = false; } + break; + + case 'S': + if (isKeyDown && !pS) { pS = true; lastV = 'S'; } + else if (isKeyUp) { pS = false; } + break; + + default: + break; + } + + Update(); + + // Block raw WASD ONLY when enabled + if (g_enabled && + (k->vkCode == 'W' || k->vkCode == 'A' || + k->vkCode == 'S' || k->vkCode == 'D')) { + return 1; + } + } + } + + return CallNextHookEx(NULL, nCode, wParam, lParam); +} + +/* ========================= + MOUSE HOOK + ========================= */ +LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) { + if (nCode == HC_ACTION) { + if (wParam == WM_LBUTTONDOWN) { + pFire = true; + Update(); + } else if (wParam == WM_LBUTTONUP) { + pFire = false; + Update(); + } + } + return CallNextHookEx(NULL, nCode, wParam, lParam); +} + +/* ========================= + INSTALL + ========================= */ +void InstallKeyboardHook() { + keyboardHook = SetWindowsHookEx( + WH_KEYBOARD_LL, + KeyboardProc, + NULL, + 0 + ); +} + +void InstallMouseHook() { + mouseHook = SetWindowsHookEx( + WH_MOUSE_LL, + MouseProc, + NULL, + 0 + ); +} diff --git a/InputState.h b/InputState.h new file mode 100644 index 0000000..535af23 --- /dev/null +++ b/InputState.h @@ -0,0 +1,63 @@ +#pragma once +#include + +// ========================= +// PHYSICAL STATE +// ========================= +extern bool pW, pA, pS, pD; +extern bool pFire; + +// ========================= +// FEATURE TOGGLES +// ========================= +extern bool g_socd_enabled; +extern bool g_mouse_override_enabled; + +// ========================= +// AXIS-SPECIFIC SOCD TOGGLES +// ========================= +extern bool g_socd_x_enabled; // A / D +extern bool g_socd_y_enabled; // W / S + + +// ========================= +// SOCD-RESOLVED STATE +// ========================= +extern bool sW, sA, sS, sD; + +// ========================= +// FINAL OUTPUT STATE +// ========================= +extern bool lW, lA, lS, lD; + +// ========================= +// PREVIOUS OUTPUT STATE +// ========================= +extern bool prevW, prevA, prevS, prevD; + +// ========================= +// LAST PRESSED (SOCD) +// ========================= +extern char lastH; +extern char lastV; + +// ========================= +// APP STATE +// ========================= +extern bool g_enabled; + +// ========================= +// CORE +// ========================= +void Update(); + +// ========================= +// HOOKS +// ========================= +void InstallKeyboardHook(); +void InstallMouseHook(); + +// ========================= +// EMISSION +// ========================= +void SendKey(WORD vk, bool down); diff --git a/LICENSE b/LICENSE index 1e32120..00ad98f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2025 cafali +Copyright (c) 2025 SAPNXTDOOR Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Logic.cpp b/Logic.cpp new file mode 100644 index 0000000..ac67f6b --- /dev/null +++ b/Logic.cpp @@ -0,0 +1,79 @@ +#include "InputState.h" + +// ========================= +// EMIT ONLY ON CHANGE +// ========================= +void EmitIfChanged() { + if (lW != prevW) SendKey('W', lW); + if (lA != prevA) SendKey('A', lA); + if (lS != prevS) SendKey('S', lS); + if (lD != prevD) SendKey('D', lD); + + prevW = lW; + prevA = lA; + prevS = lS; + prevD = lD; +} + +// ========================= +// SOCD RESOLUTION (AXIS AWARE) +// ========================= +void ResolveSOCD() { + + // -------- HORIZONTAL (A / D) -------- + if (g_socd_enabled && g_socd_x_enabled) { + if (pA && pD) { + sA = (lastH == 'A'); + sD = (lastH == 'D'); + } else { + sA = pA; + sD = pD; + } + } else { + // SOCD disabled for X axis + sA = pA; + sD = pD; + } + + // -------- VERTICAL (W / S) -------- + if (g_socd_enabled && g_socd_y_enabled) { + if (pW && pS) { + sW = (lastV == 'W'); + sS = (lastV == 'S'); + } else { + sW = pW; + sS = pS; + } + } else { + // SOCD disabled for Y axis + sW = pW; + sS = pS; + } +} + +// ========================= +// MAIN UPDATE +// ========================= +void Update() { + + // Fully disabled = transparent + if (!g_enabled) { + lW = lA = lS = lD = false; + EmitIfChanged(); + return; + } + + ResolveSOCD(); + + // -------- MOUSE OVERRIDE (UNCHANGED) -------- + if (g_mouse_override_enabled && pFire) { + lW = lA = lS = lD = false; + } else { + lW = sW; + lA = sA; + lS = sS; + lD = sD; + } + + EmitIfChanged(); +} diff --git a/README.md b/README.md index 67e93d4..be1c295 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,9 @@ -[![testsnap](https://github.com/user-attachments/assets/e9a23ba9-d394-4711-abfc-994932605d86)](https://github.com/cafali/SnapKey/releases) +[![testsnap](https://github.com/SAPNXTDOOR/SnapKey-Pro/blob/main/banner.png)](https://github.com/SAPNXTDOOR/SnapKey-Pro/releases) + + + + + **About SnapKey** -------------------------------------------------------------------------------------------------- @@ -6,47 +11,34 @@ SnapKey provides a user-friendly alternative to the Razer Snap Tap function, mak SnapKey is a lightweight, open-source tool that operates from the system tray and is designed to track inputs from the WASD keys, without interfering with any game files. Its main role is to recognize when these keys are pressed and automatically release any previously engaged commands for them. This guarantees responsive and precise input handling. SnapKey handles the WASD keys by default and lets you rebind them to your liking via the config file. -**Need More Info on SnapKey?** Visit the [**SnapKey Wiki**](https://github.com/cafali/SnapKey/wiki) [![COMPATIBLE](https://github.com/user-attachments/assets/069a7a23-cfe4-47eb-8ac2-05872fcc2028)](https://github.com/cafali/SnapKey/wiki/Compatibility-List) -Download --------------------------------------------------------------------------------------------------- -

- Download from GitHub | - Download from SourceForge | - Download from Softpedia -

- -[![latesver](https://github.com/user-attachments/assets/09694f7c-6eeb-4c80-9a02-1d777956d181)](https://github.com/cafali/SnapKey/wiki/Updates) -**SnapKey Features** +**SnapKey Pro Features** -------------------------------------------------------------------------------------------------- - Easy to use ๐Ÿงฉ -- Detailed documentation ๐Ÿ“– - Lightweight and open-source ๐ŸŒŸ - Accessible via the system tray ๐Ÿ–ฅ๏ธ - Compatible with all keyboards โœ… - Does not interact with game files ๐ŸŽฎ - Activate/Deactivate via context menu โ›” -- Double-click the tray icon to disable it ๐Ÿ‘†๐Ÿ‘† -- Builtโ€‘in and custom keyboard layout profiles ๐Ÿ—‚๏ธ +- Independent X and Y axis SOCD control ๐Ÿ‘†๐Ÿ‘† - Sticky Keys Feature: tracks the state of a pressed key โŒจ๏ธ - Enhances the precision of counter-strafing movements in games ๐ŸŽฏ -- Allows key rebinding using ASCII codes specified in the configuration file ๐Ÿ› ๏ธ -- Supports unlimited amount of keys shared across groups (default AD / WS) ๐Ÿ”„ - Facilitates smoother transitions between left and right movements without input conflicts ๐Ÿš€ - Does not use AutoHotkey or similar tools; its features rely solely on Windows API functions ๐Ÿ›ก๏ธ -**SnapKey in Action** +**SnapKey Pro in Action** -------------------------------------------------------------------------------------------------- - When you press and hold down the **"A"** key, SnapKey remembers it. - If you then press the **"D"** key while still holding down **"A"** SnapKey automatically releases the **"A"** key for you. - The same happens if you press **"A"** while holding **"D"** โ€” SnapKey releases the **"D"** key. - +- When you press Left Click to shoot. your movement kees become inactive, to stop you from moving while firing, thus increasing accuracy. + **SnapKey prevents simultaneous movement key conflicts (AD / WS)** - In many FPS games, pressing both the **"A"** and **"D"** keys simultaneously typically results in the game recognizing conflicting inputs. SnapKey automatically releases the previously held key when a new key input is detected. @@ -59,6 +51,8 @@ hold down the **"A"** key and tap the **"D"** key repeatedly, each press of **"D the **"A"** key. When you release the **"D"** key, the action associated with the **"A"** key will resume, as long as you're still holding it down. The same principle applies if you start with **"D"** held down and press **"A"** instead. +- Same goes for the Left Click as well. When any movement key is pressed down and Left Click is pressed, each click overrides the movement key. When you release the Left Click, the movement keys will resume, as +long as you're still holding it down. > [!NOTE] > SnapKey and similar solutions have been disallowed in certain games; illustrations shown are for demonstrative purposes only. @@ -71,62 +65,12 @@ press **"A"** instead. STRAFE -**Linux Support** --------------------------------------------------------------------------------------------------- -Since SnapKey isnโ€™t natively supported on Linux, itโ€™s recommended to check out @Dillacorn's guide on **[running SnapKey on Linux](https://github.com/cafali/SnapKey/issues/4#issuecomment-2251568839)**. - -[![LINUX baner](https://github.com/user-attachments/assets/794a16ed-b0ab-4320-a680-52bda1ca0fd1)](https://github.com/cafali/SnapKey/wiki/Setup-Linux) - -Looking for More Information? Got Questions or Need Help? --------------------------------------------------------------------------------------------------- -[Wikitest](https://github.com/cafali/SnapKey/wiki) -- **[About โ„น๏ธ](https://github.com/cafali/SnapKey/wiki/About)** - Discover SnapKey, explore its features and see how it can benefit you - -- **[Code Breakdown ๐Ÿง ](https://github.com/cafali/SnapKey/wiki/Code-Breakdown)** - Dive into the details of SnapKeyโ€™s code structure - -- **[Compatibility List ๐ŸŽฎ](https://github.com/cafali/SnapKey/wiki/Compatibility-List)** - Compatibility status of games with SnapKey - -- **[FAQโ“](https://github.com/cafali/SnapKey/wiki/FAQ)** - Find answers to common questions about SnapKey - -- **[License ๐Ÿ“œ](https://github.com/cafali/SnapKey/wiki/License)** - Overview of SnapKeyโ€™s licensing - -- **[Rebinding Keys โŒจ๏ธ](https://github.com/cafali/SnapKey/wiki/Rebinding-Keys)** - Instructions on how to rebind keys - -- **[Setup ๐Ÿ› ๏ธ](https://github.com/cafali/SnapKey/wiki/Setup)** - General setup instructions for getting Snapkey up and running on your system - -- **[Setup Linux ๐Ÿง](https://github.com/cafali/SnapKey/wiki/Setup-Linux)** - Setting up SnapKey on Linux distributions - -- **[System Requirements ๐Ÿ–ฅ๏ธ](https://github.com/cafali/SnapKey/wiki/System-Requirements)** - SnapKey System Requirements - -- **[Troubleshoot ๐Ÿ”ง](https://github.com/cafali/SnapKey/wiki/Troubleshoot)** - Solutions and tips for troubleshooting common issues with SnapKey - -- **[Changelog ๐Ÿ”„](https://github.com/cafali/SnapKey/wiki/Updates)** - View SnapKey releases and changes ----- - -

- SnapKey by -

- @cafali - @minteeaa - @Yaw-Dev + SnapKey Pro by

- - - + @SAPNXTDOOR

diff --git a/SnapKey Pro v1.4.1/Emitter.cpp b/SnapKey Pro v1.4.1/Emitter.cpp new file mode 100644 index 0000000..aa2858e --- /dev/null +++ b/SnapKey Pro v1.4.1/Emitter.cpp @@ -0,0 +1,10 @@ +#include +#include "InputState.h" + +void SendKey(WORD vk, bool down) { + INPUT input = {}; + input.type = INPUT_KEYBOARD; + input.ki.wVk = vk; + input.ki.dwFlags = down ? 0 : KEYEVENTF_KEYUP; + SendInput(1, &input, sizeof(INPUT)); +} diff --git a/SnapKey Pro v1.4.1/Hooks.cpp b/SnapKey Pro v1.4.1/Hooks.cpp new file mode 100644 index 0000000..138ab07 --- /dev/null +++ b/SnapKey Pro v1.4.1/Hooks.cpp @@ -0,0 +1,99 @@ +#include +#include "InputState.h" + +HHOOK keyboardHook = NULL; +HHOOK mouseHook = NULL; + +/* ========================= + KEYBOARD HOOK + ========================= */ +LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { + if (nCode == HC_ACTION) { + KBDLLHOOKSTRUCT* k = (KBDLLHOOKSTRUCT*)lParam; + + // Ignore injected input + if (k->flags & LLKHF_INJECTED) { + return CallNextHookEx(NULL, nCode, wParam, lParam); + } + + bool isKeyDown = (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN); + bool isKeyUp = (wParam == WM_KEYUP || wParam == WM_SYSKEYUP); + + if (isKeyDown || isKeyUp) { + + switch (k->vkCode) { + + case 'A': + if (isKeyDown && !pA) { pA = true; lastH = 'A'; } + else if (isKeyUp) { pA = false; } + break; + + case 'D': + if (isKeyDown && !pD) { pD = true; lastH = 'D'; } + else if (isKeyUp) { pD = false; } + break; + + case 'W': + if (isKeyDown && !pW) { pW = true; lastV = 'W'; } + else if (isKeyUp) { pW = false; } + break; + + case 'S': + if (isKeyDown && !pS) { pS = true; lastV = 'S'; } + else if (isKeyUp) { pS = false; } + break; + + default: + break; + } + + Update(); + + // Block raw WASD ONLY when enabled + if (g_enabled && + (k->vkCode == 'W' || k->vkCode == 'A' || + k->vkCode == 'S' || k->vkCode == 'D')) { + return 1; + } + } + } + + return CallNextHookEx(NULL, nCode, wParam, lParam); +} + +/* ========================= + MOUSE HOOK + ========================= */ +LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) { + if (nCode == HC_ACTION) { + if (wParam == WM_LBUTTONDOWN) { + pFire = true; + Update(); + } else if (wParam == WM_LBUTTONUP) { + pFire = false; + Update(); + } + } + return CallNextHookEx(NULL, nCode, wParam, lParam); +} + +/* ========================= + INSTALL + ========================= */ +void InstallKeyboardHook() { + keyboardHook = SetWindowsHookEx( + WH_KEYBOARD_LL, + KeyboardProc, + NULL, + 0 + ); +} + +void InstallMouseHook() { + mouseHook = SetWindowsHookEx( + WH_MOUSE_LL, + MouseProc, + NULL, + 0 + ); +} diff --git a/SnapKey Pro v1.4.1/InputState.h b/SnapKey Pro v1.4.1/InputState.h new file mode 100644 index 0000000..6b1de33 --- /dev/null +++ b/SnapKey Pro v1.4.1/InputState.h @@ -0,0 +1,69 @@ +#pragma once +#include + +// ========================= +// PHYSICAL STATE +// ========================= +extern bool pW, pA, pS, pD; +extern bool pFire; + +// ========================= +// FEATURE TOGGLES +// ========================= +extern bool g_socd_enabled; +extern bool g_mouse_override_enabled; + +// ========================= +// AXIS-SPECIFIC SOCD TOGGLES +// ========================= +extern bool g_socd_x_enabled; // A / D +extern bool g_socd_y_enabled; // W / S + +// ========================= +// AXIS-SPECIFIC MOUSE OVERRIDE TOGGLES +// ========================= +extern bool g_mouse_override_x_enabled; // A / D +extern bool g_mouse_override_y_enabled; // W / S + + +// ========================= +// SOCD-RESOLVED STATE +// ========================= +extern bool sW, sA, sS, sD; + +// ========================= +// FINAL OUTPUT STATE +// ========================= +extern bool lW, lA, lS, lD; + +// ========================= +// PREVIOUS OUTPUT STATE +// ========================= +extern bool prevW, prevA, prevS, prevD; + +// ========================= +// LAST PRESSED (SOCD) +// ========================= +extern char lastH; +extern char lastV; + +// ========================= +// APP STATE +// ========================= +extern bool g_enabled; + +// ========================= +// CORE +// ========================= +void Update(); + +// ========================= +// HOOKS +// ========================= +void InstallKeyboardHook(); +void InstallMouseHook(); + +// ========================= +// EMISSION +// ========================= +void SendKey(WORD vk, bool down); diff --git a/SnapKey Pro v1.4.1/LICENSE b/SnapKey Pro v1.4.1/LICENSE new file mode 100644 index 0000000..00ad98f --- /dev/null +++ b/SnapKey Pro v1.4.1/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 SAPNXTDOOR + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/SnapKey Pro v1.4.1/Logic.cpp b/SnapKey Pro v1.4.1/Logic.cpp new file mode 100644 index 0000000..ca02d57 --- /dev/null +++ b/SnapKey Pro v1.4.1/Logic.cpp @@ -0,0 +1,97 @@ +#include "InputState.h" + +// ========================= +// EMIT ONLY ON CHANGE +// ========================= +void EmitIfChanged() { + if (lW != prevW) SendKey('W', lW); + if (lA != prevA) SendKey('A', lA); + if (lS != prevS) SendKey('S', lS); + if (lD != prevD) SendKey('D', lD); + + prevW = lW; + prevA = lA; + prevS = lS; + prevD = lD; +} + +// ========================= +// SOCD RESOLUTION (AXIS AWARE) +// ========================= +void ResolveSOCD() { + + // -------- HORIZONTAL (A / D) -------- + if (g_socd_enabled && g_socd_x_enabled) { + if (pA && pD) { + sA = (lastH == 'A'); + sD = (lastH == 'D'); + } else { + sA = pA; + sD = pD; + } + } else { + sA = pA; + sD = pD; + } + + // -------- VERTICAL (W / S) -------- + if (g_socd_enabled && g_socd_y_enabled) { + if (pW && pS) { + sW = (lastV == 'W'); + sS = (lastV == 'S'); + } else { + sW = pW; + sS = pS; + } + } else { + sW = pW; + sS = pS; + } +} + +// ========================= +// MAIN UPDATE +// ========================= +void Update() { + + // Fully disabled = transparent + if (!g_enabled) { + lW = lA = lS = lD = false; + EmitIfChanged(); + return; + } + + // -------- SOCD -------- + ResolveSOCD(); + + // -------- MOUSE OVERRIDE (AXIS AWARE) -------- + if (g_mouse_override_enabled && pFire) { + + // Horizontal + if (g_mouse_override_x_enabled) { + lA = false; + lD = false; + } else { + lA = sA; + lD = sD; + } + + // Vertical + if (g_mouse_override_y_enabled) { + lW = false; + lS = false; + } else { + lW = sW; + lS = sS; + } + + } else { + // No mouse override โ†’ pass SOCD output + lW = sW; + lA = sA; + lS = sS; + lD = sD; + } + + EmitIfChanged(); +} diff --git a/SnapKey Pro v1.4.1/SnapKey Pro.exe b/SnapKey Pro v1.4.1/SnapKey Pro.exe new file mode 100644 index 0000000..70e72eb Binary files /dev/null and b/SnapKey Pro v1.4.1/SnapKey Pro.exe differ diff --git a/SnapKey Pro v1.4.1/admin.manifest b/SnapKey Pro v1.4.1/admin.manifest new file mode 100644 index 0000000..4cbf179 --- /dev/null +++ b/SnapKey Pro v1.4.1/admin.manifest @@ -0,0 +1,22 @@ + + + + + + SnapKey Pro + + + + + + + + + + diff --git a/SnapKey Pro v1.4.1/admin.o b/SnapKey Pro v1.4.1/admin.o new file mode 100644 index 0000000..46a491e Binary files /dev/null and b/SnapKey Pro v1.4.1/admin.o differ diff --git a/SnapKey Pro v1.4.1/admin.rc b/SnapKey Pro v1.4.1/admin.rc new file mode 100644 index 0000000..879e859 --- /dev/null +++ b/SnapKey Pro v1.4.1/admin.rc @@ -0,0 +1 @@ +1 24 "admin.manifest" diff --git a/SnapKey Pro v1.4.1/banner.png b/SnapKey Pro v1.4.1/banner.png new file mode 100644 index 0000000..22cfca9 Binary files /dev/null and b/SnapKey Pro v1.4.1/banner.png differ diff --git a/snapkey.ico b/SnapKey Pro v1.4.1/icon.ico similarity index 100% rename from snapkey.ico rename to SnapKey Pro v1.4.1/icon.ico diff --git a/SnapKey Pro v1.4.1/main.cpp b/SnapKey Pro v1.4.1/main.cpp new file mode 100644 index 0000000..1503181 --- /dev/null +++ b/SnapKey Pro v1.4.1/main.cpp @@ -0,0 +1,274 @@ +#include +#include +#include "InputState.h" +#include "resource.h" + +#include +#pragma comment(lib, "shlwapi.lib") + +wchar_t g_iniPath[MAX_PATH]; + +void InitIniPath() { + GetModuleFileNameW(NULL, g_iniPath, MAX_PATH); + PathRemoveFileSpecW(g_iniPath); + wcscat_s(g_iniPath, L"\\settings.ini"); +} + + +// ========================= +// PORTABLE SETTINGS (INI) +// ========================= +extern wchar_t g_iniPath[MAX_PATH]; +const wchar_t* INI_SECTION = L"SnapKeyPro"; + + +void SaveSettings() { + WritePrivateProfileStringW(L"SnapKeyPro", L"SnapTap", + g_socd_enabled ? L"1" : L"0", g_iniPath); + + WritePrivateProfileStringW(L"SnapKeyPro", L"SOCD_X", + g_socd_x_enabled ? L"1" : L"0", g_iniPath); + + WritePrivateProfileStringW(L"SnapKeyPro", L"SOCD_Y", + g_socd_y_enabled ? L"1" : L"0", g_iniPath); + + WritePrivateProfileStringW(L"SnapKeyPro", L"MouseOverride", + g_mouse_override_enabled ? L"1" : L"0", g_iniPath); + + WritePrivateProfileStringW(L"SnapKeyPro", L"MouseOverride_X", + g_mouse_override_x_enabled ? L"1" : L"0", g_iniPath); + + WritePrivateProfileStringW(L"SnapKeyPro", L"MouseOverride_Y", + g_mouse_override_y_enabled ? L"1" : L"0", g_iniPath); +} + + + +void LoadSettings() { + g_socd_enabled = GetPrivateProfileIntW( + L"SnapKeyPro", L"SnapTap", 1, g_iniPath); + + g_socd_x_enabled = GetPrivateProfileIntW( + L"SnapKeyPro", L"SOCD_X", 1, g_iniPath); + + g_socd_y_enabled = GetPrivateProfileIntW( + L"SnapKeyPro", L"SOCD_Y", 1, g_iniPath); + + g_mouse_override_enabled = GetPrivateProfileIntW( + L"SnapKeyPro", L"MouseOverride", 1, g_iniPath); + + g_mouse_override_x_enabled = GetPrivateProfileIntW( + L"SnapKeyPro", L"MouseOverride_X", 1, g_iniPath); + + g_mouse_override_y_enabled = GetPrivateProfileIntW( + L"SnapKeyPro", L"MouseOverride_Y", 1, g_iniPath); +} + + + + +// ========================= +// GLOBAL APP STATE +// ========================= +bool g_enabled = true; + +// SOCD toggles +bool g_socd_enabled = true; +bool g_socd_x_enabled = true; +bool g_socd_y_enabled = true; + +// Mouse override toggles +bool g_mouse_override_enabled = true; +bool g_mouse_override_x_enabled = true; +bool g_mouse_override_y_enabled = true; + +// ========================= +// INPUT STATE DEFINITIONS +// ========================= +bool pW=false, pA=false, pS=false, pD=false; +bool pFire=false; + +bool sW=false, sA=false, sS=false, sD=false; +bool lW=false, lA=false, lS=false, lD=false; + +bool prevW=false, prevA=false, prevS=false, prevD=false; + +char lastH=0; +char lastV=0; + +// ========================= +// TRAY DEFINITIONS +// ========================= +#define WM_TRAYICON (WM_USER + 1) + +#define ID_TOGGLE_SOCD 2001 +#define ID_TOGGLE_SOCD_X 2002 +#define ID_TOGGLE_SOCD_Y 2003 +#define ID_TOGGLE_MOUSE 2004 +#define ID_TOGGLE_MOUSE_X 2005 +#define ID_TOGGLE_MOUSE_Y 2006 +#define ID_HELP 2007 +#define ID_UPDATE 2008 +#define ID_VERSION 2009 +#define ID_EXIT 2010 + +NOTIFYICONDATA nid = {}; +HMENU hTrayMenu; + +// ========================= +// UPDATE MENU TEXT +// ========================= +void UpdateMenuText() { + + ModifyMenu(hTrayMenu, ID_TOGGLE_SOCD, + MF_BYCOMMAND | MF_STRING, ID_TOGGLE_SOCD, + g_socd_enabled ? TEXT("Disable SnapTap") : TEXT("Enable SnapTap")); + + ModifyMenu(hTrayMenu, ID_TOGGLE_SOCD_X, + MF_BYCOMMAND | MF_STRING, ID_TOGGLE_SOCD_X, + g_socd_x_enabled ? TEXT("Disable SOCD X (A/D)") : TEXT("Enable SOCD X (A/D)")); + + ModifyMenu(hTrayMenu, ID_TOGGLE_SOCD_Y, + MF_BYCOMMAND | MF_STRING, ID_TOGGLE_SOCD_Y, + g_socd_y_enabled ? TEXT("Disable SOCD Y (W/S)") : TEXT("Enable SOCD Y (W/S)")); + ModifyMenu(hTrayMenu, ID_TOGGLE_MOUSE, + MF_BYCOMMAND | MF_STRING, ID_TOGGLE_MOUSE, + g_mouse_override_enabled ? TEXT("Disable Mouse Override") : TEXT("Enable Mouse Override")); + + ModifyMenu(hTrayMenu, ID_TOGGLE_MOUSE_X, + MF_BYCOMMAND | MF_STRING, ID_TOGGLE_MOUSE_X, + g_mouse_override_x_enabled + ? TEXT("Disable Mouse Override X (A/D)") + : TEXT("Enable Mouse Override X (A/D)")); + + ModifyMenu(hTrayMenu, ID_TOGGLE_MOUSE_Y, + MF_BYCOMMAND | MF_STRING, ID_TOGGLE_MOUSE_Y, + g_mouse_override_y_enabled + ? TEXT("Disable Mouse Override Y (W/S)") + : TEXT("Enable Mouse Override Y (W/S)")); +} + +// ========================= +// WINDOW PROC +// ========================= +LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { + + switch (msg) { + + case WM_TRAYICON: + if (lParam == WM_RBUTTONUP) { + POINT pt; + GetCursorPos(&pt); + SetForegroundWindow(hwnd); + UpdateMenuText(); + TrackPopupMenu(hTrayMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL); + } + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + + case ID_TOGGLE_SOCD: g_socd_enabled = !g_socd_enabled; break; + case ID_TOGGLE_SOCD_X: g_socd_x_enabled = !g_socd_x_enabled; break; + case ID_TOGGLE_SOCD_Y: g_socd_y_enabled = !g_socd_y_enabled; break; + + case ID_TOGGLE_MOUSE: g_mouse_override_enabled = !g_mouse_override_enabled; break; + case ID_TOGGLE_MOUSE_X: g_mouse_override_x_enabled = !g_mouse_override_x_enabled; break; + case ID_TOGGLE_MOUSE_Y: g_mouse_override_y_enabled = !g_mouse_override_y_enabled; break; + + case ID_HELP: + MessageBox(hwnd, TEXT("Email: soma27245@gmail.com"), + TEXT("Get Help"), MB_OK | MB_ICONINFORMATION); + break; + + case ID_UPDATE: + ShellExecute(NULL, TEXT("open"), + TEXT("https://github.com/SAPNXTDOOR/SnapKey-Pro/releases"), + NULL, NULL, SW_SHOWNORMAL); + break; + + case ID_VERSION: + MessageBox(hwnd, + TEXT("SnapKey Pro v1.4.1\n" + "Release Date: 15/1/26\n" + "Repository: github.com/SAPNXTDOOR/SnapKey-Pro\n\n" + "This app is made by Saptarshi Mallick."), + TEXT("Version Info"), + MB_OK | MB_ICONINFORMATION); + break; + + case ID_EXIT: + SaveSettings(); + Shell_NotifyIcon(NIM_DELETE, &nid); + PostQuitMessage(0); + break; + } + break; + + case WM_DESTROY: + SaveSettings(); + Shell_NotifyIcon(NIM_DELETE, &nid); + PostQuitMessage(0); + break; + } + + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +// ========================= +// WINMAIN +// ========================= +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) { + + WNDCLASS wc = {}; + wc.lpfnWndProc = WindowProc; + wc.hInstance = hInstance; + wc.lpszClassName = TEXT("SnapKeyProTray"); + RegisterClass(&wc); + + HWND hwnd = CreateWindowEx(0, wc.lpszClassName, + TEXT("SnapKey Pro"), WS_OVERLAPPEDWINDOW, + 0, 0, 0, 0, NULL, NULL, hInstance, NULL); + + hTrayMenu = CreatePopupMenu(); + + AppendMenu(hTrayMenu, MF_STRING, ID_TOGGLE_SOCD, TEXT("Disable SnapTap")); + AppendMenu(hTrayMenu, MF_STRING, ID_TOGGLE_SOCD_X, TEXT("Disable SOCD X (A/D)")); + AppendMenu(hTrayMenu, MF_STRING, ID_TOGGLE_SOCD_Y, TEXT("Disable SOCD Y (W/S)")); + AppendMenu(hTrayMenu, MF_SEPARATOR, 0, NULL); + + AppendMenu(hTrayMenu, MF_STRING, ID_TOGGLE_MOUSE, TEXT("Disable Mouse Override")); + AppendMenu(hTrayMenu, MF_STRING, ID_TOGGLE_MOUSE_X, TEXT("Disable Mouse Override X (A/D)")); + AppendMenu(hTrayMenu, MF_STRING, ID_TOGGLE_MOUSE_Y, TEXT("Disable Mouse Override Y (W/S)")); + AppendMenu(hTrayMenu, MF_SEPARATOR, 0, NULL); + + AppendMenu(hTrayMenu, MF_STRING, ID_HELP, TEXT("Get Help")); + AppendMenu(hTrayMenu, MF_STRING, ID_UPDATE, TEXT("Check for updates")); + AppendMenu(hTrayMenu, MF_STRING, ID_VERSION, TEXT("Version Info")); + AppendMenu(hTrayMenu, MF_SEPARATOR, 0, NULL); + + AppendMenu(hTrayMenu, MF_STRING, ID_EXIT, TEXT("Exit")); + + nid.cbSize = sizeof(NOTIFYICONDATA); + nid.hWnd = hwnd; + nid.uID = 1; + nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; + nid.uCallbackMessage = WM_TRAYICON; + nid.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); + lstrcpy(nid.szTip, TEXT("SnapKey Pro")); + + Shell_NotifyIcon(NIM_ADD, &nid); + + InitIniPath(); + LoadSettings(); + InstallKeyboardHook(); + InstallMouseHook(); + + MSG msg; + while (GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + return 0; +} diff --git a/SnapKey Pro v1.4.1/resource.h b/SnapKey Pro v1.4.1/resource.h new file mode 100644 index 0000000..aaea70c --- /dev/null +++ b/SnapKey Pro v1.4.1/resource.h @@ -0,0 +1,3 @@ +#pragma once + +#define IDI_APP_ICON 101 diff --git a/SnapKey Pro v1.4.1/resource.o b/SnapKey Pro v1.4.1/resource.o new file mode 100644 index 0000000..82186f3 Binary files /dev/null and b/SnapKey Pro v1.4.1/resource.o differ diff --git a/SnapKey Pro v1.4.1/resource.rc b/SnapKey Pro v1.4.1/resource.rc new file mode 100644 index 0000000..fd1973b --- /dev/null +++ b/SnapKey Pro v1.4.1/resource.rc @@ -0,0 +1,3 @@ +#include "resource.h" + +IDI_APP_ICON ICON "icon.ico" diff --git a/SnapKey Pro v1.4.1/settings.ini b/SnapKey Pro v1.4.1/settings.ini new file mode 100644 index 0000000..b077ce9 --- /dev/null +++ b/SnapKey Pro v1.4.1/settings.ini @@ -0,0 +1,7 @@ +[SnapKeyPro] +SnapTap=1 +SOCD_X=1 +SOCD_Y=1 +MouseOverride=1 +MouseOverride_X=1 +MouseOverride_Y=1 diff --git a/SnapKey.cpp b/SnapKey.cpp deleted file mode 100644 index e75f4b2..0000000 --- a/SnapKey.cpp +++ /dev/null @@ -1,404 +0,0 @@ -// SnapKey 1.2.9 -// github.com/cafali/SnapKey - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -namespace fs = std::filesystem; - -#define ID_TRAY_APP_ICON 1001 -#define ID_TRAY_EXIT_CONTEXT_MENU_ITEM 3000 -#define ID_TRAY_VERSION_INFO 3001 -#define ID_TRAY_REBIND_KEYS 3002 -#define ID_TRAY_LOCK_FUNCTION 3003 -#define ID_TRAY_RESTART_SNAPKEY 3004 -#define ID_TRAY_HELP 3005 -#define ID_TRAY_CHECKUPDATE 3006 -#define ID_TRAY_LAYOUTS 3007 -#define WM_TRAYICON (WM_USER + 1) -#define ID_LAYOUT_BASE 4000 // 1.2.9 - -struct KeyState { - bool registered = false; - bool keyDown = false; - int group; - bool simulated = false; -}; - -struct GroupState { - int previousKey; - int activeKey; -}; - -unordered_map GroupInfo; -unordered_map KeyInfo; - -HHOOK hHook = NULL; -HANDLE hMutex = NULL; -NOTIFYICONDATA nid; -bool isLocked = false; - -// Forward declarations -LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam); -LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); -void InitNotifyIconData(HWND hwnd); -bool LoadConfig(const std::string& filename); -void CreateDefaultConfig(const std::string& filename); -void RestoreConfigFromBackup(const std::string& backupFilename, const std::string& destinationFilename); -std::string GetVersionInfo(); -void SendKey(int target, bool keyDown); - -// select layout via context menu v 1.2.9 -vector ListLayouts() { - vector layouts; - string path = "meta\\profiles"; - if (!fs::exists(path)) return layouts; - - for (auto& entry : fs::directory_iterator(path)) { - if (entry.is_regular_file()) { - auto ext = entry.path().extension().string(); - if (ext == ".cfg") { - layouts.push_back(entry.path().stem().string()); // ignore file extension - } - } - } - return layouts; -} - -// apply layout (replace config.cfg content) v 1.2.9 -void ApplyLayout(const string& layoutName) { - string sourcePath = "meta\\profiles\\" + layoutName + ".cfg"; - string destPath = "config.cfg"; - - ifstream src(sourcePath, ios::binary); - ofstream dst(destPath, ios::binary | ios::trunc); - - if (!src.is_open() || !dst.is_open()) { - MessageBox(NULL, TEXT("Failed to apply layout. Please check the layout file."), - TEXT("SnapKey Error"), MB_ICONERROR | MB_OK); - return; - } - - dst << src.rdbuf(); // copy file contents -} - -// restart -void RestartSnapKey() { - TCHAR szExeFileName[MAX_PATH]; - GetModuleFileName(NULL, szExeFileName, MAX_PATH); - ShellExecute(NULL, NULL, szExeFileName, NULL, NULL, SW_SHOWNORMAL); - PostQuitMessage(0); -} - -// Main entry -int main() { - if (!LoadConfig("config.cfg")) { - return 1; - } - - hMutex = CreateMutex(NULL, TRUE, TEXT("SnapKeyMutex")); - if (GetLastError() == ERROR_ALREADY_EXISTS) { - MessageBox(NULL, TEXT("SnapKey is already running!"), TEXT("SnapKey"), MB_ICONINFORMATION | MB_OK); - return 1; - } - - WNDCLASSEX wc = {0}; - wc.cbSize = sizeof(WNDCLASSEX); - wc.lpfnWndProc = WndProc; - wc.hInstance = GetModuleHandle(NULL); - wc.lpszClassName = TEXT("SnapKeyClass"); - - if (!RegisterClassEx(&wc)) { - MessageBox(NULL, TEXT("Window Registration Failed!"), TEXT("Error"), MB_ICONEXCLAMATION | MB_OK); - ReleaseMutex(hMutex); - CloseHandle(hMutex); - return 1; - } - - HWND hwnd = CreateWindowEx(0, wc.lpszClassName, TEXT("SnapKey"), WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, - NULL, NULL, wc.hInstance, NULL); - - if (hwnd == NULL) { - MessageBox(NULL, TEXT("Window Creation Failed!"), TEXT("Error"), MB_ICONEXCLAMATION | MB_OK); - ReleaseMutex(hMutex); - CloseHandle(hMutex); - return 1; - } - - InitNotifyIconData(hwnd); - - hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, NULL, 0); - if (hHook == NULL) { - MessageBox(NULL, TEXT("Failed to install hook!"), TEXT("Error"), MB_ICONEXCLAMATION | MB_OK); - ReleaseMutex(hMutex); - CloseHandle(hMutex); - return 1; - } - - MSG msg; - while (GetMessage(&msg, NULL, 0, 0)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - UnhookWindowsHookEx(hHook); - Shell_NotifyIcon(NIM_DELETE, &nid); - ReleaseMutex(hMutex); - CloseHandle(hMutex); - - return 0; -} - -// Key handling -void handleKeyDown(int keyCode) { - KeyState& currentKeyInfo = KeyInfo[keyCode]; - GroupState& currentGroupInfo = GroupInfo[currentKeyInfo.group]; - if (!currentKeyInfo.keyDown) { - currentKeyInfo.keyDown = true; - SendKey(keyCode, true); - if (currentGroupInfo.activeKey == 0 || currentGroupInfo.activeKey == keyCode) { - currentGroupInfo.activeKey = keyCode; - } else { - currentGroupInfo.previousKey = currentGroupInfo.activeKey; - currentGroupInfo.activeKey = keyCode; - SendKey(currentGroupInfo.previousKey, false); - } - } -} - -void handleKeyUp(int keyCode) { - KeyState& currentKeyInfo = KeyInfo[keyCode]; - GroupState& currentGroupInfo = GroupInfo[currentKeyInfo.group]; - if (currentGroupInfo.previousKey == keyCode && !currentKeyInfo.keyDown) { - currentGroupInfo.previousKey = 0; - } - if (currentKeyInfo.keyDown) { - currentKeyInfo.keyDown = false; - if (currentGroupInfo.activeKey == keyCode && currentGroupInfo.previousKey != 0) { - SendKey(keyCode, false); - currentGroupInfo.activeKey = currentGroupInfo.previousKey; - currentGroupInfo.previousKey = 0; - SendKey(currentGroupInfo.activeKey, true); - } else { - currentGroupInfo.previousKey = 0; - if (currentGroupInfo.activeKey == keyCode) currentGroupInfo.activeKey = 0; - SendKey(keyCode, false); - } - } -} - -bool isSimulatedKeyEvent(DWORD flags) { return flags & 0x10; } - -void SendKey(int targetKey, bool keyDown) { - INPUT input = {0}; - input.ki.wVk = targetKey; - input.ki.wScan = MapVirtualKey(targetKey, 0); - input.type = INPUT_KEYBOARD; - - DWORD flags = KEYEVENTF_SCANCODE; - input.ki.dwFlags = keyDown ? flags : flags | KEYEVENTF_KEYUP; - SendInput(1, &input, sizeof(INPUT)); -} - -LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { - if (!isLocked && nCode >= 0) { - KBDLLHOOKSTRUCT *pKeyBoard = (KBDLLHOOKSTRUCT *)lParam; - if (!isSimulatedKeyEvent(pKeyBoard->flags)) { - if (KeyInfo[pKeyBoard->vkCode].registered) { - if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) handleKeyDown(pKeyBoard->vkCode); - if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP) handleKeyUp(pKeyBoard->vkCode); - return 1; - } - } - } - return CallNextHookEx(hHook, nCode, wParam, lParam); -} - -void InitNotifyIconData(HWND hwnd) { - memset(&nid, 0, sizeof(NOTIFYICONDATA)); - nid.cbSize = sizeof(NOTIFYICONDATA); - nid.hWnd = hwnd; - nid.uID = ID_TRAY_APP_ICON; - nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; - nid.uCallbackMessage = WM_TRAYICON; - - HICON hIcon = (HICON)LoadImage(NULL, TEXT("icon.ico"), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); - nid.hIcon = hIcon ? hIcon : LoadIcon(NULL, IDI_APPLICATION); - lstrcpy(nid.szTip, TEXT("SnapKey")); - Shell_NotifyIcon(NIM_ADD, &nid); -} - -LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { - switch (msg) { - case WM_TRAYICON: - if (lParam == WM_RBUTTONDOWN) { - POINT curPoint; - GetCursorPos(&curPoint); - SetForegroundWindow(hwnd); - - HMENU hMenu = CreatePopupMenu(); - AppendMenu(hMenu, MF_STRING, ID_TRAY_REBIND_KEYS, TEXT("Rebind Keys")); - - // submenu layouts - HMENU hSubMenu = CreatePopupMenu(); - vector layouts = ListLayouts(); - if (!layouts.empty()) { - int id = 0; - for (auto& layout : layouts) { - AppendMenuA(hSubMenu, MF_STRING, ID_LAYOUT_BASE + id, layout.c_str()); - id++; - } - } else { - AppendMenu(hSubMenu, MF_GRAYED, 0, TEXT("No layouts found")); - } - AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hSubMenu, TEXT("Select Profile")); - - AppendMenu(hMenu, MF_STRING, ID_TRAY_RESTART_SNAPKEY, TEXT("Restart SnapKey")); - AppendMenu(hMenu, MF_STRING, ID_TRAY_LOCK_FUNCTION, isLocked ? TEXT("Enable SnapKey") : TEXT("Disable SnapKey")); - AppendMenu(hMenu, MF_SEPARATOR, 0, NULL); - AppendMenu(hMenu, MF_STRING, ID_TRAY_HELP, TEXT("Get Help")); - AppendMenu(hMenu, MF_STRING, ID_TRAY_CHECKUPDATE, TEXT("Check Updates")); - AppendMenu(hMenu, MF_STRING, ID_TRAY_VERSION_INFO, TEXT("Version Info (1.2.9)")); - AppendMenu(hMenu, MF_SEPARATOR, 0, NULL); - AppendMenu(hMenu, MF_STRING, ID_TRAY_EXIT_CONTEXT_MENU_ITEM, TEXT("Exit SnapKey")); - - TrackPopupMenu(hMenu, TPM_BOTTOMALIGN | TPM_LEFTALIGN, curPoint.x, curPoint.y, 0, hwnd, NULL); - DestroyMenu(hMenu); - } - else if (lParam == WM_LBUTTONDBLCLK) { - isLocked = !isLocked; - HICON hIcon = isLocked - ? (HICON)LoadImage(NULL, TEXT("icon_off.ico"), IMAGE_ICON, 0, 0, LR_LOADFROMFILE) - : (HICON)LoadImage(NULL, TEXT("icon.ico"), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); - if (hIcon) { - nid.hIcon = hIcon; - Shell_NotifyIcon(NIM_MODIFY, &nid); - DestroyIcon(hIcon); - } - } - break; - - case WM_COMMAND: - if (LOWORD(wParam) >= ID_LAYOUT_BASE) { - int layoutIndex = LOWORD(wParam) - ID_LAYOUT_BASE; - vector layouts = ListLayouts(); - if (layoutIndex >= 0 && layoutIndex < (int)layouts.size()) { - ApplyLayout(layouts[layoutIndex]); - RestartSnapKey(); // restart after applying layout - } - } - else { - switch (LOWORD(wParam)) { - case ID_TRAY_EXIT_CONTEXT_MENU_ITEM: - PostQuitMessage(0); - break; - case ID_TRAY_VERSION_INFO: - MessageBox(hwnd, GetVersionInfo().c_str(), TEXT("SnapKey Version Info"), MB_OK); - break; - case ID_TRAY_REBIND_KEYS: - ShellExecute(NULL, TEXT("open"), TEXT("config.cfg"), NULL, NULL, SW_SHOWNORMAL); - break; - case ID_TRAY_HELP: - ShellExecute(NULL, TEXT("open"), TEXT("README.pdf"), NULL, NULL, SW_SHOWNORMAL); - break; - case ID_TRAY_CHECKUPDATE: - if (MessageBox(NULL, - TEXT("You are about to visit the SnapKey GitHub page. Continue?"), - TEXT("Update SnapKey"), - MB_YESNO | MB_ICONQUESTION) == IDYES) { - ShellExecute(NULL, TEXT("open"), TEXT("https://github.com/cafali/SnapKey/releases"), NULL, NULL, SW_SHOWNORMAL); - } - break; - case ID_TRAY_RESTART_SNAPKEY: - RestartSnapKey(); - break; - case ID_TRAY_LOCK_FUNCTION: - isLocked = !isLocked; - { - HICON hIcon = isLocked - ? (HICON)LoadImage(NULL, TEXT("icon_off.ico"), IMAGE_ICON, 0, 0, LR_LOADFROMFILE) - : (HICON)LoadImage(NULL, TEXT("icon.ico"), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); - if (hIcon) { - nid.hIcon = hIcon; - Shell_NotifyIcon(NIM_MODIFY, &nid); - DestroyIcon(hIcon); - } - } - break; - } - } - break; - - case WM_DESTROY: - PostQuitMessage(0); - break; - - default: - return DefWindowProc(hwnd, msg, wParam, lParam); - } - return 0; -} - -std::string GetVersionInfo() { - return "SnapKey v1.2.9 (R18)\n" - "Version Date: August 8, 2025\n" - "Repository: github.com/cafali/SnapKey\n" - "License: MIT License\n"; -} - -void RestoreConfigFromBackup(const std::string& backupFilename, const std::string& destinationFilename) { - std::string sourcePath = "meta\\" + backupFilename; - std::string destinationPath = destinationFilename; - - if (CopyFile(sourcePath.c_str(), destinationPath.c_str(), FALSE)) { - MessageBox(NULL, TEXT("Default config restored from backup successfully."), TEXT("SnapKey"), MB_ICONINFORMATION | MB_OK); - } else { - MessageBox(NULL, TEXT("Failed to restore config from backup."), TEXT("SnapKey Error"), MB_ICONERROR | MB_OK); - } -} - -void CreateDefaultConfig(const std::string& filename) { - RestoreConfigFromBackup("backup.snapkey", filename); -} - -bool LoadConfig(const std::string& filename) { - std::ifstream configFile(filename); - if (!configFile.is_open()) { - CreateDefaultConfig(filename); - return false; - } - - string line; - int id = 0; - while (getline(configFile, line)) { - istringstream iss(line); - string key; - int value; - regex secPat(R"(\s*\[Group\]\s*)"); - if (regex_match(line, secPat)) { - id++; - } else if (getline(iss, key, '=') && (iss >> value)) { - if (key.find("key") != string::npos) { - if (!KeyInfo[value].registered) { - KeyInfo[value].registered = true; - KeyInfo[value].group = id; - } else { - MessageBox(NULL, - TEXT("The config file contains duplicate keys. Please review the setup."), - TEXT("SnapKey Error"), MB_ICONEXCLAMATION | MB_OK); - return false; - } - } - } - } - return true; -} diff --git a/SnapKeyPro.exe b/SnapKeyPro.exe new file mode 100644 index 0000000..48e0117 Binary files /dev/null and b/SnapKeyPro.exe differ diff --git a/banner.png b/banner.png new file mode 100644 index 0000000..22cfca9 Binary files /dev/null and b/banner.png differ diff --git a/config.cfg b/config.cfg deleted file mode 100644 index 367cb70..0000000 --- a/config.cfg +++ /dev/null @@ -1,86 +0,0 @@ -[Group] -key1=65 -key2=68 - -[Group] -key3=83 -key4=87 - - -# After applying the changes, please restart SnapKey. -# For further help, visit the README.pdf file. -# More about rebinding keys - github.com/cafali/SnapKey/wiki/Rebinding-Keys - -# ------------------------------------------------------------- -# Q D / Z S AZERTY Key1=81 Key2=68 / Key3=90 Key4=83 -# A D / S W QWERTY Key1=65 Key2=68 / Key3=83 Key4=87 -# A D / S W QWERTZ Key1=65 Key2=68 / Key3=83 Key4=87 -# ------------------------------------------------------------- - -# Default Keys: - -# A - 65 -# D - 68 -# S - 83 -# W - 87 - -# ASCII Code List: - -# A - 65 -# B - 66 -# C - 67 -# D - 68 -# E - 69 -# F - 70 -# G - 71 -# H - 72 -# I - 73 -# J - 74 -# K - 75 -# L - 76 -# M - 77 -# N - 78 -# O - 79 -# P - 80 -# Q - 81 -# R - 82 -# S - 83 -# T - 84 -# U - 85 -# V - 86 -# W - 87 -# X - 88 -# Y - 89 -# Z - 90 - -# Arrow Keys: - -# Up - 38 -# Down - 40 -# Left - 37 -# Right - 39 - -# Special Keys: - -# BACKSPACE - 8 -# L SHIFT - 160 -# R SHIFT - 161 -# L CONTROL - 162 -# R CONTROL - 163 -# ALT - 164 -# ESC - 27 -# SPACE - 32 -# DEL - 46 - -# Numpad Keys: - -# NUM0 - 96 -# NUM1 - 97 -# NUM2 - 98 -# NUM3 - 99 -# NUM4 - 100 -# NUM5 - 101 -# NUM6 - 102 -# NUM7 - 103 -# NUM8 - 104 -# NUM9 - 105 diff --git a/icon.ico b/icon.ico index bd8e6db..8af0d8d 100644 Binary files a/icon.ico and b/icon.ico differ diff --git a/icon_off.ico b/icon_off.ico deleted file mode 100644 index 505b29c..0000000 Binary files a/icon_off.ico and /dev/null differ diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..03e438f --- /dev/null +++ b/main.cpp @@ -0,0 +1,254 @@ +#include +#include +#include "InputState.h" +#include "resource.h" + +// ========================= +// GLOBAL APP STATE +// ========================= +bool g_enabled = true; +bool g_socd_enabled = true; +bool g_mouse_override_enabled = true; + +// Axis-specific SOCD toggles +bool g_socd_x_enabled = true; // A / D +bool g_socd_y_enabled = true; // W / S + +// ========================= +// INPUT STATE DEFINITIONS +// ========================= +bool pW=false, pA=false, pS=false, pD=false; +bool pFire=false; + +bool sW=false, sA=false, sS=false, sD=false; +bool lW=false, lA=false, lS=false, lD=false; + +bool prevW=false, prevA=false, prevS=false, prevD=false; + +char lastH=0; +char lastV=0; + +// ========================= +// TRAY DEFINITIONS +// ========================= +#define WM_TRAYICON (WM_USER + 1) + +#define ID_TOGGLE_SOCD 2001 +#define ID_TOGGLE_MOUSE 2002 +#define ID_TOGGLE_SOCD_X 2007 +#define ID_TOGGLE_SOCD_Y 2008 +#define ID_HELP 2003 +#define ID_UPDATE 2004 +#define ID_VERSION 2005 +#define ID_EXIT 2006 + +NOTIFYICONDATA nid = {}; +HMENU hTrayMenu; +HINSTANCE g_hInst; + +// ========================= +// UPDATE TRAY MENU TEXT +// ========================= +void UpdateMenuText() { + + ModifyMenu( + hTrayMenu, + ID_TOGGLE_SOCD, + MF_BYCOMMAND | MF_STRING, + ID_TOGGLE_SOCD, + g_socd_enabled ? TEXT("Disable SnapTap") : TEXT("Enable SnapTap") + ); + + ModifyMenu( + hTrayMenu, + ID_TOGGLE_SOCD_X, + MF_BYCOMMAND | MF_STRING, + ID_TOGGLE_SOCD_X, + g_socd_x_enabled ? TEXT("Disable X (A/D)") : TEXT("Enable X (A/D)") + ); + + ModifyMenu( + hTrayMenu, + ID_TOGGLE_SOCD_Y, + MF_BYCOMMAND | MF_STRING, + ID_TOGGLE_SOCD_Y, + g_socd_y_enabled ? TEXT("Disable Y (W/S)") : TEXT("Enable Y (W/S)") + ); + + ModifyMenu( + hTrayMenu, + ID_TOGGLE_MOUSE, + MF_BYCOMMAND | MF_STRING, + ID_TOGGLE_MOUSE, + g_mouse_override_enabled + ? TEXT("Disable Mouse Override") + : TEXT("Enable Mouse Override") + ); +} + +// ========================= +// WINDOW PROC +// ========================= +LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { + + switch (msg) { + + case WM_TRAYICON: + if (lParam == WM_RBUTTONUP) { + POINT pt; + GetCursorPos(&pt); + SetForegroundWindow(hwnd); + + UpdateMenuText(); + + TrackPopupMenu( + hTrayMenu, + TPM_RIGHTBUTTON, + pt.x, + pt.y, + 0, + hwnd, + NULL + ); + } + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + + case ID_TOGGLE_SOCD: + g_socd_enabled = !g_socd_enabled; + break; + + case ID_TOGGLE_SOCD_X: + g_socd_x_enabled = !g_socd_x_enabled; + break; + + case ID_TOGGLE_SOCD_Y: + g_socd_y_enabled = !g_socd_y_enabled; + break; + + case ID_TOGGLE_MOUSE: + g_mouse_override_enabled = !g_mouse_override_enabled; + break; + + case ID_HELP: + MessageBox( + hwnd, + TEXT("Email: soma27245@gmail.com"), + TEXT("Get Help"), + MB_OK | MB_ICONINFORMATION + ); + break; + + case ID_UPDATE: + ShellExecute( + NULL, + TEXT("open"), + TEXT("https://github.com/SAPNXTDOOR/SnapKey-Pro/releases"), + NULL, + NULL, + SW_SHOWNORMAL + ); + break; + + case ID_VERSION: + MessageBox( + hwnd, + TEXT( + "SnapKey Pro v1.2\n" + "Release Date: 15/1/26\n" + "Repository: github.com/SAPNXTDOOR/SnapKey-Pro\n\n" + "This app is made by Saptarshi Mallick." + ), + TEXT("Version Info"), + MB_OK | MB_ICONINFORMATION + ); + break; + + case ID_EXIT: + Shell_NotifyIcon(NIM_DELETE, &nid); + PostQuitMessage(0); + break; + } + break; + + case WM_DESTROY: + Shell_NotifyIcon(NIM_DELETE, &nid); + PostQuitMessage(0); + break; + } + + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +// ========================= +// WINMAIN +// ========================= +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) { + g_hInst = hInstance; + + WNDCLASS wc = {}; + wc.lpfnWndProc = WindowProc; + wc.hInstance = hInstance; + wc.lpszClassName = TEXT("SnapKeyProTray"); + + RegisterClass(&wc); + + HWND hwnd = CreateWindowEx( + 0, + wc.lpszClassName, + TEXT("SnapKey Pro"), + WS_OVERLAPPEDWINDOW, + 0, 0, 0, 0, + NULL, + NULL, + hInstance, + NULL + ); + + // ========================= + // TRAY MENU + // ========================= + hTrayMenu = CreatePopupMenu(); + + AppendMenu(hTrayMenu, MF_STRING, ID_TOGGLE_SOCD, TEXT("Disable SnapTap")); + AppendMenu(hTrayMenu, MF_STRING, ID_TOGGLE_SOCD_X, TEXT("Disable X (A/D)")); + AppendMenu(hTrayMenu, MF_STRING, ID_TOGGLE_SOCD_Y, TEXT("Disable Y (W/S)")); + AppendMenu(hTrayMenu, MF_STRING, ID_TOGGLE_MOUSE, TEXT("Disable Mouse Override")); + AppendMenu(hTrayMenu, MF_SEPARATOR, 0, NULL); + + AppendMenu(hTrayMenu, MF_STRING, ID_HELP, TEXT("Get Help")); + AppendMenu(hTrayMenu, MF_STRING, ID_UPDATE, TEXT("Check for updates")); + AppendMenu(hTrayMenu, MF_STRING, ID_VERSION, TEXT("Version Info")); + AppendMenu(hTrayMenu, MF_SEPARATOR, 0, NULL); + + AppendMenu(hTrayMenu, MF_STRING, ID_EXIT, TEXT("Exit")); + + // ========================= + // TRAY ICON + // ========================= + nid.cbSize = sizeof(NOTIFYICONDATA); + nid.hWnd = hwnd; + nid.uID = 1; + nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; + nid.uCallbackMessage = WM_TRAYICON; + nid.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); + lstrcpy(nid.szTip, TEXT("SnapKey Pro")); + + Shell_NotifyIcon(NIM_ADD, &nid); + + // ========================= + // INSTALL HOOKS + // ========================= + InstallKeyboardHook(); + InstallMouseHook(); + + MSG msg; + while (GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + return 0; +} diff --git a/meta/backup.snapkey b/meta/backup.snapkey deleted file mode 100644 index 367cb70..0000000 --- a/meta/backup.snapkey +++ /dev/null @@ -1,86 +0,0 @@ -[Group] -key1=65 -key2=68 - -[Group] -key3=83 -key4=87 - - -# After applying the changes, please restart SnapKey. -# For further help, visit the README.pdf file. -# More about rebinding keys - github.com/cafali/SnapKey/wiki/Rebinding-Keys - -# ------------------------------------------------------------- -# Q D / Z S AZERTY Key1=81 Key2=68 / Key3=90 Key4=83 -# A D / S W QWERTY Key1=65 Key2=68 / Key3=83 Key4=87 -# A D / S W QWERTZ Key1=65 Key2=68 / Key3=83 Key4=87 -# ------------------------------------------------------------- - -# Default Keys: - -# A - 65 -# D - 68 -# S - 83 -# W - 87 - -# ASCII Code List: - -# A - 65 -# B - 66 -# C - 67 -# D - 68 -# E - 69 -# F - 70 -# G - 71 -# H - 72 -# I - 73 -# J - 74 -# K - 75 -# L - 76 -# M - 77 -# N - 78 -# O - 79 -# P - 80 -# Q - 81 -# R - 82 -# S - 83 -# T - 84 -# U - 85 -# V - 86 -# W - 87 -# X - 88 -# Y - 89 -# Z - 90 - -# Arrow Keys: - -# Up - 38 -# Down - 40 -# Left - 37 -# Right - 39 - -# Special Keys: - -# BACKSPACE - 8 -# L SHIFT - 160 -# R SHIFT - 161 -# L CONTROL - 162 -# R CONTROL - 163 -# ALT - 164 -# ESC - 27 -# SPACE - 32 -# DEL - 46 - -# Numpad Keys: - -# NUM0 - 96 -# NUM1 - 97 -# NUM2 - 98 -# NUM3 - 99 -# NUM4 - 100 -# NUM5 - 101 -# NUM6 - 102 -# NUM7 - 103 -# NUM8 - 104 -# NUM9 - 105 diff --git a/meta/profiles/ARROW Keys.cfg b/meta/profiles/ARROW Keys.cfg deleted file mode 100644 index 05d2d22..0000000 --- a/meta/profiles/ARROW Keys.cfg +++ /dev/null @@ -1,86 +0,0 @@ -[Group] -key1=38 -key2=40 - -[Group] -key3=37 -key4=39 - - -# After applying the changes, please restart SnapKey. -# For further help, visit the README.pdf file. -# More about rebinding keys - github.com/cafali/SnapKey/wiki/Rebinding-Keys - -# ------------------------------------------------------------- -# Q D / Z S AZERTY Key1=81 Key2=68 / Key3=90 Key4=83 -# A D / S W QWERTY Key1=65 Key2=68 / Key3=83 Key4=87 -# A D / S W QWERTZ Key1=65 Key2=68 / Key3=83 Key4=87 -# ------------------------------------------------------------- - -# Default Keys: - -# A - 65 -# D - 68 -# S - 83 -# W - 87 - -# ASCII Code List: - -# A - 65 -# B - 66 -# C - 67 -# D - 68 -# E - 69 -# F - 70 -# G - 71 -# H - 72 -# I - 73 -# J - 74 -# K - 75 -# L - 76 -# M - 77 -# N - 78 -# O - 79 -# P - 80 -# Q - 81 -# R - 82 -# S - 83 -# T - 84 -# U - 85 -# V - 86 -# W - 87 -# X - 88 -# Y - 89 -# Z - 90 - -# Arrow Keys: - -# Up - 38 -# Down - 40 -# Left - 37 -# Right - 39 - -# Special Keys: - -# BACKSPACE - 8 -# L SHIFT - 160 -# R SHIFT - 161 -# L CONTROL - 162 -# R CONTROL - 163 -# ALT - 164 -# ESC - 27 -# SPACE - 32 -# DEL - 46 - -# Numpad Keys: - -# NUM0 - 96 -# NUM1 - 97 -# NUM2 - 98 -# NUM3 - 99 -# NUM4 - 100 -# NUM5 - 101 -# NUM6 - 102 -# NUM7 - 103 -# NUM8 - 104 -# NUM9 - 105 \ No newline at end of file diff --git a/meta/profiles/AZERTY Layout.cfg b/meta/profiles/AZERTY Layout.cfg deleted file mode 100644 index f775568..0000000 --- a/meta/profiles/AZERTY Layout.cfg +++ /dev/null @@ -1,86 +0,0 @@ -[Group] -key1=81 -key2=68 - -[Group] -key3=90 -key4=83 - - -# After applying the changes, please restart SnapKey. -# For further help, visit the README.pdf file. -# More about rebinding keys - github.com/cafali/SnapKey/wiki/Rebinding-Keys - -# ------------------------------------------------------------- -# Q D / Z S AZERTY Key1=81 Key2=68 / Key3=90 Key4=83 -# A D / S W QWERTY Key1=65 Key2=68 / Key3=83 Key4=87 -# A D / S W QWERTZ Key1=65 Key2=68 / Key3=83 Key4=87 -# ------------------------------------------------------------- - -# Default Keys: - -# A - 65 -# D - 68 -# S - 83 -# W - 87 - -# ASCII Code List: - -# A - 65 -# B - 66 -# C - 67 -# D - 68 -# E - 69 -# F - 70 -# G - 71 -# H - 72 -# I - 73 -# J - 74 -# K - 75 -# L - 76 -# M - 77 -# N - 78 -# O - 79 -# P - 80 -# Q - 81 -# R - 82 -# S - 83 -# T - 84 -# U - 85 -# V - 86 -# W - 87 -# X - 88 -# Y - 89 -# Z - 90 - -# Arrow Keys: - -# Up - 38 -# Down - 40 -# Left - 37 -# Right - 39 - -# Special Keys: - -# BACKSPACE - 8 -# L SHIFT - 160 -# R SHIFT - 161 -# L CONTROL - 162 -# R CONTROL - 163 -# ALT - 164 -# ESC - 27 -# SPACE - 32 -# DEL - 46 - -# Numpad Keys: - -# NUM0 - 96 -# NUM1 - 97 -# NUM2 - 98 -# NUM3 - 99 -# NUM4 - 100 -# NUM5 - 101 -# NUM6 - 102 -# NUM7 - 103 -# NUM8 - 104 -# NUM9 - 105 \ No newline at end of file diff --git a/meta/profiles/CUSTOM Profile.cfg b/meta/profiles/CUSTOM Profile.cfg deleted file mode 100644 index a703020..0000000 --- a/meta/profiles/CUSTOM Profile.cfg +++ /dev/null @@ -1,86 +0,0 @@ -[Group] -key1=65 -key2=68 - -[Group] -key3=83 -key4=87 - - -# After applying the changes, please restart SnapKey. -# For further help, visit the README.pdf file. -# More about rebinding keys - github.com/cafali/SnapKey/wiki/Rebinding-Keys - -# ------------------------------------------------------------- -# Q D / Z S AZERTY Key1=81 Key2=68 / Key3=90 Key4=83 -# A D / S W QWERTY Key1=65 Key2=68 / Key3=83 Key4=87 -# A D / S W QWERTZ Key1=65 Key2=68 / Key3=83 Key4=87 -# ------------------------------------------------------------- - -# Default Keys: - -# A - 65 -# D - 68 -# S - 83 -# W - 87 - -# ASCII Code List: - -# A - 65 -# B - 66 -# C - 67 -# D - 68 -# E - 69 -# F - 70 -# G - 71 -# H - 72 -# I - 73 -# J - 74 -# K - 75 -# L - 76 -# M - 77 -# N - 78 -# O - 79 -# P - 80 -# Q - 81 -# R - 82 -# S - 83 -# T - 84 -# U - 85 -# V - 86 -# W - 87 -# X - 88 -# Y - 89 -# Z - 90 - -# Arrow Keys: - -# Up - 38 -# Down - 40 -# Left - 37 -# Right - 39 - -# Special Keys: - -# BACKSPACE - 8 -# L SHIFT - 160 -# R SHIFT - 161 -# L CONTROL - 162 -# R CONTROL - 163 -# ALT - 164 -# ESC - 27 -# SPACE - 32 -# DEL - 46 - -# Numpad Keys: - -# NUM0 - 96 -# NUM1 - 97 -# NUM2 - 98 -# NUM3 - 99 -# NUM4 - 100 -# NUM5 - 101 -# NUM6 - 102 -# NUM7 - 103 -# NUM8 - 104 -# NUM9 - 105 \ No newline at end of file diff --git a/meta/profiles/ESDF Keys.cfg b/meta/profiles/ESDF Keys.cfg deleted file mode 100644 index 7b36d87..0000000 --- a/meta/profiles/ESDF Keys.cfg +++ /dev/null @@ -1,86 +0,0 @@ -[Group] -key1=69 -key2=68 - -[Group] -key3=83 -key4=70 - - -# After applying the changes, please restart SnapKey. -# For further help, visit the README.pdf file. -# More about rebinding keys - github.com/cafali/SnapKey/wiki/Rebinding-Keys - -# ------------------------------------------------------------- -# Q D / Z S AZERTY Key1=81 Key2=68 / Key3=90 Key4=83 -# A D / S W QWERTY Key1=65 Key2=68 / Key3=83 Key4=87 -# A D / S W QWERTZ Key1=65 Key2=68 / Key3=83 Key4=87 -# ------------------------------------------------------------- - -# Default Keys: - -# A - 65 -# D - 68 -# S - 83 -# W - 87 - -# ASCII Code List: - -# A - 65 -# B - 66 -# C - 67 -# D - 68 -# E - 69 -# F - 70 -# G - 71 -# H - 72 -# I - 73 -# J - 74 -# K - 75 -# L - 76 -# M - 77 -# N - 78 -# O - 79 -# P - 80 -# Q - 81 -# R - 82 -# S - 83 -# T - 84 -# U - 85 -# V - 86 -# W - 87 -# X - 88 -# Y - 89 -# Z - 90 - -# Arrow Keys: - -# Up - 38 -# Down - 40 -# Left - 37 -# Right - 39 - -# Special Keys: - -# BACKSPACE - 8 -# L SHIFT - 160 -# R SHIFT - 161 -# L CONTROL - 162 -# R CONTROL - 163 -# ALT - 164 -# ESC - 27 -# SPACE - 32 -# DEL - 46 - -# Numpad Keys: - -# NUM0 - 96 -# NUM1 - 97 -# NUM2 - 98 -# NUM3 - 99 -# NUM4 - 100 -# NUM5 - 101 -# NUM6 - 102 -# NUM7 - 103 -# NUM8 - 104 -# NUM9 - 105 \ No newline at end of file diff --git a/meta/profiles/WASD Keys.cfg b/meta/profiles/WASD Keys.cfg deleted file mode 100644 index a703020..0000000 --- a/meta/profiles/WASD Keys.cfg +++ /dev/null @@ -1,86 +0,0 @@ -[Group] -key1=65 -key2=68 - -[Group] -key3=83 -key4=87 - - -# After applying the changes, please restart SnapKey. -# For further help, visit the README.pdf file. -# More about rebinding keys - github.com/cafali/SnapKey/wiki/Rebinding-Keys - -# ------------------------------------------------------------- -# Q D / Z S AZERTY Key1=81 Key2=68 / Key3=90 Key4=83 -# A D / S W QWERTY Key1=65 Key2=68 / Key3=83 Key4=87 -# A D / S W QWERTZ Key1=65 Key2=68 / Key3=83 Key4=87 -# ------------------------------------------------------------- - -# Default Keys: - -# A - 65 -# D - 68 -# S - 83 -# W - 87 - -# ASCII Code List: - -# A - 65 -# B - 66 -# C - 67 -# D - 68 -# E - 69 -# F - 70 -# G - 71 -# H - 72 -# I - 73 -# J - 74 -# K - 75 -# L - 76 -# M - 77 -# N - 78 -# O - 79 -# P - 80 -# Q - 81 -# R - 82 -# S - 83 -# T - 84 -# U - 85 -# V - 86 -# W - 87 -# X - 88 -# Y - 89 -# Z - 90 - -# Arrow Keys: - -# Up - 38 -# Down - 40 -# Left - 37 -# Right - 39 - -# Special Keys: - -# BACKSPACE - 8 -# L SHIFT - 160 -# R SHIFT - 161 -# L CONTROL - 162 -# R CONTROL - 163 -# ALT - 164 -# ESC - 27 -# SPACE - 32 -# DEL - 46 - -# Numpad Keys: - -# NUM0 - 96 -# NUM1 - 97 -# NUM2 - 98 -# NUM3 - 99 -# NUM4 - 100 -# NUM5 - 101 -# NUM6 - 102 -# NUM7 - 103 -# NUM8 - 104 -# NUM9 - 105 \ No newline at end of file diff --git a/resource.h b/resource.h new file mode 100644 index 0000000..aaea70c --- /dev/null +++ b/resource.h @@ -0,0 +1,3 @@ +#pragma once + +#define IDI_APP_ICON 101 diff --git a/resource.o b/resource.o new file mode 100644 index 0000000..82186f3 Binary files /dev/null and b/resource.o differ diff --git a/resource.rc b/resource.rc new file mode 100644 index 0000000..fd1973b --- /dev/null +++ b/resource.rc @@ -0,0 +1,3 @@ +#include "resource.h" + +IDI_APP_ICON ICON "icon.ico" diff --git a/resources.rc b/resources.rc deleted file mode 100644 index 89f1106..0000000 --- a/resources.rc +++ /dev/null @@ -1,32 +0,0 @@ -#include - -// Icon resource -IDI_ICON1 ICON "snapkey.ico" - -// Version information -1 VERSIONINFO -FILEVERSION 1,2,9,0 -PRODUCTVERSION 1,2,9,0 -FILEOS 0x40004 -FILETYPE 0x1 -{ - BLOCK "StringFileInfo" - { - BLOCK "040904B0" - { - VALUE "FileDescription", "SnapKey" - VALUE "InternalName", "SnapKey.exe" - VALUE "OriginalFilename", "SnapKey.exe" - VALUE "CompanyName", "cafali" - VALUE "LegalCopyright", "Copyright \xA9 2025 cafali - MIT License (github.com/cafali/SnapKey)" - VALUE "ProductName", "SnapKey" - VALUE "FileVersion", "1.2.9.0" - VALUE "ProductVersion", "1.2.9.0" - } - } - - BLOCK "VarFileInfo" - { - VALUE "Translation", 0x0409, 0x04B0 - } -}