[BROWSEUI]
[reactos.git] / dll / win32 / browseui / shellbrowser.cpp
index 5ce9f79..ceba070 100644 (file)
@@ -25,8 +25,8 @@
 
 extern "C"
 BOOL WINAPI Shell_GetImageLists(
-    _In_  HIMAGELIST *phiml,
-    _In_  HIMAGELIST *phimlSmall
+    _Out_  HIMAGELIST *phiml,
+    _Out_  HIMAGELIST *phimlSmall
     );
 
 #include "newatlinterfaces.h"
@@ -200,8 +200,8 @@ HRESULT WINAPI SHBindToFolder(LPCITEMIDLIST path, IShellFolder **newFolder)
 {
     CComPtr<IShellFolder>                   desktop;
 
-    ::SHGetDesktopFolder(&desktop);
-    if (desktop == NULL)
+    HRESULT hr = ::SHGetDesktopFolder(&desktop);
+    if (FAILED(hr))
         return E_FAIL;
     if (path == NULL || path->mkid.cb == 0)
     {
@@ -287,7 +287,7 @@ Switch to a new bar when it receives an Exec(CGID_IDeskBand, 1, 1, vaIn, NULL);
 */
 
 class CShellBrowser :
-    public CWindowImpl<CShellBrowser, CWindow, CControlWinTraits>,
+    public CWindowImpl<CShellBrowser, CWindow, CFrameWinTraits>,
     public CComObjectRootEx<CComMultiThreadModelNoCS>,
     public IShellBrowser,
     public IDropTarget,
@@ -332,6 +332,7 @@ private:
     IOleObject                              *fHistoryObject;
     IStream                                 *fHistoryStream;
     IBindCtx                                *fHistoryBindContext;
+    HACCEL m_hAccel;
 public:
 #if 0
     ULONG InternalAddRef()
@@ -615,6 +616,7 @@ public:
     virtual HRESULT STDMETHODCALLTYPE GetPositionCookie(DWORD *pdwPositioncookie);
 
     // message handlers
+    LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
     LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
     LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
     LRESULT OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
@@ -627,6 +629,7 @@ public:
     LRESULT OnGoBack(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
     LRESULT OnGoForward(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
     LRESULT OnGoUpLevel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
+    LRESULT OnBackspace(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
     LRESULT OnGoHome(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
     LRESULT OnIsThisLegal(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
     LRESULT OnToggleStatusBarVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
@@ -652,6 +655,7 @@ public:
     }
 
     BEGIN_MSG_MAP(CShellBrowser)
+        MESSAGE_HANDLER(WM_CREATE, OnCreate)
         MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
         MESSAGE_HANDLER(WM_SIZE, OnSize)
         MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup)
@@ -675,6 +679,7 @@ public:
         COMMAND_ID_HANDLER(IDM_TOOLBARS_LINKSBAR, OnToggleLinksBandVisible)
         COMMAND_ID_HANDLER(IDM_TOOLBARS_TEXTLABELS, OnToggleTextLabels)
         COMMAND_ID_HANDLER(IDM_TOOLBARS_CUSTOMIZE, OnToolbarCustomize)
+        COMMAND_ID_HANDLER(IDM_BACKSPACE, OnBackspace)
         COMMAND_RANGE_HANDLER(IDM_GOTO_TRAVEL_FIRSTTARGET, IDM_GOTO_TRAVEL_LASTTARGET, OnGoTravel)
         MESSAGE_HANDLER(WM_COMMAND, RelayCommands)
     END_MSG_MAP()
@@ -732,7 +737,6 @@ HRESULT CShellBrowser::Initialize(LPITEMIDLIST pidl, long b, long c, long d)
     CComPtr<IPersistStreamInit>             persistStreamInit;
     CComPtr<IOleCommandTarget>              commandTarget;
     CComPtr<IObjectWithSite>                objectSite;
-    RECT                                    bounds = {0, 0, 800, 591};
     HRESULT                                 hResult;
 
     _AtlInitialConstruct();
@@ -743,7 +747,7 @@ HRESULT CShellBrowser::Initialize(LPITEMIDLIST pidl, long b, long c, long d)
     }
 
     // create window
-    Create(HWND_DESKTOP, bounds, NULL, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0U);
+    Create(HWND_DESKTOP);
     if (m_hWnd == NULL)
         return E_FAIL;
 
@@ -808,11 +812,7 @@ HRESULT CShellBrowser::Initialize(LPITEMIDLIST pidl, long b, long c, long d)
                     _AtlBaseModule.GetModuleInstance(), 0);
     fStatusBarVisible = true;
 
-    FOLDERSETTINGS                          newFolderSettings;
-
     // browse 
-    newFolderSettings.ViewMode = FVM_LIST;
-    newFolderSettings.fFlags = 0;
     hResult = BrowseToPIDL(pidl, BTP_UPDATE_NEXT_HISTORY);
     if (FAILED(hResult))
         return hResult;
@@ -831,7 +831,10 @@ HRESULT CShellBrowser::BrowseToPIDL(LPCITEMIDLIST pidl, long flags)
     // called by shell view to browse to new folder
     // also called by explorer band to navigate to new folder
     hResult = SHBindToFolder(pidl, &newFolder);
-    newFolderSettings.ViewMode = FVM_LIST;
+    if (FAILED(hResult))
+        return hResult;
+
+    newFolderSettings.ViewMode = FVM_ICON;
     newFolderSettings.fFlags = 0;
     hResult = BrowseToPath(newFolder, pidl, &newFolderSettings, flags);
     if (FAILED(hResult))
@@ -1060,7 +1063,7 @@ HRESULT CShellBrowser::BrowseToPath(IShellFolder *newShellFolder,
 
         index = SHMapPIDLToSystemImageListIndex(sf, pidlChild, &indexOpen);
 
-        Shell_GetImageLists(&himlSmall, &himlLarge);
+        Shell_GetImageLists(&himlLarge, &himlSmall);
 
         HICON icSmall = ImageList_GetIcon(himlSmall, indexOpen, 0);
         HICON icLarge = ImageList_GetIcon(himlLarge, indexOpen, 0);
@@ -1361,26 +1364,43 @@ void CShellBrowser::RepositionBars()
             if (borderSpace.top != 0)
             {
                 toolbarRect.bottom = toolbarRect.top + borderSpace.top;
-                clientRect.top += borderSpace.top;
             }
             else if (borderSpace.bottom != 0)
             {
                 toolbarRect.top = toolbarRect.bottom - borderSpace.bottom;
-                clientRect.bottom -= borderSpace.bottom;
             }
-            if (borderSpace.left != 0)
+            else if (borderSpace.left != 0)
             {
                 toolbarRect.right = toolbarRect.left + borderSpace.left;
-                clientRect.left += borderSpace.left;
             }
             else if (borderSpace.right != 0)
             {
                 toolbarRect.left = toolbarRect.right - borderSpace.right;
-                clientRect.right -= borderSpace.right;
             }
-            ::SetWindowPos(hwnd, NULL, toolbarRect.left, toolbarRect.top,
-                                toolbarRect.right - toolbarRect.left,
-                                toolbarRect.bottom - toolbarRect.top, SWP_NOOWNERZORDER | SWP_NOZORDER);
+
+            ::SetWindowPos(hwnd, NULL,
+                toolbarRect.left,
+                toolbarRect.top,
+                toolbarRect.right - toolbarRect.left,
+                toolbarRect.bottom - toolbarRect.top,
+                SWP_NOOWNERZORDER | SWP_NOZORDER);
+
+            if (borderSpace.top != 0)
+            {
+                clientRect.top = toolbarRect.bottom;
+            }
+            else if (borderSpace.bottom != 0)
+            {
+                clientRect.bottom = toolbarRect.top;
+            }
+            else if (borderSpace.left != 0)
+            {
+                clientRect.left = toolbarRect.right;
+            }
+            else if (borderSpace.right != 0)
+            {
+                clientRect.right = toolbarRect.left;
+            }
         }
     }
     ::SetWindowPos(fCurrentShellViewWindow, NULL, clientRect.left, clientRect.top,
@@ -1589,8 +1609,9 @@ bool IUnknownIsEqual(IUnknown *int1, IUnknown *int2)
 
 HRESULT STDMETHODCALLTYPE CShellBrowser::GetBorderDW(IUnknown *punkObj, LPRECT prcBorder)
 {
-    RECT                                    availableBounds;
-    static const INT                        excludeItems[] = {1, 1, 1, 0xa001, 0, 0};
+    static const INT excludeItems[] = { 1, 1, 1, 0xa001, 0, 0 };
+
+    RECT availableBounds;
 
     GetEffectiveClientRect(m_hWnd, &availableBounds, excludeItems);
     for (INT x = 0; x < 3; x++)
@@ -1853,6 +1874,15 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::RemoveMenusSB(HMENU hmenuShared)
 
 HRESULT STDMETHODCALLTYPE CShellBrowser::SetStatusTextSB(LPCOLESTR pszStatusText)
 {
+    //
+    if (pszStatusText)
+    {
+        ::SetWindowText(fStatusBar, pszStatusText);
+    }
+    else
+    {
+
+    }
     return E_NOTIMPL;
 }
 
@@ -1863,7 +1893,9 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::EnableModelessSB(BOOL fEnable)
 
 HRESULT STDMETHODCALLTYPE CShellBrowser::TranslateAcceleratorSB(MSG *pmsg, WORD wID)
 {
-    return E_NOTIMPL;
+    if (!::TranslateAcceleratorW(m_hWnd, m_hAccel, pmsg))
+        return S_FALSE;
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CShellBrowser::BrowseObject(LPCITEMIDLIST pidl, UINT wFlags)
@@ -2041,8 +2073,10 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::GetTravelLog(ITravelLog **pptl)
     HRESULT                                 hResult;
 
     // called by toolbar when displaying tooltips
-    if (pptl != NULL)
-        *pptl = NULL;
+    if (pptl == NULL)
+        return E_FAIL;
+
+    *pptl = NULL;
     if (fTravelLog.p == NULL)
     {
         hResult = CreateTravelLog(IID_PPV_ARG(ITravelLog, &fTravelLog));
@@ -2222,7 +2256,8 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::OnSize(WPARAM wParam)
 
 HRESULT STDMETHODCALLTYPE CShellBrowser::OnCreate(struct tagCREATESTRUCTW *pcs)
 {
-    return E_NOTIMPL;
+    m_hAccel = LoadAcceleratorsW(GetModuleHandle(L"browseui.dll"), MAKEINTRESOURCEW(256));
+    return S_OK;
 }
 
 LRESULT STDMETHODCALLTYPE CShellBrowser::OnCommand(WPARAM wParam, LPARAM lParam)
@@ -2501,7 +2536,13 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::_SetFocus(LPTOOLBARITEM ptbi, HWND hwnd
 
 HRESULT STDMETHODCALLTYPE CShellBrowser::v_MayTranslateAccelerator(MSG *pmsg)
 {
-    return E_NOTIMPL;
+    if (fCurrentShellView->TranslateAcceleratorW(pmsg) != S_OK)
+    {
+        if (TranslateAcceleratorSB(pmsg, 0) != S_OK)
+            return S_FALSE;
+        return S_OK;
+    }
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CShellBrowser::_GetBorderDWHelper(IUnknown *punkSrc, LPRECT lprectBorder, BOOL bUseHmonitor)
@@ -3002,6 +3043,12 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::GetPositionCookie(DWORD *pdwPositioncoo
     return E_NOTIMPL;
 }
 
+LRESULT CShellBrowser::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
+{
+    OnCreate(reinterpret_cast<LPCREATESTRUCT> (lParam));
+    return 0;
+}
+
 LRESULT CShellBrowser::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 {
     // TODO: rip down everything
@@ -3122,19 +3169,24 @@ LRESULT CShellBrowser::OnGoHome(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &
     return 0;
 }
 
+LRESULT CShellBrowser::OnBackspace(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
+{
+    HRESULT                                 hResult;
+
+    // FIXME: This does not appear to be what windows does.
+    hResult = NavigateToParent();
+    return 0;
+}
+
 LRESULT CShellBrowser::OnIsThisLegal(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 {
     HRESULT                                 hResult;
 
     typedef HRESULT (WINAPI *PSHOpenNewFrame)(LPITEMIDLIST pidl, IUnknown *b, long c, long d);
-    PSHOpenNewFrame Func;
-    HMODULE hShlwapi;
-
-    hShlwapi = LoadLibrary(TEXT("browseui.dll"));
-    if (hShlwapi != NULL)
-        Func = reinterpret_cast<PSHOpenNewFrame>(GetProcAddress(hShlwapi, (LPCSTR)103));
-    else
-        Func = NULL;
+    PSHOpenNewFrame Func = NULL;
+    HMODULE Module = GetModuleHandle(TEXT("browseui.dll"));
+    if (Module != NULL)
+        Func = reinterpret_cast<PSHOpenNewFrame>(GetProcAddress(Module, (LPCSTR) 103));
     if (Func != NULL)
     {
         LPITEMIDLIST                        desktopPIDL;
@@ -3245,56 +3297,59 @@ LRESULT CShellBrowser::RelayCommands(UINT uMsg, WPARAM wParam, LPARAM lParam, BO
     return 0;
 }
 
-//static LRESULT CALLBACK ExplorerWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-//{
-//    return DefWindowProc(hwnd, uMsg, wParam, lParam);
-//}
-
-static void ExplorerMessageLoop()
+static HRESULT ExplorerMessageLoop(IEThreadParamBlock * parameters)
 {
+    CComPtr<IShellBrowser>                  shellBrowser;
+    CComObject<CShellBrowser>               *theCabinet;
+    HRESULT                                 hResult;
     MSG Msg;
     BOOL Ret;
 
-    while (1)
+    OleInitialize(NULL);
+
+    ATLTRY(theCabinet = new CComObject<CShellBrowser>);
+    if (theCabinet == NULL)
     {
-        Ret = (GetMessage(&Msg, NULL, 0, 0) != 0);
+        hResult = E_OUTOFMEMORY;
+        goto uninitialize;
+    }
 
-        if (Ret != -1)
+    hResult = theCabinet->QueryInterface(IID_PPV_ARG(IShellBrowser, &shellBrowser));
+    if (FAILED(hResult))
+    {
+        delete theCabinet;
+        goto uninitialize;
+    }
+
+    hResult = theCabinet->Initialize(parameters->directoryPIDL, 0, 0, 0);
+    if (FAILED(hResult))
+        goto uninitialize;
+
+    while ((Ret = GetMessage(&Msg, NULL, 0, 0)) != 0)
+    {
+        if (Ret == -1)
         {
-            if (!Ret)
-                break;
+            // Error: continue or exit?
+            break;
+        }
 
+        if (theCabinet->v_MayTranslateAccelerator(&Msg) != S_OK)
+        {
             TranslateMessage(&Msg);
             DispatchMessage(&Msg);
-
-            if (Msg.message == WM_QUIT)
-                break;
         }
+
+        if (Msg.message == WM_QUIT)
+            break;
     }
+
+uninitialize:
+    OleUninitialize();
+    return hResult;
 }
 
 DWORD WINAPI BrowserThreadProc(LPVOID lpThreadParameter)
 {
-    CComPtr<IShellBrowser>                  shellBrowser;
-    CComObject<CShellBrowser>               *theCabinet;
-    IEThreadParamBlock                      *parameters;
-    HRESULT                                 hResult;
-
-    parameters = (IEThreadParamBlock *)lpThreadParameter;
-    OleInitialize(NULL);
-    ATLTRY (theCabinet = new CComObject<CShellBrowser>);
-    if (theCabinet == NULL)
-        return E_OUTOFMEMORY;
-    hResult = theCabinet->QueryInterface(IID_PPV_ARG(IShellBrowser, &shellBrowser));
-    if (FAILED(hResult))
-    {
-        delete theCabinet;
-        return hResult;
-    }
-    hResult = theCabinet->Initialize(parameters->directoryPIDL, 0, 0, 0);
-    if (FAILED(hResult))
-        return hResult;
-    ExplorerMessageLoop();
-    OleUninitialize();
-    return 0;
+    IEThreadParamBlock * parameters = (IEThreadParamBlock *) lpThreadParameter;
+    return ExplorerMessageLoop(parameters);
 }