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..888f520 --- /dev/null +++ b/Hooks.cpp @@ -0,0 +1,165 @@ +#include +#include +#include +#include + +#include "InputState.h" + +HHOOK keyboardHook = NULL; +HHOOK mouseHook = NULL; + +/* ========================= + HOTKEY STRUCT (from main) + ========================= */ +struct Hotkey +{ + UINT modifiers; + UINT vk; +}; + +extern std::vector hotkeys; +extern std::map actions; + +void HandleHotkey(int id); + +/* ========================= + CHECK MOUSE HOTKEYS + ========================= */ +void CheckMouseHotkeys(UINT vk) +{ + for(int i=0;i<(int)hotkeys.size();i++) + { + if(hotkeys[i].vk == vk) + { + HandleHotkey(i); + } + } +} + +/* ========================= + 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) { + + MSLLHOOKSTRUCT* ms = (MSLLHOOKSTRUCT*)lParam; + + switch (wParam) + { + + case WM_LBUTTONDOWN: + pFire = true; + Update(); + CheckMouseHotkeys(VK_LBUTTON); + break; + + case WM_LBUTTONUP: + pFire = false; + Update(); + break; + + case WM_RBUTTONDOWN: + CheckMouseHotkeys(VK_RBUTTON); + break; + + case WM_MBUTTONDOWN: + CheckMouseHotkeys(VK_MBUTTON); + break; + + case WM_XBUTTONDOWN: + + if(HIWORD(ms->mouseData) == XBUTTON1) + CheckMouseHotkeys(VK_XBUTTON1); + + if(HIWORD(ms->mouseData) == XBUTTON2) + CheckMouseHotkeys(VK_XBUTTON2); + + break; + } + } + + return CallNextHookEx(NULL, nCode, wParam, lParam); +} + +/* ========================= + INSTALL HOOKS + ========================= */ +void InstallKeyboardHook() { + + keyboardHook = SetWindowsHookEx( + WH_KEYBOARD_LL, + KeyboardProc, + NULL, + 0 + ); +} + +void InstallMouseHook() { + + mouseHook = SetWindowsHookEx( + WH_MOUSE_LL, + MouseProc, + NULL, + 0 + ); +} \ No newline at end of file diff --git a/How to Compile.txt b/How to Compile.txt new file mode 100644 index 0000000..40d3a00 --- /dev/null +++ b/How to Compile.txt @@ -0,0 +1 @@ +g++ *.cpp resource.o admin.o -o "SnapKey Pro.exe" -mwindows -static -static-libgcc -static-libstdc++ -luser32 -lgdi32 -lshlwapi \ No newline at end of file diff --git a/InputState.h b/InputState.h new file mode 100644 index 0000000..6b1de33 --- /dev/null +++ b/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/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..ca02d57 --- /dev/null +++ b/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/README.md b/README.md index 67e93d4..efb3ab2 100644 --- a/README.md +++ b/README.md @@ -1,132 +1,238 @@ -[![testsnap](https://github.com/user-attachments/assets/e9a23ba9-d394-4711-abfc-994932605d86)](https://github.com/cafali/SnapKey/releases) +

+ SnapKey Pro Banner +

-**About SnapKey** --------------------------------------------------------------------------------------------------- -SnapKey provides a user-friendly alternative to the Razer Snap Tap function, making it accessible across all keyboards! +

+ + + +

-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) +# SnapKey Pro -[![COMPATIBLE](https://github.com/user-attachments/assets/069a7a23-cfe4-47eb-8ac2-05872fcc2028)](https://github.com/cafali/SnapKey/wiki/Compatibility-List) +SnapKey Pro provides a user-friendly alternative to the **Razer Snap Tap** feature, making it accessible on **any keyboard**. +It is a lightweight open-source Windows utility that runs in the **system tray** and manages movement key inputs to prevent conflicts. SnapKey Pro listens to keyboard inputs and automatically releases previously held movement keys when an opposite key is pressed, ensuring **responsive and precise movement control** in games. +SnapKey Pro does **not modify or interact with any game files** and works entirely through the **Windows API**. -Download --------------------------------------------------------------------------------------------------- -

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

