From 16db65c5e255392b1cfc4afb8d2417f1d7610433 Mon Sep 17 00:00:00 2001 From: ste Date: Fri, 5 Jul 2019 22:55:52 +0100 Subject: [PATCH 1/3] GPII-4011: Showing the volume change on the screen. --- .../WindowsUtilities/WindowsUtilities.js | 6 + .../VolumeControl/VolumeControl.cpp | 217 ++++++++++-------- .../src/nativeSettingsHandler.js | 20 +- 3 files changed, 140 insertions(+), 103 deletions(-) diff --git a/gpii/node_modules/WindowsUtilities/WindowsUtilities.js b/gpii/node_modules/WindowsUtilities/WindowsUtilities.js index 20188edaa..9f0baeb68 100644 --- a/gpii/node_modules/WindowsUtilities/WindowsUtilities.js +++ b/gpii/node_modules/WindowsUtilities/WindowsUtilities.js @@ -517,6 +517,8 @@ windows.API_constants = { WM_DISPLAYCHANGE: 0x7e, // https://docs.microsoft.com/windows/desktop/winmsg/wm-themechanged WM_THEMECHANGED: 0x31a, + // https://docs.microsoft.com/windows/win32/inputdev/wm-appcommand + WM_APPCOMMAND: 0x319, // https://msdn.microsoft.com/library/aa363205 @@ -526,6 +528,10 @@ windows.API_constants = { DBT_DEVICEREMOVECOMPLETE: 0x8004, DBT_DEVTYP_VOLUME: 0x2, + // https://docs.microsoft.com/windows/win32/inputdev/wm-appcommand + APPCOMMAND_VOLUME_DOWN: 9, + APPCOMMAND_VOLUME_UP: 10, + // https://msdn.microsoft.com/library/dd375731 virtualKeyCodes: { VK_BACK: 0x08, diff --git a/gpii/node_modules/nativeSettingsHandler/nativeSolutions/VolumeControl/VolumeControl/VolumeControl.cpp b/gpii/node_modules/nativeSettingsHandler/nativeSolutions/VolumeControl/VolumeControl/VolumeControl.cpp index 6c4aa8461..776502349 100644 --- a/gpii/node_modules/nativeSettingsHandler/nativeSolutions/VolumeControl/VolumeControl/VolumeControl.cpp +++ b/gpii/node_modules/nativeSettingsHandler/nativeSolutions/VolumeControl/VolumeControl/VolumeControl.cpp @@ -1,99 +1,118 @@ -// VolumeControl.cpp : This file contains the 'main' function. Program execution begins and ends there. -// - -#include "pch.h" -#include -#include -#include - -#include - -// Operation constants -const wchar_t* Get = L"Get"; -const wchar_t* Set = L"Set"; - -int wmain(int argc, wchar_t *argv[]) { - // Payload - std::wstring operation; - float value; - // COM Interfaces - HRESULT hr = NULL; - const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator); - const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator); - IMMDeviceEnumerator* pEnumerator; - LPVOID pvReserved = NULL; - - if (argc == 2) { - operation = argv[1]; - if (operation != Get) { - std::wcout << L"{ \"code\": \"160\", \"message\": \"EINVAL\" }"; - return 0; - } - } else if (argc == 3) { - operation = argv[1]; - std::wstring strValue = argv[2]; - - // Parse the received string into a float - const wchar_t* start = strValue.c_str(); - wchar_t* end = NULL; - - value = std::wcstof(start, &end); - - if (operation != Set || (value == 0 && end == start)) { - std::wcout << L"{ \"code\": \"160\", \"message\": \"EINVAL\" }"; - return 0; - } - } else { - std::wcout << L"{ \"code\": \"160\", \"message\": \"EINVAL\" }"; - return 0; - } - - hr = CoInitialize(pvReserved); - if (hr != S_OK) { - std::wcout << L"{ \"code\": \"" << std::to_wstring(hr) << "\", \"message\": \"Failed to initialize COM\" }"; - } - - hr = CoCreateInstance( - CLSID_MMDeviceEnumerator, - NULL, - CLSCTX_ALL, - IID_IMMDeviceEnumerator, - (void**)&pEnumerator - ); - if (hr != S_OK) { - std::wcout << L"{ \"code\": \"" << std::to_wstring(hr) << "\", \"message\": \"Failed to initialize COM instance\" }"; - } - - IMMDevice* pAudioDevice; - hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eMultimedia, &pAudioDevice); - if (hr != S_OK) { - std::wcout << L"{ \"code\": \"" << std::to_wstring(hr) << "\", \"message\": \"Failed to get default audio endpoint\" }"; - } - - IAudioEndpointVolume* pEndpointVolume; - pAudioDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL, (void**)&pEndpointVolume); - if (hr != S_OK) { - std::wcout << L"{ \"code\": \"" << std::to_wstring(hr) << "\", \"message\": \"Failed to activate the audio endpoint\" }"; - } - - if (operation == Get) { - float curVolume = 0; - hr = pEndpointVolume->GetMasterVolumeLevelScalar(&curVolume); - if (hr != S_OK) { - std::wcout << L"{ \"code\": \"" << std::to_wstring(hr) << "\", \"message\": \"Failed to get current system volume\" }"; - } else { - std::wcout << L"{ \"Value\": \"" << std::to_wstring(curVolume) << "\" }"; - } - } else { - float curVolume = 0; - hr = pEndpointVolume->SetMasterVolumeLevelScalar(value, NULL); - - if (hr != S_OK) { - std::wcout << L"{ \"code\": \"" << std::to_wstring(hr) << "\", \"message\": \"Failed to set current system volume\" }"; - } else { - std::wcout << L"{ \"Value\": \"" << std::to_wstring(curVolume) << "\" }"; - } - } - - return 0; -} +// VolumeControl.cpp : This file contains the 'main' function. Program execution begins and ends there. +// + +#include "pch.h" +#include +#include +#include + +#include + +// Operation constants +const wchar_t* Get = L"Get"; +const wchar_t* Set = L"Set"; +const wchar_t* SetNear = L"SetNear"; + +int wmain(int argc, wchar_t *argv[]) { + // Payload + std::wstring operation; + float value; + // COM Interfaces + HRESULT hr = NULL; + const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator); + const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator); + IMMDeviceEnumerator* pEnumerator; + LPVOID pvReserved = NULL; + + if (argc == 2) { + operation = argv[1]; + if (operation != Get) { + std::wcout << L"{ \"code\": \"160\", \"message\": \"EINVAL\" }"; + return 0; + } + } else if (argc == 3) { + operation = argv[1]; + std::wstring strValue = argv[2]; + + // Parse the received string into a float + const wchar_t* start = strValue.c_str(); + wchar_t* end = NULL; + + value = std::wcstof(start, &end); + + if ((operation != Set && operation != SetNear) || (value == 0 && end == start)) { + std::wcout << L"{ \"code\": \"160\", \"message\": \"EINVAL\" }"; + return 0; + } + } else { + std::wcout << L"{ \"code\": \"160\", \"message\": \"EINVAL\" }"; + return 0; + } + + hr = CoInitialize(pvReserved); + if (hr != S_OK) { + std::wcout << L"{ \"code\": \"" << std::to_wstring(hr) << "\", \"message\": \"Failed to initialize COM\" }"; + } + + hr = CoCreateInstance( + CLSID_MMDeviceEnumerator, + NULL, + CLSCTX_ALL, + IID_IMMDeviceEnumerator, + (void**)&pEnumerator + ); + if (hr != S_OK) { + std::wcout << L"{ \"code\": \"" << std::to_wstring(hr) << "\", \"message\": \"Failed to initialize COM instance\" }"; + } + + IMMDevice* pAudioDevice; + hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eMultimedia, &pAudioDevice); + if (hr != S_OK) { + std::wcout << L"{ \"code\": \"" << std::to_wstring(hr) << "\", \"message\": \"Failed to get default audio endpoint\" }"; + } + + IAudioEndpointVolume* pEndpointVolume; + pAudioDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL, (void**)&pEndpointVolume); + if (hr != S_OK) { + std::wcout << L"{ \"code\": \"" << std::to_wstring(hr) << "\", \"message\": \"Failed to activate the audio endpoint\" }"; + } + + if (operation == Get) { + float curVolume = 0; + hr = pEndpointVolume->GetMasterVolumeLevelScalar(&curVolume); + if (hr != S_OK) { + std::wcout << L"{ \"code\": \"" << std::to_wstring(hr) << "\", \"message\": \"Failed to get current system volume\" }"; + } else { + std::wcout << L"{ \"Value\": \"" << std::to_wstring(curVolume) << "\" }"; + } + } else { + float curVolume = 0; + hr = pEndpointVolume->GetMasterVolumeLevelScalar(&curVolume); + + if (operation == SetNear && hr == S_OK) { + // Set the volume to near the target volume, allowing a small amount for the UI to finish the job. + if (abs(value - curVolume) > 0.02) { + value += (value > curVolume) ? -0.02 : 0.02; + } else { + value = curVolume; + } + } + + if (operation == Set || value != curVolume) { + hr = pEndpointVolume->SetMasterVolumeLevelScalar(value, NULL); + } + + if (hr != S_OK) { + std::wcout << L"{ \"code\": \"" << std::to_wstring(hr) << "\", \"message\": \"Failed to set current system volume\" }"; + } else { + float newVolume = 0; + if (pEndpointVolume->GetMasterVolumeLevelScalar(&newVolume) != S_OK) { + newVolume = value; + } + std::wcout << L"{ \"Value\": \"" << std::to_wstring(newVolume) << "\", \"Old\": \"" + << std::to_wstring(curVolume) << "\" }"; + } + } + + return 0; +} diff --git a/gpii/node_modules/nativeSettingsHandler/src/nativeSettingsHandler.js b/gpii/node_modules/nativeSettingsHandler/src/nativeSettingsHandler.js index 78624d29d..919d4213e 100644 --- a/gpii/node_modules/nativeSettingsHandler/src/nativeSettingsHandler.js +++ b/gpii/node_modules/nativeSettingsHandler/src/nativeSettingsHandler.js @@ -164,7 +164,8 @@ windows.nativeSettingsHandler.SetDoubleClickHeight = function (num) { /** * Function that handles calling the native executable for volume control. * - * @param {String} mode The operation mode, could be either "Set" or "Get". + * @param {String} mode The operation mode, could be either "Set", "SetNear" or "Get". Calling with "SetNear" will + * adjust the volume so it's near the target volume, allowing room for the shell to do the rest. * @param {Number} [num] The value to set as the current system volume. Range is normalized from 0 to 1. * @return {Promise} A promise that resolves on success or holds a object with the error information. */ @@ -176,9 +177,9 @@ windows.nativeSettingsHandler.VolumeHandler = function (mode, num) { var valueBuff; if (mode === "Get") { - valueBuff = child_process.execFileSync(fileName, ["Get"], {}); + valueBuff = child_process.execFileSync(fileName, [mode], {}); } else { - valueBuff = child_process.execFileSync(fileName, ["Set", num], {}); + valueBuff = child_process.execFileSync(fileName, [mode, num], {}); } var strRes = valueBuff.toString("utf8"); @@ -215,7 +216,18 @@ windows.nativeSettingsHandler.GetVolume = function () { * @return {Promise} A promise that resolves on success or holds a object with the error information. */ windows.nativeSettingsHandler.SetVolume = function (num) { - return windows.nativeSettingsHandler.VolumeHandler("Set", num); + return windows.nativeSettingsHandler.VolumeHandler("SetNear", num).then(function (result) { + var current = parseFloat(result); + if (current !== num) { + // Complete the last bit of the change, as though the media keys where used, in order to show the new volume + // on the screen. + var action = current < num + ? windows.API_constants.APPCOMMAND_VOLUME_UP : windows.API_constants.APPCOMMAND_VOLUME_DOWN; + // Send the volume up/down command directly to the task tray (rather than a simulated key press) + gpii.windows.messages.sendMessage("Shell_TrayWnd", windows.API_constants.WM_APPCOMMAND, 0, + windows.makeLong(0, action)); + } + }); }; /** From 57324ace4b8b07fad11ba0631630a9c9fa029f89 Mon Sep 17 00:00:00 2001 From: ste Date: Fri, 5 Jul 2019 23:42:08 +0100 Subject: [PATCH 2/3] GPII-4011: Putting line separators back to CRLF. --- .../VolumeControl/VolumeControl/VolumeControl.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/gpii/node_modules/nativeSettingsHandler/nativeSolutions/VolumeControl/VolumeControl/VolumeControl.cpp b/gpii/node_modules/nativeSettingsHandler/nativeSolutions/VolumeControl/VolumeControl/VolumeControl.cpp index 776502349..e44a472a6 100644 --- a/gpii/node_modules/nativeSettingsHandler/nativeSolutions/VolumeControl/VolumeControl/VolumeControl.cpp +++ b/gpii/node_modules/nativeSettingsHandler/nativeSolutions/VolumeControl/VolumeControl/VolumeControl.cpp @@ -87,6 +87,7 @@ int wmain(int argc, wchar_t *argv[]) { } } else { float curVolume = 0; + hr = pEndpointVolume->GetMasterVolumeLevelScalar(&curVolume); if (operation == SetNear && hr == S_OK) { From 5a5e9575c9d719dbf346aa19ac5fac2d841fa14f Mon Sep 17 00:00:00 2001 From: ste Date: Fri, 5 Jul 2019 15:46:39 -0700 Subject: [PATCH 3/3] GPII-4011: Putting line separators back to CRLF. (trying harder) --- .../VolumeControl/VolumeControl/VolumeControl.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/gpii/node_modules/nativeSettingsHandler/nativeSolutions/VolumeControl/VolumeControl/VolumeControl.cpp b/gpii/node_modules/nativeSettingsHandler/nativeSolutions/VolumeControl/VolumeControl/VolumeControl.cpp index e44a472a6..776502349 100644 --- a/gpii/node_modules/nativeSettingsHandler/nativeSolutions/VolumeControl/VolumeControl/VolumeControl.cpp +++ b/gpii/node_modules/nativeSettingsHandler/nativeSolutions/VolumeControl/VolumeControl/VolumeControl.cpp @@ -87,7 +87,6 @@ int wmain(int argc, wchar_t *argv[]) { } } else { float curVolume = 0; - hr = pEndpointVolume->GetMasterVolumeLevelScalar(&curVolume); if (operation == SetNear && hr == S_OK) {