From 216fe621f78aff8483b768b721df829819fcbe96 Mon Sep 17 00:00:00 2001 From: Demetry Date: Mon, 29 Jan 2024 21:17:00 -0500 Subject: [PATCH] Modified the Makefile to allow for debug builds The debug header is also modified to only print when in debug build. Moved resources to main exe and moved config handling to main exe Created a custom callback to handle hotkey presses. Fixed a bug where I was not passing the correct value to RegisterHotkey RegisterHotkey requires a virtual key scan code not a char as I initially believed. --- .gitignore | 10 +- Makefile | 94 ++++++++++---- actions.h | 7 -- config.c | 60 +++++---- config.h | 8 -- debug.h | 6 +- keyboard.c | 57 +++------ keyboard.h | 9 +- tiling.c | 3 +- wm.c | 92 +++++++++----- wm_dll.c | 166 ++++++------------------- wm_dll.def | 5 +- wm_dll_resources.rc => wm_resources.rc | 0 13 files changed, 233 insertions(+), 284 deletions(-) rename wm_dll_resources.rc => wm_resources.rc (100%) diff --git a/.gitignore b/.gitignore index 3a0fdbe..131e928 100644 --- a/.gitignore +++ b/.gitignore @@ -3,12 +3,12 @@ *.obj *.exp *.exe +*.pdb +*.ilk + tags .idea/ .vs/ -wm.ilk - -*.pdb - -*.ilk +debug/ +release/ \ No newline at end of file diff --git a/Makefile b/Makefile index e7d9cfb..119c8ce 100644 --- a/Makefile +++ b/Makefile @@ -1,34 +1,84 @@ -CC = cl -LD = link -RC = rc +CC = cl +LD = link +RC = rc +CFLAGS = /EHsc -EXEC = lightwm.exe -DLL = lightwm_dll.dll -RESOURCES=wm_dll_resources.obj +EXE_SRCS = wm.c tiling.c error.c config.c keyboard.c +DLL_SRCS = error.c wm_dll.c +EXE_NAME = lightwm.exe +DLL_NAME = lightwm_dll.dll +EXE_RC = wm_resources.obj +DLL_RC = -# Boiler plate -CFLAGS = /EHsc /Zi -LDFLAGS = +DBGDIR = debug +DBGEXE = $(DBGDIR)/$(EXE_NAME) +DBG_EXE_OBJS = $(addprefix $(DBGDIR)/, $(EXE_SRCS:.c=.obj)) +DBG_DLL_OBJS = $(addprefix $(DBGDIR)/, $(DLL_SRCS:.c=.obj)) +DBGDLL = $(DBGDIR)/$(DLL_NAME) +DBGCFLAGS = $(CFLAGS) /DDEBUG /Zi -EXE_SRCS = wm.c tiling.c error.c -DLL_SRCS = error.c config.c keyboard.c wm_dll.c +RELDIR = release +RELEXE = $(RELDIR)/$(EXE_NAME) +REL_EXE_OBJS = $(addprefix $(RELDIR)/, $(EXE_SRCS:.c=.obj)) +REL_DLL_OBJS = $(addprefix $(RELDIR)/, $(DLL_SRCS:.c=.obj)) +RELDLL = $(RELDIR)/$(DLL_NAME) +RELCFLAGS = $(CFLAGS) /Ox + -EXE_OBJS = $(EXE_SRCS:.c=.obj) -DLL_OBJS = $(DLL_SRCS:.c=.obj) +.PHONY: all clean debug prep release -all: $(DLL) $(EXEC) +# Default build +all: clean prep release -$(EXEC): $(EXE_OBJS) - $(CC) $(CFLAGS) /Fe:$@ $^ /link user32.lib +# +# Debug rules +# +debug: clean prep $(DBGEXE) $(DBGDLL) -$(DLL): $(DLL_OBJS) $(RESOURCES) - $(CC) $(CFLAGS) /LD /Fe:$@ $^ /link user32.lib shell32.lib ole32.lib shlwapi.lib /DEF:wm_dll.def +$(DBGEXE): $(DBG_EXE_OBJS) $(DBGDIR)/$(EXE_RC) + $(CC) $(DBGCFLAGS) /Fe:$@ $^ /link user32.lib shell32.lib ole32.lib shlwapi.lib -%.obj: %.c - $(CC) $(CFLAGS) /c /Fo:$@ $< +$(DBGDLL): $(DBG_DLL_OBJS) + $(CC) $(DBGCFLAGS) /Fe:$@ $^ /LD /link user32.lib /DEF:wm_dll.def -%.obj: %.rc +$(DBGDIR)/%.obj: %.c + $(CC) $(DBGCFLAGS) /c /Fo:$@ $< + +$(DBGDIR)/%.obj: %.rc + $(RC) /fo $@ $< + +# +# Release rules +# +release: prep $(RELEXE) $(RELDLL) + +$(RELEXE): $(REL_EXE_OBJS) $(RELDIR)/$(EXE_RESS) + $(CC) $(RELCFLAGS) /Fe:$@ $^ /link user32.lib shell32.lib ole32.lib shlwapi.lib + +$(RELDLL): $(REL_DLL_OBJS) + $(CC) $(RELCFLAGS) /Fe:$@ $^ /LD /link user32.lib /DEF:wm_dll.def + +$(RELDIR)/%.obj: %.c + $(CC) $(RELCFLAGS) /c /Fo:$@ $< + +$(RELDIR)/%.obj: %.rc $(RC) /fo $@ $< +# +# Prep and clean rules +# +prep: + @echo off > temp.bat && \ + echo IF NOT EXIST $(DBGDIR) mkdir $(DBGDIR) >> temp.bat && \ + echo IF NOT EXIST $(RELDIR) mkdir $(RELDIR) >> temp.bat && \ + temp.bat && \ + del temp.bat + clean: - del *.obj *.exe *.dll *.lib *.exp + @echo off > temp.bat && \ + echo IF EXIST $(DBGDIR) del /S /Q $(DBGDIR) >> temp.bat && \ + echo IF EXIST $(RELDIR) del /S /Q $(RELDIR) >> temp.bat && \ + echo IF EXIST $(DBGDIR) rd /S /Q $(DBGDIR) >> temp.bat && \ + echo IF EXIST $(RELDIR) rd /S /Q $(RELDIR) >> temp.bat && \ + temp.bat && \ + del temp.bat diff --git a/actions.h b/actions.h index 4e19482..b981f6f 100644 --- a/actions.h +++ b/actions.h @@ -1,10 +1,3 @@ -/** - * Actions - * - * Demetry Romanowski - * demetryromanowski@gmail.com - **/ - #pragma once //Just add the action to this preprocessor macro to generate the ENUM and string array diff --git a/config.c b/config.c index 336a643..b24d83a 100644 --- a/config.c +++ b/config.c @@ -1,10 +1,3 @@ -/** - * Config Reader and Parser - * This program will read the config for lightwm in the appdata directory - * - * Demetry Romanowski - * demetryromanowski@gmail.com - **/ #include "config.h" #include @@ -22,18 +15,12 @@ #define BUFF_SIZE 65536 -/** - * Config reader global vars - **/ PWSTR szConfigFilePath[MAX_PATH]; char* defaultConfigData = NULL; //Should probably create a meta structure that holds the total count for now just another global variable ConfigItems configItems; -/** - * Private prototypes here -**/ BOOL CreateDefaultConfigFile(HINSTANCE); BOOL LoadDefaultConfigResourceData(HINSTANCE); BOOL WriteDefaultConfigDataToFile(); @@ -48,7 +35,6 @@ DWORD ReadConfigFile() if(configFileHandle == NULL) { - SetLastError(ERROR_INVALID_HANDLE); reportWin32Error(L"Config file could not be opened"); CleanupConfigReader(); return ERROR_INVALID_HANDLE; @@ -61,14 +47,17 @@ DWORD ReadConfigFile() if(configItems.configItem == NULL) { - reportWin32Error(L"Allocation ConfigItem struct"); + reportWin32Error(L"Allocation ConfigItem memory"); CleanupConfigReader(); return ERROR_NOT_ENOUGH_MEMORY; } - for(size_t lineCount = 0; fgets(line, sizeof(line), configFileHandle); lineCount++) { + for(size_t lineCount = 0; fgets(line, sizeof(line), configFileHandle); lineCount++) + { if(strlen(line) == 0) + { continue; + } //Get the first half of the line char* token = strtok(line, " "); @@ -81,7 +70,7 @@ DWORD ReadConfigFile() configItems.configItem[lineCount].value = (char*)malloc(strlen(token) + 1); strncpy(configItems.configItem[lineCount].value, token, strlen(token) + 1); - DEBUG_PRINT("DEBUG config.c: Name: %s Value: %s Name LEN: %lu Value LEN: %lu Count: %lu\n", + DEBUG_PRINT("Name: %s Value: %s Name LEN: %lu Value LEN: %lu Count: %lu", configItems.configItem[lineCount].name, configItems.configItem[lineCount].value, strlen(configItems.configItem[lineCount].name), @@ -101,7 +90,6 @@ void GetConfigFilePath() HRESULT getAppDataPathResult = SHGetKnownFolderPath(&FOLDERID_RoamingAppData, 0, NULL, szConfigFilePath); if(!SUCCEEDED(getAppDataPathResult)) { - SetLastError(ERROR_PATH_NOT_FOUND); //SHGetKnownFolderPath does not set an error on fail so we set it manually reportWin32Error(L"Could not get the users appdata directory"); CoTaskMemFree(szConfigFilePath); exit(ERROR_PATH_NOT_FOUND); @@ -132,7 +120,6 @@ uint8_t LoadConfigFile(HINSTANCE resourceModuleHandle) { if(!CreateDefaultConfigFile(resourceModuleHandle)) { - SetLastError(ERROR_RESOURCE_NOT_AVAILABLE); reportWin32Error(L"Create a default config file"); return ERROR_RESOURCE_NOT_AVAILABLE; //TODO Maybe find a better error code here } @@ -179,10 +166,14 @@ ConfigItems* GetConfigItems() BOOL CreateDefaultConfigFile(HINSTANCE resourceModuleHandle) { if(!LoadDefaultConfigResourceData(resourceModuleHandle)) + { return FALSE; + } if(!WriteDefaultConfigDataToFile()) + { return FALSE; + } return TRUE; } @@ -248,18 +239,27 @@ void strip(char* str) char *start = str; char *end = str + len - 1; - while (*start == ' ') start++; - while (*end == ' ') end--; + while (*start == ' ') + { + start++; + } + + while (*end == ' ') + { + end--; + } memmove(str, start, end - start + 1); str[end - start + 1] = '\0'; } -void removeControlChars(char* str) { +void removeControlChars(char* str) +{ int i, j = 0; char temp[1024]; // Assuming the maximum length of the string is 1024 - for (i = 0; str[i] != '\0'; ++i) { + for (i = 0; str[i] != '\0'; ++i) + { if ((unsigned char)str[i] < 32) continue; // Skip control characters temp[j] = str[i]; ++j; @@ -277,15 +277,23 @@ size_t GetLineCount(FILE* file) { size_t res = fread(buf, 1, BUFF_SIZE, file); if (ferror(file)) - return -1; + { + return -1; + } int i; for(i = 0; i < res; i++) - if (buf[i] == '\n') + { + if (buf[i] == '\n') + { counter++; + } + } if (feof(file)) - break; + { + break; + } } fseek(file, 0, SEEK_SET); diff --git a/config.h b/config.h index 13d5c46..4375969 100644 --- a/config.h +++ b/config.h @@ -1,11 +1,3 @@ -/** - * Config Reader and Parser - * This program will read the config for lightwm in the appdata directory - * - * Demetry Romanowski - * demetryromanowski@gmail.com - **/ - #pragma once #include diff --git a/debug.h b/debug.h index 19f3f22..a7c809a 100644 --- a/debug.h +++ b/debug.h @@ -1,9 +1,7 @@ #pragma once -#define _DEBUG - -#ifdef _DEBUG -#define DEBUG_PRINT(format, ...) printf("DEBUG: Line %d: " format "\n", __LINE__, ##__VA_ARGS__) +#ifdef DEBUG +#define DEBUG_PRINT(format, ...) printf("DEBUG: %s Line %d: " format "\n", __FILE__, __LINE__, ##__VA_ARGS__) #else #define DEBUG_PRINT(format, ...) #endif \ No newline at end of file diff --git a/keyboard.c b/keyboard.c index 568b2a1..07af781 100644 --- a/keyboard.c +++ b/keyboard.c @@ -1,9 +1,3 @@ -/** - * keyboard.c Handles the keyboard controls - * - * Demetry Romanowski - * demetryromanowski@gmail.com - **/ #include #include #include @@ -13,24 +7,15 @@ #include "debug.h" -//Keyboard vars +UINT GetModifier(char* value); +UINT GetKeyCode(char* value); +void AddKeyboardKeybind(enum Action action, UINT modifier, UINT keyCode); -//Private definitions -uint8_t GetModifier(char* value); -char GetKeyCode(char* value); -void AddKeyboardKeybind(enum Action action, uint8_t modifier, uint8_t keyCode); - -HWND hotKeyWindow; - -//Public implementations -BOOL InitializeKeyboardConfig(HWND hwnd, ConfigItems* configItems) +BOOL InitializeKeyboardConfig(ConfigItems* configItems) { assert(configItems != NULL); assert(configItems->configItem != NULL); assert(configItems->configItemsCount != 0); - assert(hwnd != NULL); - - hotKeyWindow = hwnd; for(size_t i = 0; i < configItems->configItemsCount; i++) { //TODO Modify the macro to use generate all these automatically. @@ -49,37 +34,35 @@ BOOL InitializeKeyboardConfig(HWND hwnd, ConfigItems* configItems) void CleanupKeyboard() { - UnregisterHotKey(hotKeyWindow, WORKSPACE_1); - UnregisterHotKey(hotKeyWindow, WORKSPACE_2); - UnregisterHotKey(hotKeyWindow, WORKSPACE_3); - UnregisterHotKey(hotKeyWindow, WORKSPACE_4); - UnregisterHotKey(hotKeyWindow, WINDOW_UP); - UnregisterHotKey(hotKeyWindow, WINDOW_DOWN); - UnregisterHotKey(hotKeyWindow, WINDOW_LEFT); - UnregisterHotKey(hotKeyWindow, WINDOW_RIGHT); + UnregisterHotKey(NULL, WORKSPACE_1); + UnregisterHotKey(NULL, WORKSPACE_2); + UnregisterHotKey(NULL, WORKSPACE_3); + UnregisterHotKey(NULL, WORKSPACE_4); + UnregisterHotKey(NULL, WINDOW_UP); + UnregisterHotKey(NULL, WINDOW_DOWN); + UnregisterHotKey(NULL, WINDOW_LEFT); + UnregisterHotKey(NULL, WINDOW_RIGHT); } -//Private implementations -uint8_t GetModifier(char* value) +UINT GetModifier(char* value) { - // TODO + // TODO handle the different modifier values // MOD_ALT // MOD_CONTROL - // MOD_NOREPEAT // MOD_SHIFT // MOD_WIN return MOD_ALT; } -char GetKeyCode(char* value) +UINT GetKeyCode(char* value) { - // printf("DEBUG keyboard.c L146: %c\n", value[strlen(value) - 1]); - return value[strlen(value) - 1]; + DEBUG_PRINT("GetKeyCode char value '%c'", value[strlen(value) - 1]); + return VkKeyScanEx(value[strlen(value) - 1], GetKeyboardLayout(0)); } -void AddKeyboardKeybind(enum Action action, uint8_t modifier, char keyCode) +void AddKeyboardKeybind(enum Action action, UINT modifier, UINT keyCode) { - if(!RegisterHotKey(hotKeyWindow, action, modifier | MOD_NOREPEAT, keyCode)) + if(!RegisterHotKey(NULL, action, modifier | MOD_NOREPEAT, keyCode)) { if(GetLastError() == ERROR_HOTKEY_ALREADY_REGISTERED) { @@ -90,5 +73,5 @@ void AddKeyboardKeybind(enum Action action, uint8_t modifier, char keyCode) MessageBox(NULL, "Failed to register hotkey.", "Error", MB_OK | MB_ICONERROR); } - DEBUG_PRINT("DEBUG keyboard.c: Registered %s hotkey\n", ACTION_STRINGS[action]); + DEBUG_PRINT("Registered %s hotkey", ACTION_STRINGS[action]); } \ No newline at end of file diff --git a/keyboard.h b/keyboard.h index 853c953..e6b4153 100644 --- a/keyboard.h +++ b/keyboard.h @@ -1,10 +1,3 @@ -/** - * keyboard.c Handles the keyboard controls - * - * Demetry Romanowski - * demetryromanowski@gmail.com - **/ - #pragma once #include @@ -13,5 +6,5 @@ #include "config.h" #include "actions.h" -BOOL InitializeKeyboardConfig(HWND hwnd, ConfigItems* configItems); +BOOL InitializeKeyboardConfig(ConfigItems* configItems); void CleanupKeyboard(); diff --git a/tiling.c b/tiling.c index 5db98c1..a7f151a 100644 --- a/tiling.c +++ b/tiling.c @@ -42,5 +42,6 @@ void tileWindows() { return; } - TileWindows(GetDesktopWindow(), MDITILE_VERTICAL | MDITILE_SKIPDISABLED, NULL, currentManagedIndex, managed); + //TODO UNCOMMENT BEFORE MASTER MERGE + //TileWindows(GetDesktopWindow(), MDITILE_VERTICAL | MDITILE_SKIPDISABLED, NULL, currentManagedIndex, managed); } diff --git a/wm.c b/wm.c index a830a62..110a986 100644 --- a/wm.c +++ b/wm.c @@ -2,23 +2,28 @@ #include #include #include +#include #include "error.h" #include "tiling.h" +#include "keyboard.h" +#include "config.h" -//Hooks -HHOOK hookHandle; +#include "resource.h" -//Modules -HMODULE wmDll; +#include "debug.h" -//Event handles +HMODULE wmDll; +HHOOK hookShellProcHandle; HANDLE windowEvent; +//Has to absolutely match the definition in the dll +typedef LRESULT (*HotKeyProcType)(int, WPARAM, LPARAM); + void cleanupObjects() { - if (hookHandle) { - UnhookWindowsHookEx(hookHandle); + if (hookShellProcHandle) { + UnhookWindowsHookEx(hookShellProcHandle); } - + if (wmDll) { FreeLibrary(wmDll); } @@ -26,6 +31,9 @@ void cleanupObjects() { if (windowEvent) { CloseHandle(windowEvent); } + + CleanupConfigReader(); + CleanupKeyboard(); } void ctrlc(int sig) { @@ -37,11 +45,7 @@ void ctrlc(int sig) { } int main() { - //---------------------------------------------- - /** - * Load Libraries and the needed functions from those libraries - **/ - //---------------------------------------------- + // Load Libraries and the needed functions from those libraries wmDll = LoadLibraryW(L"lightwm_dll"); if (wmDll == NULL) { @@ -56,6 +60,13 @@ int main() { goto cleanup; } + HotKeyProcType HotKeyProc = (HotKeyProcType)GetProcAddress(wmDll, "HotkeyProc"); + + if (HotKeyProc == NULL) { + reportWin32Error(L"GetProcAddress failed for shell even callback"); + goto cleanup; + } + windowEvent = CreateEventW(NULL, FALSE, FALSE, L"LightWMWindowEvent"); if (windowEvent == NULL) { @@ -63,46 +74,59 @@ int main() { goto cleanup; } - hookHandle = SetWindowsHookExW(WH_SHELL, (HOOKPROC)shellProc, wmDll, 0); + hookShellProcHandle = SetWindowsHookExW(WH_SHELL, (HOOKPROC)shellProc, wmDll, 0); - if (hookHandle == NULL) { + if (hookShellProcHandle == NULL) { reportWin32Error(L"SetWindowsHookExW failed for shell hook"); goto cleanup; } signal(SIGINT, ctrlc); - - //---------------------------------------------- - /** - * Handle a message loop - **/ - //---------------------------------------------- + + //Load the configuration + if(LoadConfigFile(NULL) != ERROR_SUCCESS) + { + reportWin32Error(L"Load config file"); + goto cleanup; + } + + if(!InitializeKeyboardConfig(GetConfigItems())) + { + reportWin32Error(L"Setup keyboard config"); + goto cleanup; + } + + // Handle a message loop tileWindows(); MSG msg; while (GetMessage(&msg, NULL, 0, 0) != 0) { - //TODO Need to modify this wait so the program can handle hotkeys - // if (WaitForSingleObject(windowEvent, INFINITE) == WAIT_FAILED) { - // reportWin32Error(L"WaitForSingleObject"); - // goto cleanup; - // } + if(msg.message == WM_HOTKEY) { + //Because Win32 doesn't support hook callbacks with RegisterHotkey lets make our own callback. + assert(HotKeyProc != NULL); + + LRESULT ret = HotKeyProc(0, msg.wParam, msg.lParam); + if(ret != ERROR_SUCCESS) { + DEBUG_PRINT("HotKey was unhandled! Ret: %i", ret); + } + + TranslateMessage(&msg); + DispatchMessageW(&msg); + continue; + } else if (WaitForSingleObject(windowEvent, INFINITE) == WAIT_FAILED) { + reportWin32Error(L"WaitForSingleObject"); + goto cleanup; + } Sleep(100); tileWindows(); - + TranslateMessage(&msg); DispatchMessageW(&msg); } - //---------------------------------------------- - /** - * Cleanup and gracefully exit - **/ - //---------------------------------------------- cleanup: cleanupObjects(); - - return EXIT_FAILURE; } diff --git a/wm_dll.c b/wm_dll.c index 1e34bfb..874ce5d 100644 --- a/wm_dll.c +++ b/wm_dll.c @@ -2,15 +2,10 @@ #include #include "targetver.h" -#include "keyboard.h" -#include "config.h" +#include "actions.h" #include "debug.h" - -HWND hwnd; -const char g_szClassName[] = "HiddenWindowClass"; - __declspec(dllexport) LRESULT CALLBACK ShellProc(int code, WPARAM wparam, LPARAM lparam) { if (code == HSHELL_WINDOWCREATED || code == HSHELL_WINDOWDESTROYED) { const HANDLE windowEvent = OpenEventW(EVENT_ALL_ACCESS, FALSE, L"LightWMWindowEvent"); @@ -23,146 +18,57 @@ __declspec(dllexport) LRESULT CALLBACK ShellProc(int code, WPARAM wparam, LPARAM return CallNextHookEx(NULL, code, wparam, lparam); } -LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { - switch (msg) { - case WM_HOTKEY: - DEBUG_PRINT("DEBUG wm_dll.c L26: wParam = %i\n", wParam); - switch (wParam) { - case WORKSPACE_1: - puts("Switch to workspace 1"); //TODO - break; - case WORKSPACE_2: - puts("Switch to workspace 2"); //TODO - break; - case WORKSPACE_3: - puts("Switch to workspace 3"); //TODO - break; - case WORKSPACE_4: - puts("Switch to workspace 4"); //TODO - break; - case WINDOW_UP: - puts("Focus on window above current"); //TODO - break; - case WINDOW_DOWN: - puts("Focus on window below current"); //TODO - break; - case WINDOW_LEFT: - puts("Focus on window to the left of current"); //TODO - break; - case WINDOW_RIGHT: - puts("Focus on window to the right of current"); //TODO - break; - } - break; - default: - return DefWindowProc(hwnd, msg, wParam, lParam); - } +__declspec(dllexport) LRESULT HotkeyProc(int code, WPARAM wparam, LPARAM lparam) { + DEBUG_PRINT("HotkeyProc called - %i %i %i", code, wparam, lparam); - return 0; -} - -/** - * This is terrible... but I cannot think of any other way to do it with the RegisterHotkey function - */ -BOOL CreateHiddenWindow(HINSTANCE hModule) -{ - WNDCLASSEX wc; - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = 0; - wc.lpfnWndProc = WndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hModule; - wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); - wc.lpszMenuName = NULL; - wc.lpszClassName = g_szClassName; - wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); - - if(!RegisterClassEx(&wc)) { - MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); - return FALSE; - } - - hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName, "Hidden Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hModule, NULL); - - if(hwnd == NULL) { - MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); - return FALSE; + switch(wparam) + { + //TODO Can either trigger an event like the ShellProc callback, or handle directly. + // one method to handle virtual desktops is using the IVirtualDesktopManager in ShObjIdl but + // that is only available for Window 10 1809 or later. + case WORKSPACE_1: + puts("Switch to workspace 1"); + break; + case WORKSPACE_2: + puts("Switch to workspace 2"); + break; + case WORKSPACE_3: + puts("Switch to workspace 3"); + break; + case WORKSPACE_4: + puts("Switch to workspace 4"); + break; + case WINDOW_UP: + puts("Highlight window above"); + break; + case WINDOW_DOWN: + puts("Highlight window below"); + break; + case WINDOW_LEFT: + puts("Highlight window left"); + break; + case WINDOW_RIGHT: + puts("Highlight window right"); + break; + default: + DEBUG_PRINT("Unhandled hotkey message! Hotkey ID: %i", wparam); + break; } - - ShowWindow(hwnd, SW_HIDE); - UpdateWindow(hwnd); - return TRUE; + return CallNextHookEx(NULL, code, wparam, lparam); } BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD ulReasonForCall, LPVOID lpReserved) { switch(ulReasonForCall) { case DLL_PROCESS_ATTACH: - { - //---------------------------------------------- - /** - * Read the config file here - **/ - //---------------------------------------------- - if(LoadConfigFile(hModule) != ERROR_SUCCESS) - { - return FALSE; - } - - //---------------------------------------------- - /** - * Create a hidden window to handle the hotkey messages - **/ - //---------------------------------------------- - if(!CreateHiddenWindow(hModule)) - { - return FALSE; - } - - //---------------------------------------------- - /** - * Initialize the keyboard config and actions here - **/ - //---------------------------------------------- - if(!InitializeKeyboardConfig(hwnd, GetConfigItems())) - { - return FALSE; - } - } break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: - { - //---------------------------------------------- - /** - * Cleanup the config reader memory here - **/ - //---------------------------------------------- - CleanupConfigReader(); - - //---------------------------------------------- - /** - * Cleanup the config reader memory here - **/ - //---------------------------------------------- - CleanupKeyboard(); - - //---------------------------------------------- - /** - * Cleanup the hidden window - **/ - //---------------------------------------------- - DestroyWindow(hwnd); - } break; - default: break; } diff --git a/wm_dll.def b/wm_dll.def index ee3fed7..b674209 100644 --- a/wm_dll.def +++ b/wm_dll.def @@ -1,3 +1,4 @@ -LIBRARY wm_dll +LIBRARY lightwm_dll EXPORTS -ShellProc \ No newline at end of file +ShellProc +HotkeyProc \ No newline at end of file diff --git a/wm_dll_resources.rc b/wm_resources.rc similarity index 100% rename from wm_dll_resources.rc rename to wm_resources.rc