+--- +## Features -[![latesver](https://github.com/user-attachments/assets/09694f7c-6eeb-4c80-9a02-1d777956d181)](https://github.com/cafali/SnapKey/wiki/Updates) +* Easy to use ๐Ÿงฉ +* Lightweight and open-source ๐ŸŒŸ +* Runs from the system tray ๐Ÿ–ฅ๏ธ +* Compatible with all keyboards โœ… +* Does not interact with game files ๐ŸŽฎ +* Enable / Disable features via tray menu โ›” +* Independent **X-axis and Y-axis SOCD control** +* **Mouse override support** for improved shooting accuracy +* **Sticky Keys system** for smoother movement recovery +* **Customizable global hotkeys** via `hotkeys.txt` +* **Edit Hotkeys** option directly from the tray menu +* **Restart option** to reload configuration instantly +* **Settings persistence** (remembers your toggle states) +* Uses only **Windows API** โ€” no AutoHotkey or external scripting tools -**SnapKey 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 ๐Ÿ—‚๏ธ -- 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** --------------------------------------------------------------------------------------------------- -- 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. +## How SnapKey Pro Works -**SnapKey prevents simultaneous movement key conflicts (AD / WS)** +### Basic Example -- 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. -- The keys are separated into two different groups: A/D and W/S. In each group, **"A"** cancels out **"D"** and vice versa, while the same applies to **"W"** and **"S"**. These groups do not interfere with each other and work separately. +1. Hold **A** +2. Press **D** +3. SnapKey Pro automatically releases **A** +4. Only **D** remains active -**Sticky Keys** +If you press **A** again while holding **D**, SnapKey Pro releases **D**. -- Sticky Keys is a feature that keeps track of the state of a key you've pressed down. For example, if you -hold down the **"A"** key and tap the **"D"** key repeatedly, each press of **"D"** will temporarily override -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. +This ensures there is **never conflicting input between opposite movement keys**. -> [!NOTE] -> SnapKey and similar solutions have been disallowed in certain games; illustrations shown are for demonstrative purposes only. +--- -![Snapkey](https://github.com/user-attachments/assets/504ffa5e-50d3-4a77-9016-70f22d143cb1) +## SOCD Handling (AD / WS) -**Enhanced precision of counter-strafing** +Movement keys are divided into two independent groups: -- Automatically releases a previously held key when a new key (A/D) & (W/S) is pressed. +| Axis | Keys | +| ---------- | ----- | +| Horizontal | A / D | +| Vertical | W / S | -STRAFE +Within each group: -**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)**. +* **A cancels D** +* **D cancels A** +* **W cancels S** +* **S cancels W** -[![LINUX baner](https://github.com/user-attachments/assets/794a16ed-b0ab-4320-a680-52bda1ca0fd1)](https://github.com/cafali/SnapKey/wiki/Setup-Linux) +The two groups operate **independently**, so pressing W and A together works normally. -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 +## Sticky Keys System -- **[Code Breakdown ๐Ÿง ](https://github.com/cafali/SnapKey/wiki/Code-Breakdown)** - Dive into the details of SnapKeyโ€™s code structure +Sticky Keys keeps track of held keys and restores them after temporary overrides. -- **[Compatibility List ๐ŸŽฎ](https://github.com/cafali/SnapKey/wiki/Compatibility-List)** - Compatibility status of games with SnapKey +Example: -- **[FAQโ“](https://github.com/cafali/SnapKey/wiki/FAQ)** - Find answers to common questions about SnapKey +1. Hold **A** +2. Tap **D** +3. D temporarily overrides A +4. Release D +5. **A resumes automatically** -- **[License ๐Ÿ“œ](https://github.com/cafali/SnapKey/wiki/License)** - Overview of SnapKeyโ€™s licensing +This makes movement feel **smooth and responsive** during rapid direction changes. -- **[Rebinding Keys โŒจ๏ธ](https://github.com/cafali/SnapKey/wiki/Rebinding-Keys)** - Instructions on how to rebind keys +The same behavior applies to **mouse override**: -- **[Setup ๐Ÿ› ๏ธ](https://github.com/cafali/SnapKey/wiki/Setup)** - General setup instructions for getting Snapkey up and running on your system +* When **Left Click** is pressed while moving, movement inputs can temporarily pause. +* Once the click is released, movement resumes if the key is still held. -- **[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 +## Mouse Override -- **[Troubleshoot ๐Ÿ”ง](https://github.com/cafali/SnapKey/wiki/Troubleshoot)** - Solutions and tips for troubleshooting common issues with SnapKey +Mouse override prevents unintended movement while firing. -- **[Changelog ๐Ÿ”„](https://github.com/cafali/SnapKey/wiki/Updates)** - View SnapKey releases and changes ----- +When **Left Click** is pressed: -

