Author: gadamopoulos Date: Sat Nov 5 14:40:55 2016 New Revision: 73132
URL: http://svn.reactos.org/svn/reactos?rev=73132&view=rev Log: [BROWSEUI] - CShellBrowser: Add some checks for failures that we re missing. - CAddressEditBox: Add some checks for failures that we re missing. - SHCreateFromDesktop: Actually create the proxy desktop window when needed and keep its handle and prefer it when we try to find the proxy desktop window. - Wake the message queue of the proxy desktop after a browser thread exits so the proxy desktop can exit when the last browser thread exits. - Add a hack to prefer to show my documents if we ended up trying to open a browser window with a NULL pidl. This is a hack that is needed because SHExplorerParseCmdLine is broken. - Finally this fixes using "explorer /separate" and also fixes the separate process to exit when the last browser gets closed (this fix also applies to filebrowser.exe which no longer lives forever). CORE-12168
Modified: trunk/reactos/dll/win32/browseui/addresseditbox.cpp trunk/reactos/dll/win32/browseui/desktopipc.cpp trunk/reactos/dll/win32/browseui/shellbrowser.cpp
Modified: trunk/reactos/dll/win32/browseui/addresseditbox.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/browseui/addresse... ============================================================================== --- trunk/reactos/dll/win32/browseui/addresseditbox.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/browseui/addresseditbox.cpp [iso-8859-1] Sat Nov 5 14:40:55 2016 @@ -348,13 +348,22 @@ hr = IUnknown_QueryService(fSite, SID_STopLevelBrowser, IID_PPV_ARG(IBrowserService, &isb)); if (FAILED_UNEXPECTEDLY(hr)) return hr; - isb->GetPidl(&absolutePIDL); - - SHBindToParent(absolutePIDL, IID_PPV_ARG(IShellFolder, &sf), &pidlChild); - - sf->GetDisplayNameOf(pidlChild, SHGDN_FORADDRESSBAR | SHGDN_FORPARSING, &ret); - - StrRetToBufW(&ret, pidlChild, buf, 4095); + + hr = isb->GetPidl(&absolutePIDL); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + hr = SHBindToParent(absolutePIDL, IID_PPV_ARG(IShellFolder, &sf), &pidlChild); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + hr = sf->GetDisplayNameOf(pidlChild, SHGDN_FORADDRESSBAR | SHGDN_FORPARSING, &ret); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + hr = StrRetToBufW(&ret, pidlChild, buf, 4095); + if (FAILED_UNEXPECTEDLY(hr)) + return hr;
indexClosed = SHMapPIDLToSystemImageListIndex(sf, pidlChild, &indexOpen);
Modified: trunk/reactos/dll/win32/browseui/desktopipc.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/browseui/desktopi... ============================================================================== --- trunk/reactos/dll/win32/browseui/desktopipc.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/browseui/desktopipc.cpp [iso-8859-1] Sat Nov 5 14:40:55 2016 @@ -5,6 +5,7 @@ #define PROXY_DESKTOP_CLASS L"Proxy Desktop"
BOOL g_SeparateFolders = FALSE; +HWND g_hwndProxyDesktop = NULL;
// fields indented more are unknown ;P struct HNFBlock @@ -70,13 +71,13 @@ END_MSG_MAP() };
-static CProxyDesktop * CreateProxyDesktop(IEThreadParamBlock * parameters) -{ - return new CProxyDesktop(parameters); -} - HWND FindShellProxy(LPITEMIDLIST pidl) { + /* If there is a proxy desktop in the current process use it */ + if (g_hwndProxyDesktop) + return g_hwndProxyDesktop; + + /* Try to find the desktop of the main explorer process */ if (!g_SeparateFolders) { HWND shell = GetShellWindow(); @@ -92,6 +93,7 @@ TRACE("Separate folders setting enabled. Ignoring main desktop.\n"); }
+ /* The main desktop can't be find so try to see if another process has a proxy desktop */ HWND proxy = FindWindow(PROXY_DESKTOP_CLASS, NULL); if (proxy) { @@ -355,6 +357,12 @@ if (parameters && parameters->offsetF8) parameters->offsetF8->AddRef();
+ // HACK! This shouldn't happen! SHExplorerParseCmdLine needs fixing. + if (!parameters->directoryPIDL) + { + SHGetFolderLocation(NULL, CSIDL_PERSONAL, NULL, NULL, ¶meters->directoryPIDL); + } + hResult = CShellBrowser_CreateInstance(parameters->directoryPIDL, parameters->dwFlags, IID_PPV_ARG(IBrowserService2, &browser)); if (FAILED_UNEXPECTEDLY(hResult)) return hResult; @@ -401,6 +409,10 @@
/* Destroying the parameters releases the thread reference */ SHDestroyIETHREADPARAM(parameters); + + /* Wake up the proxy desktop thread so it can check whether the last browser thread exited */ + /* Use PostMessage in order to force GetMessage to return and check if all browser windows have exited */ + PostMessageW(FindShellProxy(NULL), WM_EXPLORER_1037, 0, 0);
OleUninitialize();
@@ -630,9 +642,11 @@
// Else, start our own message loop! HRESULT hr = CoInitialize(NULL); - CProxyDesktop * proxy = CreateProxyDesktop(parameters); + CProxyDesktop * proxy = new CProxyDesktop(parameters); if (proxy) { + g_hwndProxyDesktop = proxy->Create(0); + LONG refCount; CComPtr<IUnknown> thread; if (SHCreateThreadRef(&refCount, &thread) >= 0) @@ -652,6 +666,8 @@ DispatchMessageW(&Msg); }
+ DestroyWindow(g_hwndProxyDesktop); + delete proxy; }
Modified: trunk/reactos/dll/win32/browseui/shellbrowser.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/browseui/shellbro... ============================================================================== --- trunk/reactos/dll/win32/browseui/shellbrowser.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/browseui/shellbrowser.cpp [iso-8859-1] Sat Nov 5 14:40:55 2016 @@ -1040,25 +1040,27 @@ HIMAGELIST himlSmall, himlLarge;
CComPtr<IShellFolder> sf; - SHBindToParent(absolutePIDL, IID_PPV_ARG(IShellFolder, &sf), &pidlChild); - - index = SHMapPIDLToSystemImageListIndex(sf, pidlChild, &indexOpen); - - Shell_GetImageLists(&himlLarge, &himlSmall); - - HICON icSmall = ImageList_GetIcon(himlSmall, indexOpen, 0); - HICON icLarge = ImageList_GetIcon(himlLarge, indexOpen, 0); - - /* Hack to make it possible to release the old icons */ - /* Something seems to go wrong with WM_SETICON */ - HICON oldSmall = (HICON)SendMessage(WM_GETICON, ICON_SMALL, 0); - HICON oldLarge = (HICON)SendMessage(WM_GETICON, ICON_BIG, 0); - - SendMessage(WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(icSmall)); - SendMessage(WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(icLarge)); - - DestroyIcon(oldSmall); - DestroyIcon(oldLarge); + hResult = SHBindToParent(absolutePIDL, IID_PPV_ARG(IShellFolder, &sf), &pidlChild); + if (SUCCEEDED(hResult)) + { + index = SHMapPIDLToSystemImageListIndex(sf, pidlChild, &indexOpen); + + Shell_GetImageLists(&himlLarge, &himlSmall); + + HICON icSmall = ImageList_GetIcon(himlSmall, indexOpen, 0); + HICON icLarge = ImageList_GetIcon(himlLarge, indexOpen, 0); + + /* Hack to make it possible to release the old icons */ + /* Something seems to go wrong with WM_SETICON */ + HICON oldSmall = (HICON)SendMessage(WM_GETICON, ICON_SMALL, 0); + HICON oldLarge = (HICON)SendMessage(WM_GETICON, ICON_BIG, 0); + + SendMessage(WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(icSmall)); + SendMessage(WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(icLarge)); + + DestroyIcon(oldSmall); + DestroyIcon(oldLarge); + } }
FireCommandStateChangeAll();