--- /dev/null
+/*
+ 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;
+}
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;
}
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;
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) {
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;
, MUTE_ON_SUSPEND
, MUTE_ON_SHUTDOWN
, MUTE_ON_LOGOUT
+ , QUIETHOURS_ENABLE
+ , QUIETHOURS_START
+ , QUIETHOURS_END
};
class Settings {
#include <algorithm>
#include <windows.h>
+#include <windowsx.h>
#include <commctrl.h>
#include <WtsApi32.h>
#include <tchar.h>
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");
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() :
!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;
muteConfig_.noRestore.onShutdown =
settings_.QueryValue(SettingsKey::MUTE_ON_SHUTDOWN, 0) != 0;
+ muteConfig_.quietHours.enabled =
+ settings_.QueryValue(SettingsKey::QUIETHOURS_ENABLE, 0) != 0;
+
return true;
}
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);
}
}
break;
+ case WM_WINMUTE_QUIETHOURS_CHANGE: {
+ return 0;
+ }
case WM_SCRNSAVE_CHANGE: {
static bool wasAlreadyMuted = false;
if (wParam == SCRNSAVE_START) {
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();
}
class WinAudio;
+#define WM_WINMUTE_QUIETHOURS_CHANGE (WM_APP + 200)
+
class WinMute {
public:
WinMute();
bool onShutdown;
bool onSuspend;
} noRestore;
+ struct {
+ int enabled;
+ time_t start;
+ time_t end;
+ } quietHours;
} muteConfig_;
TrayIcon trayIcon_;
<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">
<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">
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
"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
+
/////////////////////////////////////////////////////////////////////////////
//
TOPMARGIN, 7
BOTTOMMARGIN, 49
END
+
+ IDD_QUIETHOURS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 194
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 139
+ END
END
#endif // APSTUDIO_INVOKED
0
END
+IDD_QUIETHOURS AFX_DIALOG_LAYOUT
+BEGIN
+ 0
+END
+
#endif // German (Germany) resources
/////////////////////////////////////////////////////////////////////////////
#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