Win10 refactored-light
This commit is contained in:
Родитель
4bfec5c767
Коммит
64e81d801c
|
@ -32,7 +32,7 @@ IFACEMETHODIMP shell_context_menu_win10::Initialize(PCIDLIST_ABSOLUTE, IDataObje
|
|||
IFACEMETHODIMP shell_context_menu_win10::QueryContextMenu(HMENU menu_handle, UINT menu_index, UINT menu_first_cmd_id, UINT, UINT menu_flags)
|
||||
{
|
||||
if (!NewSettingsInstance().GetEnabled()
|
||||
|| package::IsWin11OrGreater()
|
||||
|| package::IsWin11OrGreater()
|
||||
)
|
||||
{
|
||||
return E_FAIL;
|
||||
|
@ -43,107 +43,105 @@ IFACEMETHODIMP shell_context_menu_win10::QueryContextMenu(HMENU menu_handle, UIN
|
|||
return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0);
|
||||
}
|
||||
|
||||
trace.UpdateState(true);
|
||||
Trace trace_on;
|
||||
|
||||
const auto icon_x = GetSystemMetrics(SM_CXSMICON);
|
||||
const auto icon_y = GetSystemMetrics(SM_CYSMICON);
|
||||
|
||||
// Create the initial context popup menu containing the list of templates and open templates action
|
||||
HMENU sub_menu_of_templates = CreatePopupMenu();
|
||||
int menu_id = menu_first_cmd_id;
|
||||
int sub_menu_index = 0;
|
||||
|
||||
// Create the New+ menu item and point to the initial context popup menu
|
||||
static const std::wstring localized_context_menu_item =
|
||||
GET_RESOURCE_STRING_FALLBACK(IDS_CONTEXT_MENU_ITEM_NEW, L"New+");
|
||||
wchar_t newplus_menu_name[20] = { 0 };
|
||||
wcscpy_s(newplus_menu_name, ARRAYSIZE(newplus_menu_name), localized_context_menu_item.c_str());
|
||||
MENUITEMINFO newplus_menu_item;
|
||||
newplus_menu_item.cbSize = sizeof(MENUITEMINFO);
|
||||
newplus_menu_item.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_SUBMENU;
|
||||
newplus_menu_item.wID = menu_id;
|
||||
newplus_menu_item.fType = MFT_STRING;
|
||||
newplus_menu_item.dwTypeData = (PWSTR)newplus_menu_name;
|
||||
newplus_menu_item.hSubMenu = sub_menu_of_templates;
|
||||
const auto newplus_icon_index = 0;
|
||||
|
||||
if (bitmap_handles.size() == 0)
|
||||
try
|
||||
{
|
||||
const std::wstring icon_file = utilities::get_new_icon_resource_filepath(
|
||||
module_instance_handle, ThemeHelpers::GetAppTheme()).c_str();
|
||||
HICON local_icon_handle = static_cast<HICON>(
|
||||
LoadImage(NULL, icon_file.c_str(), IMAGE_ICON, icon_x, icon_y, LR_LOADFROMFILE));
|
||||
// Create the initial context popup menu containing the list of templates and open templates action
|
||||
int menu_id = menu_first_cmd_id;
|
||||
MENUITEMINFO newplus_main_context_menu_item;
|
||||
HMENU sub_menu_of_templates = CreatePopupMenu();
|
||||
int sub_menu_index = 0;
|
||||
|
||||
if (local_icon_handle)
|
||||
// Determine the New+ Template folder location
|
||||
const std::filesystem::path template_folder_root = utilities::get_new_template_folder_location();
|
||||
|
||||
// Create the New+ Template folder location if it doesn't exist (very rare scenario)
|
||||
utilities::create_folder_if_not_exist(template_folder_root);
|
||||
|
||||
// Scan the folder for any files and folders (the templates)
|
||||
templates = new template_folder(template_folder_root);
|
||||
templates->rescan_template_folder();
|
||||
const auto number_of_templates = templates->list_of_templates.size();
|
||||
|
||||
// Create the New+ menu item and point to the initial context popup menu
|
||||
static const std::wstring localized_context_menu_item =
|
||||
GET_RESOURCE_STRING_FALLBACK(IDS_CONTEXT_MENU_ITEM_NEW, L"New+");
|
||||
wchar_t newplus_menu_name[20] = { 0 };
|
||||
wcscpy_s(newplus_menu_name, ARRAYSIZE(newplus_menu_name), localized_context_menu_item.c_str());
|
||||
newplus_main_context_menu_item.cbSize = sizeof(MENUITEMINFOW);
|
||||
newplus_main_context_menu_item.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_SUBMENU;
|
||||
newplus_main_context_menu_item.wID = menu_id;
|
||||
newplus_main_context_menu_item.fType = MFT_STRING;
|
||||
newplus_main_context_menu_item.dwTypeData = (PWSTR)newplus_menu_name;
|
||||
newplus_main_context_menu_item.hSubMenu = sub_menu_of_templates;
|
||||
const auto newplus_icon_index = 0;
|
||||
|
||||
if (bitmap_handles.size() == 0)
|
||||
{
|
||||
bitmap_handles.push_back(CreateBitmapFromIcon(local_icon_handle));
|
||||
DestroyIcon(local_icon_handle);
|
||||
}
|
||||
}
|
||||
if (bitmap_handles.size() > newplus_icon_index && bitmap_handles[newplus_icon_index])
|
||||
{
|
||||
newplus_menu_item.fMask |= MIIM_BITMAP;
|
||||
newplus_menu_item.hbmpItem = bitmap_handles[newplus_icon_index];
|
||||
}
|
||||
const std::wstring icon_file = utilities::get_new_icon_resource_filepath(
|
||||
module_instance_handle, ThemeHelpers::GetAppTheme())
|
||||
.c_str();
|
||||
HICON local_icon_handle = static_cast<HICON>(
|
||||
LoadImage(NULL, icon_file.c_str(), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_LOADFROMFILE));
|
||||
|
||||
menu_id++;
|
||||
|
||||
// Determine the New+ Template folder location
|
||||
const std::filesystem::path template_folder_root = utilities::get_new_template_folder_location();
|
||||
|
||||
// Create the New+ Template folder location if it doesn't exist (very rare scenario)
|
||||
utilities::create_folder_if_not_exist(template_folder_root);
|
||||
|
||||
// Scan the folder for any files and folders (the templates)
|
||||
templates = new template_folder(template_folder_root);
|
||||
templates->rescan_template_folder();
|
||||
|
||||
// Add template items to context menu
|
||||
const auto number_of_templates = templates->list_of_templates.size();
|
||||
int index = 0;
|
||||
for (; index < number_of_templates; index++)
|
||||
{
|
||||
const auto template_item = templates->get_template_item(index);
|
||||
wchar_t menu_name[256] = { 0 };
|
||||
wcscpy_s(menu_name, ARRAYSIZE(menu_name), template_item->get_menu_title(
|
||||
!utilities::get_newplus_setting_hide_extension(),
|
||||
!utilities::get_newplus_setting_hide_starting_digits()).c_str());
|
||||
MENUITEMINFO newplus_menu_item_template;
|
||||
newplus_menu_item_template.cbSize = sizeof(MENUITEMINFO);
|
||||
newplus_menu_item_template.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_DATA;
|
||||
newplus_menu_item_template.wID = menu_id;
|
||||
newplus_menu_item_template.fType = MFT_STRING;
|
||||
newplus_menu_item_template.dwTypeData = (PWSTR)menu_name;
|
||||
const auto current_template_icon_index = index + 1;
|
||||
if (bitmap_handles.size() <= current_template_icon_index)
|
||||
{
|
||||
HICON template_icon_handle = template_item->get_explorer_icon_handle();
|
||||
if (template_icon_handle)
|
||||
if (local_icon_handle)
|
||||
{
|
||||
bitmap_handles.push_back(CreateBitmapFromIcon(template_icon_handle));
|
||||
DestroyIcon(template_icon_handle);
|
||||
bitmap_handles.push_back(CreateBitmapFromIcon(local_icon_handle));
|
||||
DestroyIcon(local_icon_handle);
|
||||
}
|
||||
}
|
||||
if (bitmap_handles.size() > current_template_icon_index && bitmap_handles[current_template_icon_index])
|
||||
if (bitmap_handles.size() > newplus_icon_index && bitmap_handles[newplus_icon_index])
|
||||
{
|
||||
newplus_menu_item_template.fMask |= MIIM_BITMAP;
|
||||
newplus_menu_item_template.hbmpItem = bitmap_handles[current_template_icon_index];
|
||||
newplus_main_context_menu_item.fMask |= MIIM_BITMAP;
|
||||
newplus_main_context_menu_item.hbmpItem = bitmap_handles[newplus_icon_index];
|
||||
}
|
||||
|
||||
InsertMenuItem(sub_menu_of_templates, sub_menu_index, TRUE, &newplus_menu_item_template);
|
||||
menu_id++;
|
||||
|
||||
// Add template items to context menu
|
||||
int index = 0;
|
||||
for (; index < number_of_templates; index++)
|
||||
{
|
||||
const auto template_item = templates->get_template_item(index);
|
||||
add_template_item_to_context_menu(sub_menu_of_templates, sub_menu_index, template_item, menu_id, index);
|
||||
menu_id++;
|
||||
sub_menu_index++;
|
||||
}
|
||||
|
||||
// Add separator to context menu
|
||||
add_separator_to_context_menu(sub_menu_of_templates, sub_menu_index);
|
||||
sub_menu_index++;
|
||||
|
||||
// Add "Open templates" item to context menu
|
||||
add_open_templates_to_context_menu(sub_menu_of_templates, sub_menu_index, template_folder_root, menu_id, index);
|
||||
menu_id++;
|
||||
|
||||
if (!InsertMenuItem(menu_handle, menu_index, TRUE, &newplus_main_context_menu_item))
|
||||
{
|
||||
Logger::error(L"QueryContextMenu() failed. {}", get_last_error_or_default(GetLastError()));
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Log that context menu was shown and with how many items
|
||||
Trace::EventShowTemplateItems(number_of_templates);
|
||||
|
||||
// Return the amount if entries inserted
|
||||
const auto number_of_items_inserted = menu_id - menu_first_cmd_id;
|
||||
return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, number_of_items_inserted);
|
||||
}
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
Logger::error(ex.what());
|
||||
}
|
||||
|
||||
// Add separator to context menu
|
||||
MENUITEMINFO menu_item_separator;
|
||||
menu_item_separator.cbSize = sizeof(MENUITEMINFO);
|
||||
menu_item_separator.fMask = MIIM_FTYPE;
|
||||
menu_item_separator.fType = MFT_SEPARATOR;
|
||||
InsertMenuItem(sub_menu_of_templates, sub_menu_index, TRUE, &menu_item_separator);
|
||||
sub_menu_index++;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Add "Open templates" item to context menu
|
||||
void shell_context_menu_win10::add_open_templates_to_context_menu(HMENU sub_menu_of_templates, int sub_menu_index, const std::filesystem::path& template_folder_root, int menu_id, int index)
|
||||
{
|
||||
static const std::wstring localized_context_menu_item_open_templates =
|
||||
GET_RESOURCE_STRING_FALLBACK(IDS_CONTEXT_MENU_ITEM_OPEN_TEMPLATES, L"Open templates");
|
||||
wchar_t menu_name_open[256] = { 0 };
|
||||
|
@ -160,9 +158,10 @@ IFACEMETHODIMP shell_context_menu_win10::QueryContextMenu(HMENU menu_handle, UIN
|
|||
if (bitmap_handles.size() <= open_templates_icon_index)
|
||||
{
|
||||
const std::wstring icon_file = utilities::get_open_templates_icon_resource_filepath(
|
||||
module_instance_handle, ThemeHelpers::GetAppTheme()).c_str();
|
||||
module_instance_handle, ThemeHelpers::GetAppTheme())
|
||||
.c_str();
|
||||
HICON open_template_icon_handle = static_cast<HICON>(
|
||||
LoadImage(NULL, icon_file.c_str(), IMAGE_ICON, icon_x, icon_y, LR_LOADFROMFILE));
|
||||
LoadImage(NULL, icon_file.c_str(), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_LOADFROMFILE));
|
||||
if (open_template_icon_handle)
|
||||
{
|
||||
bitmap_handles.push_back(CreateBitmapFromIcon(open_template_icon_handle));
|
||||
|
@ -176,24 +175,44 @@ IFACEMETHODIMP shell_context_menu_win10::QueryContextMenu(HMENU menu_handle, UIN
|
|||
}
|
||||
|
||||
InsertMenuItem(sub_menu_of_templates, sub_menu_index, TRUE, &newplus_menu_item_open_templates);
|
||||
menu_id++;
|
||||
}
|
||||
|
||||
// Log that context menu was shown and with how many items
|
||||
Trace::EventShowTemplateItems(number_of_templates);
|
||||
void shell_context_menu_win10::add_separator_to_context_menu(HMENU sub_menu_of_templates, int sub_menu_index)
|
||||
{
|
||||
MENUITEMINFO menu_item_separator;
|
||||
menu_item_separator.cbSize = sizeof(MENUITEMINFO);
|
||||
menu_item_separator.fMask = MIIM_FTYPE;
|
||||
menu_item_separator.fType = MFT_SEPARATOR;
|
||||
InsertMenuItem(sub_menu_of_templates, sub_menu_index, TRUE, &menu_item_separator);
|
||||
}
|
||||
|
||||
trace.Flush();
|
||||
trace.UpdateState(false);
|
||||
|
||||
if (!InsertMenuItem(menu_handle, menu_index, TRUE, &newplus_menu_item))
|
||||
void shell_context_menu_win10::add_template_item_to_context_menu(HMENU sub_menu_of_templates, int sub_menu_index, newplus::template_item* const template_item, int menu_id, int index)
|
||||
{
|
||||
wchar_t menu_name[256] = { 0 };
|
||||
wcscpy_s(menu_name, ARRAYSIZE(menu_name), template_item->get_menu_title(!utilities::get_newplus_setting_hide_extension(), !utilities::get_newplus_setting_hide_starting_digits()).c_str());
|
||||
MENUITEMINFO newplus_menu_item_template;
|
||||
newplus_menu_item_template.cbSize = sizeof(MENUITEMINFO);
|
||||
newplus_menu_item_template.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_DATA;
|
||||
newplus_menu_item_template.wID = menu_id;
|
||||
newplus_menu_item_template.fType = MFT_STRING;
|
||||
newplus_menu_item_template.dwTypeData = (PWSTR)menu_name;
|
||||
const auto current_template_icon_index = index + 1;
|
||||
if (bitmap_handles.size() <= current_template_icon_index)
|
||||
{
|
||||
Logger::error(L"QueryContextMenu() failed. {}", get_last_error_or_default(GetLastError()));
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
HICON template_icon_handle = template_item->get_explorer_icon_handle();
|
||||
if (template_icon_handle)
|
||||
{
|
||||
bitmap_handles.push_back(CreateBitmapFromIcon(template_icon_handle));
|
||||
DestroyIcon(template_icon_handle);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (bitmap_handles.size() > current_template_icon_index && bitmap_handles[current_template_icon_index])
|
||||
{
|
||||
const auto number_of_items_inserted = menu_id - menu_first_cmd_id;
|
||||
return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, number_of_items_inserted);
|
||||
newplus_menu_item_template.fMask |= MIIM_BITMAP;
|
||||
newplus_menu_item_template.hbmpItem = bitmap_handles[current_template_icon_index];
|
||||
}
|
||||
|
||||
InsertMenuItem(sub_menu_of_templates, sub_menu_index, TRUE, &newplus_menu_item_template);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP shell_context_menu_win10::InvokeCommand(CMINVOKECOMMANDINFO* params)
|
||||
|
@ -203,13 +222,13 @@ IFACEMETHODIMP shell_context_menu_win10::InvokeCommand(CMINVOKECOMMANDINFO* para
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Get selected menu item (a template or the "Open templates" item)
|
||||
const auto selected_menu_item_index = LOWORD(params->lpVerb) - 1;
|
||||
if (selected_menu_item_index < 0)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
const auto number_of_templates = templates->list_of_templates.size();
|
||||
const bool is_template_item = selected_menu_item_index < number_of_templates;
|
||||
|
||||
|
@ -218,63 +237,17 @@ IFACEMETHODIMP shell_context_menu_win10::InvokeCommand(CMINVOKECOMMANDINFO* para
|
|||
// It's a template menu item
|
||||
const auto template_entry = templates->get_template_item(selected_menu_item_index);
|
||||
|
||||
try
|
||||
{
|
||||
trace.UpdateState(true);
|
||||
|
||||
Logger::info(L"Copying template");
|
||||
|
||||
// Determine target path of where context menu was displayed
|
||||
const auto target_path_name = utilities::get_path_from_unknown_site(site_of_folder);
|
||||
|
||||
// Determine initial filename
|
||||
std::filesystem::path source_fullpath = template_entry->path;
|
||||
std::filesystem::path target_fullpath = std::wstring(target_path_name);
|
||||
|
||||
// Only append name to target if source is not a directory
|
||||
if (!utilities::is_directory(source_fullpath))
|
||||
{
|
||||
target_fullpath.append(template_entry->get_target_filename(
|
||||
!utilities::get_newplus_setting_hide_starting_digits()));
|
||||
}
|
||||
|
||||
// Copy file and determine final filename
|
||||
std::filesystem::path target_final_fullpath = template_entry->copy_object_to(
|
||||
GetActiveWindow(), target_fullpath);
|
||||
|
||||
Trace::EventCopyTemplate(target_final_fullpath.extension().c_str());
|
||||
|
||||
// Refresh folder item
|
||||
template_entry->refresh_target(target_final_fullpath);
|
||||
|
||||
// Enter rename mode
|
||||
template_entry->enter_rename_mode(target_final_fullpath);
|
||||
|
||||
Trace::EventCopyTemplateResult(S_OK);
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
Trace::EventCopyTemplateResult(S_FALSE);
|
||||
Logger::error(ex.what());
|
||||
|
||||
hr = S_FALSE;
|
||||
}
|
||||
return newplus::utilities::copy_template(template_entry, site_of_folder);
|
||||
}
|
||||
else
|
||||
{
|
||||
// It's the "Open templates" menu item
|
||||
Logger::info(L"Opening templates folder");
|
||||
const std::filesystem::path template_folder_root = utilities::get_new_template_folder_location();
|
||||
const std::wstring verb_hardcoded_do_not_change = L"open";
|
||||
ShellExecute(nullptr, verb_hardcoded_do_not_change.c_str(), template_folder_root.c_str(), NULL, NULL, SW_SHOWNORMAL);
|
||||
|
||||
Trace::EventOpenTemplates();
|
||||
return newplus::utilities::open_template_folder(template_folder_root);
|
||||
}
|
||||
|
||||
trace.Flush();
|
||||
trace.UpdateState(false);
|
||||
|
||||
return hr;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP shell_context_menu_win10::GetCommandString(UINT_PTR, UINT, UINT*, CHAR*, UINT)
|
||||
|
|
|
@ -34,6 +34,10 @@ public:
|
|||
#pragma endregion
|
||||
|
||||
protected:
|
||||
void add_open_templates_to_context_menu(HMENU sub_menu_of_templates, int sub_menu_index, const std::filesystem::path& template_folder_root, int menu_id, int index);
|
||||
void add_separator_to_context_menu(HMENU sub_menu_of_templates, int sub_menu_index);
|
||||
void add_template_item_to_context_menu(HMENU sub_menu_of_templates, int sub_menu_index, newplus::template_item* const template_item, int menu_id, int index);
|
||||
|
||||
HINSTANCE instance_handle = 0;
|
||||
ComPtr<IUnknown> site_of_folder;
|
||||
newplus::template_folder* templates = nullptr;
|
||||
|
|
|
@ -7,9 +7,13 @@
|
|||
|
||||
#include "constants.h"
|
||||
#include "settings.h"
|
||||
#include "template_item.h"
|
||||
#include "trace.h"
|
||||
|
||||
#pragma comment(lib, "Shlwapi.lib")
|
||||
|
||||
using namespace newplus;
|
||||
|
||||
namespace newplus::utilities
|
||||
{
|
||||
|
||||
|
@ -217,7 +221,6 @@ namespace newplus::utilities
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
inline void explorer_enter_rename_mode(const std::filesystem::path target_fullpath_of_new_instance)
|
||||
{
|
||||
const std::filesystem::path path_without_new_file_or_dir = target_fullpath_of_new_instance.parent_path();
|
||||
|
@ -296,26 +299,116 @@ namespace newplus::utilities
|
|||
shell_view.As(&folder_view);
|
||||
|
||||
// Find the newly created object (file or folder)
|
||||
// And put into edit mode (SVSI_EDIT)
|
||||
// And put object into edit mode (SVSI_EDIT) and if desktop also reposition
|
||||
int number_of_objects_in_view = 0;
|
||||
bool done = false;
|
||||
folder_view->ItemCount(SVGIO_ALLVIEW, &number_of_objects_in_view);
|
||||
for (int i = 0; i < number_of_objects_in_view; ++i)
|
||||
for (int i = 0; i < number_of_objects_in_view && !done; ++i)
|
||||
{
|
||||
std::wstring path_of_item(MAX_PATH, 0);
|
||||
LPITEMIDLIST shell_item_ids;
|
||||
|
||||
folder_view->Item(i, &shell_item_ids);
|
||||
SHGetPathFromIDList(shell_item_ids, &path_of_item[0]);
|
||||
CoTaskMemFree(shell_item_ids);
|
||||
|
||||
std::wstring current_filename = std::filesystem::path(path_of_item.c_str()).filename();
|
||||
const std::wstring current_filename = std::filesystem::path(path_of_item.c_str()).filename();
|
||||
|
||||
//if (utilities::wstring_same_when_comparing_ignore_case(filename, current_filename))
|
||||
if (StrCmpIW(new_file_or_dir_without_path.c_str(), current_filename.c_str()) == 0)
|
||||
if (utilities::wstring_same_when_comparing_ignore_case(new_file_or_dir_without_path, current_filename))
|
||||
{
|
||||
folder_view->SelectItem(i, SVSI_EDIT | SVSI_SELECT | SVSI_DESELECTOTHERS | SVSI_ENSUREVISIBLE | SVSI_FOCUSED);
|
||||
break;
|
||||
const DWORD common_select_flags = SVSI_EDIT | SVSI_SELECT | SVSI_DESELECTOTHERS | SVSI_ENSUREVISIBLE | SVSI_FOCUSED;
|
||||
|
||||
if (object_created_on_desktop)
|
||||
{
|
||||
// Newly created object is on the desktop -- reposition under mouse and enter rename mode
|
||||
LPCITEMIDLIST shell_item_to_select_and_position[] = { shell_item_ids };
|
||||
POINT mouse_position;
|
||||
GetCursorPos(&mouse_position);
|
||||
mouse_position.x -= GetSystemMetrics(SM_CXMENUSIZE);
|
||||
mouse_position.x = max(mouse_position.x, 20);
|
||||
mouse_position.y -= GetSystemMetrics(SM_CXMENUSIZE)/2;
|
||||
mouse_position.y = max(mouse_position.y, 20);
|
||||
POINT position[] = { mouse_position };
|
||||
folder_view->SelectAndPositionItems(1, shell_item_to_select_and_position, position, common_select_flags | SVSI_POSITIONITEM);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Enter rename mode
|
||||
folder_view->SelectItem(i, common_select_flags);
|
||||
}
|
||||
done = true;
|
||||
}
|
||||
CoTaskMemFree(shell_item_ids);
|
||||
}
|
||||
}
|
||||
|
||||
inline HRESULT copy_template(const template_item* template_entry, const ComPtr<IUnknown> site_of_folder)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
Trace trace_on;
|
||||
|
||||
try
|
||||
{
|
||||
Logger::info(L"Copying template");
|
||||
|
||||
// Determine target path of where context menu was displayed
|
||||
const auto target_path_name = utilities::get_path_from_unknown_site(site_of_folder);
|
||||
|
||||
// Determine initial filename
|
||||
std::filesystem::path source_fullpath = template_entry->path;
|
||||
std::filesystem::path target_fullpath = std::wstring(target_path_name);
|
||||
|
||||
// Only append name to target if source is not a directory
|
||||
if (!utilities::is_directory(source_fullpath))
|
||||
{
|
||||
target_fullpath.append(template_entry->get_target_filename(!utilities::get_newplus_setting_hide_starting_digits()));
|
||||
}
|
||||
|
||||
// Copy file and determine final filename
|
||||
std::filesystem::path target_final_fullpath = template_entry->copy_object_to(GetActiveWindow(), target_fullpath);
|
||||
|
||||
Trace::EventCopyTemplate(target_final_fullpath.extension().c_str());
|
||||
|
||||
// Refresh folder items
|
||||
template_entry->refresh_target(target_final_fullpath);
|
||||
|
||||
// Enter rename mode
|
||||
template_entry->enter_rename_mode(target_final_fullpath);
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
Logger::error(ex.what());
|
||||
|
||||
hr = S_FALSE;
|
||||
}
|
||||
|
||||
Trace::EventCopyTemplateResult(hr);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
inline HRESULT open_template_folder(const std::filesystem::path template_folder)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
Trace trace_on;
|
||||
|
||||
try
|
||||
{
|
||||
Logger::info(L"Open templates folder");
|
||||
|
||||
const std::wstring verb_hardcoded_do_not_change = L"open";
|
||||
ShellExecute(nullptr, verb_hardcoded_do_not_change.c_str(), template_folder.c_str(), NULL, NULL, SW_SHOWNORMAL);
|
||||
|
||||
Trace::EventOpenTemplates();
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
Logger::error(ex.what());
|
||||
|
||||
hr = S_FALSE;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,49 +63,7 @@ IFACEMETHODIMP shell_context_sub_menu_item::GetState(_In_opt_ IShellItemArray* s
|
|||
|
||||
IFACEMETHODIMP shell_context_sub_menu_item::Invoke(_In_opt_ IShellItemArray*, _In_opt_ IBindCtx*) noexcept
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
try
|
||||
{
|
||||
trace.UpdateState(true);
|
||||
|
||||
// Determine target path of where context menu was displayed
|
||||
const auto target_path_name = utilities::get_path_from_unknown_site(site_of_folder);
|
||||
|
||||
// Determine initial filename
|
||||
std::filesystem::path source_fullpath = template_entry->path;
|
||||
std::filesystem::path target_fullpath = std::wstring(target_path_name);
|
||||
|
||||
// Only append name to target if source is not a directory
|
||||
if (!utilities::is_directory(source_fullpath))
|
||||
{
|
||||
target_fullpath.append(template_entry->get_target_filename(!utilities::get_newplus_setting_hide_starting_digits()));
|
||||
}
|
||||
|
||||
// Copy file and determine final filename
|
||||
std::filesystem::path target_final_fullpath = template_entry->copy_object_to(GetActiveWindow(), target_fullpath);
|
||||
|
||||
Trace::EventCopyTemplate(target_final_fullpath.extension().c_str());
|
||||
|
||||
// Refresh folder items
|
||||
template_entry->refresh_target(target_final_fullpath);
|
||||
|
||||
// Enter rename mode
|
||||
template_entry->enter_rename_mode(target_final_fullpath);
|
||||
|
||||
Trace::EventCopyTemplateResult(S_OK);
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
Trace::EventCopyTemplateResult(S_FALSE);
|
||||
Logger::error(ex.what());
|
||||
|
||||
hr = S_FALSE;
|
||||
}
|
||||
|
||||
trace.Flush();
|
||||
trace.UpdateState(false);
|
||||
|
||||
return hr;
|
||||
return newplus::utilities::copy_template(template_entry, site_of_folder);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP shell_context_sub_menu_item::GetFlags(_Out_ EXPCMDFLAGS* returned_flags)
|
||||
|
@ -162,9 +120,5 @@ IFACEMETHODIMP template_folder_context_menu_item::GetIcon(_In_opt_ IShellItemArr
|
|||
|
||||
IFACEMETHODIMP template_folder_context_menu_item::Invoke(_In_opt_ IShellItemArray* selection, _In_opt_ IBindCtx*) noexcept
|
||||
{
|
||||
Logger::info(L"Open templates folder");
|
||||
const std::wstring verb_hardcoded_do_not_change = L"open";
|
||||
ShellExecute(nullptr, verb_hardcoded_do_not_change.c_str(), shell_template_folder.c_str(), NULL, NULL, SW_SHOWNORMAL);
|
||||
|
||||
return S_OK;
|
||||
return newplus::utilities::open_template_folder(shell_template_folder);
|
||||
}
|
||||
|
|
|
@ -131,8 +131,8 @@ void template_item::enter_rename_mode(const std::filesystem::path target_fullpat
|
|||
void template_item::rename_on_other_thread_workaround(const std::filesystem::path target_fullpath)
|
||||
{
|
||||
// Have been unable to have Windows Explorer Shell enter rename mode from the main thread
|
||||
// Sleep for a bit to only enter rename mode when icon has been drawn. Not strictly needed.
|
||||
const std::chrono::milliseconds approx_wait_for_icon_redraw_not_needed{ 250 };
|
||||
// Sleep for a bit to only enter rename mode when icon has been drawn.
|
||||
const std::chrono::milliseconds approx_wait_for_icon_redraw_not_needed{ 50 };
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(approx_wait_for_icon_redraw_not_needed));
|
||||
|
||||
newplus::utilities::explorer_enter_rename_mode(target_fullpath);
|
||||
|
|
|
@ -10,6 +10,16 @@ TRACELOGGING_DEFINE_PROVIDER(
|
|||
(0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74),
|
||||
TraceLoggingOptionProjectTelemetry());
|
||||
|
||||
Trace::Trace()
|
||||
{
|
||||
trace.UpdateState(true);
|
||||
}
|
||||
Trace::~Trace()
|
||||
{
|
||||
trace.Flush();
|
||||
trace.UpdateState(false);
|
||||
}
|
||||
|
||||
void Trace::EventToggleOnOff(_In_ const bool enabled) noexcept
|
||||
{
|
||||
TraceLoggingWriteWrapper(
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
class Trace : public telemetry::TraceBase
|
||||
{
|
||||
public:
|
||||
Trace();
|
||||
~Trace();
|
||||
static void EventToggleOnOff(_In_ const bool new_enabled_state) noexcept;
|
||||
static void EventChangedTemplateLocation() noexcept;
|
||||
static void EventShowTemplateItems(_In_ const size_t number_of_templates) noexcept;
|
||||
|
|
Загрузка…
Ссылка в новой задаче