* Ensure rename dialog is centered

* Ensure children are renamed before parent items
* Add settings handler
* Replace old text referencing smart rename with power rename
This commit is contained in:
Chris Davis
2019-11-11 11:00:42 -08:00
parent 997ea3a2f5
commit 1e89054897
21 changed files with 1042 additions and 281 deletions

View File

@@ -25,6 +25,71 @@ HRESULT GetIconIndexFromPath(_In_ PCWSTR path, _Out_ int* index)
return hr;
}
HBITMAP CreateBitmapFromIcon(_In_ HICON hIcon, _In_opt_ UINT width, _In_opt_ UINT height)
{
HBITMAP hBitmapResult = NULL;
// Create compatible DC
HDC hDC = CreateCompatibleDC(NULL);
if (hDC != NULL)
{
// Get bitmap rectangle size
RECT rc = { 0 };
rc.left = 0;
rc.right = (width != 0) ? width : GetSystemMetrics(SM_CXSMICON);
rc.top = 0;
rc.bottom = (height != 0) ? height : GetSystemMetrics(SM_CYSMICON);
// Create bitmap compatible with DC
BITMAPINFO BitmapInfo;
ZeroMemory(&BitmapInfo, sizeof(BITMAPINFO));
BitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
BitmapInfo.bmiHeader.biWidth = rc.right;
BitmapInfo.bmiHeader.biHeight = rc.bottom;
BitmapInfo.bmiHeader.biPlanes = 1;
BitmapInfo.bmiHeader.biBitCount = 32;
BitmapInfo.bmiHeader.biCompression = BI_RGB;
HDC hDCBitmap = GetDC(NULL);
HBITMAP hBitmap = CreateDIBSection(hDCBitmap, &BitmapInfo, DIB_RGB_COLORS, NULL, NULL, 0);
ReleaseDC(NULL, hDCBitmap);
if (hBitmap != NULL)
{
// Select bitmap into DC
HBITMAP hBitmapOld = (HBITMAP)SelectObject(hDC, hBitmap);
if (hBitmapOld != NULL)
{
// Draw icon into DC
if (DrawIconEx(hDC, 0, 0, hIcon, rc.right, rc.bottom, 0, NULL, DI_NORMAL))
{
// Restore original bitmap in DC
hBitmapResult = (HBITMAP)SelectObject(hDC, hBitmapOld);
hBitmapOld = NULL;
hBitmap = NULL;
}
if (hBitmapOld != NULL)
{
SelectObject(hDC, hBitmapOld);
}
}
if (hBitmap != NULL)
{
DeleteObject(hBitmap);
}
}
DeleteDC(hDC);
}
return hBitmapResult;
}
HRESULT _ParseEnumItems(_In_ IEnumShellItems* pesi, _In_ IPowerRenameManager* psrm, _In_ int depth = 0)
{
HRESULT hr = E_INVALIDARG;
@@ -40,7 +105,7 @@ HRESULT _ParseEnumItems(_In_ IEnumShellItems* pesi, _In_ IPowerRenameManager* ps
while ((S_OK == pesi->Next(1, &spsi, &celtFetched)) && (SUCCEEDED(hr)))
{
CComPtr<IPowerRenameItemFactory> spsrif;
hr = psrm->get_smartRenameItemFactory(&spsrif);
hr = psrm->get_renameItemFactory(&spsrif);
if (SUCCEEDED(hr))
{
CComPtr<IPowerRenameItem> spNewItem;

View File

@@ -1,8 +1,8 @@
#pragma once
#include "stdafx.h"
HRESULT EnumerateDataObject(_In_ IDataObject* pdo, _In_ IPowerRenameManager* psrm);
HRESULT GetIconIndexFromPath(_In_ PCWSTR path, _Out_ int* index);
HBITMAP CreateBitmapFromIcon(_In_ HICON hIcon, _In_opt_ UINT width = 0, _In_opt_ UINT height = 0);
HWND CreateMsgWindow(_In_ HINSTANCE hInst, _In_ WNDPROC pfnWndProc, _In_ void* p);
BOOL GetEnumeratedFileName(
__out_ecount(cchMax) PWSTR pszUniqueName, UINT cchMax,

View File

@@ -93,10 +93,10 @@ public:
IFACEMETHOD(GetRenameItemCount)(_Out_ UINT* count) = 0;
IFACEMETHOD(get_flags)(_Out_ DWORD* flags) = 0;
IFACEMETHOD(put_flags)(_In_ DWORD flags) = 0;
IFACEMETHOD(get_smartRenameRegEx)(_COM_Outptr_ IPowerRenameRegEx** ppRegEx) = 0;
IFACEMETHOD(put_smartRenameRegEx)(_In_ IPowerRenameRegEx* pRegEx) = 0;
IFACEMETHOD(get_smartRenameItemFactory)(_COM_Outptr_ IPowerRenameItemFactory** ppItemFactory) = 0;
IFACEMETHOD(put_smartRenameItemFactory)(_In_ IPowerRenameItemFactory* pItemFactory) = 0;
IFACEMETHOD(get_renameRegEx)(_COM_Outptr_ IPowerRenameRegEx** ppRegEx) = 0;
IFACEMETHOD(put_renameRegEx)(_In_ IPowerRenameRegEx* pRegEx) = 0;
IFACEMETHOD(get_renameItemFactory)(_COM_Outptr_ IPowerRenameItemFactory** ppItemFactory) = 0;
IFACEMETHOD(put_renameItemFactory)(_In_ IPowerRenameItemFactory* pItemFactory) = 0;
};
interface __declspec(uuid("E6679DEB-460D-42C1-A7A8-E25897061C99")) IPowerRenameUI : public IUnknown
@@ -107,3 +107,9 @@ public:
IFACEMETHOD(Update)() = 0;
};
interface __declspec(uuid("04AAFABE-B76E-4E13-993A-B5941F52B139")) IPowerRenameMRU : public IUnknown
{
public:
IFACEMETHOD(AddMRUString)(_In_ PCWSTR entry) = 0;
};

View File

@@ -1,171 +1,173 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{51920F1F-C28C-4ADF-8660-4238766796C2}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>PowerRenameLib</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>..\;..\..\..\common;..\..\..\common\telemetry;..\..\</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>..\;..\..\..\common;..\..\..\common\telemetry;..\..\</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="Helpers.h" />
<ClInclude Include="PowerRenameItem.h" />
<ClInclude Include="PowerRenameInterfaces.h" />
<ClInclude Include="PowerRenameManager.h" />
<ClInclude Include="PowerRenameRegEx.h" />
<ClInclude Include="srwlock.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="trace.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Helpers.cpp" />
<ClCompile Include="PowerRenameItem.cpp" />
<ClCompile Include="PowerRenameManager.cpp" />
<ClCompile Include="PowerRenameRegEx.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="trace.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{51920F1F-C28C-4ADF-8660-4238766796C2}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>PowerRenameLib</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>..\;..\..\..\common;..\..\..\common\telemetry;..\..\</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>..\;..\..\..\common;..\..\..\common\telemetry;..\..\</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="Helpers.h" />
<ClInclude Include="PowerRenameItem.h" />
<ClInclude Include="PowerRenameInterfaces.h" />
<ClInclude Include="PowerRenameManager.h" />
<ClInclude Include="PowerRenameRegEx.h" />
<ClInclude Include="Settings.h" />
<ClInclude Include="srwlock.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="trace.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Helpers.cpp" />
<ClCompile Include="PowerRenameItem.cpp" />
<ClCompile Include="PowerRenameManager.cpp" />
<ClCompile Include="PowerRenameRegEx.cpp" />
<ClCompile Include="Settings.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="trace.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -44,7 +44,7 @@ IFACEMETHODIMP CPowerRenameManager::Advise(_In_ IPowerRenameManagerEvents* renam
{
CSRWExclusiveAutoLock lock(&m_lockEvents);
m_cookie++;
SMART_RENAME_MGR_EVENT srme;
RENAME_MGR_EVENT srme;
srme.cookie = m_cookie;
srme.pEvents = renameOpEvents;
renameOpEvents->AddRef();
@@ -117,9 +117,9 @@ IFACEMETHODIMP CPowerRenameManager::AddItem(_In_ IPowerRenameItem* pItem)
int id = 0;
pItem->get_id(&id);
// Verify the item isn't already added
if (m_smartRenameItems.find(id) == m_smartRenameItems.end())
if (m_renameItems.find(id) == m_renameItems.end())
{
m_smartRenameItems[id] = pItem;
m_renameItems[id] = pItem;
pItem->AddRef();
hr = S_OK;
}
@@ -138,9 +138,9 @@ IFACEMETHODIMP CPowerRenameManager::GetItemByIndex(_In_ UINT index, _COM_Outptr_
*ppItem = nullptr;
CSRWSharedAutoLock lock(&m_lockItems);
HRESULT hr = E_FAIL;
if (index < m_smartRenameItems.size())
if (index < m_renameItems.size())
{
std::map<int, IPowerRenameItem*>::iterator it = m_smartRenameItems.begin();
std::map<int, IPowerRenameItem*>::iterator it = m_renameItems.begin();
std::advance(it, index);
*ppItem = it->second;
(*ppItem)->AddRef();
@@ -157,10 +157,10 @@ IFACEMETHODIMP CPowerRenameManager::GetItemById(_In_ int id, _COM_Outptr_ IPower
CSRWSharedAutoLock lock(&m_lockItems);
HRESULT hr = E_FAIL;
std::map<int, IPowerRenameItem*>::iterator it;
it = m_smartRenameItems.find(id);
if (it != m_smartRenameItems.end())
it = m_renameItems.find(id);
if (it != m_renameItems.end())
{
*ppItem = m_smartRenameItems[id];
*ppItem = m_renameItems[id];
(*ppItem)->AddRef();
hr = S_OK;
}
@@ -171,7 +171,7 @@ IFACEMETHODIMP CPowerRenameManager::GetItemById(_In_ int id, _COM_Outptr_ IPower
IFACEMETHODIMP CPowerRenameManager::GetItemCount(_Out_ UINT* count)
{
CSRWSharedAutoLock lock(&m_lockItems);
*count = static_cast<UINT>(m_smartRenameItems.size());
*count = static_cast<UINT>(m_renameItems.size());
return S_OK;
}
@@ -180,7 +180,7 @@ IFACEMETHODIMP CPowerRenameManager::GetSelectedItemCount(_Out_ UINT* count)
*count = 0;
CSRWSharedAutoLock lock(&m_lockItems);
for (auto it : m_smartRenameItems)
for (auto it : m_renameItems)
{
IPowerRenameItem* pItem = it.second;
bool selected = false;
@@ -198,7 +198,7 @@ IFACEMETHODIMP CPowerRenameManager::GetRenameItemCount(_Out_ UINT* count)
*count = 0;
CSRWSharedAutoLock lock(&m_lockItems);
for (auto it : m_smartRenameItems)
for (auto it : m_renameItems)
{
IPowerRenameItem* pItem = it.second;
bool shouldRename = false;
@@ -229,7 +229,7 @@ IFACEMETHODIMP CPowerRenameManager::put_flags(_In_ DWORD flags)
return S_OK;
}
IFACEMETHODIMP CPowerRenameManager::get_smartRenameRegEx(_COM_Outptr_ IPowerRenameRegEx** ppRegEx)
IFACEMETHODIMP CPowerRenameManager::get_renameRegEx(_COM_Outptr_ IPowerRenameRegEx** ppRegEx)
{
*ppRegEx = nullptr;
HRESULT hr = _EnsureRegEx();
@@ -241,14 +241,14 @@ IFACEMETHODIMP CPowerRenameManager::get_smartRenameRegEx(_COM_Outptr_ IPowerRena
return hr;
}
IFACEMETHODIMP CPowerRenameManager::put_smartRenameRegEx(_In_ IPowerRenameRegEx* pRegEx)
IFACEMETHODIMP CPowerRenameManager::put_renameRegEx(_In_ IPowerRenameRegEx* pRegEx)
{
_ClearRegEx();
m_spRegEx = pRegEx;
return S_OK;
}
IFACEMETHODIMP CPowerRenameManager::get_smartRenameItemFactory(_COM_Outptr_ IPowerRenameItemFactory** ppItemFactory)
IFACEMETHODIMP CPowerRenameManager::get_renameItemFactory(_COM_Outptr_ IPowerRenameItemFactory** ppItemFactory)
{
*ppItemFactory = nullptr;
HRESULT hr = E_FAIL;
@@ -261,7 +261,7 @@ IFACEMETHODIMP CPowerRenameManager::get_smartRenameItemFactory(_COM_Outptr_ IPow
return hr;
}
IFACEMETHODIMP CPowerRenameManager::put_smartRenameItemFactory(_In_ IPowerRenameItemFactory* pItemFactory)
IFACEMETHODIMP CPowerRenameManager::put_renameItemFactory(_In_ IPowerRenameItemFactory* pItemFactory)
{
m_spItemFactory = pItemFactory;
return S_OK;
@@ -281,7 +281,7 @@ IFACEMETHODIMP CPowerRenameManager::OnReplaceTermChanged(_In_ PCWSTR /*replaceTe
IFACEMETHODIMP CPowerRenameManager::OnFlagsChanged(_In_ DWORD flags)
{
// Flags were updated in the smart rename regex. Update our preview.
// Flags were updated in the rename regex. Update our preview.
m_flags = flags;
_PerformRegExRename();
return S_OK;
@@ -330,7 +330,7 @@ HRESULT CPowerRenameManager::_Init()
// Custom messages for worker threads
enum
{
SRM_REGEX_ITEM_UPDATED = (WM_APP + 1), // Single smart rename item processed by regex worker thread
SRM_REGEX_ITEM_UPDATED = (WM_APP + 1), // Single rename item processed by regex worker thread
SRM_REGEX_STARTED, // RegEx operation was started
SRM_REGEX_CANCELED, // Regex operation was canceled
SRM_REGEX_COMPLETE, // Regex worker thread completed
@@ -546,7 +546,7 @@ DWORD WINAPI CPowerRenameManager::s_fileOpWorkerThread(_In_ void* pv)
if (WaitForSingleObject(pwtd->startEvent, INFINITE) == WAIT_OBJECT_0)
{
CComPtr<IPowerRenameRegEx> spRenameRegEx;
if (SUCCEEDED(pwtd->spsrm->get_smartRenameRegEx(&spRenameRegEx)))
if (SUCCEEDED(pwtd->spsrm->get_renameRegEx(&spRenameRegEx)))
{
// Create IFileOperation interface
CComPtr<IFileOperation> spFileOp;
@@ -557,24 +557,45 @@ DWORD WINAPI CPowerRenameManager::s_fileOpWorkerThread(_In_ void* pv)
UINT itemCount = 0;
pwtd->spsrm->GetItemCount(&itemCount);
// Add each rename operation
for (UINT u = 0; u <= itemCount; u++)
// We add the items to the operation in depth-first order. This allows child items to be
// renamed before parent items.
// Creating a vector of vectors of items of the same depth
std::vector<std::vector<UINT>> matrix(itemCount);
for (UINT u = 0; u < itemCount; u++)
{
CComPtr<IPowerRenameItem> spItem;
if (SUCCEEDED(pwtd->spsrm->GetItemByIndex(u, &spItem)))
{
bool shouldRename = false;
if (SUCCEEDED(spItem->ShouldRenameItem(flags, &shouldRename)) && shouldRename)
UINT depth = 0;
spItem->get_depth(&depth);
matrix[depth].push_back(u);
}
}
// From the greatest depth first, add all items of that depth to the operation
for (LONG v = itemCount - 1; v >= 0; v--)
{
for (auto it : matrix[v])
{
CComPtr<IPowerRenameItem> spItem;
if (SUCCEEDED(pwtd->spsrm->GetItemByIndex(it, &spItem)))
{
PWSTR newName = nullptr;
if (SUCCEEDED(spItem->get_newName(&newName)))
bool shouldRename = false;
if (SUCCEEDED(spItem->ShouldRenameItem(flags, &shouldRename)) && shouldRename)
{
CComPtr<IShellItem> spShellItem;
if (SUCCEEDED(spItem->get_shellItem(&spShellItem)))
PWSTR newName = nullptr;
if (SUCCEEDED(spItem->get_newName(&newName)))
{
spFileOp->RenameItem(spShellItem, newName, nullptr);
CComPtr<IShellItem> spShellItem;
if (SUCCEEDED(spItem->get_shellItem(&spShellItem)))
{
spFileOp->RenameItem(spShellItem, newName, nullptr);
}
CoTaskMemFree(newName);
}
CoTaskMemFree(newName);
}
}
}
@@ -674,7 +695,7 @@ DWORD WINAPI CPowerRenameManager::s_regexWorkerThread(_In_ void* pv)
if (WaitForSingleObject(pwtd->startEvent, INFINITE) == WAIT_OBJECT_0)
{
CComPtr<IPowerRenameRegEx> spRenameRegEx;
if (SUCCEEDED(pwtd->spsrm->get_smartRenameRegEx(&spRenameRegEx)))
if (SUCCEEDED(pwtd->spsrm->get_renameRegEx(&spRenameRegEx)))
{
DWORD flags = 0;
spRenameRegEx->get_flags(&flags);
@@ -1022,14 +1043,14 @@ void CPowerRenameManager::_ClearPowerRenameItems()
{
CSRWExclusiveAutoLock lock(&m_lockItems);
// Cleanup smart rename items
for (auto it : m_smartRenameItems)
// Cleanup rename items
for (auto it : m_renameItems)
{
IPowerRenameItem* pItem = it.second;
pItem->Release();
}
m_smartRenameItems.clear();
m_renameItems.clear();
}
void CPowerRenameManager::_Cleanup()

View File

@@ -29,10 +29,10 @@ public:
IFACEMETHODIMP GetRenameItemCount(_Out_ UINT* count);
IFACEMETHODIMP get_flags(_Out_ DWORD* flags);
IFACEMETHODIMP put_flags(_In_ DWORD flags);
IFACEMETHODIMP get_smartRenameRegEx(_COM_Outptr_ IPowerRenameRegEx** ppRegEx);
IFACEMETHODIMP put_smartRenameRegEx(_In_ IPowerRenameRegEx* pRegEx);
IFACEMETHODIMP get_smartRenameItemFactory(_COM_Outptr_ IPowerRenameItemFactory** ppItemFactory);
IFACEMETHODIMP put_smartRenameItemFactory(_In_ IPowerRenameItemFactory* pItemFactory);
IFACEMETHODIMP get_renameRegEx(_COM_Outptr_ IPowerRenameRegEx** ppRegEx);
IFACEMETHODIMP put_renameRegEx(_In_ IPowerRenameRegEx* pRegEx);
IFACEMETHODIMP get_renameItemFactory(_COM_Outptr_ IPowerRenameItemFactory** ppItemFactory);
IFACEMETHODIMP put_renameItemFactory(_In_ IPowerRenameItemFactory* pItemFactory);
// IPowerRenameRegExEvents
IFACEMETHODIMP OnSearchTermChanged(_In_ PCWSTR searchTerm);
@@ -99,7 +99,7 @@ protected:
DWORD m_cookie = 0;
DWORD m_regExAdviseCookie = 0;
struct SMART_RENAME_MGR_EVENT
struct RENAME_MGR_EVENT
{
IPowerRenameManagerEvents* pEvents;
DWORD cookie;
@@ -108,8 +108,8 @@ protected:
CComPtr<IPowerRenameItemFactory> m_spItemFactory;
CComPtr<IPowerRenameRegEx> m_spRegEx;
_Guarded_by_(m_lockEvents) std::vector<SMART_RENAME_MGR_EVENT> m_PowerRenameManagerEvents;
_Guarded_by_(m_lockItems) std::map<int, IPowerRenameItem*> m_smartRenameItems;
_Guarded_by_(m_lockEvents) std::vector<RENAME_MGR_EVENT> m_PowerRenameManagerEvents;
_Guarded_by_(m_lockItems) std::map<int, IPowerRenameItem*> m_renameItems;
// Parent HWND used by IFileOperation
HWND m_hwndParent = nullptr;

View File

@@ -37,11 +37,11 @@ IFACEMETHODIMP CPowerRenameRegEx::Advise(_In_ IPowerRenameRegExEvents* regExEven
{
CSRWExclusiveAutoLock lock(&m_lockEvents);
m_cookie++;
SMART_RENAME_REGEX_EVENT srre;
RENAME_REGEX_EVENT srre;
srre.cookie = m_cookie;
srre.pEvents = regExEvents;
regExEvents->AddRef();
m_smartRenameRegExEvents.push_back(srre);
m_renameRegExEvents.push_back(srre);
*cookie = m_cookie;
@@ -53,7 +53,7 @@ IFACEMETHODIMP CPowerRenameRegEx::UnAdvise(_In_ DWORD cookie)
HRESULT hr = E_FAIL;
CSRWExclusiveAutoLock lock(&m_lockEvents);
for (auto it : m_smartRenameRegExEvents)
for (auto it : m_renameRegExEvents)
{
if (it.cookie == cookie)
{
@@ -265,7 +265,7 @@ void CPowerRenameRegEx::_OnSearchTermChanged()
{
CSRWSharedAutoLock lock(&m_lockEvents);
for (auto it : m_smartRenameRegExEvents)
for (auto it : m_renameRegExEvents)
{
if (it.pEvents)
{
@@ -278,7 +278,7 @@ void CPowerRenameRegEx::_OnReplaceTermChanged()
{
CSRWSharedAutoLock lock(&m_lockEvents);
for (auto it : m_smartRenameRegExEvents)
for (auto it : m_renameRegExEvents)
{
if (it.pEvents)
{
@@ -291,7 +291,7 @@ void CPowerRenameRegEx::_OnFlagsChanged()
{
CSRWSharedAutoLock lock(&m_lockEvents);
for (auto it : m_smartRenameRegExEvents)
for (auto it : m_renameRegExEvents)
{
if (it.pEvents)
{

View File

@@ -46,13 +46,13 @@ protected:
DWORD m_cookie = 0;
struct SMART_RENAME_REGEX_EVENT
struct RENAME_REGEX_EVENT
{
IPowerRenameRegExEvents* pEvents;
DWORD cookie;
};
_Guarded_by_(m_lockEvents) std::vector<SMART_RENAME_REGEX_EVENT> m_smartRenameRegExEvents;
_Guarded_by_(m_lockEvents) std::vector<RENAME_REGEX_EVENT> m_renameRegExEvents;
long m_refCount = 0;
};

View File

@@ -0,0 +1,483 @@
#include "stdafx.h"
#include <commctrl.h>
#include "Settings.h"
const wchar_t c_rootRegPath[] = L"Software\\Microsoft\\PowerRename";
const wchar_t c_mruSearchRegPath[] = L"SearchMRU";
const wchar_t c_mruReplaceRegPath[] = L"ReplaceMRU";
const wchar_t c_enabled[] = L"Enabled";
const wchar_t c_showIconOnMenu[] = L"ShowIcon";
const wchar_t c_extendedContextMenuOnly[] = L"ExtendedContextMenuOnly";
const wchar_t c_persistState[] = L"PersistState";
const wchar_t c_maxMRUSize[] = L"MaxMRUSize";
const wchar_t c_flags[] = L"Flags";
const wchar_t c_searchText[] = L"SearchText";
const wchar_t c_replaceText[] = L"ReplaceText";
const wchar_t c_mruEnabled[] = L"MRUEnabled";
const bool c_enabledDefault = true;
const bool c_showIconOnMenuDefault = true;
const bool c_extendedContextMenuOnlyDefaut = false;
const bool c_persistStateDefault = true;
const bool c_mruEnabledDefault = true;
const DWORD c_maxMRUSizeDefault = 10;
const DWORD c_flagsDefault = 0;
bool CSettings::GetEnabled()
{
return GetRegBoolValue(c_enabled, c_enabledDefault);
}
bool CSettings::SetEnabled(_In_ bool enabled)
{
return SetRegBoolValue(c_enabled, enabled);
}
bool CSettings::GetShowIconOnMenu()
{
return GetRegBoolValue(c_showIconOnMenu, c_showIconOnMenuDefault);
}
bool CSettings::SetShowIconOnMenu(_In_ bool show)
{
return SetRegBoolValue(c_showIconOnMenu, show);
}
bool CSettings::GetExtendedContextMenuOnly()
{
return GetRegBoolValue(c_extendedContextMenuOnly, c_extendedContextMenuOnlyDefaut);
}
bool CSettings::SetExtendedContextMenuOnly(_In_ bool extendedOnly)
{
return SetRegBoolValue(c_extendedContextMenuOnly, extendedOnly);
}
bool CSettings::GetPersistState()
{
return GetRegBoolValue(c_persistState, c_persistStateDefault);
}
bool CSettings::SetPersistState(_In_ bool persistState)
{
return SetRegBoolValue(c_persistState, persistState);
}
bool CSettings::GetMRUEnabled()
{
return GetRegBoolValue(c_mruEnabled, c_mruEnabledDefault);
}
bool CSettings::SetMRUEnabled(_In_ bool enabled)
{
return SetRegBoolValue(c_mruEnabled, enabled);
}
DWORD CSettings::GetMaxMRUSize()
{
return GetRegDWORDValue(c_maxMRUSize, c_maxMRUSizeDefault);
}
bool CSettings::SetMaxMRUSize(_In_ DWORD maxMRUSize)
{
return SetRegDWORDValue(c_maxMRUSize, maxMRUSize);
}
DWORD CSettings::GetFlags()
{
return GetRegDWORDValue(c_flags, c_flagsDefault);
}
bool CSettings::SetFlags(_In_ DWORD flags)
{
return SetRegDWORDValue(c_flags, flags);
}
bool CSettings::GetSearchText(__out_ecount(cchBuf) PWSTR text, DWORD cchBuf)
{
return GetRegStringValue(c_searchText, text, cchBuf);
}
bool CSettings::SetSearchText(_In_ PCWSTR text)
{
return SetRegStringValue(c_searchText, text);
}
bool CSettings::GetReplaceText(__out_ecount(cchBuf) PWSTR text, DWORD cchBuf)
{
return GetRegStringValue(c_replaceText, text, cchBuf);
}
bool CSettings::SetReplaceText(_In_ PCWSTR text)
{
return SetRegStringValue(c_replaceText, text);
}
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)));
}
typedef int (CALLBACK* MRUCMPPROC)(LPCWSTR, LPCWSTR);
typedef struct {
DWORD cbSize;
UINT uMax;
UINT fFlags;
HKEY hKey;
LPCTSTR lpszSubKey;
MRUCMPPROC lpfnCompare;
} MRUINFO;
typedef HANDLE (*CreateMRUListFn)(MRUINFO* pmi);
typedef int (*AddMRUStringFn)(HANDLE hMRU, LPCWSTR data);
typedef int (*EnumMRUListFn)(HANDLE hMRU, int nItem, void* lpData, UINT uLen);
typedef int (*FreeMRUListFn)(HANDLE hMRU);
class CRenameMRU :
public IEnumString,
public IPowerRenameMRU
{
public:
// IUnknown
IFACEMETHODIMP_(ULONG) AddRef();
IFACEMETHODIMP_(ULONG) Release();
IFACEMETHODIMP QueryInterface(_In_ REFIID riid, _Outptr_ void** ppv);
// IEnumString
IFACEMETHODIMP Next(__in ULONG celt, __out_ecount_part(celt, *pceltFetched) LPOLESTR* rgelt, __out_opt ULONG* pceltFetched);
IFACEMETHODIMP Skip(__in ULONG celt) { return E_NOTIMPL; }
IFACEMETHODIMP Reset();
IFACEMETHODIMP Clone(__deref_out IEnumString** ppenum) { *ppenum = nullptr; return E_NOTIMPL; }
// IPowerRenameMRU
IFACEMETHODIMP AddMRUString(_In_ PCWSTR entry);
static HRESULT CreateInstance(_In_ PCWSTR regPathMRU, _In_ ULONG maxMRUSize, _Outptr_ IUnknown** ppUnk);
private:
CRenameMRU();
~CRenameMRU();
HRESULT _Initialize(_In_ PCWSTR regPathMRU, __in ULONG maxMRUSize);
HRESULT _CreateMRUList(_In_ MRUINFO* pmi);
int _AddMRUString(_In_ PCWSTR data);
int _EnumMRUList(_In_ int nItem, _Out_ void* lpData, _In_ UINT uLen);
void _FreeMRUList();
long m_refCount = 0;
HKEY m_hKey = NULL;
ULONG m_maxMRUSize = 0;
ULONG m_mruIndex = 0;
ULONG m_mruSize = 0;
HANDLE m_mruHandle = NULL;
HMODULE m_hComctl32Dll = NULL;
PWSTR m_regPath = nullptr;
};
CRenameMRU::CRenameMRU() :
m_refCount(1)
{}
CRenameMRU::~CRenameMRU()
{
if (m_hKey)
{
RegCloseKey(m_hKey);
}
_FreeMRUList();
if (m_hComctl32Dll)
{
FreeLibrary(m_hComctl32Dll);
}
CoTaskMemFree(m_regPath);
}
HRESULT CRenameMRU::CreateInstance(_In_ PCWSTR regPathMRU, _In_ ULONG maxMRUSize, _Outptr_ IUnknown** ppUnk)
{
*ppUnk = nullptr;
HRESULT hr = (regPathMRU && maxMRUSize > 0) ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
CRenameMRU* renameMRU = new CRenameMRU();
hr = renameMRU ? S_OK : E_OUTOFMEMORY;
if (SUCCEEDED(hr))
{
hr = renameMRU->_Initialize(regPathMRU, maxMRUSize);
if (SUCCEEDED(hr))
{
hr = renameMRU->QueryInterface(IID_PPV_ARGS(ppUnk));
}
renameMRU->Release();
}
}
return hr;
}
// IUnknown
IFACEMETHODIMP_(ULONG) CRenameMRU::AddRef()
{
return InterlockedIncrement(&m_refCount);
}
IFACEMETHODIMP_(ULONG) CRenameMRU::Release()
{
long refCount = InterlockedDecrement(&m_refCount);
if (refCount == 0)
{
delete this;
}
return refCount;
}
IFACEMETHODIMP CRenameMRU::QueryInterface(_In_ REFIID riid, _Outptr_ void** ppv)
{
static const QITAB qit[] = {
QITABENT(CRenameMRU, IEnumString),
QITABENT(CRenameMRU, IPowerRenameMRU),
{ 0 }
};
return QISearch(this, qit, riid, ppv);
}
HRESULT CRenameMRU::_Initialize(_In_ PCWSTR regPathMRU, __in ULONG maxMRUSize)
{
m_maxMRUSize = maxMRUSize;
wchar_t regPath[MAX_PATH] = { 0 };
HRESULT hr = StringCchPrintf(regPath, ARRAYSIZE(regPath), L"%s\\%s", c_rootRegPath, regPathMRU);
if (SUCCEEDED(hr))
{
hr = SHStrDup(regPathMRU, &m_regPath);
if (SUCCEEDED(hr))
{
MRUINFO mi = {
sizeof(MRUINFO),
maxMRUSize,
0,
HKEY_CURRENT_USER,
regPath,
nullptr
};
hr = _CreateMRUList(&mi);
if (SUCCEEDED(hr))
{
m_mruSize = _EnumMRUList(-1, NULL, 0);
}
else
{
hr = E_FAIL;
}
}
}
return hr;
}
// IEnumString
IFACEMETHODIMP CRenameMRU::Reset()
{
m_mruIndex = 0;
return S_OK;
}
#define MAX_ENTRY_STRING 1024
IFACEMETHODIMP CRenameMRU::Next(__in ULONG celt, __out_ecount_part(celt, *pceltFetched) LPOLESTR* rgelt, __out_opt ULONG* pceltFetched)
{
HRESULT hr = S_OK;
WCHAR mruEntry[MAX_ENTRY_STRING];
mruEntry[0] = L'\0';
if (pceltFetched)
{
*pceltFetched = 0;
}
if (!celt)
{
return S_OK;
}
if (!rgelt)
{
return S_FALSE;
}
hr = S_FALSE;
if (m_mruIndex <= m_mruSize && _EnumMRUList(m_mruIndex++, (void*)mruEntry, ARRAYSIZE(mruEntry)) > 0)
{
hr = SHStrDup(mruEntry, rgelt);
if (SUCCEEDED(hr) && pceltFetched != nullptr)
{
*pceltFetched = 1;
}
}
return hr;
}
IFACEMETHODIMP CRenameMRU::AddMRUString(_In_ PCWSTR entry)
{
return (_AddMRUString(entry) < 0) ? E_FAIL : S_OK;
}
HRESULT CRenameMRU::_CreateMRUList(_In_ MRUINFO* pmi)
{
HRESULT hr = E_FAIL;
if (m_mruHandle != NULL)
{
_FreeMRUList();
}
if (m_hComctl32Dll == NULL)
{
m_hComctl32Dll = LoadLibraryEx(L"comctl32.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
}
if (m_hComctl32Dll != nullptr)
{
CreateMRUListFn pfnCreateMRUList = reinterpret_cast<CreateMRUListFn>(GetProcAddress(m_hComctl32Dll, (LPCSTR)MAKEINTRESOURCE(400)));
if (pfnCreateMRUList != nullptr)
{
m_mruHandle = pfnCreateMRUList(pmi);
}
}
return (m_mruHandle != NULL) ? S_OK : E_FAIL;
}
int CRenameMRU::_AddMRUString(_In_ PCWSTR data)
{
int retVal = -1;
if (m_mruHandle != NULL)
{
if (m_hComctl32Dll == NULL)
{
m_hComctl32Dll = LoadLibraryEx(L"comctl32.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
}
if (m_hComctl32Dll != nullptr)
{
AddMRUStringFn pfnAddMRUString = reinterpret_cast<AddMRUStringFn>(GetProcAddress(m_hComctl32Dll, (LPCSTR)MAKEINTRESOURCE(401)));
if (pfnAddMRUString != nullptr)
{
retVal = pfnAddMRUString(m_mruHandle, data);
}
}
}
return retVal;
}
int CRenameMRU::_EnumMRUList(_In_ int nItem, _Out_ void* lpData, _In_ UINT uLen)
{
int retVal = -1;
if (m_mruHandle != NULL)
{
if (m_hComctl32Dll == NULL)
{
m_hComctl32Dll = LoadLibraryEx(L"comctl32.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
}
if (m_hComctl32Dll != nullptr)
{
EnumMRUListFn pfnEnumMRUList = reinterpret_cast<EnumMRUListFn>(GetProcAddress(m_hComctl32Dll, (LPCSTR)MAKEINTRESOURCE(403)));
if (pfnEnumMRUList != nullptr)
{
retVal = pfnEnumMRUList(m_mruHandle, nItem, lpData, uLen);
}
}
}
return retVal;
}
void CRenameMRU::_FreeMRUList()
{
if (m_mruHandle != NULL)
{
if (m_hComctl32Dll == NULL)
{
m_hComctl32Dll = LoadLibraryEx(L"comctl32.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
}
if (m_hComctl32Dll != nullptr)
{
FreeMRUListFn pfnFreeMRUList = reinterpret_cast<FreeMRUListFn>(GetProcAddress(m_hComctl32Dll, (LPCSTR)MAKEINTRESOURCE(152)));
if (pfnFreeMRUList != nullptr)
{
pfnFreeMRUList(m_mruHandle);
}
}
m_mruHandle = NULL;
}
}
HRESULT CRenameMRUSearch_CreateInstance(_Outptr_ IUnknown** ppUnk)
{
return CRenameMRU::CreateInstance(c_mruSearchRegPath, CSettings::GetMaxMRUSize(), ppUnk);
}
HRESULT CRenameMRUReplace_CreateInstance(_Outptr_ IUnknown** ppUnk)
{
return CRenameMRU::CreateInstance(c_mruReplaceRegPath, CSettings::GetMaxMRUSize(), ppUnk);
}

View File

@@ -0,0 +1,43 @@
#pragma once
class CSettings
{
public:
static bool GetEnabled();
static bool SetEnabled(_In_ bool enabled);
static bool GetShowIconOnMenu();
static bool SetShowIconOnMenu(_In_ bool show);
static bool GetExtendedContextMenuOnly();
static bool SetExtendedContextMenuOnly(_In_ bool extendedOnly);
static bool GetPersistState();
static bool SetPersistState(_In_ bool extendedOnly);
static bool GetMRUEnabled();
static bool SetMRUEnabled(_In_ bool enabled);
static DWORD GetMaxMRUSize();
static bool SetMaxMRUSize(_In_ DWORD maxMRUSize);
static DWORD GetFlags();
static bool SetFlags(_In_ DWORD flags);
static bool GetSearchText(__out_ecount(cchBuf) PWSTR text, DWORD cchBuf);
static bool SetSearchText(_In_ PCWSTR text);
static bool GetReplaceText(__out_ecount(cchBuf) PWSTR text, DWORD cchBuf);
static bool SetReplaceText(_In_ PCWSTR text);
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);
};
HRESULT CRenameMRUSearch_CreateInstance(_Outptr_ IUnknown** ppUnk);
HRESULT CRenameMRUReplace_CreateInstance(_Outptr_ IUnknown** ppUnk);

View File

@@ -16,6 +16,7 @@
#include <pathcch.h>
#include <shobjidl.h>
#include <shellapi.h>
#include <shlwapi.h>
#include <ProjectTelemetry.h>