|
15 | 15 | #include <uxtheme.h> |
16 | 16 | #include <map> |
17 | 17 | #include <algorithm> |
| 18 | +#include <thread> |
18 | 19 |
|
19 | 20 | const KNOWNFOLDERID FOLDERID_DesktopRoot={'DESK', 'TO', 'P', {'D', 'E', 'S', 'K', 'T', 'O', 'P', 0x00}}; |
20 | 21 |
|
@@ -1193,7 +1194,7 @@ bool BrowseCommandHelper( HWND parent, wchar_t *text ) |
1193 | 1194 | ofn.lpstrFile=text; |
1194 | 1195 | ofn.nMaxFile=_MAX_PATH; |
1195 | 1196 | ofn.Flags=OFN_DONTADDTORECENT|OFN_ENABLESIZING|OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_NOCHANGEDIR|OFN_NODEREFERENCELINKS; |
1196 | | - if (GetOpenFileName(&ofn)) |
| 1197 | + if (GetOpenFileNameSafe(&ofn)) |
1197 | 1198 | { |
1198 | 1199 | wchar_t buf[_MAX_PATH]; |
1199 | 1200 | UnExpandEnvStrings(text,buf,_countof(buf)); |
@@ -2011,7 +2012,7 @@ LRESULT CBrowseForIconDlg::OnBrowse( WORD wNotifyCode, WORD wID, HWND hWndCtl, B |
2011 | 2012 | CString title=LoadStringEx(IDS_ICON_TITLE); |
2012 | 2013 | ofn.lpstrTitle=title; |
2013 | 2014 | ofn.Flags=OFN_DONTADDTORECENT|OFN_ENABLESIZING|OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_NOCHANGEDIR; |
2014 | | - if (GetOpenFileName(&ofn)) |
| 2015 | + if (GetOpenFileNameSafe(&ofn)) |
2015 | 2016 | { |
2016 | 2017 | wchar_t buf[_MAX_PATH]; |
2017 | 2018 | UnExpandEnvStrings(path,buf,_countof(buf)); |
@@ -2210,7 +2211,7 @@ bool BrowseForBitmap( HWND hWndParent, wchar_t *path, bool bAllowJpeg ) |
2210 | 2211 | CString title=LoadStringEx(IDS_BMP_TITLE); |
2211 | 2212 | ofn.lpstrTitle=title; |
2212 | 2213 | ofn.Flags=OFN_DONTADDTORECENT|OFN_ENABLESIZING|OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_NOCHANGEDIR; |
2213 | | - if (GetOpenFileName(&ofn)) |
| 2214 | + if (GetOpenFileNameSafe(&ofn)) |
2214 | 2215 | { |
2215 | 2216 | wchar_t buf[_MAX_PATH]; |
2216 | 2217 | UnExpandEnvStrings(path,buf,_countof(buf)); |
@@ -2242,7 +2243,7 @@ bool BrowseForSound( HWND hWndParent, wchar_t *path ) |
2242 | 2243 | CString title=LoadStringEx(IDS_WAV_TITLE); |
2243 | 2244 | ofn.lpstrTitle=title; |
2244 | 2245 | ofn.Flags=OFN_DONTADDTORECENT|OFN_ENABLESIZING|OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_NOCHANGEDIR; |
2245 | | - if (GetOpenFileName(&ofn)) |
| 2246 | + if (GetOpenFileNameSafe(&ofn)) |
2246 | 2247 | { |
2247 | 2248 | wchar_t buf[_MAX_PATH]; |
2248 | 2249 | UnExpandEnvStrings(path,buf,_countof(buf)); |
@@ -3630,3 +3631,49 @@ DWORD ParseColor(const wchar_t* str) |
3630 | 3631 | wchar_t* end; |
3631 | 3632 | return wcstoul(str, &end, 16) & 0xFFFFFF; |
3632 | 3633 | } |
| 3634 | + |
| 3635 | +// Run GetOpenFileName/GetSaveFileName on a separate STA thread and pump messages on the caller |
| 3636 | +template <typename auto Fnc> |
| 3637 | +static BOOL GetFileNameSafe(OPENFILENAME* pOfn) |
| 3638 | +{ |
| 3639 | + BOOL result = FALSE; |
| 3640 | + |
| 3641 | + std::thread worker([&pOfn, &result]() mutable { |
| 3642 | + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); |
| 3643 | + result = Fnc(pOfn); |
| 3644 | + CoUninitialize(); |
| 3645 | + }); |
| 3646 | + |
| 3647 | + // Pump messages while waiting for the worker (dialog) to finish |
| 3648 | + while (true) |
| 3649 | + { |
| 3650 | + HANDLE hWorker = worker.native_handle(); |
| 3651 | + if (MsgWaitForMultipleObjects(1, &hWorker, FALSE, INFINITE, QS_ALLINPUT) == WAIT_OBJECT_0) |
| 3652 | + break; |
| 3653 | + |
| 3654 | + MSG msg; |
| 3655 | + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) |
| 3656 | + { |
| 3657 | + if (msg.message == WM_QUIT) |
| 3658 | + { |
| 3659 | + PostQuitMessage((int)msg.wParam); |
| 3660 | + break; |
| 3661 | + } |
| 3662 | + TranslateMessage(&msg); |
| 3663 | + DispatchMessage(&msg); |
| 3664 | + } |
| 3665 | + } |
| 3666 | + worker.join(); |
| 3667 | + |
| 3668 | + return result; |
| 3669 | +} |
| 3670 | + |
| 3671 | +BOOL GetOpenFileNameSafe(OPENFILENAME* pOfn) |
| 3672 | +{ |
| 3673 | + return GetFileNameSafe<GetOpenFileNameW>(pOfn); |
| 3674 | +} |
| 3675 | + |
| 3676 | +BOOL GetSaveFileNameSafe(OPENFILENAME* pOfn) |
| 3677 | +{ |
| 3678 | + return GetFileNameSafe<GetSaveFileNameW>(pOfn); |
| 3679 | +} |
0 commit comments