- SnapKey by -

+* Movement inputs can be temporarily disabled +* This improves **shooting accuracy** in certain scenarios. -

- @cafali - @minteeaa - @Yaw-Dev -

+--- -

- - - -

+## Hotkeys Configuration + +SnapKey Pro supports **custom global hotkeys**. + +Hotkeys are configured in: + +``` +hotkeys.txt +``` + +Example: + +``` +toggle_snapkey=Ctrl+Alt+S +toggle_socd_x=Ctrl+L +toggle_socd_y=Ctrl+Shift+1 +toggle_mouse_override=F13 +toggle_mouse_override_x=Alt+F14 +toggle_mouse_override_y=MouseX2 +``` + +Supported keys: + +* A-Z +* 0-9 +* F1โ€“F24 +* Ctrl +* Alt +* Shift +* Win +* MouseLeft +* MouseRight +* MouseMiddle +* MouseX1 +* MouseX2 + +Hotkeys can combine multiple modifiers: + +``` +Ctrl+Shift+F12 +Alt+F14 +Ctrl+Alt+S +``` + +After editing hotkeys: + +1. Right-click the tray icon +2. Click **Restart** + +or restart the application. + +--- + +## Tray Menu Options + +Right-click the tray icon to access: + +* Toggle SnapTap +* Toggle SOCD X +* Toggle SOCD Y +* Toggle Mouse Override +* Toggle Mouse Override X +* Toggle Mouse Override Y +* **Edit Hotkeys** +* **Restart** +* Get Help +* Check for Updates +* About +* Exit + +--- + +## Installation + +1. Download the latest release. +2. Extract the folder. +3. Ensure these files are together: + +``` +SnapKey Pro.exe +settings.ini +hotkeys.txt +``` + +4. Run: + +``` +SnapKey Pro.exe +``` + +The application will appear in the **system tray**. + +--- + +## Run at Startup (Optional) + +1. Press **Win + R** +2. Type: + +``` +shell:startup +``` + +3. Place a shortcut of **SnapKey Pro.exe** inside the folder. + +--- + +## Disclaimer + +Some games may restrict or disallow software that modifies input behavior. +SnapKey Pro is intended for **educational and demonstration purposes**. + +Please ensure that using this tool complies with the **rules of the games you play**. + +--- + +## Author + +SnapKey Pro by +**@SAPNXTDOOR** + +--- + +## License + +Open-source project. +See repository for license information. diff --git a/SnapKey Pro.exe b/SnapKey Pro.exe new file mode 100644 index 0000000..e5f2a6c Binary files /dev/null and b/SnapKey Pro.exe differ 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/admin.manifest b/admin.manifest new file mode 100644 index 0000000..4cbf179 --- /dev/null +++ b/admin.manifest @@ -0,0 +1,22 @@ + + + + + + SnapKey Pro + + + + + + + + + + diff --git a/admin.o b/admin.o new file mode 100644 index 0000000..46a491e Binary files /dev/null and b/admin.o differ diff --git a/admin.rc b/admin.rc new file mode 100644 index 0000000..879e859 --- /dev/null +++ b/admin.rc @@ -0,0 +1 @@ +1 24 "admin.manifest" 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/hotkeys.txt b/hotkeys.txt new file mode 100644 index 0000000..6082094 --- /dev/null +++ b/hotkeys.txt @@ -0,0 +1,32 @@ +toggle_snapkey=Ctrl+Alt+S +toggle_socd_x=Ctrl+L +toggle_socd_y=Ctrl+Shift+1 +toggle_mouse_override=Ctrl+Shift+2 +toggle_mouse_override_x=F6 +toggle_mouse_override_y=MouseX1 + + + + +# Format: +# action=key_combination + + + +# Supported keys: +# A-Z +# 0-9 +# F1-F24 +# Ctrl +# Alt +# Shift +# Win +# MouseLeft +# MouseRight +# MouseMiddle +# MouseX1 <- Side Button 1 +# MouseX2 <- Side Button 2 + + + +# After editing this file, DONT forget to save it and then restart SnapKey Pro or use the "Restart" option in the tray menu. 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..6a4941d --- /dev/null +++ b/main.cpp @@ -0,0 +1,447 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "InputState.h" +#include "resource.h" + +#pragma comment(lib,"shlwapi.lib") + +char g_iniPath[MAX_PATH]; + +void InitIniPath() +{ + GetModuleFileNameA(NULL,g_iniPath,MAX_PATH); + PathRemoveFileSpecA(g_iniPath); + strcat_s(g_iniPath,"\\settings.ini"); +} + +bool g_enabled = true; + +bool g_socd_enabled = true; +bool g_socd_x_enabled = true; +bool g_socd_y_enabled = true; + +bool g_mouse_override_enabled = true; +bool g_mouse_override_x_enabled = true; +bool g_mouse_override_y_enabled = true; + +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; + +#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_EDIT_HOTKEYS 2010 +#define ID_RESTART 2011 +#define ID_EXIT 2012 + +NOTIFYICONDATA nid = {}; +HMENU hTrayMenu; + +/* ================= SETTINGS ================= */ + +void LoadSettings() +{ + g_socd_enabled = + GetPrivateProfileInt("Settings","socd",1,g_iniPath); + + g_socd_x_enabled = + GetPrivateProfileInt("Settings","socd_x",1,g_iniPath); + + g_socd_y_enabled = + GetPrivateProfileInt("Settings","socd_y",1,g_iniPath); + + g_mouse_override_enabled = + GetPrivateProfileInt("Settings","mouse_override",1,g_iniPath); + + g_mouse_override_x_enabled = + GetPrivateProfileInt("Settings","mouse_override_x",1,g_iniPath); + + g_mouse_override_y_enabled = + GetPrivateProfileInt("Settings","mouse_override_y",1,g_iniPath); +} + +void SaveSettings() +{ + WritePrivateProfileString("Settings","socd", + g_socd_enabled?"1":"0",g_iniPath); + + WritePrivateProfileString("Settings","socd_x", + g_socd_x_enabled?"1":"0",g_iniPath); + + WritePrivateProfileString("Settings","socd_y", + g_socd_y_enabled?"1":"0",g_iniPath); + + WritePrivateProfileString("Settings","mouse_override", + g_mouse_override_enabled?"1":"0",g_iniPath); + + WritePrivateProfileString("Settings","mouse_override_x", + g_mouse_override_x_enabled?"1":"0",g_iniPath); + + WritePrivateProfileString("Settings","mouse_override_y", + g_mouse_override_y_enabled?"1":"0",g_iniPath); +} + +/* ================= HOTKEY SYSTEM ================= */ + +struct Hotkey +{ + UINT modifiers; + UINT vk; +}; + +std::vector hotkeys; +std::map actions; + +UINT ParseModifier(const std::string& key) +{ + if(key=="Ctrl") return MOD_CONTROL; + if(key=="Alt") return MOD_ALT; + if(key=="Shift") return MOD_SHIFT; + if(key=="Win") return MOD_WIN; + return 0; +} + +UINT ParseKey(const std::string& key) +{ + if(key.length()==1) + return VkKeyScan(key[0]) & 0xFF; + + if(key[0]=='F') + { + int n = atoi(key.substr(1).c_str()); + if(n>=1 && n<=24) + return VK_F1 + n - 1; + } + + if(key == "MouseLeft") return VK_LBUTTON; + if(key == "MouseRight") return VK_RBUTTON; + if(key == "MouseMiddle") return VK_MBUTTON; + if(key == "MouseX1") return VK_XBUTTON1; + if(key == "MouseX2") return VK_XBUTTON2; + + return 0; +} + +Hotkey ParseCombo(std::string combo) +{ + Hotkey hk{}; + hk.modifiers=0; + hk.vk=0; + + std::stringstream ss(combo); + std::string part; + + while(getline(ss,part,'+')) + { + part.erase(remove_if(part.begin(),part.end(),isspace),part.end()); + + UINT mod = ParseModifier(part); + + if(mod) + hk.modifiers |= mod; + else + hk.vk = ParseKey(part); + } + + return hk; +} + +void LoadHotkeys(HWND hwnd) +{ + std::ifstream file("hotkeys.txt"); + + if(!file.is_open()) + return; + + std::string line; + int id=0; + + while(getline(file,line)) + { + size_t pos=line.find('='); + if(pos==std::string::npos) continue; + + std::string action=line.substr(0,pos); + std::string combo=line.substr(pos+1); + + Hotkey hk = ParseCombo(combo); + + hotkeys.push_back(hk); + actions[id]=action; + + RegisterHotKey(hwnd,6000+id,hk.modifiers,hk.vk); + + id++; + } +} + +void HandleHotkey(int id) +{ + std::string action = actions[id]; + + if(action=="toggle_snapkey") + g_socd_enabled=!g_socd_enabled; + + else if(action=="toggle_socd_x") + g_socd_x_enabled=!g_socd_x_enabled; + + else if(action=="toggle_socd_y") + g_socd_y_enabled=!g_socd_y_enabled; + + else if(action=="toggle_mouse_override") + g_mouse_override_enabled=!g_mouse_override_enabled; + + else if(action=="toggle_mouse_override_x") + g_mouse_override_x_enabled=!g_mouse_override_x_enabled; + + else if(action=="toggle_mouse_override_y") + g_mouse_override_y_enabled=!g_mouse_override_y_enabled; + + SaveSettings(); +} + +/* ================= TRAY MENU ================= */ + +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_HOTKEY: + HandleHotkey(wParam-6000); + break; + + 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; + SaveSettings(); + break; + + case ID_TOGGLE_SOCD_X: + g_socd_x_enabled=!g_socd_x_enabled; + SaveSettings(); + break; + + case ID_TOGGLE_SOCD_Y: + g_socd_y_enabled=!g_socd_y_enabled; + SaveSettings(); + break; + + case ID_TOGGLE_MOUSE: + g_mouse_override_enabled=!g_mouse_override_enabled; + SaveSettings(); + break; + + case ID_TOGGLE_MOUSE_X: + g_mouse_override_x_enabled=!g_mouse_override_x_enabled; + SaveSettings(); + break; + + case ID_TOGGLE_MOUSE_Y: + g_mouse_override_y_enabled=!g_mouse_override_y_enabled; + SaveSettings(); + break; + + case ID_EDIT_HOTKEYS: + ShellExecuteA(NULL, + "open", + "hotkeys.txt", + NULL, + NULL, + SW_SHOWNORMAL); + break; + + case ID_RESTART: + { + char path[MAX_PATH]; + GetModuleFileNameA(NULL,path,MAX_PATH); + + ShellExecuteA(NULL,"open",path,NULL,NULL,SW_SHOWNORMAL); + + Shell_NotifyIcon(NIM_DELETE,&nid); + ExitProcess(0); + } + break; + + case ID_HELP: + MessageBox(hwnd, + TEXT("Email: soma27245@gmail.com"), + TEXT("Help"), + MB_OK|MB_ICONINFORMATION); + break; + + case ID_UPDATE: + ShellExecute(NULL,"open", + "https://github.com/SAPNXTDOOR/SnapKey-Pro/releases", + NULL,NULL,SW_SHOWNORMAL); + break; + + case ID_VERSION: + MessageBoxA(hwnd, + "SnapKey Pro v1.5.1\n" + "Release Date: 6/3/26\n" + "Repository: https://github.com/SAPNXTDOOR/SnapKey-Pro\n" + "\n" + "This app is made by Saptarshi Mallick.", + "About SnapKey Pro", + 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) +{ + + 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_EDIT_HOTKEYS,TEXT("Edit Hotkeys")); + AppendMenu(hTrayMenu,MF_STRING,ID_RESTART,TEXT("Restart")); + + 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("About")); + + 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(); + LoadHotkeys(hwnd); + + InstallKeyboardHook(); + InstallMouseHook(); + + MSG msg; + + while(GetMessage(&msg,NULL,0,0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + return 0; +} \ No newline at end of file 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/snapkey.ico b/resource.o similarity index 96% rename from snapkey.ico rename to resource.o index 8af0d8d..82186f3 100644 Binary files a/snapkey.ico 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 - } -} diff --git a/settings.ini b/settings.ini new file mode 100644 index 0000000..3d98195 --- /dev/null +++ b/settings.ini @@ -0,0 +1,8 @@ +[Settings] +socd=1 +socd_x=1 +socd_y=1 +mouse_override=1 +mouse_override_x=1 +mouse_override_y=1 +