[BROWSEUI]
[reactos.git] / dll / win32 / browseui / addressband.cpp
index 0010f5f..2f5ef7c 100644 (file)
 /*
 Implements the navigation band of the cabinet window
 */
-#include <windows.h>
-#include <shlobj.h>
-#include <shlobj_undoc.h>
-#include <shlguid.h>
-#include <shlguid_undoc.h>
-#include <tchar.h>
-#include <atlbase.h>
-#include <atlcom.h>
-#include <atlwin.h>
-#include "resource.h"
-#include "addressband.h"
+
+#include "precomp.h"
+#include <commoncontrols.h>
+#include <shlwapi_undoc.h>
+#include <shellapi.h>
+
+HRESULT CreateAddressEditBox(REFIID riid, void **ppv);
+
+extern "C"
+HRESULT WINAPI SHGetImageList(
+    _In_   int iImageList,
+    _In_   REFIID riid,
+    _Out_  void **ppv
+    );
 
 /*
 TODO:
@@ -50,10 +53,11 @@ TODO:
 
 CAddressBand::CAddressBand()
 {
-       fEditControl = NULL;
-       fGoButton = NULL;
-       fComboBox = NULL;
-       fGoButtonShown = false;
+    fEditControl = NULL;
+    fGoButton = NULL;
+    fComboBox = NULL;
+    fGoButtonShown = false;
+    fAdviseCookie = 0;
 }
 
 CAddressBand::~CAddressBand()
@@ -62,141 +66,181 @@ CAddressBand::~CAddressBand()
 
 void CAddressBand::FocusChange(BOOL bFocus)
 {
-//     m_bFocus = bFocus;
+//    m_bFocus = bFocus;
 
-       //Inform the input object site that the focus has changed.
-       if (fSite)
-       {
+    //Inform the input object site that the focus has changed.
+    if (fSite)
+    {
 #if 0
-               fSite->OnFocusChangeIS((IDockingWindow *)this, bFocus);
+        fSite->OnFocusChangeIS((IDockingWindow *)this, bFocus);
 #endif
-       }
+    }
 }
 
 HRESULT STDMETHODCALLTYPE CAddressBand::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO *pdbi)
 {
-       if (pdbi->dwMask & DBIM_MINSIZE)
-       {
-               pdbi->ptMinSize.x = 400;
-               pdbi->ptMinSize.y = 22;
-       }
-       if (pdbi->dwMask & DBIM_MAXSIZE)
-       {
-               pdbi->ptMaxSize.x = 0;
-               pdbi->ptMaxSize.y = 0;
-       }
-       if (pdbi->dwMask & DBIM_INTEGRAL)
-       {
-               pdbi->ptIntegral.x = 0;
-               pdbi->ptIntegral.y = 0;
-       }
-       if (pdbi->dwMask & DBIM_ACTUAL)
-       {
-               pdbi->ptActual.x = 400;
-               pdbi->ptActual.y = 22;
-       }
-       if (pdbi->dwMask & DBIM_TITLE)
-               wcscpy(pdbi->wszTitle, L"Address");
-       if (pdbi->dwMask & DBIM_MODEFLAGS)
-               pdbi->dwModeFlags = DBIMF_UNDELETEABLE;
-       if (pdbi->dwMask & DBIM_BKCOLOR)
-               pdbi->crBkgnd = 0;
-       return S_OK;
+    if (pdbi->dwMask & DBIM_MINSIZE)
+    {
+        pdbi->ptMinSize.x = 400;
+        pdbi->ptMinSize.y = 22;
+    }
+    if (pdbi->dwMask & DBIM_MAXSIZE)
+    {
+        pdbi->ptMaxSize.x = 0;
+        pdbi->ptMaxSize.y = 0;
+    }
+    if (pdbi->dwMask & DBIM_INTEGRAL)
+    {
+        pdbi->ptIntegral.x = 0;
+        pdbi->ptIntegral.y = 0;
+    }
+    if (pdbi->dwMask & DBIM_ACTUAL)
+    {
+        pdbi->ptActual.x = 400;
+        pdbi->ptActual.y = 22;
+    }
+    if (pdbi->dwMask & DBIM_TITLE)
+        wcscpy(pdbi->wszTitle, L"Address");
+    if (pdbi->dwMask & DBIM_MODEFLAGS)
+        pdbi->dwModeFlags = DBIMF_UNDELETEABLE;
+    if (pdbi->dwMask & DBIM_BKCOLOR)
+        pdbi->crBkgnd = 0;
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CAddressBand::SetSite(IUnknown *pUnkSite)
 {
-       CComPtr<IShellService>                                  shellService;
-       CComPtr<IUnknown>                                               offset34;
-       HWND                                                                    parentWindow;
-       IOleWindow                                                              *oleWindow;
-       HWND                                                                    toolbar;
-       static const TBBUTTON                                   buttonInfo[] = { {0, 1, TBSTATE_ENABLED, 0} };
-       HIMAGELIST                                                              normalImagelist;
-       HIMAGELIST                                                              hotImageList;
-       HINSTANCE                                                               shellInstance;
-       HRESULT                                                                 hResult;
-
-       fSite.Release();
-       if (pUnkSite == NULL)
-               return S_OK;
-       hResult = pUnkSite->QueryInterface(IID_IDockingWindowSite, (void **)&fSite);
-       if (FAILED(hResult))
-               return hResult;
-       parentWindow = NULL;
-       hResult = pUnkSite->QueryInterface(IID_IOleWindow, (void **)&oleWindow);
-       if (SUCCEEDED(hResult))
-       {
-               oleWindow->GetWindow(&parentWindow);
-               oleWindow->Release();
-       }
-       if (!::IsWindow(parentWindow))
-               return E_FAIL;
-
-       toolbar = CreateWindowEx(WS_EX_TOOLWINDOW, WC_COMBOBOXEXW, NULL, WS_CHILD | WS_VISIBLE |
-                                       WS_CLIPCHILDREN | WS_TABSTOP | CCS_NODIVIDER | CCS_NOMOVEY,
-                                       0, 0, 500, 250, parentWindow, (HMENU)0xa205, _AtlBaseModule.GetModuleInstance(), 0);
-       if (toolbar == NULL)
-               return E_FAIL;
-       SubclassWindow(toolbar);
-       SendMessage(CBEM_SETEXTENDEDSTYLE, CBES_EX_CASESENSITIVE | CBES_EX_NOSIZELIMIT, CBES_EX_CASESENSITIVE | CBES_EX_NOSIZELIMIT);
-       fEditControl = (HWND)SendMessage(CBEM_GETEDITCONTROL, 0, 0);
-       fComboBox = (HWND)SendMessage(CBEM_GETCOMBOCONTROL, 0, 0);
+    CComPtr<IBrowserService>                browserService;
+    CComPtr<IOleWindow>                     oleWindow;
+    CComPtr<IShellService>                  shellService;
+    CComPtr<IUnknown>                       offset34;
+    HWND                                    parentWindow;
+    HWND                                    combobox;
+    static const TBBUTTON                   buttonInfo[] = { {0, 1, TBSTATE_ENABLED, 0} };
+    HIMAGELIST                              normalImagelist;
+    HIMAGELIST                              hotImageList;
+    HINSTANCE                               shellInstance;
+    HRESULT                                 hResult;
+
+    if (pUnkSite == NULL)
+    {
+        hResult = AtlUnadvise(fSite, DIID_DWebBrowserEvents, fAdviseCookie);
+        fSite.Release();
+        return S_OK;
+    }
+
+    fSite.Release();
+
+    hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &fSite));
+    if (FAILED(hResult))
+        return hResult;
+
+    // get window handle of parent
+    parentWindow = NULL;
+    hResult = IUnknown_GetWindow(pUnkSite, &parentWindow);
+
+    if (!::IsWindow(parentWindow))
+        return E_FAIL;
+
+    // create combo box ex
+    combobox = CreateWindowEx(WS_EX_TOOLWINDOW, WC_COMBOBOXEXW, NULL, WS_CHILD | WS_VISIBLE |
+        WS_CLIPCHILDREN | WS_TABSTOP | CCS_NODIVIDER | CCS_NOMOVEY | CBS_OWNERDRAWFIXED,
+                    0, 0, 500, 250, parentWindow, (HMENU)0xa205, _AtlBaseModule.GetModuleInstance(), 0);
+    if (combobox == NULL)
+        return E_FAIL;
+    SubclassWindow(combobox);
+
+    SendMessage(CBEM_SETEXTENDEDSTYLE,
+        CBES_EX_CASESENSITIVE | CBES_EX_NOSIZELIMIT, CBES_EX_CASESENSITIVE | CBES_EX_NOSIZELIMIT);
+
+    fEditControl = reinterpret_cast<HWND>(SendMessage(CBEM_GETEDITCONTROL, 0, 0));
+    fComboBox = reinterpret_cast<HWND>(SendMessage(CBEM_GETCOMBOCONTROL, 0, 0));
 #if 1
-       hResult = CoCreateInstance(CLSID_AddressEditBox, NULL, CLSCTX_INPROC_SERVER, IID_IAddressEditBox, (void **)&fAddressEditBox);
-       if (FAILED(hResult))
-               return hResult;
+    hResult = CoCreateInstance(CLSID_AddressEditBox, NULL, CLSCTX_INPROC_SERVER,
+        IID_PPV_ARG(IAddressEditBox, &fAddressEditBox));
 #else
-       // instantiate new version
+    hResult = E_FAIL;
 #endif
-       hResult = fAddressEditBox->QueryInterface(IID_IShellService, (void **)&shellService);
-       if (FAILED(hResult))
-               return hResult;
-       hResult = fAddressEditBox->Init(toolbar, fEditControl, 8, pUnkSite /*(IAddressBand *)this*/ );
-       if (FAILED(hResult))
-               return hResult;
-       hResult = shellService->SetOwner(pUnkSite);
-       if (FAILED(hResult))
-               return hResult;
-
-       // TODO: properly initialize this from registry
-       fGoButtonShown = true;
-
-       shellInstance = GetModuleHandle(_T("shell32.dll"));
-       normalImagelist = ImageList_LoadImageW(shellInstance, MAKEINTRESOURCE(IDB_GOBUTTON_NORMAL), 20, 0, RGB(255, 0, 255), IMAGE_BITMAP, LR_CREATEDIBSECTION);
-       hotImageList = ImageList_LoadImageW(shellInstance, MAKEINTRESOURCE(IDB_GOBUTTON_HOT), 20, 0, RGB(255, 0, 255), IMAGE_BITMAP, LR_CREATEDIBSECTION);
-
-       fGoButton = CreateWindowEx(WS_EX_TOOLWINDOW, TOOLBARCLASSNAMEW, 0, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TBSTYLE_LIST |
-                                               TBSTYLE_FLAT | TBSTYLE_TOOLTIPS | CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_NORESIZE,
-                                               0, 0, 0, 0, m_hWnd, NULL, _AtlBaseModule.GetModuleInstance(), NULL);
-       SendMessage(fGoButton, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
-       SendMessage(fGoButton, TB_SETMAXTEXTROWS, 1, 0);
-       SendMessage(fGoButton, TB_SETIMAGELIST, 0, (LPARAM)normalImagelist);
-       SendMessage(fGoButton, TB_SETHOTIMAGELIST, 0, (LPARAM)hotImageList);
-       SendMessage(fGoButton, TB_ADDSTRINGW, (WPARAM)_AtlBaseModule.GetResourceInstance(), IDS_GOBUTTONLABEL);
-       SendMessage(fGoButton, TB_ADDBUTTONSW, 1, (LPARAM)&buttonInfo);
-
-       return hResult;
+    if (FAILED(hResult))
+    {
+        // instantiate new version
+        hResult = CreateAddressEditBox(IID_PPV_ARG(IAddressEditBox, &fAddressEditBox));
+        if (FAILED(hResult))
+            return hResult;
+    }
+
+    hResult = fAddressEditBox->QueryInterface(IID_PPV_ARG(IShellService, &shellService));
+    if (FAILED(hResult))
+        return hResult;
+    hResult = fAddressEditBox->Init(combobox, fEditControl, 8, pUnkSite /*(IAddressBand *)this*/);
+    if (FAILED(hResult))
+        return hResult;
+    hResult = shellService->SetOwner(pUnkSite);
+    if (FAILED(hResult))
+        return hResult;
+
+    // TODO: properly initialize this from registry
+    fGoButtonShown = true;
+
+    shellInstance = GetModuleHandle(_T("shell32.dll"));
+    normalImagelist = ImageList_LoadImageW(shellInstance, MAKEINTRESOURCE(IDB_GOBUTTON_NORMAL),
+        20, 0, RGB(255, 0, 255), IMAGE_BITMAP, LR_CREATEDIBSECTION);
+    hotImageList = ImageList_LoadImageW(shellInstance, MAKEINTRESOURCE(IDB_GOBUTTON_HOT),
+        20, 0, RGB(255, 0, 255), IMAGE_BITMAP, LR_CREATEDIBSECTION);
+
+    fGoButton = CreateWindowEx(WS_EX_TOOLWINDOW, TOOLBARCLASSNAMEW, 0, WS_CHILD | WS_CLIPSIBLINGS |
+        WS_CLIPCHILDREN | TBSTYLE_LIST | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS | CCS_NODIVIDER |
+        CCS_NOPARENTALIGN | CCS_NORESIZE,
+        0, 0, 0, 0, m_hWnd, NULL, _AtlBaseModule.GetModuleInstance(), NULL);
+    SendMessage(fGoButton, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
+    SendMessage(fGoButton, TB_SETMAXTEXTROWS, 1, 0);
+    if (normalImagelist)
+        SendMessage(fGoButton, TB_SETIMAGELIST, 0, reinterpret_cast<LPARAM>(normalImagelist));
+    if (hotImageList)
+        SendMessage(fGoButton, TB_SETHOTIMAGELIST, 0, reinterpret_cast<LPARAM>(hotImageList));
+    SendMessage(fGoButton, TB_ADDSTRINGW,
+        reinterpret_cast<WPARAM>(_AtlBaseModule.GetResourceInstance()), IDS_GOBUTTONLABEL);
+    SendMessage(fGoButton, TB_ADDBUTTONSW, 1, (LPARAM)&buttonInfo);
+
+    IImageList * piml;
+    HRESULT hr = SHGetImageList(SHIL_SMALL, IID_PPV_ARG(IImageList, &piml));
+    if (FAILED_UNEXPECTEDLY(hr))
+    {
+        SendMessageW(combobox, CBEM_SETIMAGELIST, 0, 0);
+    }
+    else
+    {
+        SendMessageW(combobox, CBEM_SETIMAGELIST, 0, reinterpret_cast<LPARAM>(piml));
+    }
+
+    // take advice to watch events
+    hResult = IUnknown_QueryService(pUnkSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
+    if (SUCCEEDED(hResult))
+    {
+        hResult = AtlAdvise(browserService, static_cast<IDispatch *>(this), DIID_DWebBrowserEvents, &fAdviseCookie);
+    }
+
+    return hResult;
 }
 
 HRESULT STDMETHODCALLTYPE CAddressBand::GetSite(REFIID riid, void **ppvSite)
 {
-       if (fSite == NULL)
-               return E_FAIL;
-       return fSite->QueryInterface(riid, ppvSite);
+    if (fSite == NULL)
+        return E_FAIL;
+    return fSite->QueryInterface(riid, ppvSite);
 }
 
 HRESULT STDMETHODCALLTYPE CAddressBand::GetWindow(HWND *lphwnd)
 {
-       if (lphwnd == NULL)
-               return E_POINTER;
-       *lphwnd = m_hWnd;
-       return S_OK;
+    if (lphwnd == NULL)
+        return E_POINTER;
+    *lphwnd = m_hWnd;
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CAddressBand::ContextSensitiveHelp(BOOL fEnterMode)
 {
-       return E_NOTIMPL;
+    return E_NOTIMPL;
 }
 
 HRESULT STDMETHODCALLTYPE CAddressBand::CloseDW(DWORD dwReserved)
@@ -211,9 +255,10 @@ HRESULT STDMETHODCALLTYPE CAddressBand::CloseDW(DWORD dwReserved)
     return S_OK;
 }
 
-HRESULT STDMETHODCALLTYPE CAddressBand::ResizeBorderDW(const RECT *prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
+HRESULT STDMETHODCALLTYPE CAddressBand::ResizeBorderDW(
+    const RECT *prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
 {
-       return E_NOTIMPL;
+    return E_NOTIMPL;
 }
 
 HRESULT STDMETHODCALLTYPE CAddressBand::ShowDW(BOOL fShow)
@@ -228,282 +273,393 @@ HRESULT STDMETHODCALLTYPE CAddressBand::ShowDW(BOOL fShow)
     return S_OK;
 }
 
-HRESULT STDMETHODCALLTYPE CAddressBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[  ], OLECMDTEXT *pCmdText)
+HRESULT STDMETHODCALLTYPE CAddressBand::QueryStatus(
+    const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[  ], OLECMDTEXT *pCmdText)
 {
-       CComPtr<IOleCommandTarget>                              oleCommandTarget;
-       HRESULT                                                                 hResult;
+    CComPtr<IOleCommandTarget>              oleCommandTarget;
+    HRESULT                                 hResult;
 
-       hResult = fAddressEditBox->QueryInterface(IID_IOleCommandTarget, (void **)&oleCommandTarget);
-       if (FAILED(hResult))
-               return hResult;
-       return oleCommandTarget->QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText);
+    hResult = fAddressEditBox->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
+    if (FAILED(hResult))
+        return hResult;
+    return oleCommandTarget->QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText);
 }
 
