[ContextMenus]Update context menu labels and improve localization calls (#31000)

* Update file locksmith

* ImageResizer

* Update imageresizer context menu

* Changes

* [PowerRename]Don't use app name for context menu caption

* [ImageResizer]Apply string to old context menu too

* Add localization to the PowerRenameContextMenu project

* Show actual context menu string in PowerRename

* New Ids for the resource strings

* Add do not loc comments

* Add fallback and cache resource values

* Update src/modules/imageresizer/dll/ContextMenuHandler.cpp

Co-authored-by: Stefan Markovic <57057282+stefansjfw@users.noreply.github.com>

* Remove do not loc comments from Image Resizer

---------

Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
Co-authored-by: Stefan Markovic <57057282+stefansjfw@users.noreply.github.com>
This commit is contained in:
Niels Laute
2024-01-25 13:27:25 +01:00
committed by GitHub
parent 43aa80fb1e
commit fc214a80c5
18 changed files with 194 additions and 50 deletions

View File

@@ -21,3 +21,4 @@ inline std::wstring get_resource_string(UINT resource_id, HINSTANCE instance, co
extern "C" IMAGE_DOS_HEADER __ImageBase; extern "C" IMAGE_DOS_HEADER __ImageBase;
// Wrapper for getting a string from the resource file. Returns the resource id text when fails. // Wrapper for getting a string from the resource file. Returns the resource id text when fails.
#define GET_RESOURCE_STRING(resource_id) get_resource_string(resource_id, reinterpret_cast<HINSTANCE>(&__ImageBase), L#resource_id) #define GET_RESOURCE_STRING(resource_id) get_resource_string(resource_id, reinterpret_cast<HINSTANCE>(&__ImageBase), L#resource_id)
#define GET_RESOURCE_STRING_FALLBACK(resource_id, fallback) get_resource_string(resource_id, reinterpret_cast<HINSTANCE>(&__ImageBase), fallback)

View File

@@ -9,6 +9,7 @@
#include <common/themes/icon_helpers.h> #include <common/themes/icon_helpers.h>
#include <common/utils/process_path.h> #include <common/utils/process_path.h>
#include <common/utils/resources.h>
// Implementations of inherited IUnknown methods // Implementations of inherited IUnknown methods
@@ -42,9 +43,7 @@ IFACEMETHODIMP_(ULONG) ExplorerCommand::Release()
IFACEMETHODIMP ExplorerCommand::GetTitle(IShellItemArray* psiItemArray, LPWSTR* ppszName) IFACEMETHODIMP ExplorerCommand::GetTitle(IShellItemArray* psiItemArray, LPWSTR* ppszName)
{ {
WCHAR buffer[128]; return SHStrDup(context_menu_caption.c_str(), ppszName);
LoadStringW(globals::instance, IDS_FILELOCKSMITH_COMMANDTITLE, buffer, ARRAYSIZE(buffer));
return SHStrDupW(buffer, ppszName);
} }
IFACEMETHODIMP ExplorerCommand::GetIcon(IShellItemArray* psiItemArray, LPWSTR* ppszIcon) IFACEMETHODIMP ExplorerCommand::GetIcon(IShellItemArray* psiItemArray, LPWSTR* ppszIcon)
@@ -126,18 +125,15 @@ IFACEMETHODIMP ExplorerCommand::QueryContextMenu(HMENU hmenu, UINT indexMenu, UI
HRESULT hr = E_UNEXPECTED; HRESULT hr = E_UNEXPECTED;
if (m_data_obj && !(uFlags & (CMF_DEFAULTONLY | CMF_VERBSONLY | CMF_OPTIMIZEFORINVOKE))) if (m_data_obj && !(uFlags & (CMF_DEFAULTONLY | CMF_VERBSONLY | CMF_OPTIMIZEFORINVOKE)))
{ {
wchar_t menuName[128] = { 0 };
wcscpy_s(menuName, ARRAYSIZE(menuName), context_menu_caption.c_str());
MENUITEMINFO mii; MENUITEMINFO mii;
mii.cbSize = sizeof(MENUITEMINFO); mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_STATE; mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_STATE;
mii.wID = idCmdFirst++; mii.wID = idCmdFirst++;
mii.fType = MFT_STRING; mii.fType = MFT_STRING;
mii.dwTypeData = (PWSTR)menuName;
hr = GetTitle(NULL, &mii.dwTypeData);
if (FAILED(hr))
{
return hr;
}
mii.fState = MFS_ENABLED; mii.fState = MFS_ENABLED;
// icon from file // icon from file
@@ -237,6 +233,7 @@ HRESULT ExplorerCommand::s_CreateInstance(IUnknown* pUnkOuter, REFIID riid, void
ExplorerCommand::ExplorerCommand() ExplorerCommand::ExplorerCommand()
{ {
++globals::ref_count; ++globals::ref_count;
context_menu_caption = GET_RESOURCE_STRING_FALLBACK(IDS_FILELOCKSMITH_CONTEXT_MENU_ENTRY, L"Unlock with File Locksmith");
} }
ExplorerCommand::~ExplorerCommand() ExplorerCommand::~ExplorerCommand()

View File

@@ -49,4 +49,5 @@ private:
std::atomic<ULONG> m_ref_count = 1; std::atomic<ULONG> m_ref_count = 1;
IDataObject* m_data_obj = NULL; IDataObject* m_data_obj = NULL;
std::wstring context_menu_caption;
}; };

View File

@@ -117,9 +117,9 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="FileLocksmith_CommandTitle" xml:space="preserve"> <data name="FileLocksmith_Context_Menu_Entry" xml:space="preserve">
<value>What's using this file?</value> <value>Unlock with File Locksmith</value>
<comment>This text will be shown when the user opens the context menu (right clicks) a file.</comment> <comment>This text will be shown when the user opens the context menu (right clicks) a file. File Locksmith is the product name, do not loc.</comment>
</data> </data>
<data name="FileLocksmith_PowerToyName" xml:space="preserve"> <data name="FileLocksmith_PowerToyName" xml:space="preserve">
<value>File Locksmith</value> <value>File Locksmith</value>

View File

@@ -117,8 +117,8 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="Resize_Pictures_Title" xml:space="preserve"> <data name="ImageResizer_Context_Menu_Entry" xml:space="preserve">
<value>Resize pictures</value> <value>Resize with Image Resizer</value>
</data> </data>
<data name="ImageResizer_App_Name" xml:space="preserve"> <data name="ImageResizer_App_Name" xml:space="preserve">
<value>Image Resizer</value> <value>Image Resizer</value>

View File

@@ -51,10 +51,7 @@ public:
// IExplorerCommand // IExplorerCommand
IFACEMETHODIMP GetTitle(_In_opt_ IShellItemArray* items, _Outptr_result_nullonfailure_ PWSTR* name) IFACEMETHODIMP GetTitle(_In_opt_ IShellItemArray* items, _Outptr_result_nullonfailure_ PWSTR* name)
{ {
wchar_t strResizePictures[64] = { 0 }; return SHStrDup(context_menu_caption.c_str(), name);
LoadString(g_hInst, IDS_RESIZE_PICTURES_TITLE, strResizePictures, ARRAYSIZE(strResizePictures));
return SHStrDup(strResizePictures, name);
} }
IFACEMETHODIMP GetIcon(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* icon) IFACEMETHODIMP GetIcon(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* icon)
@@ -272,7 +269,7 @@ private:
std::thread create_pipe_thread; std::thread create_pipe_thread;
HANDLE hPipe = INVALID_HANDLE_VALUE; HANDLE hPipe = INVALID_HANDLE_VALUE;
std::wstring app_name = L"ImageResizer"; std::wstring context_menu_caption = GET_RESOURCE_STRING_FALLBACK(IDS_IMAGERESIZER_CONTEXT_MENU_ENTRY, L"Resize with Image Resizer");
}; };
CoCreatableClass(ImageResizerContextMenuCommand) CoCreatableClass(ImageResizerContextMenuCommand)

View File

@@ -18,7 +18,8 @@ CContextMenuHandler::CContextMenuHandler()
{ {
m_pidlFolder = NULL; m_pidlFolder = NULL;
m_pdtobj = NULL; m_pdtobj = NULL;
app_name = GET_RESOURCE_STRING(IDS_RESIZE_PICTURES); context_menu_caption = GET_RESOURCE_STRING_FALLBACK(IDS_IMAGERESIZER_CONTEXT_MENU_ENTRY, L"Resize with Image Resizer");
context_menu_caption_here = GET_RESOURCE_STRING_FALLBACK(IDS_IMAGERESIZER_CONTEXT_MENU_ENTRY_HERE, L"Resize with Image Resizer here");
} }
CContextMenuHandler::~CContextMenuHandler() CContextMenuHandler::~CContextMenuHandler()
@@ -105,22 +106,16 @@ HRESULT CContextMenuHandler::QueryContextMenu(_In_ HMENU hmenu, UINT indexMenu,
if (type == PERCEIVED_TYPE_IMAGE) if (type == PERCEIVED_TYPE_IMAGE)
{ {
HRESULT hr = E_UNEXPECTED; HRESULT hr = E_UNEXPECTED;
wchar_t strResizePictures[64] = { 0 }; wchar_t strResizePictures[128] = { 0 };
// If handling drag-and-drop... // If handling drag-and-drop...
if (m_pidlFolder) if (m_pidlFolder)
{ {
// Suppressing C6031 warning since return value is not required. dragDropFlag=true;
#pragma warning(suppress : 6031) wcscpy_s(strResizePictures, ARRAYSIZE(strResizePictures), context_menu_caption_here.c_str());
// Load 'Resize pictures here' string
LoadString(g_hInst_imageResizer, IDS_RESIZE_PICTURES_HERE, strResizePictures, ARRAYSIZE(strResizePictures));
dragDropFlag = true;
} }
else else
{ {
// Suppressing C6031 warning since return value is not required. wcscpy_s(strResizePictures, ARRAYSIZE(strResizePictures), context_menu_caption.c_str());
#pragma warning(suppress : 6031)
// Load 'Resize pictures' string
LoadString(g_hInst_imageResizer, IDS_RESIZE_PICTURES, strResizePictures, ARRAYSIZE(strResizePictures));
} }
MENUITEMINFO mii; MENUITEMINFO mii;
@@ -348,7 +343,7 @@ HRESULT CContextMenuHandler::ResizePictures(CMINVOKECOMMANDINFO* pici, IShellIte
HRESULT __stdcall CContextMenuHandler::GetTitle(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszName) HRESULT __stdcall CContextMenuHandler::GetTitle(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszName)
{ {
return SHStrDup(app_name.c_str(), ppszName); return SHStrDup(context_menu_caption.c_str(), ppszName);
} }
HRESULT __stdcall CContextMenuHandler::GetIcon(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszIcon) HRESULT __stdcall CContextMenuHandler::GetIcon(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszIcon)

View File

@@ -51,7 +51,8 @@ private:
PCIDLIST_ABSOLUTE m_pidlFolder; PCIDLIST_ABSOLUTE m_pidlFolder;
IDataObject* m_pdtobj; IDataObject* m_pdtobj;
HBITMAP m_hbmpIcon = nullptr; HBITMAP m_hbmpIcon = nullptr;
std::wstring app_name; std::wstring context_menu_caption;
std::wstring context_menu_caption_here;
}; };
OBJECT_ENTRY_AUTO(__uuidof(ContextMenuHandler), CContextMenuHandler) OBJECT_ENTRY_AUTO(__uuidof(ContextMenuHandler), CContextMenuHandler)

View File

@@ -117,11 +117,11 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="Resize_Pictures" xml:space="preserve"> <data name="ImageResizer_Context_Menu_Entry" xml:space="preserve">
<value>Resize pictures</value> <value>Resize with Image Resizer</value>
</data> </data>
<data name="Resize_Pictures_Here" xml:space="preserve"> <data name="ImageResizer_Context_Menu_Entry_Here" xml:space="preserve">
<value>Resize pictures here</value> <value>Resize with Image Resizer here</value>
</data> </data>
<data name="ImageResizer" xml:space="preserve"> <data name="ImageResizer" xml:space="preserve">
<value>Image Resizer</value> <value>Image Resizer</value>

View File

@@ -1,6 +1,6 @@
#include <windows.h> #include <windows.h>
#include "resource.h" #include "Generated Files/resource.h"
#include "../../../common/version/version.h" #include "../../../../common/version/version.h"
#define APSTUDIO_READONLY_SYMBOLS #define APSTUDIO_READONLY_SYMBOLS
#include "winres.h" #include "winres.h"

View File

@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.props')" /> <Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.props')" />
<Target Name="GenerateResourceFiles" BeforeTargets="PrepareForBuild">
<Exec Command="powershell -NonInteractive -executionpolicy Unrestricted $(SolutionDir)tools\build\convert-resx-to-rc.ps1 $(MSBuildThisFileDirectory) resource.base.h resource.h PowerRenameContextMenu.base.rc PowerRenameContextMenu.rc" />
</Target>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion> <VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
@@ -85,7 +88,8 @@ MakeAppx.exe pack /d . /p $(OutDir)PowerRenameContextMenuPackage.msix /nv</Comma
<ItemGroup> <ItemGroup>
<ClInclude Include="framework.h" /> <ClInclude Include="framework.h" />
<ClInclude Include="pch.h" /> <ClInclude Include="pch.h" />
<ClInclude Include="resource.h" /> <None Include="resource.base.h" />
<ClInclude Include="Generated Files/resource.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="dllmain.cpp" /> <ClCompile Include="dllmain.cpp" />
@@ -97,7 +101,8 @@ MakeAppx.exe pack /d . /p $(OutDir)PowerRenameContextMenuPackage.msix /nv</Comma
<None Include="packages.config" /> <None Include="packages.config" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="PowerRenameContextMenu.rc" /> <ResourceCompile Include="Generated Files/PowerRenameContextMenu.rc" />
<None Include="PowerRenameContextMenu.base.rc" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="Assets\PowerRename\**" CopyToOutputDirectory="PreserveNewest" /> <None Include="Assets\PowerRename\**" CopyToOutputDirectory="PreserveNewest" />
@@ -110,6 +115,9 @@ MakeAppx.exe pack /d . /p $(OutDir)PowerRenameContextMenuPackage.msix /nv</Comma
<Project>{51920f1f-c28c-4adf-8660-4238766796c2}</Project> <Project>{51920f1f-c28c-4adf-8660-4238766796c2}</Project>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="Resources.resx" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Import Project="..\..\..\..\deps\spdlog.props" /> <Import Project="..\..\..\..\deps\spdlog.props" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@@ -21,7 +21,7 @@
<ClInclude Include="pch.h"> <ClInclude Include="pch.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="resource.h"> <ClInclude Include="Generated Files/resource.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
@@ -38,9 +38,18 @@
<None Include="Assets\PowerRename\**"> <None Include="Assets\PowerRename\**">
<Filter>Resource Files</Filter> <Filter>Resource Files</Filter>
</None> </None>
<None Include="resource.base.h">
<Filter>Header Files</Filter>
</None>
<None Include="PowerRenameContextMenu.base.rc">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources.resx">
<Filter>Resource Files</Filter>
</None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="PowerRenameContextMenu.rc"> <ResourceCompile Include="Generated Files/PowerRenameContextMenu.rc">
<Filter>Resource Files</Filter> <Filter>Resource Files</Filter>
</ResourceCompile> </ResourceCompile>
</ItemGroup> </ItemGroup>

View File

@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="PowerRename_App_Name" xml:space="preserve">
<value>PowerRename</value>
<comment>do not loc, product name</comment>
</data>
<data name="PowerRename_Context_Menu_Entry" xml:space="preserve">
<value>Rename with PowerRename</value>
<comment>PowerRename is a product name. do not loc it</comment>
</data>
</root>

View File

@@ -16,8 +16,11 @@
#include <wrl/implements.h> #include <wrl/implements.h>
#include <wrl/client.h> #include <wrl/client.h>
#include "Generated Files/resource.h"
#include <common/utils/elevation.h> #include <common/utils/elevation.h>
#include <common/utils/process_path.h> #include <common/utils/process_path.h>
#include <common/utils/resources.h>
#include <Helpers.h> #include <Helpers.h>
#include <Settings.h> #include <Settings.h>
#include <trace.h> #include <trace.h>
@@ -60,7 +63,7 @@ public:
// IExplorerCommand // IExplorerCommand
IFACEMETHODIMP GetTitle(_In_opt_ IShellItemArray* items, _Outptr_result_nullonfailure_ PWSTR* name) IFACEMETHODIMP GetTitle(_In_opt_ IShellItemArray* items, _Outptr_result_nullonfailure_ PWSTR* name)
{ {
return SHStrDup(app_name.c_str(), name); return SHStrDup(context_menu_caption.c_str(), name);
} }
IFACEMETHODIMP GetIcon(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* icon) IFACEMETHODIMP GetIcon(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* icon)
@@ -261,7 +264,7 @@ private:
std::thread create_pipe_thread; std::thread create_pipe_thread;
HANDLE hPipe = INVALID_HANDLE_VALUE; HANDLE hPipe = INVALID_HANDLE_VALUE;
std::wstring app_name = L"PowerRename"; std::wstring context_menu_caption = GET_RESOURCE_STRING_FALLBACK(IDS_POWERRENAME_CONTEXT_MENU_ENTRY, L"Rename with PowerRename");
}; };
CoCreatableClass(PowerRenameContextMenuCommand) CoCreatableClass(PowerRenameContextMenuCommand)

View File

@@ -22,7 +22,7 @@ struct InvokeStruct
CPowerRenameMenu::CPowerRenameMenu() CPowerRenameMenu::CPowerRenameMenu()
{ {
ModuleAddRef(); ModuleAddRef();
app_name = GET_RESOURCE_STRING(IDS_POWERRENAME_APP_NAME); context_menu_caption = GET_RESOURCE_STRING_FALLBACK(IDS_POWERRENAME_CONTEXT_MENU_ENTRY, L"Rename with PowerRename");
} }
CPowerRenameMenu::~CPowerRenameMenu() CPowerRenameMenu::~CPowerRenameMenu()
@@ -87,8 +87,8 @@ HRESULT CPowerRenameMenu::QueryContextMenu(HMENU hMenu, UINT index, UINT uIDFirs
HRESULT hr = E_UNEXPECTED; HRESULT hr = E_UNEXPECTED;
if (m_spdo && !(uFlags & (CMF_DEFAULTONLY | CMF_VERBSONLY | CMF_OPTIMIZEFORINVOKE))) if (m_spdo && !(uFlags & (CMF_DEFAULTONLY | CMF_VERBSONLY | CMF_OPTIMIZEFORINVOKE)))
{ {
wchar_t menuName[64] = { 0 }; wchar_t menuName[128] = { 0 };
LoadString(g_hInst, IDS_POWERRENAME, menuName, ARRAYSIZE(menuName)); wcscpy_s(menuName, ARRAYSIZE(menuName), context_menu_caption.c_str());
MENUITEMINFO mii; MENUITEMINFO mii;
mii.cbSize = sizeof(MENUITEMINFO); mii.cbSize = sizeof(MENUITEMINFO);
@@ -251,7 +251,7 @@ HRESULT CPowerRenameMenu::RunPowerRename(CMINVOKECOMMANDINFO* pici, IShellItemAr
HRESULT __stdcall CPowerRenameMenu::GetTitle(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszName) HRESULT __stdcall CPowerRenameMenu::GetTitle(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszName)
{ {
return SHStrDup(app_name.c_str(), ppszName); return SHStrDup(context_menu_caption.c_str(), ppszName);
} }
HRESULT __stdcall CPowerRenameMenu::GetIcon(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszIcon) HRESULT __stdcall CPowerRenameMenu::GetIcon(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszIcon)

View File

@@ -72,5 +72,5 @@ private:
std::atomic<long> m_refCount = 1; std::atomic<long> m_refCount = 1;
HBITMAP m_hbmpIcon = nullptr; HBITMAP m_hbmpIcon = nullptr;
CComPtr<IDataObject> m_spdo; CComPtr<IDataObject> m_spdo;
std::wstring app_name; std::wstring context_menu_caption;
}; };

View File

@@ -125,6 +125,10 @@
<value>PowerRename</value> <value>PowerRename</value>
<comment>do not loc, product name</comment> <comment>do not loc, product name</comment>
</data> </data>
<data name="PowerRename_Context_Menu_Entry" xml:space="preserve">
<value>Rename with PowerRename</value>
<comment>PowerRename is a product name. do not loc it</comment>
</data>
<data name="Settings_Description" xml:space="preserve"> <data name="Settings_Description" xml:space="preserve">
<value>A Windows Shell extension for more advanced bulk renaming using search and replace or regular expressions.</value> <value>A Windows Shell extension for more advanced bulk renaming using search and replace or regular expressions.</value>
</data> </data>