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/address…
==============================================================================
--- 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/desktop…
==============================================================================
--- 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/shellbr…
==============================================================================
--- 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();