From: lx-s Date: Mon, 1 Aug 2022 14:35:08 +0000 (+0200) Subject: Added Bluetooth UI and device name based muting X-Git-Tag: 2.1.0.0~8 X-Git-Url: https://repos.lx-s.de/gitweb/?a=commitdiff_plain;h=d8a72da7c8da9482f73086f6540f9a18efc3803c;p=winmute.git Added Bluetooth UI and device name based muting --- diff --git a/Dist/bin/changelog.txt b/Dist/bin/changelog.txt index 191b318..b424bc5 100644 --- a/Dist/bin/changelog.txt +++ b/Dist/bin/changelog.txt @@ -1,3 +1,9 @@ +Version 2.1.0 (2022-09-xx) + * Added new feature to mute workstation when an audio bluetooth device + disconnects (and re-enable audio if it reconnects) + * Fixed storage of SSID-lists + * Fixed some spelling errors + Version 2.0.0 (2022-05-01) * WinMute now mutes all audio endpoints and not just the default endpoint. It also stores all endpoint states and restores them if the appropriate @@ -50,44 +56,34 @@ Version 1.4.3 (2016-08-11) * Use more modern UI elements Version 1.4.1/1.4.2 (2014-07-17) - * Fixed screensaver muting: It sometimes happened that WinMute muted Windows Audio for no apparent reason and "forgot" to unmute. This is now fixed. Version 1.4 (2014-07-10) - * WinMute can now also mute if the screensaver starts Due to windows restrictions, unmuting the audio can take up to one second after the screensaver resumes. - * Added a toggle switch to configure if WinMute should unmute at all after a workstation lock or a screensaver run Version 1.3 (2012-02-23) - * Right-click menu is now correctly dismissed if the user clicks somewhere outside of the menu. - * Embedded Visual C++ 2010 DLLs. This increases file size by about 100kb, but enables the usage of this tool in workplaces that do not have deployed the Visual C++ 2010 Runtime Environment yet. - * Vista/7/8: Correctly mute the new device, if the default audio endpoint changes. - * XP: Greatly improved hardware detection code. WinMute now mutes all devices, instead of just setting the volume of the first device it finds to zero. If the Mute-Button is locked via Group Policies, WinMute will try to use the Volume Slider to "emulate" sound muting. - * XP: Actively tries to prevent other programs from unmuting the system. Version 1.2 (2011-05-30) - * Fixed a bug where WinMute could malfunction if the audio device was changed or disconnected during a windows session. Version 0.0 - 1.1 - * These documents have been lost forever... diff --git a/WinMute/BluetoothDetector.cpp b/WinMute/BluetoothDetector.cpp index 0896b5b..317f3a2 100644 --- a/WinMute/BluetoothDetector.cpp +++ b/WinMute/BluetoothDetector.cpp @@ -34,7 +34,8 @@ POSSIBILITY OF SUCH DAMAGE. #include "common.h" BluetoothDetector::BluetoothDetector() : - hNotifyWnd_(NULL), hBluetoothNotify_(NULL), initialized_(false) + hNotifyWnd_(NULL), hBluetoothNotify_(NULL), + initialized_(false), useDeviceList_(false) { } @@ -60,8 +61,8 @@ bool BluetoothDetector::LoadRadioNotifications() auto& log = WMLog::GetInstance(); notificationHandles_.clear(); - BLUETOOTH_FIND_RADIO_PARAMS bfrp = { sizeof(BLUETOOTH_FIND_RADIO_PARAMS) }; HANDLE btHandle; + BLUETOOTH_FIND_RADIO_PARAMS bfrp = { sizeof(BLUETOOTH_FIND_RADIO_PARAMS) }; HBLUETOOTH_RADIO_FIND hRadiosFind = BluetoothFindFirstRadio(&bfrp, &btHandle); if (hRadiosFind == nullptr) { log.WriteWindowsError(L"BluetoothFindFirstRadio", GetLastError()); @@ -117,6 +118,14 @@ void BluetoothDetector::Unload() initialized_ = false; } +void BluetoothDetector::SetDeviceList( + const std::vector& devices, + bool useDeviceList) +{ + deviceNames_ = devices; + useDeviceList_ = useDeviceList; +} + BluetoothDetector::BluetoothStatus BluetoothDetector::GetBluetoothStatus( const UINT message, const WPARAM wParam, const LPARAM lParam) { @@ -141,12 +150,18 @@ BluetoothDetector::BluetoothStatus BluetoothDetector::GetBluetoothStatus( // only react to audio devices and not (e. g.) game controllers if ((inRangeInfo->deviceInfo.flags & BDIF_COD) && - GET_COD_MAJOR(inRangeInfo->deviceInfo.classOfDevice) != COD_MAJOR_AUDIO && - GET_COD_MAJOR(inRangeInfo->deviceInfo.classOfDevice) != COD_MAJOR_PHONE) { + GET_COD_MAJOR(inRangeInfo->deviceInfo.classOfDevice) != COD_MAJOR_AUDIO) { return BluetoothStatus::Unknown; } auto& log = WMLog::GetInstance(); + if (useDeviceList_) { + auto pos = std::find(begin(deviceNames_), end(deviceNames_), inRangeInfo->deviceInfo.name); + if (pos == end(deviceNames_)) { + log.Write(L"Bluetooth device \"S\" not in list.", inRangeInfo->deviceInfo.name); + return BluetoothStatus::Unknown; + } + } if (inRangeInfo->deviceInfo.flags & BDIF_CONNECTED) { log.Write(L"Bluetooth Audio device \"%S\" connected.", inRangeInfo->deviceInfo.name); return BluetoothStatus::Connected; diff --git a/WinMute/BluetoothDetector.h b/WinMute/BluetoothDetector.h index dc7cd06..62baf90 100644 --- a/WinMute/BluetoothDetector.h +++ b/WinMute/BluetoothDetector.h @@ -46,6 +46,8 @@ public: BluetoothDetector(const WifiDetector&) = delete; BluetoothDetector& operator=(const WifiDetector&) = delete; + void SetDeviceList(const std::vector& devices, bool useDeviceList); + bool Init(HWND hNotifyWnd); void Unload(); @@ -62,4 +64,6 @@ private: void UnloadRadioNotifications(); bool initialized_; + bool useDeviceList_; + std::vector deviceNames_; }; diff --git a/WinMute/SettingsDlg.cpp b/WinMute/SettingsDlg.cpp index 5cbb4ea..7092bb4 100644 --- a/WinMute/SettingsDlg.cpp +++ b/WinMute/SettingsDlg.cpp @@ -38,6 +38,7 @@ enum SettingsTabsIDs { SETTINGS_TAB_MUTE, SETTINGS_TAB_QUIETHOURS, SETTINGS_TAB_WIFI, + SETTINGS_TAB_BLUETOOTH, SETTINGS_TAB_COUNT }; @@ -60,7 +61,6 @@ extern INT_PTR CALLBACK Settings_GeneralDlgProc(HWND, UINT, WPARAM, LPARAM); extern INT_PTR CALLBACK Settings_MuteDlgProc(HWND, UINT, WPARAM, LPARAM); extern INT_PTR CALLBACK Settings_BluetoothDlgProc(HWND, UINT, WPARAM, LPARAM); extern INT_PTR CALLBACK Settings_WifiDlgProc(HWND, UINT, WPARAM, LPARAM); -extern INT_PTR CALLBACK Settings_GeneralWifiDlgProc(HWND, UINT, WPARAM, LPARAM); extern HINSTANCE hglobInstance; @@ -116,7 +116,7 @@ static void ResizeTabs(HWND hTabCtrl, HWND* hTabs, int tabCount) tabCtrlRect.right - tabCtrlRect.left, tabCtrlRect.bottom - tabCtrlRect.top, 0); - if (hdwp == NULL) { + if (newHdwp == NULL) { PrintWindowsError(_T("DeferWindowPos"), GetLastError()); break; } else { @@ -144,6 +144,7 @@ INT_PTR CALLBACK SettingsDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lPar InsertTabItem(dlgData->hTabCtrl, SETTINGS_TAB_MUTE, _T("Mute")); InsertTabItem(dlgData->hTabCtrl, SETTINGS_TAB_QUIETHOURS, _T("Quiet Hours")); InsertTabItem(dlgData->hTabCtrl, SETTINGS_TAB_WIFI, _T("WLAN")); + InsertTabItem(dlgData->hTabCtrl, SETTINGS_TAB_BLUETOOTH, _T("Bluetooth")); dlgData->hTabs[SETTINGS_TAB_GENERAL] = CreateDialogParam( hglobInstance, @@ -167,7 +168,13 @@ INT_PTR CALLBACK SettingsDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lPar hglobInstance, MAKEINTRESOURCE(IDD_SETTINGS_WIFI), hDlg, - Settings_GeneralWifiDlgProc, + Settings_WifiDlgProc, + reinterpret_cast(settings)); + dlgData->hTabs[SETTINGS_TAB_BLUETOOTH] = CreateDialogParam( + hglobInstance, + MAKEINTRESOURCE(IDD_SETTINGS_BLUETOOTH), + hDlg, + Settings_BluetoothDlgProc, reinterpret_cast(settings)); // Init tab pages diff --git a/WinMute/Settings_BluetoothDlg.cpp b/WinMute/Settings_BluetoothDlg.cpp index 4538184..7f2723d 100644 --- a/WinMute/Settings_BluetoothDlg.cpp +++ b/WinMute/Settings_BluetoothDlg.cpp @@ -33,64 +33,97 @@ POSSIBILITY OF SUCH DAMAGE. #include "common.h" -static constexpr int SSID_MAX_LEN = 32; +static constexpr int BT_DEV_NAME_MAX_LEN = 100; -struct WiFiData { - tstring ssidName; +struct BtDeviceName { + tstring devName; }; +static bool GetPairedBtAudioDevices(std::vector& devices) +{ + auto& log = WMLog::GetInstance(); + + BLUETOOTH_DEVICE_SEARCH_PARAMS bfrp; + ZeroMemory(&bfrp, sizeof(bfrp)); + bfrp.dwSize = sizeof(bfrp); + bfrp.fReturnRemembered = 1; + BLUETOOTH_DEVICE_INFO btdi; + ZeroMemory(&btdi, sizeof(btdi)); + btdi.dwSize = sizeof(btdi); + HBLUETOOTH_DEVICE_FIND hBtDevFind = BluetoothFindFirstDevice(&bfrp, &btdi); + if (hBtDevFind == NULL) { + PrintWindowsError(L"BluetoothFindFirstDevice"); + log.WriteWindowsError(L"BluetoothFindFirstDevice", GetLastError()); + } else { + do { + if (GET_COD_MAJOR(btdi.ulClassofDevice) == COD_MAJOR_AUDIO) { + devices.push_back(btdi.szName); + } + } while (BluetoothFindNextDevice(hBtDevFind, &btdi)); + BluetoothFindDeviceClose(hBtDevFind); + return true; + } + return false; +} + static INT_PTR CALLBACK Settings_BluetoothAddDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: { - HWND hSsid = GetDlgItem(hDlg, IDC_WIFI_NAME); - WiFiData* wifiData = reinterpret_cast(lParam); - if (wifiData == nullptr) { + HWND hBtDevName = GetDlgItem(hDlg, IDC_BT_DEVICE_NAME); + BtDeviceName* btDeviceData = reinterpret_cast(lParam); + if (btDeviceData == nullptr) { return FALSE; } - SetWindowLongPtr(hDlg, GWLP_USERDATA, reinterpret_cast(wifiData)); + SetWindowLongPtr(hDlg, GWLP_USERDATA, reinterpret_cast(btDeviceData)); - if (wifiData->ssidName.length() == 0) { - if (!SetWindowText(hDlg, _T("Add WiFi network"))) { - PrintWindowsError(_T("SetWindowText"), GetLastError()); + if (btDeviceData->devName.length() == 0) { + if (!SetWindowText(hDlg, _T("Add Bluetooth device"))) { + PrintWindowsError(_T("SetWindowText"), GetLastError()); return FALSE; } - } - else { - if (!SetWindowText(hDlg, _T("Edit WiFi network")) - || !SetWindowText( - GetDlgItem(hDlg, IDC_WIFI_NAME), - wifiData->ssidName.c_str())) { + } else { + if (!SetWindowText(hDlg, _T("Edit Bluetooth device")) + || !SetWindowText(GetDlgItem(hDlg, IDC_BT_DEVICE_NAME), + btDeviceData->devName.c_str())) { PrintWindowsError(_T("SetWindowText"), GetLastError()); return FALSE; } } - Edit_LimitText(hSsid, SSID_MAX_LEN); - if (GetDlgCtrlID(reinterpret_cast(wParam)) != IDC_WIFI_NAME) { - SetFocus(hSsid); + // Fill Combobox + std::vector registeredBtDevices; + if (GetPairedBtAudioDevices(registeredBtDevices)) { + for (const auto& devName : registeredBtDevices) { + ComboBox_AddString(hBtDevName, devName.c_str()); + } + } + + Edit_LimitText(hBtDevName, BT_DEV_NAME_MAX_LEN); + if (GetDlgCtrlID(reinterpret_cast(wParam)) != IDC_BT_DEVICE_NAME) { + SetFocus(hBtDevName); return FALSE; } return TRUE; } case WM_COMMAND: if (LOWORD(wParam) == IDOK) { - HWND hSsid = GetDlgItem(hDlg, IDC_WIFI_NAME); - int textLen = Edit_GetTextLength(hSsid); + HWND hDevName = GetDlgItem(hDlg, IDC_BT_DEVICE_NAME); + int textLen = Edit_GetTextLength(hDevName); if (textLen == 0) { EDITBALLOONTIP ebt; ZeroMemory(&ebt, sizeof(ebt)); ebt.cbStruct = sizeof(ebt); - ebt.pszText = _T("Please enter a SSID/WIFI name"); - ebt.pszTitle = _T("SSID Name"); + ebt.pszText = _T("Please enter a Bluetooth device name"); + ebt.pszTitle = _T("Bluetooth Device Name"); ebt.ttiIcon = TTI_INFO; - Edit_ShowBalloonTip(hSsid, &ebt); + Edit_ShowBalloonTip(hDevName, &ebt); } else { - TCHAR ssidBuf[SSID_MAX_LEN + 1]; - WiFiData* wifiData = reinterpret_cast(GetWindowLongPtr(hDlg, GWLP_USERDATA)); - if (wifiData != nullptr) { - Edit_GetText(hSsid, ssidBuf, ARRAY_SIZE(ssidBuf)); - wifiData->ssidName = ssidBuf; + TCHAR devNameBuf[BT_DEV_NAME_MAX_LEN + 1]; + BtDeviceName* btDevName = reinterpret_cast(GetWindowLongPtr(hDlg, GWLP_USERDATA)); + if (btDevName != nullptr) { + Edit_GetText(hDevName, devNameBuf, ARRAY_SIZE(devNameBuf)); + btDevName->devName = devNameBuf; EndDialog(hDlg, 0); } else { @@ -111,12 +144,12 @@ static INT_PTR CALLBACK Settings_BluetoothAddDlgProc(HWND hDlg, UINT msg, WPARAM return FALSE; } -static std::vector ExportSsidListItems(HWND hList) +static std::vector ExportBluetoothDeviceList(HWND hList) { std::vector items; DWORD itemCount = ListBox_GetCount(hList); for (DWORD i = 0; i < itemCount; ++i) { - TCHAR textBuf[SSID_MAX_LEN + 1] = { 0 }; + TCHAR textBuf[BT_DEV_NAME_MAX_LEN + 1] = { 0 }; DWORD textLen = ListBox_GetTextLen(hList, i); if (textLen < ARRAY_SIZE(textBuf)) { ListBox_GetText(hList, i, textBuf); @@ -128,12 +161,13 @@ static std::vector ExportSsidListItems(HWND hList) static bool IsBluetoothAvailable() { - HANDLE wlanHandle; - DWORD vers = 2; - if (WlanOpenHandle(vers, NULL, &vers, &wlanHandle) != ERROR_SUCCESS) { + HANDLE btHandle; + BLUETOOTH_FIND_RADIO_PARAMS bfrp = { sizeof(BLUETOOTH_FIND_RADIO_PARAMS) }; + HBLUETOOTH_RADIO_FIND hRadiosFind = BluetoothFindFirstRadio(&bfrp, &btHandle); + if (hRadiosFind == nullptr) { return false; } - WlanCloseHandle(wlanHandle, NULL); + BluetoothFindRadioClose(hRadiosFind); return true; } @@ -149,71 +183,74 @@ INT_PTR CALLBACK Settings_BluetoothDlgProc(HWND hDlg, UINT msg, WPARAM wParam, L assert(settings != nullptr); SetWindowLongPtr(hDlg, GWLP_USERDATA, reinterpret_cast(settings)); - DWORD enabled = settings->QueryValue(SettingsKey::MUTE_ON_WLAN); - Button_SetCheck(GetDlgItem(hDlg, IDC_ENABLE_WIFI_MUTE), + DWORD enabled = settings->QueryValue(SettingsKey::MUTE_ON_BLUETOOTH); + + Button_SetCheck(GetDlgItem(hDlg, IDC_ENABLE_BLUETOOTH_MUTE), enabled ? BST_CHECKED : BST_UNCHECKED); - Button_Enable(GetDlgItem(hDlg, IDC_IS_PERMITLIST), enabled); - enabled = settings->QueryValue(SettingsKey::MUTE_ON_WLAN_ALLOWLIST); - Button_SetCheck(GetDlgItem(hDlg, IDC_IS_PERMITLIST), + Button_Enable(GetDlgItem(hDlg, IDC_ENABLE_BLUETOOTH_MUTE_DEVICE_LIST), enabled); + + enabled = settings->QueryValue(SettingsKey::MUTE_ON_BLUETOOTH_DEVICELIST); + Button_SetCheck(GetDlgItem(hDlg, IDC_ENABLE_BLUETOOTH_MUTE_DEVICE_LIST), enabled ? BST_CHECKED : BST_UNCHECKED); - Button_Enable(GetDlgItem(hDlg, IDC_WIFI_EDIT), FALSE); - Button_Enable(GetDlgItem(hDlg, IDC_WIFI_REMOVE), FALSE); + Button_Enable(GetDlgItem(hDlg, IDC_BLUETOOTH_EDIT), FALSE); + Button_Enable(GetDlgItem(hDlg, IDC_BLUETOOTH_REMOVE), FALSE); - HWND hList = GetDlgItem(hDlg, IDC_WIFI_LIST); - const auto networks = settings->GetWifiNetworks(); - for (const auto& n : networks) { - ListBox_AddString(hList, n.c_str()); + HWND hList = GetDlgItem(hDlg, IDC_BLUETOOTH_LIST); + const auto devices = settings->GetBluetoothDevicesW(); + for (const auto& dev : devices) { + ListBox_AddString(hList, dev.c_str()); } - Button_Enable(GetDlgItem(hDlg, IDC_WIFI_REMOVEALL), + Button_Enable( + GetDlgItem(hDlg, IDC_BLUETOOTH_REMOVEALL), ListBox_GetCount(hList) > 0); if (!IsBluetoothAvailable()) { - ShowWindow(GetDlgItem(hDlg, IDC_STATIC_WLAN_NOT_AVAILABLE), SW_SHOW); - Button_SetCheck(GetDlgItem(hDlg, IDC_ENABLE_WIFI_MUTE), BST_UNCHECKED); - Button_Enable(GetDlgItem(hDlg, IDC_ENABLE_WIFI_MUTE), FALSE); - Button_SetCheck(GetDlgItem(hDlg, IDC_IS_PERMITLIST), BST_UNCHECKED); - Button_Enable(GetDlgItem(hDlg, IDC_IS_PERMITLIST), FALSE); + ShowWindow(GetDlgItem(hDlg, IDC_STATIC_BLUETOOTH_NOT_AVAILABLE), SW_SHOW); + Button_SetCheck(GetDlgItem(hDlg, IDC_ENABLE_BLUETOOTH_MUTE), BST_UNCHECKED); + Button_Enable(GetDlgItem(hDlg, IDC_ENABLE_BLUETOOTH_MUTE), FALSE); + Button_SetCheck(GetDlgItem(hDlg, IDC_ENABLE_BLUETOOTH_MUTE_DEVICE_LIST), BST_UNCHECKED); + Button_Enable(GetDlgItem(hDlg, IDC_ENABLE_BLUETOOTH_MUTE_DEVICE_LIST), FALSE); } else { - ShowWindow(GetDlgItem(hDlg, IDC_STATIC_WLAN_NOT_AVAILABLE), SW_HIDE); + ShowWindow(GetDlgItem(hDlg, IDC_STATIC_BLUETOOTH_NOT_AVAILABLE), SW_HIDE); } return TRUE; } case WM_COMMAND: { - if (LOWORD(wParam) == IDC_ENABLE_WIFI_MUTE) { - DWORD checked = Button_GetCheck(GetDlgItem(hDlg, IDC_ENABLE_WIFI_MUTE)); - Button_Enable(GetDlgItem(hDlg, IDC_IS_PERMITLIST), checked == BST_CHECKED); + if (LOWORD(wParam) == IDC_ENABLE_BLUETOOTH_MUTE) { + DWORD checked = Button_GetCheck(GetDlgItem(hDlg, IDC_ENABLE_BLUETOOTH_MUTE)); + Button_Enable(GetDlgItem(hDlg, IDC_ENABLE_BLUETOOTH_MUTE_DEVICE_LIST), checked == BST_CHECKED); } else if (LOWORD(wParam) == IDC_BLUETOOTH_LIST) { HWND hList = GetDlgItem(hDlg, IDC_BLUETOOTH_LIST); if (HIWORD(wParam) == LBN_SELCHANGE || HIWORD(wParam) == LBN_SELCANCEL) { bool entrySelected = (ListBox_GetCurSel(hList) != LB_ERR); - Button_Enable(GetDlgItem(hDlg, IDC_WIFI_EDIT), entrySelected); - Button_Enable(GetDlgItem(hDlg, IDC_WIFI_REMOVE), entrySelected); + Button_Enable(GetDlgItem(hDlg, IDC_BLUETOOTH_EDIT), entrySelected); + Button_Enable(GetDlgItem(hDlg, IDC_BLUETOOTH_REMOVE), entrySelected); } else if (HIWORD(wParam) == LBN_KILLFOCUS) { bool entrySelected = (ListBox_GetCurSel(hList) != LB_ERR); - Button_Enable(GetDlgItem(hDlg, IDC_WIFI_EDIT), entrySelected); - Button_Enable(GetDlgItem(hDlg, IDC_WIFI_REMOVE), entrySelected); + Button_Enable(GetDlgItem(hDlg, IDC_BLUETOOTH_EDIT), entrySelected); + Button_Enable(GetDlgItem(hDlg, IDC_BLUETOOTH_REMOVE), entrySelected); } } else if (LOWORD(wParam) == IDC_BLUETOOTH_ADD) { - WiFiData wifiData; + BtDeviceName btDeviceName; if (DialogBoxParam( NULL, MAKEINTRESOURCE(IDD_SETTINGS_BLUETOOTH_ADD), hDlg, Settings_BluetoothAddDlgProc, - reinterpret_cast(&wifiData)) == 0) { - std::vector networks = ExportSsidListItems(GetDlgItem(hDlg, IDC_BLUETOOTH_LIST)); - if (std::find(begin(networks), end(networks), wifiData.ssidName) == end(networks)) { + reinterpret_cast(&btDeviceName)) == 0) { + std::vector devices = ExportBluetoothDeviceList(GetDlgItem(hDlg, IDC_BLUETOOTH_LIST)); + if (std::find(begin(devices), end(devices), btDeviceName.devName) == end(devices)) { ListBox_AddString( GetDlgItem(hDlg, IDC_BLUETOOTH_LIST), - wifiData.ssidName.c_str()); - HWND hRemoveAll = GetDlgItem(hDlg, IDC_WIFI_REMOVEALL); + btDeviceName.devName.c_str()); + HWND hRemoveAll = GetDlgItem(hDlg, IDC_BLUETOOTH_REMOVEALL); if (!IsWindowEnabled(hRemoveAll)) { Button_Enable(hRemoveAll, TRUE); } @@ -221,7 +258,7 @@ INT_PTR CALLBACK Settings_BluetoothDlgProc(HWND hDlg, UINT msg, WPARAM wParam, L } } else if (LOWORD(wParam) == IDC_BLUETOOTH_EDIT) { - HWND hList = GetDlgItem(hDlg, IDC_WIFI_LIST); + HWND hList = GetDlgItem(hDlg, IDC_BLUETOOTH_LIST); WPARAM sel = ListBox_GetCurSel(hList); if (sel != LB_ERR) { int len = ListBox_GetTextLen(hList, sel); @@ -230,8 +267,8 @@ INT_PTR CALLBACK Settings_BluetoothDlgProc(HWND hDlg, UINT msg, WPARAM wParam, L if ((textBuf = new TCHAR[static_cast(len) + 1]) != NULL) { ListBox_GetText(hList, sel, textBuf); - WiFiData wifiData; - wifiData.ssidName = textBuf; + BtDeviceName btDevName; + btDevName.devName = textBuf; delete[] textBuf; if (DialogBoxParam( @@ -239,10 +276,10 @@ INT_PTR CALLBACK Settings_BluetoothDlgProc(HWND hDlg, UINT msg, WPARAM wParam, L MAKEINTRESOURCE(IDD_SETTINGS_BLUETOOTH_ADD), hDlg, Settings_BluetoothAddDlgProc, - reinterpret_cast(&wifiData)) == 0) { - std::vector networks = ExportSsidListItems(GetDlgItem(hDlg, IDC_WIFI_LIST)); - if (std::find(begin(networks), end(networks), wifiData.ssidName) == end(networks)) { - ListBox_InsertString(hList, sel, wifiData.ssidName.c_str()); + reinterpret_cast(&btDevName)) == 0) { + std::vector networks = ExportBluetoothDeviceList(GetDlgItem(hDlg, IDC_WIFI_LIST)); + if (std::find(begin(networks), end(networks), btDevName.devName) == end(networks)) { + ListBox_InsertString(hList, sel, btDevName.devName.c_str()); ListBox_DeleteString(hList, sel + 1); } else { @@ -274,15 +311,15 @@ INT_PTR CALLBACK Settings_BluetoothDlgProc(HWND hDlg, UINT msg, WPARAM wParam, L return 0; } case WM_SAVESETTINGS: { - /*WMSettings* settings = reinterpret_cast(GetWindowLongPtr(hDlg, GWLP_USERDATA)); - std::vector networks = ExportSsidListItems(GetDlgItem(hDlg, IDC_WIFI_LIST)); - settings->StoreWifiNetworks(networks); + WMSettings* settings = reinterpret_cast(GetWindowLongPtr(hDlg, GWLP_USERDATA)); + std::vector devices = ExportBluetoothDeviceList(GetDlgItem(hDlg, IDC_BLUETOOTH_LIST)); + settings->StoreBluetoothDevices(devices); - DWORD checked = Button_GetCheck(GetDlgItem(hDlg, IDC_ENABLE_WIFI_MUTE)); - settings->SetValue(SettingsKey::MUTE_ON_WLAN, checked == BST_CHECKED); + DWORD checked = Button_GetCheck(GetDlgItem(hDlg, IDC_ENABLE_BLUETOOTH_MUTE)); + settings->SetValue(SettingsKey::MUTE_ON_BLUETOOTH, checked == BST_CHECKED); - checked = Button_GetCheck(GetDlgItem(hDlg, IDC_IS_PERMITLIST)); - settings->SetValue(SettingsKey::MUTE_ON_WLAN_ALLOWLIST, checked == BST_CHECKED);*/ + checked = Button_GetCheck(GetDlgItem(hDlg, IDC_ENABLE_BLUETOOTH_MUTE_DEVICE_LIST)); + settings->SetValue(SettingsKey::MUTE_ON_BLUETOOTH_DEVICELIST, checked == BST_CHECKED); return 0; } diff --git a/WinMute/WMSettings.cpp b/WinMute/WMSettings.cpp index 51622f8..fc0d7da 100644 --- a/WinMute/WMSettings.cpp +++ b/WinMute/WMSettings.cpp @@ -150,7 +150,8 @@ static DWORD GetDefaultSetting(SettingsKey key) } -static void NormalizeStringList(std::vector& items) +template +static void NormalizeStringList(std::vector> &items) { if (items.size() > 1) { std::sort(std::begin(items), std::end(items)); @@ -289,7 +290,7 @@ bool WMSettings::IsAutostartEnabled() WMLog& log = WMLog::GetInstance(); TCHAR wmPath[MAX_PATH + 1]; if (GetModuleFileName(NULL, wmPath, sizeof(wmPath) / sizeof(wmPath[0])) == 0) { - log.Write(_T("Failed to get path of win mute")); + log.Write(_T("Failed to get path of winmute")); } else { HKEY hRunKey = OpenAutostartKey(KEY_READ); if (hRunKey != NULL) { @@ -315,7 +316,7 @@ void WMSettings::EnableAutostart(bool enable) if (enable) { TCHAR wmPath[MAX_PATH + 1]; if (GetModuleFileName(NULL, wmPath, sizeof(wmPath) / sizeof(wmPath[0])) == 0) { - log.Write(_T("Failed to get path of win mute")); + log.Write(_T("Failed to get path of winmute")); } else { DWORD regError = RegSetKeyValue( hRunKey, @@ -414,8 +415,8 @@ bool WMSettings::StoreWifiNetworks(std::vector& networks) NormalizeStringList(networks); for (size_t i = 0; i < networks.size(); ++i) { - TCHAR valueName[10]; - StringCchPrintfW(valueName, ARRAY_SIZE(valueName), _T("WiFi %03zu"), i + 1); + TCHAR valueName[25]; + StringCchPrintfW(valueName, ARRAY_SIZE(valueName), _T("WiFi %03d"), i + 1); const tstring& v = networks[i]; DWORD regError = RegSetValueEx( hWifiKey_, @@ -482,12 +483,10 @@ bool WMSettings::StoreBluetoothDevices(std::vector& devices) NULL); if (regError == ERROR_NO_MORE_ITEMS) { break; - } - else if (regError != ERROR_SUCCESS) { + } else if (regError != ERROR_SUCCESS) { PrintWindowsError(_T("RegEnumValue"), regError); return false; - } - else { + } else { regError = RegDeleteValue(hBluetoothKey_, valueName); if (regError != ERROR_SUCCESS) { PrintWindowsError(_T("RegDeleteValue"), regError); @@ -499,14 +498,14 @@ bool WMSettings::StoreBluetoothDevices(std::vector& devices) NormalizeStringList(devices); for (size_t i = 0; i < devices.size(); ++i) { - TCHAR valueName[10]; + TCHAR valueName[25]; StringCchPrintfW( valueName, ARRAY_SIZE(valueName), - _T("Bluetooth %03zu"), i + 1); + _T("Bluetooth %03d"), i + 1); const tstring& v = devices[i]; DWORD regError = RegSetValueEx( - hWifiKey_, + hBluetoothKey_, valueName, NULL, REG_SZ, @@ -521,17 +520,17 @@ bool WMSettings::StoreBluetoothDevices(std::vector& devices) return true; } -std::vector WMSettings::GetBluetoothDevices() const +std::vector WMSettings::GetBluetoothDevicesA() const { - std::vector devices; + std::vector devices; for (int valIdx = 0; ; ++valIdx) { - TCHAR valueName[260] = { 0 }; - TCHAR dataBuf[260] = { 0 }; + char valueName[260] = { 0 }; + char dataBuf[260] = { 0 }; DWORD valueSize = ARRAY_SIZE(valueName); DWORD valType = 0; DWORD dataLen = ARRAY_SIZE(dataBuf); - DWORD regError = RegEnumValue( + DWORD regError = RegEnumValueA( hBluetoothKey_, valIdx, valueName, @@ -542,12 +541,42 @@ std::vector WMSettings::GetBluetoothDevices() const &dataLen); if (regError == ERROR_NO_MORE_ITEMS) { break; - } - else if (regError != ERROR_SUCCESS) { + } else if (regError != ERROR_SUCCESS) { PrintWindowsError(_T("RegEnumValue"), regError); return {}; + } else { + devices.push_back(dataBuf); } - else { + } + NormalizeStringList(devices); + return devices; +} + +std::vector WMSettings::GetBluetoothDevicesW() const +{ + std::vector devices; + for (int valIdx = 0; ; ++valIdx) { + wchar_t valueName[260] = { 0 }; + wchar_t dataBuf[260] = { 0 }; + DWORD valueSize = ARRAY_SIZE(valueName); + DWORD valType = 0; + DWORD dataLen = ARRAY_SIZE(dataBuf); + + DWORD regError = RegEnumValueW( + hBluetoothKey_, + valIdx, + valueName, + &valueSize, + NULL, + &valType, + reinterpret_cast(dataBuf), + &dataLen); + if (regError == ERROR_NO_MORE_ITEMS) { + break; + } else if (regError != ERROR_SUCCESS) { + PrintWindowsError(_T("RegEnumValue"), regError); + return {}; + } else { devices.push_back(dataBuf); } } diff --git a/WinMute/WMSettings.h b/WinMute/WMSettings.h index 7800d1e..807f05e 100644 --- a/WinMute/WMSettings.h +++ b/WinMute/WMSettings.h @@ -75,7 +75,8 @@ public: std::vector GetWifiNetworks() const; bool StoreBluetoothDevices(std::vector& networks); - std::vector GetBluetoothDevices() const; + std::vector GetBluetoothDevicesW() const; + std::vector GetBluetoothDevicesA() const; DWORD QueryValue(SettingsKey key) const; bool SetValue(SettingsKey key, DWORD value); diff --git a/WinMute/WinMute.cpp b/WinMute/WinMute.cpp index 90a6c2a..9e75d7f 100644 --- a/WinMute/WinMute.cpp +++ b/WinMute/WinMute.cpp @@ -277,17 +277,6 @@ bool WinMute::Init() return false; } - if (!btDetector_.Init(hWnd_)) { - log.Write(_T("Error loading bluetooth detector")); - TaskDialog(nullptr, nullptr, - PROGRAM_NAME, - _T("Bluetooth not available"), - _T("Either the Bluetooth service has not been started, ") - _T("or your device is not capable of using bluetooth devices. ") - _T("This feature will be disabled for this computer"), - TDCBF_OK_BUTTON, TD_INFORMATION_ICON, nullptr); - } - bool isDarkMode = true; IsDarkMode(isDarkMode); hTrayIcon_ = LoadIcon( @@ -334,12 +323,10 @@ bool WinMute::LoadSettings() if (!muteConfig_.muteOnBluetooth) { btDetector_.Unload(); } else if (!btDetector_.Init(hWnd_)) { - TaskDialog(nullptr, nullptr, PROGRAM_NAME, - _T("Bluetooth not available"), - _T("Either the Bluetooth service has not been started, ") - _T("or your device is not capable of using bluetooth connections. ") - _T("This feature will be disabled for this computer."), - TDCBF_OK_BUTTON, TD_INFORMATION_ICON, nullptr); + trayIcon_.ShowPopup( + _T("Bluetooth muting disabled"), + _T("Bluetooth is not available or disabled. ") + _T("Bluetooth muting will be disabled on this computer")); settings_.SetValue(SettingsKey::MUTE_ON_BLUETOOTH, FALSE); } @@ -348,12 +335,10 @@ bool WinMute::LoadSettings() wifiDetector_.Unload(); } else { if (!wifiDetector_.Init(hWnd_)) { - TaskDialog(nullptr, nullptr, PROGRAM_NAME, - _T("WLAN not available"), - _T("Either the WLAN service has not been started, ") - _T("or your device is not capable of using wireless networks. ") - _T("This feature will be disabled for this computer"), - TDCBF_OK_BUTTON, TD_INFORMATION_ICON, nullptr); + trayIcon_.ShowPopup( + _T("WLAN muting disabled"), + _T("WLAN is not available or disabled. ") + _T("WLAN muting will be disabled on this computer")); settings_.SetValue(SettingsKey::MUTE_ON_WLAN, FALSE); } else { bool isMuteList = !settings_.QueryValue(SettingsKey::MUTE_ON_WLAN_ALLOWLIST); diff --git a/WinMute/WinMute.rc b/WinMute/WinMute.rc index 688e504..e533f4f 100644 --- a/WinMute/WinMute.rc +++ b/WinMute/WinMute.rc @@ -156,7 +156,7 @@ BEGIN PUSHBUTTON "Remove all",IDC_WIFI_REMOVEALL,179,123,56,16 LTEXT "Note: WLAN is not available on your device, so some options have been disabled.",IDC_STATIC_WLAN_NOT_AVAILABLE,7,179,228,18 CONTROL "Enable WLAN based muting",IDC_ENABLE_WIFI_MUTE,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,7,26,228,14 - CONTROL "Mute workstation if the WLAN network name is NOT in the list\n(default: mute if it is in the list)",IDC_IS_PERMITLIST, + CONTROL "Mute workstation if the WLAN network name is NOT in the list\n(default: mute if it is on the list)",IDC_IS_PERMITLIST, "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,20,41,215,18 LTEXT """WLAN Mute"" allows you to mute your workstation based on the name of the connected wireless network.",IDC_STATIC,7,7,228,19 END @@ -177,28 +177,28 @@ STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - LISTBOX IDC_BLUETOOTH_LIST,7,79,170,90,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Add",IDC_BLUETOOTH_ADD,179,78,56,16 - PUSHBUTTON "Edit",IDC_BLUETOOTH_EDIT,179,98,56,16 - PUSHBUTTON "Remove",IDC_BLUETOOTH_REMOVE,179,116,56,16 - PUSHBUTTON "Remove all",IDC_BLUETOOTH_REMOVEALL,179,136,56,16 + LISTBOX IDC_BLUETOOTH_LIST,7,90,170,79,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Add",IDC_BLUETOOTH_ADD,179,89,56,16 + PUSHBUTTON "Edit",IDC_BLUETOOTH_EDIT,179,109,56,16 + PUSHBUTTON "Remove",IDC_BLUETOOTH_REMOVE,179,127,56,16 + PUSHBUTTON "Remove all",IDC_BLUETOOTH_REMOVEALL,179,147,56,16 LTEXT "Note: Bluetooth is not available on your device, so some options have been disabled.",IDC_STATIC_BLUETOOTH_NOT_AVAILABLE,7,172,228,18 - CONTROL "Enable Bluetooth based muting",IDC_ENABLE_WIFI_MUTE, - "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,7,37,228,14 - CONTROL "Only mute when one of the following devices connect to or disconnect from your PC.",IDC_IS_PERMITLIST, - "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,20,52,215,18 - LTEXT """Bluetooth Muting"" enables muting based on the presence of a bluetooth audio-class device.\nWinMute mutes your workstation if an audio-class bluetooth device is disconnected from your PC.",IDC_STATIC,7,0,228,31 + CONTROL "Enable Bluetooth based muting",IDC_ENABLE_BLUETOOTH_MUTE, + "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,7,52,228,14 + CONTROL "Only mute when one of the following devices connect to or disconnect from your PC.",IDC_ENABLE_BLUETOOTH_MUTE_DEVICE_LIST, + "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,20,66,215,18 + LTEXT """Bluetooth Muting"" enables if an audio-class bluetooth device is disconnected from, and re-enables audio if a device is reconnected to your pc.\nYou can enable this behaviour for all audio bluetooth devices or only for a specific set of devices.",IDC_STATIC,7,7,228,43 END IDD_SETTINGS_BLUETOOTH_ADD DIALOGEX 0, 0, 201, 62 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Dialog" +CAPTION "Add Bluetooth device" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "Save",IDOK,91,41,50,14 PUSHBUTTON "Cancel",IDCANCEL,144,41,50,14 LTEXT "Bluetooth device name:",IDC_STATIC,7,7,187,14 - EDITTEXT IDC_WIFI_NAME,7,20,187,16,ES_AUTOHSCROLL + COMBOBOX IDC_BT_DEVICE_NAME,7,22,187,17,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP END @@ -394,7 +394,6 @@ BEGIN MENUITEM "... Workstation is locked", ID_TRAYMENU_MUTEONLOCK, CHECKED MENUITEM "... Screensaver starts", ID_TRAYMENU_MUTEONSCREENSAVER, CHECKED MENUITEM "... Screen turns off", ID_TRAYMENU_MUTEONSCREENSUSPEND, CHECKED - MENUITEM "...Bluetooth Device disconnects", ID_TRAYMENU_MUTEONBLUETOOTH MENUITEM SEPARATOR MENUITEM "Restore volume afterwards", ID_TRAYMENU_RESTOREAUDIO, CHECKED MENUITEM SEPARATOR diff --git a/WinMute/resource.h b/WinMute/resource.h index f7b4594..b352470 100644 --- a/WinMute/resource.h +++ b/WinMute/resource.h @@ -67,6 +67,9 @@ #define IDC_BLUETOOTH_REMOVE 1033 #define IDC_BLUETOOTH_REMOVEALL 1034 #define IDC_BLUETOOTH_LIST 1035 +#define IDC_ENABLE_BLUETOOTH_MUTE 1036 +#define IDC_ENABLE_BLUETOOTH_MUTE_DEVICE_LIST 1037 +#define IDC_BT_DEVICE_NAME 1038 #define ID_TRAYMENU_INFO 40001 #define ID_TRAYMENU_ 40002 #define ID_TRAYMENU_MUTEON 40003 @@ -99,14 +102,18 @@ #define ID_TRAYMENU_BLUETOOTH 40030 #define ID_TRAYMENU_MUTEONBLUETOOTH 40031 #define ID_TRAYMENU_MUTEONSCREENSUSPEND 40032 +#define ID_TRAYMENU_SPECIAL 40033 +#define ID_TRAYMENU_40034 40034 +#define ID_TRAYMENU_WIFIMUTING 40035 +#define ID_TRAYMENU_MUTEONWIFI 40036 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 135 -#define _APS_NEXT_COMMAND_VALUE 40033 -#define _APS_NEXT_CONTROL_VALUE 1036 +#define _APS_NEXT_COMMAND_VALUE 40037 +#define _APS_NEXT_CONTROL_VALUE 1040 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif