mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
[PowerRename] Add PowerRename to directory background context menu (#24522)
* Add PowerRename to directory background context menu * Fix analyzer error * Add more checks
This commit is contained in:
2
.github/actions/spell-check/expect.txt
vendored
2
.github/actions/spell-check/expect.txt
vendored
@@ -742,7 +742,7 @@ IDD
|
|||||||
IDesktop
|
IDesktop
|
||||||
IDirect
|
IDirect
|
||||||
idl
|
idl
|
||||||
IDLIST
|
idlist
|
||||||
IDOn
|
IDOn
|
||||||
IDR
|
IDR
|
||||||
idx
|
idx
|
||||||
|
|||||||
@@ -28,6 +28,9 @@
|
|||||||
<RegistryKey Root="HKLM" Key="SOFTWARE\Classes\AllFileSystemObjects\ShellEx\ContextMenuHandlers\PowerRenameExt">
|
<RegistryKey Root="HKLM" Key="SOFTWARE\Classes\AllFileSystemObjects\ShellEx\ContextMenuHandlers\PowerRenameExt">
|
||||||
<RegistryValue Type="string" Value="{0440049F-D1DC-4E46-B27B-98393D79486B}"/>
|
<RegistryValue Type="string" Value="{0440049F-D1DC-4E46-B27B-98393D79486B}"/>
|
||||||
</RegistryKey>
|
</RegistryKey>
|
||||||
|
<RegistryKey Root="HKLM" Key="SOFTWARE\Classes\Directory\background\ShellEx\ContextMenuHandlers\PowerRenameExt">
|
||||||
|
<RegistryValue Type="string" Value="{0440049F-D1DC-4E46-B27B-98393D79486B}"/>
|
||||||
|
</RegistryKey>
|
||||||
|
|
||||||
</Component>
|
</Component>
|
||||||
</DirectoryRef>
|
</DirectoryRef>
|
||||||
|
|||||||
@@ -93,12 +93,6 @@ public:
|
|||||||
{
|
{
|
||||||
*cmdState = ECS_ENABLED;
|
*cmdState = ECS_ENABLED;
|
||||||
|
|
||||||
// We've observed that it's possible that a null gets passed instead of an empty array. Just don't show the context menu in this case.
|
|
||||||
if (nullptr == selection) {
|
|
||||||
*cmdState = ECS_HIDDEN;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!CSettingsInstance().GetEnabled())
|
if (!CSettingsInstance().GetEnabled())
|
||||||
{
|
{
|
||||||
*cmdState = ECS_HIDDEN;
|
*cmdState = ECS_HIDDEN;
|
||||||
@@ -112,6 +106,12 @@ public:
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When right clicking directory background, selection is empty. This prevents checking if there
|
||||||
|
// are renamable items, but internal PowerRename logic will prevent renaming non-renamable items anyway.
|
||||||
|
if (nullptr == selection) {
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if at least one of the selected items is actually renamable.
|
// Check if at least one of the selected items is actually renamable.
|
||||||
if (!ShellItemArrayContainsRenamableItem(selection))
|
if (!ShellItemArrayContainsRenamableItem(selection))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -46,14 +46,26 @@ HRESULT CPowerRenameMenu::s_CreateInstance(_In_opt_ IUnknown*, _In_ REFIID riid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IShellExtInit
|
// IShellExtInit
|
||||||
HRESULT CPowerRenameMenu::Initialize(_In_opt_ PCIDLIST_ABSOLUTE, _In_ IDataObject* pdtobj, HKEY)
|
HRESULT CPowerRenameMenu::Initialize(_In_opt_ PCIDLIST_ABSOLUTE idlist, _In_ IDataObject* pdtobj, HKEY)
|
||||||
{
|
{
|
||||||
// Check if we have disabled ourselves
|
// Check if we have disabled ourselves
|
||||||
if (!CSettingsInstance().GetEnabled())
|
if (!CSettingsInstance().GetEnabled())
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
// Cache the data object to be used later
|
// Cache the data object to be used later
|
||||||
m_spdo = pdtobj;
|
if (idlist != NULL)
|
||||||
|
{
|
||||||
|
CComPtr<IShellItemArray> spsia;
|
||||||
|
if (SUCCEEDED(SHCreateShellItemArrayFromIDLists(1, &idlist, &spsia)) && spsia != NULL)
|
||||||
|
{
|
||||||
|
spsia->BindToHandler(NULL, BHID_DataObject, IID_IDataObject, reinterpret_cast<void**>(&m_spdo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_spdo = pdtobj;
|
||||||
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +136,7 @@ HRESULT CPowerRenameMenu::RunPowerRename(CMINVOKECOMMANDINFO* pici, IShellItemAr
|
|||||||
HRESULT hr = E_FAIL;
|
HRESULT hr = E_FAIL;
|
||||||
|
|
||||||
if (CSettingsInstance().GetEnabled() &&
|
if (CSettingsInstance().GetEnabled() &&
|
||||||
(IS_INTRESOURCE(pici->lpVerb)) &&
|
pici && (IS_INTRESOURCE(pici->lpVerb)) &&
|
||||||
(LOWORD(pici->lpVerb) == 0))
|
(LOWORD(pici->lpVerb) == 0))
|
||||||
{
|
{
|
||||||
Trace::Invoked();
|
Trace::Invoked();
|
||||||
@@ -163,14 +175,7 @@ HRESULT CPowerRenameMenu::RunPowerRename(CMINVOKECOMMANDINFO* pici, IShellItemAr
|
|||||||
startupInfo.cb = sizeof(STARTUPINFO);
|
startupInfo.cb = sizeof(STARTUPINFO);
|
||||||
startupInfo.hStdInput = hReadPipe;
|
startupInfo.hStdInput = hReadPipe;
|
||||||
startupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
|
startupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
|
||||||
if (pici)
|
startupInfo.wShowWindow = static_cast<WORD>(pici->nShow);
|
||||||
{
|
|
||||||
startupInfo.wShowWindow = static_cast<WORD>(pici->nShow);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
startupInfo.wShowWindow = SW_SHOWNORMAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PROCESS_INFORMATION processInformation;
|
PROCESS_INFORMATION processInformation;
|
||||||
|
|
||||||
@@ -201,15 +206,18 @@ HRESULT CPowerRenameMenu::RunPowerRename(CMINVOKECOMMANDINFO* pici, IShellItemAr
|
|||||||
// psiItemArray is NULL if called from InvokeCommand. This part is used for the MSI installer. It is not NULL if it is called from Invoke (MSIX).
|
// psiItemArray is NULL if called from InvokeCommand. This part is used for the MSI installer. It is not NULL if it is called from Invoke (MSIX).
|
||||||
if (!psiItemArray)
|
if (!psiItemArray)
|
||||||
{
|
{
|
||||||
// Stream the input files
|
if (m_spdo)
|
||||||
HDropIterator i(m_spdo);
|
|
||||||
for (i.First(); !i.IsDone(); i.Next())
|
|
||||||
{
|
{
|
||||||
CString fileName(i.CurrentItem());
|
// Stream the input files
|
||||||
// File name can't contain '?'
|
HDropIterator i(m_spdo);
|
||||||
fileName.Append(_T("?"));
|
for (i.First(); !i.IsDone(); i.Next())
|
||||||
|
{
|
||||||
|
CString fileName(i.CurrentItem());
|
||||||
|
// File name can't contain '?'
|
||||||
|
fileName.Append(_T("?"));
|
||||||
|
|
||||||
writePipe.Write(fileName, fileName.GetLength() * sizeof(TCHAR));
|
writePipe.Write(fileName, fileName.GetLength() * sizeof(TCHAR));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -551,7 +551,7 @@ bool DataObjectContainsRenamableItem(_In_ IUnknown* dataSource)
|
|||||||
{
|
{
|
||||||
bool hasRenamable = false;
|
bool hasRenamable = false;
|
||||||
CComPtr<IShellItemArray> spsia;
|
CComPtr<IShellItemArray> spsia;
|
||||||
if (SUCCEEDED(GetShellItemArrayFromDataObject(dataSource, &spsia)))
|
if (dataSource && SUCCEEDED(GetShellItemArrayFromDataObject(dataSource, &spsia)))
|
||||||
{
|
{
|
||||||
CComPtr<IEnumShellItems> spesi;
|
CComPtr<IEnumShellItems> spesi;
|
||||||
if (SUCCEEDED(spsia->EnumItems(&spesi)))
|
if (SUCCEEDED(spsia->EnumItems(&spesi)))
|
||||||
|
|||||||
Reference in New Issue
Block a user