From: lx-s Date: Tue, 27 Oct 2020 08:24:54 +0000 (+0100) Subject: New dialog and settings for quiet hours. X-Git-Tag: 1.6.0~16 X-Git-Url: https://repos.lx-s.de/gitweb/?a=commitdiff_plain;h=34930e35f84dc793b9f1711c8d1060ad2d4e529b;p=winmute.git New dialog and settings for quiet hours. --- diff --git a/WinMute/QuietHoursDlg.cpp b/WinMute/QuietHoursDlg.cpp new file mode 100644 index 0000000..8d51e19 --- /dev/null +++ b/WinMute/QuietHoursDlg.cpp @@ -0,0 +1,170 @@ +/* + WinMute + Copyright (c) 2020, Alexander Steinhoefer + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the author nor the names of its contributors may + be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +#include "StdAfx.h" + +static bool IsValidTimeRange( + const LPSYSTEMTIME start, + const LPSYSTEMTIME end) +{ + bool isValid = false; + if (start->wHour == end->wHour) { + if (start->wMinute == end->wMinute) { + if (start->wSecond < end->wSecond) { + isValid = true; + } + } else if (start->wMinute < end->wMinute) { + isValid = true; + } + } else if (start->wHour < end->wHour) { + isValid = true; + } + return isValid; +} + +static bool SaveQuietHours( + Settings *settings, + const int enabled, + const LPSYSTEMTIME start, + const LPSYSTEMTIME end) +{ + if (enabled) { + if (!IsValidTimeRange(start, end)) { + TaskDialog( + nullptr, + nullptr, + PROGRAM_NAME, + _T("Invalid time range"), + _T("Quiet hours must end before they start.\n") + _T("Please correct your input.\n"), + TDCBF_OK_BUTTON, + TD_WARNING_ICON, + nullptr); + return false; + } + } + + int setStart = start->wHour * 3600 + start->wMinute * 60 + start->wSecond; + int setEnd = end->wHour * 3600 + end->wMinute * 60 + end->wSecond; + + if (!settings->SetValue(SettingsKey::QUIETHOURS_ENABLE, enabled) || + !settings->SetValue(SettingsKey::QUIETHOURS_START, setStart) || + !settings->SetValue(SettingsKey::QUIETHOURS_END, setEnd)) { + TaskDialog( + nullptr, + nullptr, + PROGRAM_NAME, + _T("Failed to save quiet hours settings"), + _T("Something went wrong while saving your settings."), + TDCBF_OK_BUTTON, + TD_ERROR_ICON, + nullptr); + return false; + } + + return true; +} + +INT_PTR CALLBACK QuietHoursDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + UNREFERENCED_PARAMETER(lParam); + switch (msg) { + case WM_INITDIALOG: { + HWND hEnable = GetDlgItem(hDlg, IDC_ENABLEQUIETHOURS); + HWND hStart = GetDlgItem(hDlg, IDC_QUIETHOURS_START); + HWND hEnd = GetDlgItem(hDlg, IDC_QUIETHOURS_END); + Settings *settings = reinterpret_cast(lParam); + assert(settings != NULL); + SetWindowLongPtr(hDlg, GWLP_USERDATA, reinterpret_cast(settings)); + + DWORD qhEnabled = !!settings->QueryValue(SettingsKey::QUIETHOURS_ENABLE, FALSE); + Button_SetCheck(hEnable, qhEnabled ? BST_CHECKED : BST_UNCHECKED); + EnableWindow(hStart, qhEnabled); + EnableWindow(hEnd, qhEnabled); + + int setStart = settings->QueryValue(SettingsKey::QUIETHOURS_START, 0); + int setEnd = settings->QueryValue(SettingsKey::QUIETHOURS_END, 0); + + SYSTEMTIME start; + GetLocalTime(&start); + if (setStart > 0) { + start.wSecond = static_cast(setStart % 60); + start.wMinute = static_cast(((setStart - start.wSecond) / 60) % 60); + start.wHour = static_cast((setStart - start.wMinute - start.wSecond) / 3600); + } + DateTime_SetSystemtime(hStart, GDT_VALID, &start); + + SYSTEMTIME end; + GetLocalTime(&end); + if (setEnd > 0) { + end.wSecond = static_cast(setEnd % 60); + end.wMinute = static_cast(((setEnd - end.wSecond) / 60) % 60); + end.wHour = static_cast((setEnd - end.wMinute - end.wSecond) / 3600); + } + DateTime_SetSystemtime(hEnd, GDT_VALID, &end); + + return TRUE; + } + case WM_COMMAND: { + HWND hEnable = GetDlgItem(hDlg, IDC_ENABLEQUIETHOURS); + HWND hStart = GetDlgItem(hDlg, IDC_QUIETHOURS_START); + HWND hEnd = GetDlgItem(hDlg, IDC_QUIETHOURS_END); + if (LOWORD(wParam) == IDOK) { + SYSTEMTIME start; + SYSTEMTIME end; + Settings *settings = reinterpret_cast(GetWindowLongPtr(hDlg, GWLP_USERDATA)); + int qhEnabled = Button_GetCheck(hEnable) == BST_CHECKED; + DateTime_GetSystemtime(hStart, &start); + DateTime_GetSystemtime(hEnd, &end); + settings->SetValue(SettingsKey::QUIETHOURS_ENABLE, qhEnabled); + if (SaveQuietHours(settings, qhEnabled, &start, &end)) { + SendMessage(GetParent(hDlg), WM_WINMUTE_QUIETHOURS_CHANGE, 0, 0); + EndDialog(hDlg, 0); + } + } else if (LOWORD(wParam) == IDCANCEL) { + EndDialog(hDlg, 0); + } else if (LOWORD(wParam) == IDC_ENABLEQUIETHOURS) { + int qhEnabled = Button_GetCheck(hEnable) == BST_CHECKED; + EnableWindow(hStart, qhEnabled); + EnableWindow(hEnd, qhEnabled); + } + return 0; + } + case WM_CLOSE: + EndDialog(hDlg, 0); + return TRUE; + default: + break; + } + return FALSE; +} diff --git a/WinMute/Settings.cpp b/WinMute/Settings.cpp index f13d21c..f0d18fb 100644 --- a/WinMute/Settings.cpp +++ b/WinMute/Settings.cpp @@ -58,6 +58,16 @@ static LPCWSTR KeyToStr(SettingsKey key) break; case SettingsKey::MUTE_ON_LOGOUT: keyStr = _T("MuteOnLogout"); + break; + case SettingsKey::QUIETHOURS_ENABLE: + keyStr = _T("QuietHoursEnabled"); + break; + case SettingsKey::QUIETHOURS_START: + keyStr = _T("QuietHoursStart"); + break; + case SettingsKey::QUIETHOURS_END: + keyStr = _T("QuietHoursEnd"); + break; } return keyStr; } @@ -75,15 +85,16 @@ Settings::~Settings() bool Settings::Init() { if (hRegSettingsKey_ == nullptr) { - DWORD regError = RegCreateKeyEx(HKEY_CURRENT_USER, - LX_SYSTEMS_SUBKEY, - 0, - nullptr, - 0, - KEY_READ | KEY_WRITE, - nullptr, - &hRegSettingsKey_, - nullptr); + DWORD regError = RegCreateKeyEx( + HKEY_CURRENT_USER, + LX_SYSTEMS_SUBKEY, + 0, + nullptr, + 0, + KEY_READ | KEY_WRITE, + nullptr, + &hRegSettingsKey_, + nullptr); if (regError != ERROR_SUCCESS) { PrintWindowsError(_T("RegCreateKeyEx"), regError); return false; @@ -106,12 +117,13 @@ DWORD Settings::QueryValue(SettingsKey key, DWORD defValue) DWORD value; DWORD size = sizeof(DWORD); - DWORD regError = RegQueryValueEx(hRegSettingsKey_, - keyStr, - 0, - nullptr, - reinterpret_cast(&value), - &size); + DWORD regError = RegQueryValueEx( + hRegSettingsKey_, + keyStr, + 0, + nullptr, + reinterpret_cast(&value), + &size); if (regError == ERROR_FILE_NOT_FOUND) { return defValue; } else if (regError != ERROR_SUCCESS) { @@ -127,12 +139,13 @@ bool Settings::SetValue(SettingsKey key, DWORD value) auto keyStr = KeyToStr(key); assert(keyStr != nullptr); - DWORD regError = RegSetValueEx(hRegSettingsKey_, - keyStr, - 0, - REG_DWORD, - reinterpret_cast(&value), - sizeof(DWORD)); + DWORD regError = RegSetValueEx( + hRegSettingsKey_, + keyStr, + 0, + REG_DWORD, + reinterpret_cast(&value), + sizeof(DWORD)); if (regError != ERROR_SUCCESS) { PrintWindowsError(_T("RegCreateKeyEx"), regError); return false; diff --git a/WinMute/Settings.h b/WinMute/Settings.h index dc02b32..2476a6d 100644 --- a/WinMute/Settings.h +++ b/WinMute/Settings.h @@ -42,6 +42,9 @@ enum class SettingsKey { , MUTE_ON_SUSPEND , MUTE_ON_SHUTDOWN , MUTE_ON_LOGOUT + , QUIETHOURS_ENABLE + , QUIETHOURS_START + , QUIETHOURS_END }; class Settings { diff --git a/WinMute/StdAfx.h b/WinMute/StdAfx.h index 0a23875..b62e5f9 100644 --- a/WinMute/StdAfx.h +++ b/WinMute/StdAfx.h @@ -56,6 +56,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#include #include #include #include diff --git a/WinMute/WinMute.cpp b/WinMute/WinMute.cpp index 9d4b4a0..5eb7acd 100644 --- a/WinMute/WinMute.cpp +++ b/WinMute/WinMute.cpp @@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE. extern HINSTANCE hglobInstance; extern INT_PTR CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM); +extern INT_PTR CALLBACK QuietHoursDlgProc(HWND, UINT, WPARAM, LPARAM); static LPCTSTR WINMUTE_CLASS_NAME = _T("WinMute"); @@ -67,6 +68,10 @@ WinMute::MuteConfig::MuteConfig() this->noRestore.onLogoff = false; this->noRestore.onSuspend = false; this->noRestore.onShutdown = false; + + this->quietHours.enabled = false; + this->quietHours.start = 0; + this->quietHours.end = 0; } WinMute::WinMute() : @@ -143,7 +148,8 @@ bool WinMute::InitTrayMenu() !CHECK_MENU_ITEM(RESTOREAUDIO, muteConfig_.restoreAudio) || !CHECK_MENU_ITEM(MUTEONSUSPEND, muteConfig_.noRestore.onSuspend) || !CHECK_MENU_ITEM(MUTEONSHUTDOWN, muteConfig_.noRestore.onShutdown) || - !CHECK_MENU_ITEM(MUTEONLOGOUT, muteConfig_.noRestore.onLogoff)) { + !CHECK_MENU_ITEM(MUTEONLOGOUT, muteConfig_.noRestore.onLogoff) || + !CHECK_MENU_ITEM(CONFIGUREQUIETHOURS, muteConfig_.quietHours.enabled)) { return false; } return true; @@ -209,6 +215,9 @@ bool WinMute::LoadDefaults() muteConfig_.noRestore.onShutdown = settings_.QueryValue(SettingsKey::MUTE_ON_SHUTDOWN, 0) != 0; + muteConfig_.quietHours.enabled = + settings_.QueryValue(SettingsKey::QUIETHOURS_ENABLE, 0) != 0; + return true; } @@ -236,10 +245,19 @@ LRESULT CALLBACK WinMute::WindowProc(HWND hWnd, UINT msg, case WM_COMMAND: { switch (LOWORD(wParam)) { case ID_TRAYMENU_INFO: - DialogBox(hglobInstance, - MAKEINTRESOURCE(IDD_ABOUT), - hWnd_, - AboutDlgProc); + DialogBox( + hglobInstance, + MAKEINTRESOURCE(IDD_ABOUT), + hWnd_, + AboutDlgProc); + break; + case ID_TRAYMENU_CONFIGUREQUIETHOURS: + DialogBoxParam( + hglobInstance, + MAKEINTRESOURCE(IDD_QUIETHOURS), + hWnd_, + QuietHoursDlgProc, + reinterpret_cast(&settings_)); break; case ID_TRAYMENU_EXIT: SendMessage(hWnd, WM_CLOSE, 0, 0); @@ -352,6 +370,9 @@ LRESULT CALLBACK WinMute::WindowProc(HWND hWnd, UINT msg, } } break; + case WM_WINMUTE_QUIETHOURS_CHANGE: { + return 0; + } case WM_SCRNSAVE_CHANGE: { static bool wasAlreadyMuted = false; if (wParam == SCRNSAVE_START) { @@ -369,7 +390,7 @@ LRESULT CALLBACK WinMute::WindowProc(HWND hWnd, UINT msg, return 0; } default: - if (msg == uTaskbarRestart) { // restore trayicon if explorer.exe crashes + if (msg == uTaskbarRestart) { // Restore trayicon if explorer.exe crashes trayIcon_.Hide(); trayIcon_.Show(); } diff --git a/WinMute/WinMute.h b/WinMute/WinMute.h index a172170..530bfaf 100644 --- a/WinMute/WinMute.h +++ b/WinMute/WinMute.h @@ -37,6 +37,8 @@ POSSIBILITY OF SUCH DAMAGE. class WinAudio; +#define WM_WINMUTE_QUIETHOURS_CHANGE (WM_APP + 200) + class WinMute { public: WinMute(); @@ -65,6 +67,11 @@ private: bool onShutdown; bool onSuspend; } noRestore; + struct { + int enabled; + time_t start; + time_t end; + } quietHours; } muteConfig_; TrayIcon trayIcon_; diff --git a/WinMute/WinMute.vcxproj b/WinMute/WinMute.vcxproj index 79a5956..a3d6153 100644 --- a/WinMute/WinMute.vcxproj +++ b/WinMute/WinMute.vcxproj @@ -215,6 +215,7 @@ + diff --git a/WinMute/WinMute.vcxproj.filters b/WinMute/WinMute.vcxproj.filters index 006f288..a34564c 100644 --- a/WinMute/WinMute.vcxproj.filters +++ b/WinMute/WinMute.vcxproj.filters @@ -59,6 +59,9 @@ Source Files\Settings + + Source Files\UI + diff --git a/WinMute/res.rc b/WinMute/res.rc index ef9f7d2..81c1683 100644 --- a/WinMute/res.rc +++ b/WinMute/res.rc @@ -62,6 +62,8 @@ BEGIN MENUITEM SEPARATOR MENUITEM "... Restore volume when returning", ID_TRAYMENU_RESTOREAUDIO, CHECKED MENUITEM SEPARATOR + MENUITEM "Configure Quiet Hours...", ID_TRAYMENU_CONFIGUREQUIETHOURS + MENUITEM SEPARATOR MENUITEM "Mute on (no volume restore)...", ID_TRAYMENU_AFTERWARDS, INACTIVE MENUITEM "... Shutdown", ID_TRAYMENU_MUTEONSHUTDOWN MENUITEM "... Sleep", ID_TRAYMENU_MUTEONSUSPEND @@ -94,6 +96,21 @@ BEGIN "SysLink",WS_TABSTOP,119,35,36,13 END +IDD_QUIETHOURS DIALOGEX 0, 0, 201, 146 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Configure Quiet Hours" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "Enable Quiet Hours",IDC_ENABLEQUIETHOURS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,38,77,10 + CONTROL "",IDC_QUIETHOURS_START,"SysDateTimePick32",DTS_RIGHTALIGN | DTS_UPDOWN | WS_TABSTOP | 0x8,79,58,54,15 + CONTROL "",IDC_QUIETHOURS_END,"SysDateTimePick32",DTS_RIGHTALIGN | DTS_UPDOWN | WS_TABSTOP | 0x8,79,80,54,15 + DEFPUSHBUTTON "Save",IDOK,63,120,50,14 + PUSHBUTTON "Cancel",IDCANCEL,123,120,50,14 + LTEXT "During Quiet Hours WinMute automatically mutes your PC volumes and unmutes it afterwards.",IDC_STATIC,15,9,174,24 + LTEXT "Start time:",IDC_STATIC,31,60,42,12 + LTEXT "End time:",IDC_STATIC,31,82,43,12 +END + ///////////////////////////////////////////////////////////////////////////// // @@ -111,6 +128,14 @@ BEGIN TOPMARGIN, 7 BOTTOMMARGIN, 49 END + + IDD_QUIETHOURS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 194 + TOPMARGIN, 7 + BOTTOMMARGIN, 139 + END END #endif // APSTUDIO_INVOKED @@ -187,6 +212,11 @@ BEGIN 0 END +IDD_QUIETHOURS AFX_DIALOG_LAYOUT +BEGIN + 0 +END + #endif // German (Germany) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/WinMute/resource.h b/WinMute/resource.h index ca7cab9..673ca56 100644 --- a/WinMute/resource.h +++ b/WinMute/resource.h @@ -7,9 +7,13 @@ #define IDI_APP 106 #define IDI_ICON1 107 #define IDI_TRAY 107 +#define IDD_QUIETHOURS 108 #define IDC_LINK_HOMEPAGE 1001 #define IDC_LINK_HOMEPAGE2 1002 #define IDC_LINK_SUPPORT 1002 +#define IDC_QUIETHOURS_START 1002 +#define IDC_ENABLEQUIETHOURS 1003 +#define IDC_QUIETHOURS_END 1004 #define ID_TRAYMENU_INFO 40001 #define ID_TRAYMENU_EXIT 40002 #define ID_TRAYMENU_MUTEONLOCK 40003 @@ -35,14 +39,16 @@ #define ID_TRAYMENU_MUTEONLOGOFF 40023 #define ID_TRAYMENU_MUTEONLOGOUT 40024 #define ID_TRAYMENU_40025 40025 +#define ID_TRAYMENU_CONFIGUREQUIETHOURS 40026 +#define ID_TRAYMENU_40027 40027 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 108 -#define _APS_NEXT_COMMAND_VALUE 40026 -#define _APS_NEXT_CONTROL_VALUE 1002 +#define _APS_NEXT_RESOURCE_VALUE 110 +#define _APS_NEXT_COMMAND_VALUE 40028 +#define _APS_NEXT_CONTROL_VALUE 1004 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif