@@ -180,6 +180,100 @@ CComPtr<IShellBrowser> GetIShellBrowserRecursive(HWND hWnd) {
180180 return res;
181181}
182182
183+ namespace {
184+ using namespace mb_shell ::js;
185+ using namespace mb_shell ;
186+ void populate_folder_view_context_impl (HWND hWnd,
187+ js_menu_context &event_data,
188+ perf_counter &perf) {
189+ char className[256 ];
190+ if (!GetClassNameA (hWnd, className, sizeof (className))) {
191+ return ;
192+ }
193+
194+ std::string class_name = className;
195+ if (class_name != " SysListView32" && class_name != " DirectUIHWND" &&
196+ class_name != " SHELLDLL_DefView" && class_name != " CabinetWClass" ) {
197+ return ;
198+ }
199+
200+ spdlog::info (" Target window is a folder view (hwnd: {})\n " , (void *)hWnd);
201+
202+ if (CComPtr<IShellBrowser> psb = GetIShellBrowserRecursive (hWnd)) {
203+ perf.end (" IShellBrowser - GetIShellBrowserRecursive" );
204+ spdlog::info (" shell browser: {}\n " , (void *)psb.p );
205+
206+ CComPtr<IShellView> psv;
207+ if (SUCCEEDED (psb->QueryActiveShellView (&psv))) {
208+ CComPtr<IFolderView> pfv;
209+ if (SUCCEEDED (psv->QueryInterface (IID_IFolderView, (void **)&pfv))) {
210+ event_data.folder_view =
211+ std::make_shared<folder_view_controller>();
212+ auto fv = *event_data.folder_view ;
213+ fv->$hwnd = hWnd;
214+ fv->$controller = psb.p ;
215+ fv->$render_target = menu_render::current.value ()->rt .get ();
216+
217+ int focusIndex = -1 ;
218+ if (SUCCEEDED (pfv->GetFocusedItem (&focusIndex)) &&
219+ focusIndex >= 0 ) {
220+ PIDLIST_ABSOLUTE pidl = nullptr ;
221+ if (SUCCEEDED (pfv->Item (focusIndex, &pidl)) && pidl) {
222+ fv->focused_file_path = folder_id_to_path (pidl);
223+ CoTaskMemFree (pidl);
224+ }
225+ }
226+
227+ CComPtr<IShellItem> psi;
228+ if (SUCCEEDED (pfv->GetFolder (IID_IShellItem, (void **)&psi))) {
229+ PWSTR pszPath = nullptr ;
230+ if (SUCCEEDED (
231+ psi->GetDisplayName (SIGDN_FILESYSPATH, &pszPath)) &&
232+ pszPath) {
233+ fv->current_path = mb_shell::wstring_to_utf8 (pszPath);
234+ CoTaskMemFree (pszPath);
235+ }
236+ }
237+
238+ CComPtr<IShellItemArray> psia;
239+ if (SUCCEEDED (pfv->Items (SVGIO_SELECTION, IID_IShellItemArray,
240+ (void **)&psia))) {
241+ DWORD count = 0 ;
242+ if (SUCCEEDED (psia->GetCount (&count))) {
243+ for (DWORD i = 0 ; i < count; i++) {
244+ CComPtr<IShellItem> item;
245+ if (SUCCEEDED (psia->GetItemAt (i, &item))) {
246+ PWSTR pszPath = nullptr ;
247+ if (SUCCEEDED (item->GetDisplayName (
248+ SIGDN_FILESYSPATH, &pszPath)) &&
249+ pszPath) {
250+ fv->selected_files .push_back (
251+ mb_shell::wstring_to_utf8 (pszPath));
252+ CoTaskMemFree (pszPath);
253+ }
254+ }
255+ }
256+ }
257+ }
258+ }
259+ }
260+ } else {
261+ spdlog::info (" Failed to get IShellBrowser" );
262+ }
263+ }
264+
265+ __declspec (noinline) void populate_folder_view_context_seh (
266+ HWND hWnd, mb_shell::js::js_menu_context &event_data,
267+ mb_shell::perf_counter &perf) {
268+ __try {
269+ populate_folder_view_context_impl (hWnd, event_data, perf);
270+ } __except (EXCEPTION_CONTINUE_EXECUTION) {
271+ spdlog::info (" Get IShellBrowser crashed!" );
272+ }
273+ }
274+
275+ } // namespace
276+
183277namespace mb_shell ::js {
184278
185279js_menu_context js_menu_context::$from_window(void *_hwnd) {
@@ -210,106 +304,7 @@ js_menu_context js_menu_context::$from_window(void *_hwnd) {
210304
211305 perf.end (" Edit" );
212306
213- [&]() {
214- __try {
215- [&] {
216- if (GetClassNameA (hWnd, className, sizeof (className))) {
217- std::string class_name = className;
218- if (class_name == " SysListView32" ||
219- class_name == " DirectUIHWND" ||
220- class_name == " SHELLDLL_DefView" ||
221- class_name == " CabinetWClass" ) {
222- spdlog::info (" Target window is a folder view (hwnd: {})\n " ,
223- (void *)hWnd);
224- // Check if the foreground window is an Explorer window
225-
226- if (CComPtr<IShellBrowser> psb =
227- GetIShellBrowserRecursive (hWnd)) {
228- perf.end (
229- " IShellBrowser - GetIShellBrowserRecursive" );
230- spdlog::info (" shell browser: {}\n " , (void *)psb.p );
231-
232- CComPtr<IShellView> psv;
233- if (SUCCEEDED (psb->QueryActiveShellView (&psv))) {
234- CComPtr<IFolderView> pfv;
235- if (SUCCEEDED (psv->QueryInterface (
236- IID_IFolderView, (void **)&pfv))) {
237- // It's an Explorer window
238- event_data.folder_view = std::make_shared<
239- folder_view_controller>();
240- auto fv = *event_data.folder_view ;
241- fv->$hwnd = hWnd;
242- fv->$controller = psb.p ;
243- fv->$render_target =
244- menu_render::current.value ()->rt .get ();
245-
246- int focusIndex = -1 ;
247- if (SUCCEEDED (
248- pfv->GetFocusedItem (&focusIndex)) &&
249- focusIndex >= 0 ) {
250- PIDLIST_ABSOLUTE pidl = nullptr ;
251- if (SUCCEEDED (
252- pfv->Item (focusIndex, &pidl)) &&
253- pidl) {
254- fv->focused_file_path =
255- folder_id_to_path (pidl);
256- CoTaskMemFree (pidl);
257- }
258- }
259-
260- CComPtr<IShellItem> psi;
261- if (SUCCEEDED (pfv->GetFolder (
262- IID_IShellItem, (void **)&psi))) {
263- PWSTR pszPath = nullptr ;
264- if (SUCCEEDED (psi->GetDisplayName (
265- SIGDN_FILESYSPATH, &pszPath)) &&
266- pszPath) {
267- fv->current_path =
268- mb_shell::wstring_to_utf8 (
269- pszPath);
270- CoTaskMemFree (pszPath);
271- }
272- }
273-
274- CComPtr<IShellItemArray> psia;
275- if (SUCCEEDED (
276- pfv->Items (SVGIO_SELECTION,
277- IID_IShellItemArray,
278- (void **)&psia))) {
279- DWORD count = 0 ;
280- if (SUCCEEDED (psia->GetCount (&count))) {
281- for (DWORD i = 0 ; i < count; i++) {
282- CComPtr<IShellItem> item;
283- if (SUCCEEDED (psia->GetItemAt (
284- i, &item))) {
285- PWSTR pszPath = nullptr ;
286- if (SUCCEEDED (
287- item->GetDisplayName (
288- SIGDN_FILESYSPATH,
289- &pszPath)) &&
290- pszPath) {
291- fv->selected_files .push_back (
292- mb_shell::
293- wstring_to_utf8 (
294- pszPath));
295- CoTaskMemFree (pszPath);
296- }
297- }
298- }
299- }
300- }
301- }
302- }
303- } else {
304- spdlog::info (" Failed to get IShellBrowser" );
305- }
306- }
307- }
308- }();
309- } __except (EXCEPTION_CONTINUE_EXECUTION) {
310- spdlog::info (" Get IShellBrowser crashed!" );
311- }
312- }();
307+ populate_folder_view_context_seh (hWnd, event_data, perf);
313308 perf.end (" IShellBrowser" );
314309
315310 if (hWnd) {
0 commit comments