diff --git a/src/modules/imageresizer/ShellExtensions/ContextMenuHandler.cpp b/src/modules/imageresizer/ShellExtensions/ContextMenuHandler.cpp index 55d1ac3a68bf..8a849016f24b 100644 --- a/src/modules/imageresizer/ShellExtensions/ContextMenuHandler.cpp +++ b/src/modules/imageresizer/ShellExtensions/ContextMenuHandler.cpp @@ -3,6 +3,7 @@ #include "stdafx.h" #include "ContextMenuHandler.h" #include "HDropIterator.h" +#include "Settings.h" CContextMenuHandler::CContextMenuHandler() { @@ -51,7 +52,10 @@ HRESULT CContextMenuHandler::QueryContextMenu(_In_ HMENU hmenu, UINT indexMenu, { return S_OK; } - + if (!CSettings::GetEnabled()) + { + return E_FAIL; + } // NB: We just check the first item. We could iterate through more if the first one doesn't meet the criteria HDropIterator i(m_pdtobj); i.First(); diff --git a/src/modules/imageresizer/ShellExtensions/Settings.cpp b/src/modules/imageresizer/ShellExtensions/Settings.cpp new file mode 100644 index 000000000000..f8b446c43d25 --- /dev/null +++ b/src/modules/imageresizer/ShellExtensions/Settings.cpp @@ -0,0 +1,66 @@ +#include "stdafx.h" +#include +#include "Settings.h" + +const wchar_t c_rootRegPath[] = L"Software\\Microsoft\\ImageResizer"; +const wchar_t c_enabled[] = L"Enabled"; +const bool c_enabledDefault = true; + +bool CSettings::GetEnabled() +{ + return GetRegBoolValue(c_enabled, c_enabledDefault); +} + +bool CSettings::SetEnabled(_In_ bool enabled) +{ + return SetRegBoolValue(c_enabled, enabled); +} + +bool CSettings::SetRegBoolValue(_In_ PCWSTR valueName, _In_ bool value) +{ + DWORD dwValue = value ? 1 : 0; + return SetRegDWORDValue(valueName, dwValue); +} + +bool CSettings::GetRegBoolValue(_In_ PCWSTR valueName, _In_ bool defaultValue) +{ + DWORD value = GetRegDWORDValue(valueName, (defaultValue == 0) ? false : true); + return (value == 0) ? false : true; +} + +bool CSettings::SetRegDWORDValue(_In_ PCWSTR valueName, _In_ DWORD value) +{ + return (SUCCEEDED(HRESULT_FROM_WIN32(SHSetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName, REG_DWORD, &value, sizeof(value))))); +} + +DWORD CSettings::GetRegDWORDValue(_In_ PCWSTR valueName, _In_ DWORD defaultValue) +{ + DWORD retVal = defaultValue; + DWORD type = REG_DWORD; + DWORD dwEnabled = 0; + DWORD cb = sizeof(dwEnabled); + if (SHGetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName, &type, &dwEnabled, &cb) == ERROR_SUCCESS) + { + retVal = dwEnabled; + } + + return retVal; +} + +bool CSettings::SetRegStringValue(_In_ PCWSTR valueName, _In_ PCWSTR value) +{ + ULONG cb = (DWORD)((wcslen(value) + 1) * sizeof(*value)); + return (SUCCEEDED(HRESULT_FROM_WIN32(SHSetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName, REG_SZ, (const BYTE*)value, cb)))); +} + +bool CSettings::GetRegStringValue(_In_ PCWSTR valueName, __out_ecount(cchBuf) PWSTR value, DWORD cchBuf) +{ + if (cchBuf > 0) + { + value[0] = L'\0'; + } + + DWORD type = REG_SZ; + ULONG cb = cchBuf * sizeof(*value); + return (SUCCEEDED(HRESULT_FROM_WIN32(SHGetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName, &type, value, &cb) == ERROR_SUCCESS))); +} \ No newline at end of file diff --git a/src/modules/imageresizer/ShellExtensions/Settings.h b/src/modules/imageresizer/ShellExtensions/Settings.h new file mode 100644 index 000000000000..aa00f9b30d33 --- /dev/null +++ b/src/modules/imageresizer/ShellExtensions/Settings.h @@ -0,0 +1,16 @@ +#pragma once + +class CSettings +{ +public: + static bool GetEnabled(); + static bool SetEnabled(_In_ bool enabled); + +private: + static bool GetRegBoolValue(_In_ PCWSTR valueName, _In_ bool defaultValue); + static bool SetRegBoolValue(_In_ PCWSTR valueName, _In_ bool value); + static bool SetRegDWORDValue(_In_ PCWSTR valueName, _In_ DWORD value); + static DWORD GetRegDWORDValue(_In_ PCWSTR valueName, _In_ DWORD defaultValue); + static bool SetRegStringValue(_In_ PCWSTR valueName, _In_ PCWSTR value); + static bool GetRegStringValue(_In_ PCWSTR valueName, __out_ecount(cchBuf) PWSTR value, DWORD cchBuf); +}; \ No newline at end of file diff --git a/src/modules/imageresizer/ShellExtensions/ShellExtensions.vcxproj b/src/modules/imageresizer/ShellExtensions/ShellExtensions.vcxproj index 548f691606c7..1c554447ef39 100644 --- a/src/modules/imageresizer/ShellExtensions/ShellExtensions.vcxproj +++ b/src/modules/imageresizer/ShellExtensions/ShellExtensions.vcxproj @@ -1,287 +1,306 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {0B43679E-EDFA-4DA0-AD30-F4628B308B1B} - 10.0 - AtlProj - - - - DynamicLibrary - true - Static - v142 - Unicode - - - DynamicLibrary - false - Static - v142 - Unicode - - - DynamicLibrary - true - Static - v142 - Unicode - - - DynamicLibrary - false - Static - v142 - Unicode - - - - - - - - - - - - - - - - - - - true - true - - - true - true - - - true - false - - - true - false - - - - Use - Level3 - Disabled - WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions) - true - MultiThreadedDebug - - - false - Win32 - _DEBUG;%(PreprocessorDefinitions) - ShellExtensions_i.h - ShellExtensions_i.c - ShellExtensions_p.c - true - $(IntDir)ShellExtensions.tlb - - true - - - 0x0409 - $(IntDir);%(AdditionalIncludeDirectories) - _DEBUG;%(PreprocessorDefinitions) - - - Windows - .\ShellExtensions.def - true - true - true - - - - - Use - Level3 - Disabled - _WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions) - true - MultiThreadedDebug - - - false - _DEBUG;%(PreprocessorDefinitions) - ShellExtensions_i.h - ShellExtensions_i.c - ShellExtensions_p.c - true - $(IntDir)ShellExtensions.tlb - - true - - - 0x0409 - $(IntDir);%(AdditionalIncludeDirectories) - _DEBUG;%(PreprocessorDefinitions) - - - Windows - .\ShellExtensions.def - true - true - true - - - - - Use - Level3 - MaxSpeed - WIN32;_WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions) - true - MultiThreaded - - - false - Win32 - NDEBUG;%(PreprocessorDefinitions) - ShellExtensions_i.h - ShellExtensions_i.c - ShellExtensions_p.c - true - $(IntDir)ShellExtensions.tlb - - true - - - 0x0409 - $(IntDir);%(AdditionalIncludeDirectories) - NDEBUG;%(PreprocessorDefinitions) - - - Windows - .\ShellExtensions.def - true - true - true - true - true - - - - - Use - Level3 - MaxSpeed - _WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions) - true - MultiThreaded - - - false - NDEBUG;%(PreprocessorDefinitions) - ShellExtensions_i.h - ShellExtensions_i.c - ShellExtensions_p.c - true - $(IntDir)ShellExtensions.tlb - - true - - - 0x0409 - $(IntDir);%(AdditionalIncludeDirectories) - NDEBUG;%(PreprocessorDefinitions) - - - Windows - .\ShellExtensions.def - true - true - true - true - true - - - - - - - false - - - false - - - false - - - false - - - - - - false - - - false - - - false - - - false - - - - - Create - Create - Create - Create - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {0B43679E-EDFA-4DA0-AD30-F4628B308B1B} + 10.0 + AtlProj + + + + DynamicLibrary + true + Static + v142 + Unicode + + + DynamicLibrary + false + Static + v142 + Unicode + + + DynamicLibrary + true + Static + v142 + Unicode + + + DynamicLibrary + false + Static + v142 + Unicode + + + + + + + + + + + + + + + + + + + true + true + $(SolutionDir)$(Platform)\$(Configuration)\modules\ + + + true + true + $(SolutionDir)$(Platform)\$(Configuration)\modules\ + + + true + false + $(SolutionDir)$(Platform)\$(Configuration)\modules\ + + + true + false + $(SolutionDir)$(Platform)\$(Configuration)\modules\ + + + + Use + Level3 + Disabled + WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions) + true + MultiThreadedDebug + ..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + stdcpplatest + + + false + Win32 + _DEBUG;%(PreprocessorDefinitions) + ShellExtensions_i.h + ShellExtensions_i.c + ShellExtensions_p.c + true + $(IntDir)ShellExtensions.tlb + + true + + + 0x0409 + $(IntDir);%(AdditionalIncludeDirectories) + _DEBUG;%(PreprocessorDefinitions) + + + Windows + .\ShellExtensions.def + true + true + true + + + + + Use + Level3 + Disabled + _WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions) + true + MultiThreadedDebug + ..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;..\..\..\..\deps\cpprestsdk\include;%(AdditionalIncludeDirectories) + stdcpplatest + + + false + _DEBUG;%(PreprocessorDefinitions) + ShellExtensions_i.h + ShellExtensions_i.c + ShellExtensions_p.c + true + $(IntDir)ShellExtensions.tlb + + true + + + 0x0409 + $(IntDir);%(AdditionalIncludeDirectories) + _DEBUG;%(PreprocessorDefinitions) + + + Windows + .\ShellExtensions.def + true + true + true + + + + + Use + Level3 + MaxSpeed + WIN32;_WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions) + true + MultiThreaded + ..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + stdcpplatest + + + false + Win32 + NDEBUG;%(PreprocessorDefinitions) + ShellExtensions_i.h + ShellExtensions_i.c + ShellExtensions_p.c + true + $(IntDir)ShellExtensions.tlb + + true + + + 0x0409 + $(IntDir);%(AdditionalIncludeDirectories) + NDEBUG;%(PreprocessorDefinitions) + + + Windows + .\ShellExtensions.def + true + true + true + true + true + + + + + Use + Level3 + MaxSpeed + _WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions) + true + MultiThreaded + ..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;..\..\..\..\deps\cpprestsdk\include;%(AdditionalIncludeDirectories) + stdcpplatest + + + false + NDEBUG;%(PreprocessorDefinitions) + ShellExtensions_i.h + ShellExtensions_i.c + ShellExtensions_p.c + true + $(IntDir)ShellExtensions.tlb + + true + + + 0x0409 + $(IntDir);%(AdditionalIncludeDirectories) + NDEBUG;%(PreprocessorDefinitions) + + + Windows + .\ShellExtensions.def + true + true + true + true + true + + + + + + + false + + + false + + + false + + + false + + + + + + false + + + false + + + false + + + false + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + {74485049-c722-400f-abe5-86ac52d929b3} + + + + + \ No newline at end of file diff --git a/src/modules/imageresizer/ShellExtensions/ShellExtensions.vcxproj.filters b/src/modules/imageresizer/ShellExtensions/ShellExtensions.vcxproj.filters index f6ced56a9d6f..dbf5c78b4708 100644 --- a/src/modules/imageresizer/ShellExtensions/ShellExtensions.vcxproj.filters +++ b/src/modules/imageresizer/ShellExtensions/ShellExtensions.vcxproj.filters @@ -1,85 +1,91 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {87bc9b81-f7fa-45d9-87cc-c99e55473868} - False - - - - - Source Files - - - Source Files - - - Source Files - - - Generated Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Generated Files - - - Header Files - - - Header Files - - - - - Resource Files - - - - - Resource Files - - - Source Files - - - Resource Files - - - - - Source Files - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {87bc9b81-f7fa-45d9-87cc-c99e55473868} + False + + + + + Source Files + + + Source Files + + + Source Files + + + Generated Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Generated Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + + + Resource Files + + + Source Files + + + Resource Files + + + + + Source Files + + \ No newline at end of file diff --git a/src/modules/imageresizer/ShellExtensions/dllmain.cpp b/src/modules/imageresizer/ShellExtensions/dllmain.cpp index 9c9903e8d25a..654ce197c4ce 100644 --- a/src/modules/imageresizer/ShellExtensions/dllmain.cpp +++ b/src/modules/imageresizer/ShellExtensions/dllmain.cpp @@ -2,6 +2,9 @@ #include "resource.h" #include "ShellExtensions_i.h" #include "dllmain.h" +#include +#include +#include "Settings.h" CShellExtensionsModule _AtlModule; @@ -9,3 +12,134 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpRes { return _AtlModule.DllMain(dwReason, lpReserved); } + +// The PowerToy name that will be shown in the settings. +const static wchar_t* MODULE_NAME = L"ImageResizer"; +// Add a description that will we shown in the module settings page. +const static wchar_t* MODULE_DESC = L""; + +class ImageResizerModule : public PowertoyModuleIface +{ +private: + // The PowerToy state. + bool m_enabled = false; + + // Load initial settings from the persisted values. + void init_settings(); + +public: + // Constructor + ImageResizerModule() + { + init_settings(); + }; + + // Destroy the powertoy and free memory + virtual void destroy() override + { + delete this; + } + + // Return the display name of the powertoy, this will be cached by the runner + virtual const wchar_t* get_name() override + { + return MODULE_NAME; + } + + // Return array of the names of all events that this powertoy listens for, with + // nullptr as the last element of the array. Nullptr can also be retured for empty + // list. + virtual const wchar_t** get_events() override + { + static const wchar_t* events[] = { nullptr }; + // Available events: + // - ll_keyboard + // - win_hook_event + // + // static const wchar_t* events[] = { ll_keyboard, + // win_hook_event, + // nullptr }; + + return events; + } + + // Return JSON with the configuration options. + virtual bool get_config(wchar_t* buffer, int* buffer_size) override + { + HINSTANCE hinstance = reinterpret_cast(&__ImageBase); + + // Create a Settings object. + PowerToysSettings::Settings settings(hinstance, get_name()); + settings.set_description(MODULE_DESC); + return settings.serialize_to_buffer(buffer, buffer_size); + } + + // Signal from the Settings editor to call a custom action. + // This can be used to spawn more complex editors. + virtual void call_custom_action(const wchar_t* action) override {} + + // Called by the runner to pass the updated settings values as a serialized JSON. + virtual void set_config(const wchar_t* config) override + { + try + { + // Parse the input JSON string. + PowerToysSettings::PowerToyValues values = PowerToysSettings::PowerToyValues::from_json_string(config); + // If you don't need to do any custom processing of the settings, proceed + // to persists the values calling: + values.save_to_settings_file(); + } + catch (std::exception ex) + { + // Improper JSON. + } + } + + // Enable the powertoy + virtual void enable() + { + m_enabled = true; + CSettings::SetEnabled(m_enabled); + } + + // Disable the powertoy + virtual void disable() + { + m_enabled = false; + CSettings::SetEnabled(m_enabled); + } + + // Returns if the powertoys is enabled + virtual bool is_enabled() override + { + return m_enabled; + } + + // Handle incoming event, data is event-specific + virtual intptr_t signal_event(const wchar_t* name, intptr_t data) override + { + return 0; + } + + virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) override {} + virtual void signal_system_menu_action(const wchar_t* name) override {} +}; + +// Load the settings file. +void ImageResizerModule::init_settings() +{ + try + { + // Load and parse the settings file for this PowerToy. + PowerToysSettings::PowerToyValues settings = PowerToysSettings::PowerToyValues::load_from_settings_file(get_name()); + } + catch (std::exception ex) + { + // Error while loading from the settings file. Let default values stay as they are. + } +} + +extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create() +{ + return new ImageResizerModule(); +} \ No newline at end of file diff --git a/src/modules/imageresizer/ShellExtensions/stdafx.cpp b/src/modules/imageresizer/ShellExtensions/stdafx.cpp index fd4f341c7b24..a8b5e27d4054 100644 --- a/src/modules/imageresizer/ShellExtensions/stdafx.cpp +++ b/src/modules/imageresizer/ShellExtensions/stdafx.cpp @@ -1 +1,2 @@ #include "stdafx.h" +#pragma comment(lib, "windowsapp") \ No newline at end of file diff --git a/src/modules/imageresizer/ShellExtensions/targetver.h b/src/modules/imageresizer/ShellExtensions/targetver.h index 895f499ce391..1530e99ea64a 100644 --- a/src/modules/imageresizer/ShellExtensions/targetver.h +++ b/src/modules/imageresizer/ShellExtensions/targetver.h @@ -1,7 +1,4 @@ #pragma once -#define _WIN32_WINNT _WIN32_WINNT_WINXP -#define _WIN32_IE _WIN32_IE_XPSP2 - #include #include diff --git a/src/runner/main.cpp b/src/runner/main.cpp index d39bcad1281d..b800b5cb26c5 100644 --- a/src/runner/main.cpp +++ b/src/runner/main.cpp @@ -52,7 +52,8 @@ int runner() std::unordered_set known_dlls = { L"shortcut_guide.dll", L"fancyzones.dll", - L"PowerRenameExt.dll" + L"PowerRenameExt.dll", + L"ShellExtensions.dll" }; for (auto& file : std::filesystem::directory_iterator(L"modules/")) {