Files
PowerToys/src/modules/NewPlus/NewShellExtensionContextMenu/shell_context_menu.cpp

113 lines
3.4 KiB
C++
Raw Normal View History

#include "pch.h"
#include "shell_context_menu.h"
#include "shell_context_sub_menu.h"
#include "shell_context_sub_menu_item.h"
#include "template_folder.h"
#include "new_utilities.h"
#include "settings.h"
#include "trace.h"
#include "Generated Files/resource.h"
using namespace Microsoft::WRL;
using namespace newplus;
#pragma region IExplorerCommand
IFACEMETHODIMP shell_context_menu::GetTitle(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* returned_title)
{
static const std::wstring localized_context_menu_item =
GET_RESOURCE_STRING_FALLBACK(IDS_CONTEXT_MENU_ITEM_NEW, L"New+");
return SHStrDup(localized_context_menu_item.c_str(), returned_title);
}
IFACEMETHODIMP shell_context_menu::GetIcon(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* returned_icon)
{
*returned_icon = nullptr;
static const auto icon_resource_filepath = utilities::get_new_icon_resource_filepath(module_instance_handle, ThemeHelpers::GetAppTheme());
return SHStrDup(icon_resource_filepath.c_str(), returned_icon);
}
IFACEMETHODIMP shell_context_menu::GetToolTip(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* returned_tool_tip)
{
*returned_tool_tip = nullptr;
return E_NOTIMPL;
}
IFACEMETHODIMP shell_context_menu::GetCanonicalName(_Out_ GUID* returned_id)
{
*returned_id = __uuidof(this);
return S_OK;
}
IFACEMETHODIMP shell_context_menu::GetState(_In_opt_ IShellItemArray*, _In_ BOOL, _Out_ EXPCMDSTATE* returned_state)
{
if (!NewSettingsInstance().GetEnabled())
{
*returned_state = ECS_HIDDEN;
}
else
{
*returned_state = ECS_ENABLED;
}
return S_OK;
}
IFACEMETHODIMP shell_context_menu::Invoke(_In_opt_ IShellItemArray*, _In_opt_ IBindCtx*) noexcept
{
return E_NOTIMPL;
}
IFACEMETHODIMP shell_context_menu::GetFlags(_Out_ EXPCMDFLAGS* returned_menu_item_flags)
{
*returned_menu_item_flags = ECF_HASSUBCOMMANDS;
return S_OK;
}
IFACEMETHODIMP shell_context_menu::EnumSubCommands(_COM_Outptr_ IEnumExplorerCommand** returned_enum_commands)
{
try
{
New+ Rename and Desktop icon positioning improvements (#48083) New+ Rename and Desktop icon positioning improvements. Manually tested on Windows 11. Windows 10 updates have NOT been tested. ## Summary of the Pull Request * Obtain cursor position early in the lifecycle of the context menu * Busy wait until copy is complete and shell is aware of icon * If context menu is on desktop, reposition the icon using the cursor position obtained scaled using monitor appropriate DPI * Slight refactor to help port code from New++ to New+ ## PR Checklist - [x] Closes: #36440 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [n/a] **Localization:** All end-user-facing strings can be localized - [n/a] **Dev docs:** Added/updated - [n/a] **New binaries:** Added on the required places - [n/a] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [n/a] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [n/a] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [n/a] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [n/a] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments * n/a ## Validation Steps Performed **Windows 11** * x64: Manually tested * ARM64: Not tested **Windows 10** * Not tested --------- Co-authored-by: Boliang Zhang (from Dev Box) <bozhang@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 41b6b39b-b620-4e02-b7ca-8ae470a9c1e2
2026-08-11 23:23:48 -07:00
// Get the cursor position as early as possible to get as close to the point where the context menu was
// invoked for Desktop icon placement.
// Capture in per-monitor-DPI-aware context so the stored position is always in physical screen pixels.
POINT cursor_position = { -1, -1 };
const DPI_AWARENESS_CONTEXT prev_dpi_ctx = SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
if (!GetCursorPos(&cursor_position))
{
cursor_position = { -1, -1 };
}
SetThreadDpiAwarenessContext(prev_dpi_ctx);
auto e = Make<shell_context_sub_menu>(site_of_folder, cursor_position);
return e->QueryInterface(IID_PPV_ARGS(returned_enum_commands));
}
catch (const std::exception& ex)
{
Logger::error("New+ create submenu error: {}", ex.what());
return E_FAIL;
}
catch (...)
{
Logger::error("New+ create submenu error");
return E_FAIL;
}
}
#pragma endregion
#pragma region IObjectWithSite
IFACEMETHODIMP shell_context_menu::SetSite(_In_ IUnknown* site) noexcept
{
this->site_of_folder = site;
return S_OK;
}
IFACEMETHODIMP shell_context_menu::GetSite(_In_ REFIID interface_type, _COM_Outptr_ void** returned_site) noexcept
{
return this->site_of_folder.CopyTo(interface_type, returned_site);
}
#pragma endregion