-HRESULT STDMETHODCALLTYPE CAddressBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
+HRESULT STDMETHODCALLTYPE CAddressBand::Exec(const GUID *pguidCmdGroup,
+    DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
 {
-       // incomplete
-       return E_NOTIMPL;
+    // incomplete
+    return E_NOTIMPL;
 }
 
 HRESULT STDMETHODCALLTYPE CAddressBand::HasFocusIO()
 {
-       if (GetFocus() == fEditControl || SendMessage(CB_GETDROPPEDSTATE, 0, 0))
-               return S_OK;
-       return S_FALSE;
+    if (GetFocus() == fEditControl || SendMessage(CB_GETDROPPEDSTATE, 0, 0))
+        return S_OK;
+    return S_FALSE;
 }
 
 HRESULT STDMETHODCALLTYPE CAddressBand::TranslateAcceleratorIO(LPMSG lpMsg)
 {
-       // incomplete
-       return S_FALSE;
+    // incomplete
+    return S_FALSE;
 }
 
 HRESULT STDMETHODCALLTYPE CAddressBand::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
 {
-       CComPtr<IInputObjectSite>                               inputObjectSite;
-       HRESULT                                                                 hResult;
-
-       if (fActivate)
-       {
-               hResult = fSite->QueryInterface(IID_IInputObjectSite, (void **)&inputObjectSite);
-               if (FAILED(hResult))
-                       return hResult;
-               hResult = inputObjectSite->OnFocusChangeIS((IDeskBand *)this, fActivate);
-               SetFocus();
-       }
-       return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE CAddressBand::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
-{
-       CComPtr<IWinEventHandler>                               winEventHandler;
-       HRESULT                                                                 hResult;
-
-       switch (uMsg)
-       {
-               case WM_WININICHANGE:
-                       break;
-               case WM_COMMAND:
-                       if (wParam == IDM_TOOLBARS_GOBUTTON)
-                       {
-                               // toggle whether the Go button is displayed
-                               // setting is Yes or No, stored in key "Software\Microsoft\Internet Explorer\Main" in value ShowGoButton
-                               // broadcast change notification to all explorer windows
-                       }
-                       break;
-       }
-       hResult = fAddressEditBox->QueryInterface(IID_IWinEventHandler, (void **)&winEventHandler);
-       if (FAILED(hResult))
-               return hResult;
-       return winEventHandler->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
+    CComPtr<IInputObjectSite>               inputObjectSite;
+    HRESULT                                 hResult;
+
+    if (fActivate)
+    {
+        hResult = fSite->QueryInterface(IID_PPV_ARG(IInputObjectSite, &inputObjectSite));
+        if (FAILED(hResult))
+            return hResult;
+        hResult = inputObjectSite->OnFocusChangeIS(static_cast<IDeskBand *>(this), fActivate);
+        SetFocus();
+    }
+    return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CAddressBand::OnWinEvent(
+    HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
+{
+    CComPtr<IWinEventHandler>               winEventHandler;
+    HRESULT                                 hResult;
+
+    switch (uMsg)
+    {
+        case WM_WININICHANGE:
+            break;
+        case WM_COMMAND:
+            if (wParam == IDM_TOOLBARS_GOBUTTON)
+            {
+                // toggle whether the Go button is displayed
+                // setting is Yes or No, stored in key "Software\Microsoft\Internet Explorer\Main" in value ShowGoButton
+                // broadcast change notification to all explorer windows
+            }
+            break;
+    }
+    hResult = fAddressEditBox->QueryInterface(IID_PPV_ARG(IWinEventHandler, &winEventHandler));
+    if (FAILED(hResult))
+        return hResult;
+    return winEventHandler->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
 }
 
 HRESULT STDMETHODCALLTYPE CAddressBand::IsWindowOwner(HWND hWnd)
 {
-       CComPtr<IWinEventHandler>                               winEventHandler;
-       HRESULT                                                                 hResult;
+    CComPtr<IWinEventHandler>               winEventHandler;
+    HRESULT                                 hResult;
 
-       hResult = fAddressEditBox->QueryInterface(IID_IWinEventHandler, (void **)&winEventHandler);
-       if (FAILED(hResult))
-               return hResult;
-       return winEventHandler->IsWindowOwner(hWnd);
+    if (fAddressEditBox)
+    {
+        hResult = fAddressEditBox->QueryInterface(IID_PPV_ARG(IWinEventHandler, &winEventHandler));
+        if (FAILED(hResult))
+            return hResult;
+        return winEventHandler->IsWindowOwner(hWnd);
+    }
+    return S_FALSE;
 }
 
 HRESULT STDMETHODCALLTYPE CAddressBand::FileSysChange(long param8, long paramC)
 {
-       CComPtr<IAddressBand>                                   addressBand;
-       HRESULT                                                                 hResult;
+    CComPtr<IAddressBand>                   addressBand;
+    HRESULT                                 hResult;
 
-       hResult = fAddressEditBox->QueryInterface(IID_IAddressBand, (void **)&addressBand);
-       if (FAILED(hResult))
-               return hResult;
-       return addressBand->FileSysChange(param8, paramC);
+    hResult = fAddressEditBox->QueryInterface(IID_PPV_ARG(IAddressBand, &addressBand));
+    if (FAILED(hResult))
+        return hResult;
+    return addressBand->FileSysChange(param8, paramC);
 }
 
 HRESULT STDMETHODCALLTYPE CAddressBand::Refresh(long param8)
 {
-       CComPtr<IAddressBand>                                   addressBand;
-       HRESULT                                                                 hResult;
+    CComPtr<IAddressBand>                   addressBand;
+    HRESULT                                 hResult;
 
-       hResult = fAddressEditBox->QueryInterface(IID_IAddressBand, (void **)&addressBand);
-       if (FAILED(hResult))
-               return hResult;
-       return addressBand->Refresh(param8);
+    hResult = fAddressEditBox->QueryInterface(IID_PPV_ARG(IAddressBand, &addressBand));
+    if (FAILED(hResult))
+        return hResult;
+    return addressBand->Refresh(param8);
 }
 
 HRESULT STDMETHODCALLTYPE CAddressBand::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
 {
-       return E_NOTIMPL;
+    return E_NOTIMPL;
 }
 
 HRESULT STDMETHODCALLTYPE CAddressBand::OnFocusChangeIS(IUnknown *punkObj, BOOL fSetFocus)
 {
-       return E_NOTIMPL;
+    return E_NOTIMPL;
 }
 
 HRESULT STDMETHODCALLTYPE CAddressBand::GetClassID(CLSID *pClassID)
 {
-       if (pClassID == NULL)
-               return E_POINTER;
-       *pClassID = CLSID_SH_AddressBand;
-       return S_OK;
+    if (pClassID == NULL)
+        return E_POINTER;
+    *pClassID = CLSID_SH_AddressBand;
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CAddressBand::IsDirty()
 {
-       return E_NOTIMPL;
+    return E_NOTIMPL;
 }
 
 HRESULT STDMETHODCALLTYPE CAddressBand::Load(IStream *pStm)
 {
-       // incomplete
-       return E_NOTIMPL;
+    // incomplete
+    return E_NOTIMPL;
 }
 
 HRESULT STDMETHODCALLTYPE CAddressBand::Save(IStream *pStm, BOOL fClearDirty)
 {
-       // incomplete
-       return E_NOTIMPL;
+    // incomplete
+    return E_NOTIMPL;
 }
 
 HRESULT STDMETHODCALLTYPE CAddressBand::GetSizeMax(ULARGE_INTEGER *pcbSize)
 {
-       // incomplete
-       return E_NOTIMPL;
+    // incomplete
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CAddressBand::GetTypeInfoCount(UINT *pctinfo)
+{
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CAddressBand::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
+{
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CAddressBand::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames,
+    LCID lcid, DISPID *rgDispId)
+{
+    return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CAddressBand::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
+    DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
+{
+    CComPtr<IBrowserService> isb;
+    CComPtr<IShellFolder> sf;
+    HRESULT hr;
+    INT indexClosed, indexOpen, itemExists, oldIndex;
+    DWORD result;
+    COMBOBOXEXITEMW item;
+    PIDLIST_ABSOLUTE absolutePIDL;
+    LPCITEMIDLIST pidlChild;
+    LPITEMIDLIST pidlPrevious;
+    STRRET ret;
+    WCHAR buf[4096];
+
+    if (pDispParams == NULL)
+        return E_INVALIDARG;
+
+    switch (dispIdMember)
+    {
+    case DISPID_NAVIGATECOMPLETE2:
+    case DISPID_DOCUMENTCOMPLETE:
+
+        oldIndex = SendMessage(m_hWnd, CB_GETCURSEL, 0, 0);
+
+        item.mask = CBEIF_LPARAM;
+        item.iItem = 0;
+        itemExists = SendMessage(m_hWnd, CBEM_GETITEM, 0, reinterpret_cast<LPARAM>(&item));
+        if (itemExists)
+        {
+            pidlPrevious = reinterpret_cast<LPITEMIDLIST>(item.lParam);
+        }
+
+        hr = IUnknown_QueryService(fSite, SID_STopLevelBrowser, IID_PPV_ARG(IBrowserService, &isb));
+        if (FAILED(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);
+
+        indexClosed = SHMapPIDLToSystemImageListIndex(sf, pidlChild, &indexOpen);
+
+        item.mask = CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_TEXT | CBEIF_LPARAM;
+        item.iItem = 0;
+        item.iImage = indexClosed;
+        item.iSelectedImage = indexOpen;
+        item.pszText = buf;
+        item.lParam = reinterpret_cast<LPARAM>(absolutePIDL);
+
+        if (itemExists)
+        {
+            result = SendMessage(m_hWnd, CBEM_SETITEM, 0, reinterpret_cast<LPARAM>(&item));
+
+            if (result)
+            {
+                ILFree(pidlPrevious);
+            }
+        }
+        else
+        {
+            oldIndex = SendMessage(m_hWnd, CBEM_INSERTITEM, 0, reinterpret_cast<LPARAM>(&item));
+
+            if (oldIndex < 0)
+                DbgPrint("ERROR %d\n", GetLastError());
+        }
+
+        SendMessage(m_hWnd, CB_SETCURSEL, oldIndex, 0);
+
+        //fAddressEditBox->SetCurrentDir(index);
+
+        break;
+    }
+    return S_OK;
 }
 
 LRESULT CAddressBand::OnNotifyClick(WPARAM wParam, NMHDR *notifyHeader, BOOL &bHandled)
 {
-       if (notifyHeader->hwndFrom == fGoButton)
-       {
-               SendMessage(fEditControl, WM_KEYDOWN, 13, 0);
-               SendMessage(fEditControl, WM_KEYUP, 13, 0);
-       }
-       return 0;
+    if (notifyHeader->hwndFrom == fGoButton)
+    {
+        fAddressEditBox->ParseNow(0);
+        fAddressEditBox->Execute(0);
+    }
+    return 0;
 }
 
 LRESULT CAddressBand::OnTipText(UINT idControl, NMHDR *notifyHeader, BOOL &bHandled)
 {
-       if (notifyHeader->hwndFrom == fGoButton)
-       {
-               // TODO
-               // Go to "destination path"
-       }
-       return 0;
+    if (notifyHeader->hwndFrom == fGoButton)
+    {
+        // TODO
+        // Go to "destination path"
+    }
+    return 0;
 }
 
 LRESULT CAddressBand::OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 {
-       POINT                                                                   pt;
-       POINT                                                                   ptOrig;
-       HWND                                                                    parentWindow;
-       LRESULT                                                                 result;
-
-       if (fGoButtonShown == false)
-       {
-               bHandled = FALSE;
-               return 0;
-       }
-       pt.x = 0;
-       pt.y = 0;
-       parentWindow = GetParent();
-       ::MapWindowPoints(m_hWnd, parentWindow, &pt, 1);
-       OffsetWindowOrgEx((HDC)wParam, pt.x, pt.y, &ptOrig);
-       result = SendMessage(parentWindow, WM_ERASEBKGND, wParam, 0);
-       SetWindowOrgEx((HDC)wParam, ptOrig.x, ptOrig.y, NULL);
-       if (result == 0)
-       {
-               bHandled = FALSE;
-               return 0;
-       }
-       return result;
+    POINT                                   pt;
+    POINT                                   ptOrig;
+    HWND                                    parentWindow;
+    LRESULT                                 result;
+
+    if (fGoButtonShown == false)
+    {
+        bHandled = FALSE;
+        return 0;
+    }
+    pt.x = 0;
+    pt.y = 0;
+    parentWindow = GetParent();
+    ::MapWindowPoints(m_hWnd, parentWindow, &pt, 1);
+    OffsetWindowOrgEx(reinterpret_cast<HDC>(wParam), pt.x, pt.y, &ptOrig);
+    result = SendMessage(parentWindow, WM_ERASEBKGND, wParam, 0);
+    SetWindowOrgEx(reinterpret_cast<HDC>(wParam), ptOrig.x, ptOrig.y, NULL);
+    if (result == 0)
+    {
+        bHandled = FALSE;
+        return 0;
+    }
+    return result;
 }
 
 LRESULT CAddressBand::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 {
-       RECT                                                                    goButtonBounds;
-       RECT                                                                    buttonBounds;
-       long                                                                    buttonWidth;
-       long                                                                    buttonHeight;
-       RECT                                                                    comboBoxBounds;
-       long                                                                    newHeight;
-       long                                                                    newWidth;
-
-       if (fGoButtonShown == false)
-       {
-               bHandled = FALSE;
-               return 0;
-       }
-       newHeight = HIWORD(lParam);
-       newWidth = LOWORD(lParam);
-       SendMessage(fGoButton, TB_GETITEMRECT, 0, (LPARAM)&buttonBounds);
-       buttonWidth = buttonBounds.right - buttonBounds.left;
-       buttonHeight = buttonBounds.bottom - buttonBounds.top;
-       DefWindowProc(WM_SIZE, wParam, MAKELONG(newWidth - buttonWidth - 2, newHeight));
-       ::GetWindowRect(fComboBox, &comboBoxBounds);
-       ::SetWindowPos(fGoButton, NULL, newWidth - buttonWidth, (comboBoxBounds.bottom - comboBoxBounds.top - buttonHeight) / 2,
-                                       buttonWidth, buttonHeight, SWP_NOOWNERZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOZORDER);
-       goButtonBounds.left = newWidth - buttonWidth;
-       goButtonBounds.top = 0;
-       goButtonBounds.right = newWidth - buttonWidth;
-       goButtonBounds.bottom = newHeight;
-       InvalidateRect(&goButtonBounds, TRUE);
-       SendMessage(fComboBox, CB_SETDROPPEDWIDTH, 200, 0);
-       return 0;
+    RECT                                    goButtonBounds;
+    RECT                                    buttonBounds;
+    long                                    buttonWidth;
+    long                                    buttonHeight;
+    RECT                                    comboBoxBounds;
+    long                                    newHeight;
+    long                                    newWidth;
+
+    if (fGoButtonShown == false)
+    {
+        bHandled = FALSE;
+        return 0;
+    }
+
+    newHeight = HIWORD(lParam);
+    newWidth = LOWORD(lParam);
+
+    SendMessage(fGoButton, TB_GETITEMRECT, 0, reinterpret_cast<LPARAM>(&buttonBounds));
+    buttonWidth = buttonBounds.right - buttonBounds.left;
+    buttonHeight = buttonBounds.bottom - buttonBounds.top;
+
+    DefWindowProc(WM_SIZE, wParam, MAKELONG(newWidth - buttonWidth - 2, newHeight));
+    ::GetWindowRect(fComboBox, &comboBoxBounds);
+    ::SetWindowPos(fGoButton, NULL, newWidth - buttonWidth, (comboBoxBounds.bottom - comboBoxBounds.top - buttonHeight) / 2,
+                    buttonWidth, buttonHeight, SWP_NOOWNERZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOZORDER);
+
+    goButtonBounds.left = newWidth - buttonWidth;
+    goButtonBounds.top = 0;
+    goButtonBounds.right = newWidth - buttonWidth;
+    goButtonBounds.bottom = newHeight;
+    InvalidateRect(&goButtonBounds, TRUE);
+
+    SendMessage(fComboBox, CB_SETDROPPEDWIDTH, 200, 0);
+    return 0;
 }
 
 LRESULT CAddressBand::OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 {
-       RECT                                                                    goButtonBounds;
-       RECT                                                                    buttonBounds;
-       long                                                                    buttonWidth;
-       long                                                                    buttonHeight;
-       RECT                                                                    comboBoxBounds;
-       WINDOWPOS                                                               positionInfoCopy;
-       long                                                                    newHeight;
-       long                                                                    newWidth;
-
-       if (fGoButtonShown == false)
-       {
-               bHandled = FALSE;
-               return 0;
-       }
-       positionInfoCopy = *(WINDOWPOS *)lParam;
-       newHeight = positionInfoCopy.cy;
-       newWidth = positionInfoCopy.cx;
-       SendMessage(fGoButton, TB_GETITEMRECT, 0, (LPARAM)&buttonBounds);
-       buttonWidth = buttonBounds.right - buttonBounds.left;
-       buttonHeight = buttonBounds.bottom - buttonBounds.top;
-       positionInfoCopy.cx = newWidth - 2 - buttonWidth;
-       DefWindowProc(WM_WINDOWPOSCHANGING, wParam, (LPARAM)&positionInfoCopy);
-       ::GetWindowRect(fComboBox, &comboBoxBounds);
-       ::SetWindowPos(fGoButton, NULL, newWidth - buttonWidth, (comboBoxBounds.bottom - comboBoxBounds.top - buttonHeight) / 2,
-                                       buttonWidth, buttonHeight, SWP_NOOWNERZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOZORDER);
-       goButtonBounds.left = newWidth - buttonWidth;
-       goButtonBounds.top = 0;
-       goButtonBounds.right = newWidth - buttonWidth;
-       goButtonBounds.bottom = newHeight;
-       InvalidateRect(&goButtonBounds, TRUE);
-       SendMessage(fComboBox, CB_SETDROPPEDWIDTH, 200, 0);
-       return 0;
+    RECT                                    goButtonBounds;
+    RECT                                    buttonBounds;
+    long                                    buttonWidth;
+    long                                    buttonHeight;
+    RECT                                    comboBoxBounds;
+    WINDOWPOS                               positionInfoCopy;
+    long                                    newHeight;
+    long                                    newWidth;
+
+    if (!fGoButtonShown)
+    {
+        bHandled = FALSE;
+        return 0;
+    }
+
+    positionInfoCopy = *reinterpret_cast<WINDOWPOS *>(lParam);
+    newHeight = positionInfoCopy.cy;
+    newWidth = positionInfoCopy.cx;
+    SendMessage(fGoButton, TB_GETITEMRECT, 0, reinterpret_cast<LPARAM>(&buttonBounds));
+
+    buttonWidth = buttonBounds.right - buttonBounds.left;
+    buttonHeight = buttonBounds.bottom - buttonBounds.top;
+    positionInfoCopy.cx = newWidth - 2 - buttonWidth;
+    DefWindowProc(WM_WINDOWPOSCHANGING, wParam, reinterpret_cast<LPARAM>(&positionInfoCopy));
+    ::GetWindowRect(fComboBox, &comboBoxBounds);
+    ::SetWindowPos(fGoButton, NULL, newWidth - buttonWidth, (comboBoxBounds.bottom - comboBoxBounds.top - buttonHeight) / 2,
+                    buttonWidth, buttonHeight, SWP_NOOWNERZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOZORDER);
+
+    goButtonBounds.left = newWidth - buttonWidth;
+    goButtonBounds.top = 0;
+    goButtonBounds.right = newWidth - buttonWidth;
+    goButtonBounds.bottom = newHeight;
+    InvalidateRect(&goButtonBounds, TRUE);
+
+    SendMessage(fComboBox, CB_SETDROPPEDWIDTH, 200, 0);
+    return 0;
 }
 
 HRESULT CreateAddressBand(REFIID riid, void **ppv)
 {
-       CComObject<CAddressBand>                                *theMenuBar;
-       HRESULT                                                                 hResult;
-
-       if (ppv == NULL)
-               return E_POINTER;
-       *ppv = NULL;
-       ATLTRY (theMenuBar = new CComObject<CAddressBand>);
-       if (theMenuBar == NULL)
-               return E_OUTOFMEMORY;
-       hResult = theMenuBar->QueryInterface (riid, (void **)ppv);
-       if (FAILED (hResult))
-       {
-               delete theMenuBar;
-               return hResult;
-       }
-       return S_OK;
+    CComObject<CAddressBand>                *theMenuBar;
+    HRESULT                                 hResult;
+
+    if (ppv == NULL)
+        return E_POINTER;
+    *ppv = NULL;
+    ATLTRY (theMenuBar = new CComObject<CAddressBand>);
+    if (theMenuBar == NULL)
+        return E_OUTOFMEMORY;
+    hResult = theMenuBar->QueryInterface(riid, reinterpret_cast<void **>(ppv));
+    if (FAILED(hResult))
+    {
+        delete theMenuBar;
+        return hResult;
+    }
+    return S_OK;
 }