From dc06e6adbbde73a2860eaf3331038d3f444c3ef6 Mon Sep 17 00:00:00 2001 From: Dimitri Apostal Date: Sun, 18 Jan 2026 21:22:00 -0500 Subject: [PATCH] Refactor thread handling and improve memory management; add configuration for testing --- .claude/settings.local.json | 13 ++++ CLAUDE.md | 64 +++++++++++++++++ include/applications.h | 2 +- include/common.h | 17 +++-- include/menu.h | 2 +- src/components/applications.c | 118 ++++++++++++++++++++----------- src/components/menu.c | 10 +-- src/components/settings.c | 13 ++-- src/components/update.c | 12 +++- src/components/win.c | 2 +- src/main.c | 80 ++++++++++----------- src/ui.c | 2 +- tests/test_resources/test1.DLOCK | Bin 28 -> 32 bytes 13 files changed, 229 insertions(+), 106 deletions(-) create mode 100644 .claude/settings.local.json create mode 100644 CLAUDE.md diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..9fd89c9 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,13 @@ +{ + "permissions": { + "allow": [ + "Bash(wc:*)", + "Bash(cmake:*)", + "Bash(ctest:*)", + "Bash(\"build/tests/Release/display-lock-unittests.exe\")", + "Bash(\"display-lock-unittests.exe\")", + "Bash(\"./display-lock-unittests.exe\")", + "Bash(xxd:*)" + ] + } +} diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..5d0032a --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,64 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +Display-Lock is a lightweight Windows application that locks the cursor to a selected window. Written primarily in C using the Win32 API, it's designed for gamers and multi-monitor users who need to keep their cursor confined to a specific window. + +## Build Commands + +```bash +# Configure and build (Release) +cmake -B build -DCMAKE_BUILD_TYPE=Release +cmake --build build --config Release + +# Configure and build (Debug) +cmake -B build -DCMAKE_BUILD_TYPE=Debug +cmake --build build --config Debug + +# Run tests (requires Conan for GTest dependency) +pip install conan==1.59.0 +ctest --test-dir build -C Release +``` + +The build requires Visual Studio 2022 (MSVC) on Windows. Conan package manager is used to fetch Google Test for unit testing. + +## Architecture + +**Component Library (`src/components/`)**: Core functionality as a static library (`display_lock_components`) +- `win.c` - Cursor locking logic and window manipulation +- `settings.c` - Binary config file persistence (`.DLOCK` format in `%APPDATA%/DisplayLock/`) +- `applications.c` - Application whitelist management and monitoring thread +- `notify.c` - System tray icon and notifications +- `update.c` - Version checking via HTTP +- `menu.c` - Menu UI handling + +**Main Application (`src/`)**: Win32 dialog-based UI +- `main.c` - Entry point, window class registration, message loop +- `ui.c` - Tab view rendering (Window Select, Settings, Applications) +- `procedures/` - Dialog procedure handlers + +**Key Data Structures (`include/common.h`)**: +- `SETTINGS` - User preferences (minimize on start, fullscreen, borderless, etc.) +- `WINDOWLIST` - Array of up to 35 windows for selection +- `APPLICATION_LIST` - Whitelisted applications for automatic cursor locking + +**Threading Model**: Cursor locking and application monitoring run in dedicated threads, synchronized via mutex (`DLockApplicationMutex`). + +## Testing + +Tests use Google Test (fetched via Conan). Test files are in `tests/` with test resources copied to the build directory. + +```bash +# Run a single test +ctest --test-dir build -C Release -R SettingsTest +``` + +## Contributing Guidelines + +- Work on `develop` branch for features, `master` for hotfixes +- Avoid external dependencies (keep it lightweight) +- Do not manually change version numbers or build scripts +- Update CHANGELOG.md with changes +- All builds and tests must pass before merge diff --git a/include/applications.h b/include/applications.h index 7803aff..ba016e9 100644 --- a/include/applications.h +++ b/include/applications.h @@ -20,7 +20,7 @@ BOOL createApplicationDirectory(wchar_t *outPath); BOOL createApplicationSettings(const wchar_t *appPath, APPLICATION_SETTINGS *application); BOOL startApplicationThread(HANDLE *thread, int (*callback)(void *parameters), void *args); -void closeApplicationThread(HANDLE thread, BOOL *status); +void closeApplicationThread(HANDLE *thread, volatile BOOL *status); DWORD getPidFromName(const wchar_t *name); BOOL CALLBACK EnumWindowsProcPID(HWND hwnd, LPARAM lParam); diff --git a/include/common.h b/include/common.h index dd69248..a39f4db 100644 --- a/include/common.h +++ b/include/common.h @@ -25,6 +25,12 @@ #define APPLICATION_VIEW 2 #define APPLICATION_MUTEX_NAME L"DLockApplicationMutex" + +// Magic number constants +#define MAX_WINDOW_COUNT 35 +#define MAX_TITLE_LENGTH 500 +#define MAX_CLASS_NAME 500 + // custom messages #define NOTIFY_MSG (WM_USER + 0x1) @@ -86,7 +92,7 @@ struct MAIN_WINDOW_CONTROLS struct WINDOW { - char title[500]; + char title[MAX_TITLE_LENGTH]; int x; int y; RECT size; @@ -97,7 +103,7 @@ struct WINDOW struct WINDOWLIST { int count; - WINDOW windows[35]; + WINDOW windows[MAX_WINDOW_COUNT]; }; struct WINDOW_VIEW_CONTROLS @@ -125,7 +131,7 @@ struct SETTINGS_VIEW_CONTROLS struct MENU { - void (*closeThread)(HANDLE thread, BOOL *status); + void (*closeThread)(HANDLE *thread, volatile BOOL *status); void (*updateComboBox)(HWND control, WINDOWLIST *windows, void (*callback)(WINDOWLIST *)); BOOL (*startThread) (HANDLE *thread, int (*callback)(void *parameters), void *args); @@ -145,7 +151,7 @@ struct SETTINGS struct ARGS { SETTINGS *settings; - BOOL *clipRunning; + volatile BOOL *clipRunning; WINDOW selectedWindow; HWND hWnd; MAIN_WINDOW_CONTROLS controls; @@ -154,7 +160,8 @@ struct ARGS struct APPLICATION_ARGS { APPLICATION_LIST *applicationList; - BOOL *clipRunning; + volatile BOOL *clipRunning; + HANDLE mutex; }; union VERSION diff --git a/include/menu.h b/include/menu.h index dfe3da1..92b7772 100644 --- a/include/menu.h +++ b/include/menu.h @@ -23,4 +23,4 @@ void initMenuObj(MENU *menu); void updateComboBox(HWND control, WINDOWLIST *windows, void (*callback)(WINDOWLIST *)); BOOL startThread(HANDLE *thread, int (*callback)(void *parameters), void *args); -void closeThread(HANDLE thread, BOOL *status); \ No newline at end of file +void closeThread(HANDLE *thread, volatile BOOL *status); \ No newline at end of file diff --git a/src/components/applications.c b/src/components/applications.c index 2b741db..ddaeaec 100644 --- a/src/components/applications.c +++ b/src/components/applications.c @@ -30,15 +30,42 @@ BOOL readApplicationList(APPLICATION_LIST *applicationList, const wchar_t *path) return FALSE; } - fread(&applicationList->count, sizeof(int), 1, file); - applicationList->applications = (APPLICATION_SETTINGS *)malloc(sizeof(APPLICATION_SETTINGS) * applicationList->count); - for (int i = 0; i < applicationList->count; i++) + if (fread(&applicationList->count, sizeof(int), 1, file) != 1) { - fread(&applicationList->applications[i], sizeof(APPLICATION_SETTINGS), 1, file); + applicationList->count = 0; + applicationList->applications = NULL; + fclose(file); + return FALSE; + } + + if (applicationList->count > 0) + { + applicationList->applications = (APPLICATION_SETTINGS *)malloc(sizeof(APPLICATION_SETTINGS) * applicationList->count); + if (applicationList->applications == NULL) + { + applicationList->count = 0; + fclose(file); + return FALSE; + } + + for (int i = 0; i < applicationList->count; i++) + { + if (fread(&applicationList->applications[i], sizeof(APPLICATION_SETTINGS), 1, file) != 1) + { + free(applicationList->applications); + applicationList->applications = NULL; + applicationList->count = 0; + fclose(file); + return FALSE; + } + } + } + else + { + applicationList->applications = NULL; } fclose(file); - _fcloseall(); return TRUE; } @@ -64,7 +91,6 @@ BOOL writeApplicationList(APPLICATION_LIST *applicationList, const wchar_t *path } fclose(file); - _fcloseall(); return TRUE; } @@ -76,6 +102,8 @@ BOOL addApplication(APPLICATION_LIST *applicationList, APPLICATION_SETTINGS appl { applicationList->count = 1; applicationList->applications = (APPLICATION_SETTINGS *)malloc(sizeof(APPLICATION_SETTINGS)); + if (applicationList->applications == NULL) + return FALSE; applicationList->applications[0] = application; } else @@ -87,8 +115,11 @@ BOOL addApplication(APPLICATION_LIST *applicationList, APPLICATION_SETTINGS appl return FALSE; } + APPLICATION_SETTINGS *temp = (APPLICATION_SETTINGS *)realloc(applicationList->applications, sizeof(APPLICATION_SETTINGS) * (applicationList->count + 1)); + if (temp == NULL) + return FALSE; + applicationList->applications = temp; applicationList->count++; - applicationList->applications = (APPLICATION_SETTINGS *)realloc(applicationList->applications, sizeof(APPLICATION_SETTINGS) * applicationList->count); applicationList->applications[applicationList->count - 1] = application; } @@ -119,7 +150,10 @@ BOOL removeApplication(APPLICATION_LIST *applicationList, int index) } applicationList->count--; - applicationList->applications = (APPLICATION_SETTINGS *)realloc(applicationList->applications, sizeof(APPLICATION_SETTINGS) * applicationList->count); + APPLICATION_SETTINGS *temp = (APPLICATION_SETTINGS *)realloc(applicationList->applications, sizeof(APPLICATION_SETTINGS) * applicationList->count); + if (temp != NULL) + applicationList->applications = temp; + // If realloc fails, keep the old pointer (memory is still valid, just larger than needed) } return TRUE; @@ -153,7 +187,7 @@ BOOL createApplicationDirectory(wchar_t *outPath) if (!SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_RoamingAppData, 0, NULL, &path))) return FALSE; - wcscpy(outPath, path); + wcscpy_s(outPath, MAX_PATH, path); // create directory PathAppend(outPath, TEXT("DisplayLock")); @@ -173,8 +207,8 @@ BOOL createApplicationSettings(const wchar_t *appPath, APPLICATION_SETTINGS *app if (basename == appPath) return FALSE; - wcscpy(application->application_path, appPath); - wcscpy(application->application_name, basename); + wcscpy_s(application->application_path, MAX_PATH, appPath); + wcscpy_s(application->application_name, MAX_PATH, basename); application->borderless = FALSE; application->fullscreen = FALSE; application->enabled = TRUE; @@ -185,7 +219,7 @@ BOOL createApplicationSettings(const wchar_t *appPath, APPLICATION_SETTINGS *app BOOL startApplicationThread(HANDLE *thread, int (*callback)(void *parameters), void *args) { // TODO: check better error checking - *thread = (HANDLE)_beginthreadex(NULL, 0, callback, args, 0, NULL); + *thread = (HANDLE)(uintptr_t)_beginthreadex(NULL, 0, callback, args, 0, NULL); if (*thread == NULL) return FALSE; @@ -194,15 +228,15 @@ BOOL startApplicationThread(HANDLE *thread, int (*callback)(void *parameters), v } // safely closes the thread -void closeApplicationThread(HANDLE thread, BOOL *status) +void closeApplicationThread(HANDLE *thread, volatile BOOL *status) { // check to see if thread is running - if (thread != NULL) + if (*thread != NULL) { *status = FALSE; - WaitForSingleObject(thread, INFINITE); - CloseHandle(thread); - thread = NULL; + WaitForSingleObject(*thread, INFINITE); + CloseHandle(*thread); + *thread = NULL; } } @@ -251,8 +285,7 @@ int CALLBACK cursorLockApplications(void *parameters) while (*(args->clipRunning)) { - HANDLE mutex = CreateMutex(NULL, FALSE, APPLICATION_MUTEX_NAME); - WaitForSingleObject(mutex, INFINITE); + WaitForSingleObject(args->mutex, INFINITE); for (int i = 0; i < args->applicationList->count; i++) { @@ -260,53 +293,53 @@ int CALLBACK cursorLockApplications(void *parameters) if (application.enabled) { - EnumWindowsProcPIDArgs args; - args.pid = getPidFromName(application.application_name); - args.hwnd = NULL; + EnumWindowsProcPIDArgs enumArgs; + enumArgs.pid = getPidFromName(application.application_name); + enumArgs.hwnd = NULL; - if (args.pid != 0) - EnumWindows(EnumWindowsProcPID, (LPARAM)&args); + if (enumArgs.pid != 0) + EnumWindows(EnumWindowsProcPID, (LPARAM)&enumArgs); - if (args.hwnd != NULL) + if (enumArgs.hwnd != NULL) { RECT rect; - GetWindowRect(args.hwnd, &rect); + GetWindowRect(enumArgs.hwnd, &rect); if (application.borderless) { - const long long borderlessStyle = GetWindowLongPtr(args.hwnd, GWL_STYLE); - const long long borderlessStyleEx = GetWindowLongPtr(args.hwnd, GWL_EXSTYLE); + const long long borderlessStyle = GetWindowLongPtr(enumArgs.hwnd, GWL_STYLE); + const long long borderlessStyleEx = GetWindowLongPtr(enumArgs.hwnd, GWL_EXSTYLE); const long long mask = WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU | WS_CAPTION; const long long exMask = WS_EX_WINDOWEDGE; if ((borderlessStyle & mask) != 0) - SetWindowLongPtr(args.hwnd, GWL_STYLE, borderlessStyle & ~mask); + SetWindowLongPtr(enumArgs.hwnd, GWL_STYLE, borderlessStyle & ~mask); if ((borderlessStyleEx & exMask) != 0) - SetWindowLongPtr(args.hwnd, GWL_EXSTYLE, borderlessStyleEx & ~exMask); + SetWindowLongPtr(enumArgs.hwnd, GWL_EXSTYLE, borderlessStyleEx & ~exMask); } else if (application.fullscreen) { - RECT rect = {0}; - GetClientRect(args.hwnd, &rect); - ClientToScreen(args.hwnd, (LPPOINT)&rect.left); - ClientToScreen(args.hwnd, (LPPOINT)&rect.right); + RECT fsRect = {0}; + GetClientRect(enumArgs.hwnd, &fsRect); + ClientToScreen(enumArgs.hwnd, (LPPOINT)&fsRect.left); + ClientToScreen(enumArgs.hwnd, (LPPOINT)&fsRect.right); - if (rect.left != 0 || rect.top != 0 || rect.right != GetSystemMetrics(SM_CXSCREEN) || rect.bottom != GetSystemMetrics(SM_CYSCREEN)) - SetWindowPos(args.hwnd, NULL, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 0); + if (fsRect.left != 0 || fsRect.top != 0 || fsRect.right != GetSystemMetrics(SM_CXSCREEN) || fsRect.bottom != GetSystemMetrics(SM_CYSCREEN)) + SetWindowPos(enumArgs.hwnd, NULL, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 0); } // TODO: lock cursor HWND active = GetForegroundWindow(); - if (args.hwnd == active) + if (enumArgs.hwnd == active) { GetCursorPos(&cursorPosition); RECT windowRect = {0}; - GetClientRect(args.hwnd, &windowRect); - ClientToScreen(args.hwnd, (LPPOINT)&windowRect.left); - ClientToScreen(args.hwnd, (LPPOINT)&windowRect.right); + GetClientRect(enumArgs.hwnd, &windowRect); + ClientToScreen(enumArgs.hwnd, (LPPOINT)&windowRect.left); + ClientToScreen(enumArgs.hwnd, (LPPOINT)&windowRect.right); if ((cursorPosition.y <= windowRect.bottom && cursorPosition.y >= windowRect.top) && (cursorPosition.x >= windowRect.left && cursorPosition.x <= windowRect.right)) ClipCursor(&windowRect); @@ -315,11 +348,10 @@ int CALLBACK cursorLockApplications(void *parameters) } } } - Sleep(1); } - ReleaseMutex(mutex); - CloseHandle(mutex); + ReleaseMutex(args->mutex); + Sleep(1); } ClipCursor(NULL); diff --git a/src/components/menu.c b/src/components/menu.c index 9399da5..e108bec 100644 --- a/src/components/menu.c +++ b/src/components/menu.c @@ -53,14 +53,14 @@ BOOL startThread(HANDLE *thread, int (*callback)(void *parameters), void *args) } // safely closes the thread -void closeThread(HANDLE thread, BOOL *status) +void closeThread(HANDLE *thread, volatile BOOL *status) { // check to see if thread is running - if (thread != NULL) + if (*thread != NULL) { *status = FALSE; - WaitForSingleObject(thread, INFINITE); - CloseHandle(thread); - thread = NULL; + WaitForSingleObject(*thread, INFINITE); + CloseHandle(*thread); + *thread = NULL; } } diff --git a/src/components/settings.c b/src/components/settings.c index ff36966..6c37d74 100644 --- a/src/components/settings.c +++ b/src/components/settings.c @@ -80,7 +80,7 @@ BOOL findPath(wchar_t *outPath) if (!SUCCEEDED(hr)) return FALSE; - wcscpy(outPath, path); + wcscpy_s(outPath, MAX_PATH, path); LPCWSTR x = L"DisplayLock\\settings.DLOCK"; PathAppend(outPath, x); @@ -95,7 +95,7 @@ BOOL createDirectory(wchar_t *outPath) if (!SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_RoamingAppData, 0, NULL, &path))) return FALSE; - wcscpy(outPath, path); + wcscpy_s(outPath, MAX_PATH, path); // create directory PathAppend(outPath, TEXT("DisplayLock")); @@ -120,10 +120,14 @@ BOOL readSettings(SETTINGS *settings, const wchar_t *versionStr, const wchar_t * return FALSE; } - fread(settings, sizeof(SETTINGS), 1, file); + if (fread(settings, sizeof(SETTINGS), 1, file) != 1) + { + fclose(file); + defaultSettings(settings, versionStr); + return FALSE; + } fclose(file); - _fcloseall(); if (!checkVersion(settings, versionStr)) defaultSettings(settings, versionStr); @@ -144,7 +148,6 @@ BOOL writeSettings(SETTINGS settings, const wchar_t *path) fwrite(&settings, sizeof(settings), 1, file); fclose(file); - _fcloseall(); return TRUE; } diff --git a/src/components/update.c b/src/components/update.c index 889d62e..bd797af 100644 --- a/src/components/update.c +++ b/src/components/update.c @@ -26,10 +26,16 @@ void resizeString(STRING *string, int size) char *data = string->data; if (string->data != NULL) { - string->data = (char *)realloc(string->data, ((size_t)newSize + 1)); - if (string->data == NULL) + char *temp = (char *)realloc(string->data, ((size_t)newSize + 1)); + if (temp == NULL) + { free(data); - string->size = size; + string->data = NULL; + string->size = 0; + return; + } + string->data = temp; + string->size = newSize; } } diff --git a/src/components/win.c b/src/components/win.c index 44db9d5..52217ee 100644 --- a/src/components/win.c +++ b/src/components/win.c @@ -162,7 +162,7 @@ int CALLBACK cursorLock(void *arguments) ARGS *args = (ARGS *)arguments; SETTINGS *settings = args->settings; WINDOW selectedWindow = args->selectedWindow; - BOOL *isRunning = args->clipRunning; + volatile BOOL *isRunning = args->clipRunning; POINT cursorPos; BOOL styleChanged = FALSE; PREVIOUSRECT previousRect; diff --git a/src/main.c b/src/main.c index e9345fc..b974991 100644 --- a/src/main.c +++ b/src/main.c @@ -91,6 +91,9 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, } } + if (hAccelTable != NULL) + DestroyAcceleratorTable(hAccelTable); + return (int)msg.wParam; } @@ -172,16 +175,19 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) initalUpdate = !compareVersion(&gVersion); } - CreateDialog(NULL, MAKEINTRESOURCE(IDD_MAIN_VIEW), hWnd, MainWindow); + { + HWND hMainDlg = CreateDialog(NULL, MAKEINTRESOURCE(IDD_MAIN_VIEW), hWnd, MainWindow); + if (hMainDlg == NULL) + { + // Dialog creation failed + return -1; + } + } invokeReadSettings(&settings); notifyInit(hWnd, &sysTray); Shell_NotifyIcon(NIM_ADD, &sysTray); Shell_NotifyIcon(NIM_SETVERSION, &sysTray); - HANDLE mutex = CreateMutex(NULL, FALSE, APPLICATION_MUTEX_NAME); - ReleaseMutex(mutex); - CloseHandle(mutex); - break; case NOTIFY_MSG: @@ -405,7 +411,7 @@ INT_PTR CALLBACK windowViewProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM l } break; case WM_DESTROY: - menu.closeThread(windowControls.clipThread, &running); + menu.closeThread(&windowControls.clipThread, &running); break; default: return DefWindowProc(hDlg, message, wParam, lParam); @@ -524,6 +530,12 @@ INT_PTR CALLBACK applicationsViewProc(HWND hDlg, UINT message, WPARAM wParam, LP args.applicationList = &applicationList; args.clipRunning = &applicationRunning; + args.mutex = CreateMutex(NULL, FALSE, APPLICATION_MUTEX_NAME); + if (args.mutex == NULL) + { + // Mutex creation failed + return (INT_PTR)FALSE; + } startApplicationThread(&controls.clipThread, cursorLockApplications, (void *)&args); @@ -568,13 +580,10 @@ INT_PTR CALLBACK applicationsViewProc(HWND hDlg, UINT message, WPARAM wParam, LP if (GetOpenFileName(&ofn)) { + DWORD waitResult = WaitForSingleObject(args.mutex, INFINITE); - HANDLE mutex = CreateMutex(NULL, FALSE, APPLICATION_MUTEX_NAME); - DWORD result = WaitForSingleObject(mutex, INFINITE); - - if ((result == 0) || (result == WAIT_ABANDONED)) + if ((waitResult == WAIT_OBJECT_0) || (waitResult == WAIT_ABANDONED)) { - APPLICATION_SETTINGS application; ZeroMemory(&application, sizeof(application)); createApplicationSettings(ofn.lpstrFile, &application); @@ -582,33 +591,27 @@ INT_PTR CALLBACK applicationsViewProc(HWND hDlg, UINT message, WPARAM wParam, LP if (addApplication(&applicationList, application)) SendMessage(controls.listView, LB_ADDSTRING, 0, (LPARAM)application.application_name); } - ReleaseMutex(mutex); - CloseHandle(mutex); + ReleaseMutex(args.mutex); } break; case IDC_BTN_APP_RMV: { - - int current_selected = 0; - int result = SendMessage(controls.listView, LB_GETCURSEL, (WPARAM)¤t_selected, 0); - if (result != LB_ERR) + int current_selected = (int)SendMessage(controls.listView, LB_GETCURSEL, 0, 0); + if (current_selected != LB_ERR) { + DWORD waitResult = WaitForSingleObject(args.mutex, INFINITE); - HANDLE mutex = CreateMutex(NULL, FALSE, APPLICATION_MUTEX_NAME); - DWORD result = WaitForSingleObject(mutex, INFINITE); - - if ((result == 0) || (result == WAIT_ABANDONED)) + if ((waitResult == WAIT_OBJECT_0) || (waitResult == WAIT_ABANDONED)) { SendMessage(controls.listView, LB_DELETESTRING, current_selected, 0); removeApplication(&applicationList, current_selected); } - ReleaseMutex(mutex); - CloseHandle(mutex); + ReleaseMutex(args.mutex); } - result = SendMessage(controls.listView, LB_GETCURSEL, 0, 0); - if (result != LB_ERR) + int selResult = (int)SendMessage(controls.listView, LB_GETCURSEL, 0, 0); + if (selResult != LB_ERR) { EnableWindow(controls.settingsButton, TRUE); EnableWindow(controls.removeButton, TRUE); @@ -622,22 +625,18 @@ INT_PTR CALLBACK applicationsViewProc(HWND hDlg, UINT message, WPARAM wParam, LP break; case IDC_BTN_APP_SETTINGS: { - int current_selected = 0; - int result = SendMessage(controls.listView, LB_GETCURSEL, (WPARAM)¤t_selected, 0); + int current_selected = (int)SendMessage(controls.listView, LB_GETCURSEL, 0, 0); - if (result != LB_ERR) + if (current_selected != LB_ERR) { + DWORD waitResult = WaitForSingleObject(args.mutex, INFINITE); - HANDLE mutex = CreateMutex(NULL, FALSE, APPLICATION_MUTEX_NAME); - DWORD result = WaitForSingleObject(mutex, INFINITE); - - if ((result == 0) || (result == WAIT_ABANDONED)) + if ((waitResult == WAIT_OBJECT_0) || (waitResult == WAIT_ABANDONED)) { - APPLICATION_SETTINGS *settings = &applicationList.applications[current_selected]; - DialogBoxParam(hInst, MAKEINTRESOURCE(IDC_APP_SETTINGS), hDlg, appSettingsProc, (LPARAM)settings); + APPLICATION_SETTINGS *appSettings = &applicationList.applications[current_selected]; + DialogBoxParam(hInst, MAKEINTRESOURCE(IDC_APP_SETTINGS), hDlg, appSettingsProc, (LPARAM)appSettings); } - ReleaseMutex(mutex); - CloseHandle(mutex); + ReleaseMutex(args.mutex); } } break; @@ -648,14 +647,13 @@ INT_PTR CALLBACK applicationsViewProc(HWND hDlg, UINT message, WPARAM wParam, LP } case WM_DESTROY: { - closeApplicationThread(controls.clipThread, args.clipRunning); + closeApplicationThread(&controls.clipThread, args.clipRunning); closeApplicationList(&applicationList); - HANDLE mutex = CreateMutex(NULL, FALSE, APPLICATION_MUTEX_NAME); - if (mutex != NULL) + if (args.mutex != NULL) { - ReleaseMutex(mutex); - CloseHandle(mutex); + CloseHandle(args.mutex); + args.mutex = NULL; } EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; diff --git a/src/ui.c b/src/ui.c index 99cdc20..39a06a0 100644 --- a/src/ui.c +++ b/src/ui.c @@ -203,7 +203,7 @@ void windowsButtonStop(MENU menu, WINDOW_VIEW_CONTROLS *windowControls) EnableWindow(windowControls->startButton, TRUE); EnableWindow(windowControls->stopButton, FALSE); EnableWindow(windowControls->comboBox, TRUE); - menu.closeThread(windowControls->clipThread, windowControls->runningClip); + menu.closeThread(&windowControls->clipThread, windowControls->runningClip); } void invokeReadSettings(SETTINGS *settings) diff --git a/tests/test_resources/test1.DLOCK b/tests/test_resources/test1.DLOCK index 4d631f129fe56422768b5c40aed58d5a4fae4a41..bc8556448c336b8cb42990d6a4069a02f7f39f6e 100644 GIT binary patch delta 9 Ocmb19m>|Q#00aOAu>kD= delta 4 LcmY$8nIHoI0u%u0