mirror of
https://github.com/Open-Shell/Open-Shell-Menu.git
synced 2026-08-09 09:31:13 +10:00
Fix "Open file location" getting stuck after Windows 11 update
We will run InvokeCommand API on separate STA thread and pump messages while waiting for them to finish. Fixes #2303 Fixes #2321 Fixes #2375
This commit is contained in:
@@ -24,6 +24,52 @@
|
|||||||
#include <propvarutil.h>
|
#include <propvarutil.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <propkey.h>
|
#include <propkey.h>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
// Execute function on a separate STA thread while pumping messages on caller thread.
|
||||||
|
template <typename TFunc>
|
||||||
|
static auto ExecuteOnSTAThread(TFunc&& func) -> decltype(func())
|
||||||
|
{
|
||||||
|
using ReturnType = decltype(func());
|
||||||
|
ReturnType result{};
|
||||||
|
|
||||||
|
std::thread worker([&func, &result]() mutable {
|
||||||
|
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||||
|
result = func();
|
||||||
|
CoUninitialize();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Pump messages while waiting for the worker (dialog) to finish
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
HANDLE hWorker = worker.native_handle();
|
||||||
|
if (MsgWaitForMultipleObjects(1, &hWorker, FALSE, INFINITE, QS_ALLINPUT) == WAIT_OBJECT_0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
MSG msg;
|
||||||
|
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||||
|
{
|
||||||
|
if (msg.message == WM_QUIT)
|
||||||
|
{
|
||||||
|
PostQuitMessage((int)msg.wParam);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
worker.join();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrapper for IContextMenu::InvokeCommand that runs on separate STA thread and pumps messages
|
||||||
|
static HRESULT InvokeCommandSafe(IContextMenu* pMenu, LPCMINVOKECOMMANDINFO pInfo)
|
||||||
|
{
|
||||||
|
return ExecuteOnSTAThread([&]() {
|
||||||
|
return pMenu->InvokeCommand(pInfo);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static CString g_RenameText;
|
static CString g_RenameText;
|
||||||
static POINT g_RenamePos;
|
static POINT g_RenamePos;
|
||||||
@@ -3113,7 +3159,7 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HRESULT hr=pInvokeMenu->InvokeCommand((LPCMINVOKECOMMANDINFO)&info);
|
HRESULT hr=InvokeCommandSafe(pInvokeMenu,(LPCMINVOKECOMMANDINFO)&info);
|
||||||
LOG_MENU(LOG_EXECUTE,L"Invoke command, ptr=%p, res=%d",this,hr);
|
LOG_MENU(LOG_EXECUTE,L"Invoke command, ptr=%p, res=%d",this,hr);
|
||||||
executeSuccess=SUCCEEDED(hr);
|
executeSuccess=SUCCEEDED(hr);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user