]> repos.lx-s.de Git - winmute.git/commitdiff
New dialog and settings for quiet hours.
authorlx-s <hello@lx-s.de>
Tue, 27 Oct 2020 08:24:54 +0000 (09:24 +0100)
committerlx-s <hello@lx-s.de>
Tue, 27 Oct 2020 08:43:23 +0000 (09:43 +0100)
WinMute/QuietHoursDlg.cpp [new file with mode: 0644]
WinMute/Settings.cpp
WinMute/Settings.h
WinMute/StdAfx.h
WinMute/WinMute.cpp
WinMute/WinMute.h
WinMute/WinMute.vcxproj
WinMute/WinMute.vcxproj.filters
WinMute/res.rc
WinMute/resource.h

diff --git a/WinMute/QuietHoursDlg.cpp b/WinMute/QuietHoursDlg.cpp
new file mode 100644 (file)
index 0000000..8d51e19
--- /dev/null
@@ -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<Settings*>(lParam);
+      assert(settings != NULL);
+      SetWindowLongPtr(hDlg, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(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<WORD>(setStart % 60);
+         start.wMinute = static_cast<WORD>(((setStart - start.wSecond) / 60) % 60);
+         start.wHour = static_cast<WORD>((setStart - start.wMinute - start.wSecond) / 3600);
+      }
+      DateTime_SetSystemtime(hStart, GDT_VALID, &start);
+
+      SYSTEMTIME end;
+      GetLocalTime(&end);
+      if (setEnd > 0) {
+         end.wSecond = static_cast<WORD>(setEnd % 60);
+         end.wMinute = static_cast<WORD>(((setEnd - end.wSecond) / 60) % 60);
+         end.wHour = static_cast<WORD>((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<Settings*>(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;
+}
index f13d21c8132b1adbc1147de612e79ffb3b65cf68..f0d18fbb6038d3f04344d49bfd0eb5948769cb5a 100644 (file)
@@ -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<LPBYTE>(&value),
-                                    &size);
+   DWORD regError = RegQueryValueEx(
+      hRegSettingsKey_,
+      keyStr,
+      0,
+      nullptr,
+      reinterpret_cast<LPBYTE>(&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<BYTE*>(&value),
-                                  sizeof(DWORD));
+   DWORD regError = RegSetValueEx(
+      hRegSettingsKey_,
+      keyStr,
+      0,
+      REG_DWORD,
+      reinterpret_cast<BYTE*>(&value),
+      sizeof(DWORD));
    if (regError != ERROR_SUCCESS) {
       PrintWindowsError(_T("RegCreateKeyEx"), regError);
       return false;
index dc02b32dbbd3de0cac0c8115b2a59088d4c502e0..2476a6db4abf3d093e147a27da59779a7f0258f8 100644 (file)
@@ -42,6 +42,9 @@ enum class SettingsKey {
    , MUTE_ON_SUSPEND
    , MUTE_ON_SHUTDOWN
    , MUTE_ON_LOGOUT
+   , QUIETHOURS_ENABLE
+   , QUIETHOURS_START
+   , QUIETHOURS_END
 };
 
 class Settings {
index 0a2387558178c1d194f9596ac152dfc46480daa1..b62e5f9b4a6876f4d0ea277dc53ae7cfcd1566c9 100644 (file)
@@ -56,6 +56,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #include <algorithm>
 
 #include <windows.h>
+#include <windowsx.h>
 #include <commctrl.h>
 #include <WtsApi32.h>
 #include <tchar.h>
index 9d4b4a08b0f398dea0263ca15528a2f2bd576284..5eb7acd729a9c1efb0bfb41449d44bbc560da55c 100644 (file)
@@ -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<LPARAM>(&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();
       }
index a1721704b1788e2f27c670e0134bc1b17c92c4df..530bfaf1a4c377751ecd78641e632ff8d7313556 100644 (file)
@@ -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_;
index 79a5956ba46f1b3130055f922d5136ee700734dc..a3d6153dffe9206522ef3117535cfbb6d7960e81 100644 (file)
   <ItemGroup>
     <ClCompile Include="AboutDlg.cpp" />
     <ClCompile Include="MMNotificationClient.cpp" />
+    <ClCompile Include="QuietHoursDlg.cpp" />
     <ClCompile Include="ScreensaverNotifier.cpp" />
     <ClCompile Include="Settings.cpp" />
     <ClCompile Include="StdAfx.cpp">
index 006f28882f7d944a73bcc9cd325a827c35e1043e..a34564cf8eab4313de44a43c27150cdbb4bb02f0 100644 (file)
@@ -59,6 +59,9 @@
     <ClCompile Include="Settings.cpp">
       <Filter>Source Files\Settings</Filter>
     </ClCompile>
+    <ClCompile Include="QuietHoursDlg.cpp">
+      <Filter>Source Files\UI</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="resource.h">
index ef9f7d239b1c70563c97abe06deb1836e3243f7c..81c16838335925d5bb3f9f0a518d5dd81a97ee1a 100644 (file)
@@ -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
 /////////////////////////////////////////////////////////////////////////////
 
index ca7cab9b48f01118e50de085e602bc762ab151d0..673ca5694297a5a4b28da043f311d47fab0f617b 100644 (file)
@@ -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
 #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