Version 2.5.1 (2024-05-03)
* Added new language: Simplified Chinese (thanks to https://translate.codeberg.org/user/richzhl/)
+ * Updated translations (thanks to all contributors!)
Version 2.5.0.1 (2024-02-26)
* Fixed update-check file for chocolatey package manager
--- /dev/null
+/*
+ WinMute
+ Copyright (c) 2024, 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 "common.h"
+
+static void TranslateLogDlgProc(HWND hDlg)
+{
+ WMi18n &i18n = WMi18n::GetInstance();
+ SetWindowText(hDlg, i18n.GetTranslationW("log.title").c_str());
+}
+
+INT_PTR CALLBACK AboutDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ AboutDlgData *dlgData =
+ reinterpret_cast<AboutDlgData *>(GetWindowLongPtr(hDlg, GWLP_USERDATA));
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ dlgData = new AboutDlgData();
+ SetWindowLongPtr(hDlg, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(dlgData));
+
+ dlgData->hTabCtrl = GetDlgItem(hDlg, IDC_ABOUT_TAB);
+
+ WMi18n &i18n = WMi18n::GetInstance();
+ InsertTabItem(dlgData->hTabCtrl, ABOUT_TAB_GENERAL, i18n.GetTranslationW("about.tab.winmute"));
+ InsertTabItem(dlgData->hTabCtrl, ABOUT_TAB_LICENSE, i18n.GetTranslationW("about.tab.license"));
+
+ TranslateAboutDlgProc(hDlg);
+
+ dlgData->hTabs[ABOUT_TAB_GENERAL] = CreateDialog(
+ nullptr,
+ MAKEINTRESOURCE(IDD_ABOUT_WINMUTE),
+ hDlg,
+ About_GeneralDlgProc);
+ dlgData->hTabs[ABOUT_TAB_LICENSE] = CreateDialog(
+ nullptr,
+ MAKEINTRESOURCE(IDD_ABOUT_LICENSE),
+ hDlg,
+ About_LicenseDlgProc);
+
+
+ // Set title font
+ LOGFONT font;
+ font.lfHeight = 32;
+ font.lfWidth = 0;
+ font.lfEscapement = 0;
+ font.lfOrientation = 0;
+ font.lfWeight = FW_BOLD;
+ font.lfItalic = false;
+ font.lfUnderline = false;
+ font.lfStrikeOut = false;
+ font.lfEscapement = 0;
+ font.lfOrientation = 0;
+ font.lfOutPrecision = OUT_DEFAULT_PRECIS;
+ font.lfClipPrecision = CLIP_STROKE_PRECIS | CLIP_MASK | CLIP_TT_ALWAYS | CLIP_LH_ANGLES;
+ font.lfQuality = CLEARTYPE_QUALITY;
+ font.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN;
+ wcscpy_s(font.lfFaceName, L"Segoe UI");
+
+ dlgData->hTitleFont = CreateFontIndirect(&font);
+ SendMessage(
+ hTitle,
+ WM_SETFONT,
+ reinterpret_cast<WPARAM>(dlgData->hTitleFont),
+ TRUE);
+
+ HICON hIcon = LoadIcon(
+ GetModuleHandle(nullptr),
+ MAKEINTRESOURCE(IDI_TRAY_DARK));
+ SendMessageW(hDlg, WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(hIcon));
+
+ return TRUE;
+ }
+ case WM_COMMAND:
+ return 0;
+ case WM_DESTROY:
+ DeleteObject(dlgData->hTitleFont);
+ delete dlgData;
+ SetWindowLongPtrW(hDlg, GWLP_USERDATA, 0);
+ return 0;
+ case WM_CLOSE:
+ EndDialog(hDlg, 0);
+ return TRUE;
+ default:
+ break;
+ }
+ return FALSE;
+}
const int enableLog = Button_GetCheck(hLogging) == BST_CHECKED;
dlgData->settings->SetValue(SettingsKey::LOGGING_ENABLED, enableLog);
- WMLog::GetInstance().SetEnabled(enableLog);
+ WMLog::GetInstance().EnableLogFile(enableLog);
HWND hLanguageSelector = GetDlgItem(hDlg, IDC_LANGUAGE);
const auto curLangSel = ComboBox_GetCurSel(hLanguageSelector);
DeleteFileW(logFilePath.c_str());
}
-void WMLog::SetEnabled(bool enable)
+void WMLog::EnableLogFile(bool enable)
{
const std::lock_guard lock(logMutex_);
if (enable == enabled_) {
logFile_.flush();
}
+std::vector<LogMessage> WMLog::GetLogMessages() const
+{
+ const std::scoped_lock<std::mutex> lock(logMutex_);
+ return logMessages_;
+}
+
void WMLog::LogDebug(_In_z_ _Printf_format_string_ const wchar_t *fmt, ...)
{
if (!enabled_) {
#include "common.h"
+enum class LogLevel {
+ Debug,
+ Info,
+ Error,
+};
+
+struct LogMessage {
+ LogLevel level;
+ std::string time;
+ std::string message;
+};
+
class WMLog {
public:
static WMLog& GetInstance();
void LogError(_In_z_ _Printf_format_string_ const wchar_t *fmt, ...);
void LogWinError(const wchar_t *functionName, DWORD errorCode = -1);
- void SetEnabled(bool enable);
+ void EnableLogFile(bool enable);
bool IsEnabled() const;
std::wstring GetLogFilePath();
+ std::vector<LogMessage> GetLogMessages() const;
+
private:
WMLog();
~WMLog();
void WriteMessage(const wchar_t *level, const wchar_t *msg);
void DeleteLogFile();
- std::mutex logMutex_;
+ mutable std::mutex logMutex_;
bool enabled_;
std::wofstream logFile_;
+ std::vector<LogMessage> logMessages_;
};
hAppIcon_ = LoadIconW(hglobInstance, MAKEINTRESOURCE(IDI_APP));
#ifdef _DEBUG
- WMLog::GetInstance().SetEnabled(true);
+ WMLog::GetInstance().EnableLogFile(true);
#else
- WMLog::GetInstance().SetEnabled(settings_.QueryValue(SettingsKey::LOGGING_ENABLED));
+ WMLog::GetInstance().EnableLogFile(settings_.QueryValue(SettingsKey::LOGGING_ENABLED));
#endif
log.LogInfo(L"Starting new session...");
PUSHBUTTON "Cancel",IDCANCEL,144,41,50,14
END
+IDD_LOG DIALOGEX 0, 0, 307, 176
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+CAPTION "WinMute Log"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ EDITTEXT IDC_LOG_CONTENT,0,0,306,174,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | NOT WS_BORDER | WS_VSCROLL
+END
+
/////////////////////////////////////////////////////////////////////////////
//
TOPMARGIN, 7
BOTTOMMARGIN, 55
END
+
+ IDD_LOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 300
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 168
+ END
END
#endif // APSTUDIO_INVOKED
0
END
+IDD_LOG AFX_DIALOG_LAYOUT
+BEGIN
+ 0,
+ 0, 0, 100, 100
+END
+
/////////////////////////////////////////////////////////////////////////////
//
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
+ <ClCompile Include="LogDialog.cpp" />
<ClCompile Include="Settings_BluetoothDlg.cpp" />
<ClCompile Include="Settings_ManageEndpointsDlg.cpp" />
<ClCompile Include="Settings_MuteDlg.cpp" />
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copy translation "%(Filename)" to build directory</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutputPath)lang\%(Filename)%(Extension)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutputPath)lang\%(Filename)%(Extension)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">mkdir $(OutputPath)lang >nul 2>&1
+copy /Y %(FullPath) $(OutputPath)lang</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">mkdir $(OutputPath)lang >nul 2>&1
+copy /Y %(FullPath) $(OutputPath)lang</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copy translation "%(Filename)" to build directory</Message>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copy translation "%(Filename)" to build directory</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutputPath)lang\%(Filename)%(Extension)</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutputPath)lang\%(Filename)%(Extension)</Outputs>
</CustomBuild>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ClCompile Include="AboutDlg.cpp">
<Filter>Source Files\UI\Dialogs\Settings</Filter>
</ClCompile>
+ <ClCompile Include="LogDialog.cpp">
+ <Filter>Source Files\UI\Dialogs</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\Translations\lang-de.json">
#define IDD_MANAGE_ENDPOINTS_ADD 137
#define IDI_APP_UPDATE 141
#define IDI_APPUPDATE 141
+#define IDD_LOG 142
#define IDC_LINK_HOMEPAGE 1001
#define IDC_LINK_SUPPORT 1002
#define IDC_LINK_PROJECT 1002
#define IDC_UPDATES_VIA_PACKAGE_MANAGER_NOTICE 1072
#define IDC_UPDATE_OPTIONS_DISABLED 1072
#define IDC_LINK_HELP_TRANSLATING 1073
+#define IDC_EDIT1 1075
+#define IDC_LOG_CONTENT 1075
#define ID_TRAYMENU_INFO 40001
#define ID_TRAYMENU_ 40002
#define ID_TRAYMENU_MUTEON 40003
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 142
+#define _APS_NEXT_RESOURCE_VALUE 144
#define _APS_NEXT_COMMAND_VALUE 40041
-#define _APS_NEXT_CONTROL_VALUE 1074
+#define _APS_NEXT_CONTROL_VALUE 1076
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif