Sync with trunk r63502.
authorDavid Quintana <gigaherz@gmail.com>
Fri, 30 May 2014 17:56:10 +0000 (17:56 +0000)
committerDavid Quintana <gigaherz@gmail.com>
Fri, 30 May 2014 17:56:10 +0000 (17:56 +0000)
svn path=/branches/shell-experiments/; revision=63503

157 files changed:
1  2 
base/applications/cmdutils/help/help.c
base/applications/mscutils/servman/precomp.h
base/applications/mscutils/servman/propsheet_depends.c
base/applications/mscutils/servman/query.c
base/applications/mscutils/servman/stop_dependencies.c
base/applications/mstsc/connectdialog.c
base/applications/network/net/CMakeLists.txt
base/applications/network/net/cmdAccounts.c
base/applications/network/net/main.c
base/applications/network/net/net.h
base/applications/shutdown/shutdown.c
base/services/tcpsvcs/discard.c
base/services/tcpsvcs/echo.c
base/services/tcpsvcs/skelserver.c
base/services/tcpsvcs/tcpsvcs.c
base/services/tcpsvcs/tcpsvcs.h
base/setup/setup/setup.c
base/system/userinit/CMakeLists.txt
base/system/userinit/userinit.c
boot/bootdata/CMakeLists.txt
boot/bootdata/hivecls.inf
boot/bootdata/hivedef.inf
boot/bootdata/hivesft.inf
boot/bootdata/hivesys.inf
cmake/CMakeMacros.cmake
cmake/msvc.cmake
dll/cpl/appwiz/createlink.c
dll/ntdll/def/ntdll.spec
dll/win32/advapi32/misc/logon.c
dll/win32/browseui/internettoolbar.cpp
dll/win32/browseui/shellbrowser.cpp
dll/win32/kernel32/client/file/copy.c
dll/win32/lsasrv/authpackage.c
dll/win32/msgina/lsa.c
dll/win32/msvcrt/msvcrt.spec
dll/win32/powrprof/powrprof.c
dll/win32/setupapi/CMakeLists.txt
dll/win32/setupapi/dirid.c
dll/win32/setupapi/setupapi_private.h
include/asm/CMakeLists.txt
include/asm/genincdata.c
include/asm/ksarm.template.h
include/asm/kxarm.h
include/crt/conio.h
include/crt/crtdefs.h
include/crt/msc/intrin.h
include/ndk/arm/ketypes.h
include/psdk/basetsd.h
include/psdk/ntdef.h
include/psdk/ras.h
include/psdk/wingdi.h
include/psdk/winnls.h
include/psdk/winnt.h
include/reactos/arm/armddk.h
include/reactos/idl/ms-dtyp.idl
include/reactos/libs/fast486/fast486.h
include/reactos/msvctarget.h
lib/3rdparty/stlport/src/stdio_streambuf.cpp
lib/atl/statreg.h
lib/fast486/common.c
lib/fast486/common.h
lib/fast486/common.inl
lib/fast486/opcodes.c
lib/fast486/opgroups.c
lib/pseh/CMakeLists.txt
lib/rtl/bitmap.c
lib/sdk/crt/crt.cmake
lib/sdk/crt/include/internal/locale.h
lib/sdk/crt/libcntpr.cmake
lib/sdk/crt/string/scanf.c
lib/sdk/crt/string/scanf.h
lib/sdk/crt/string/winesup.c
lib/sdk/crt/string/winesup.h
media/doc/3rd Party Files.txt
media/fonts/CMakeLists.txt
media/fonts/OpenSans-Bold.ttf
media/fonts/OpenSans-BoldItalic.ttf
media/fonts/OpenSans-CondBold.ttf
media/fonts/OpenSans-CondLight.ttf
media/fonts/OpenSans-CondLightItalic.ttf
media/fonts/OpenSans-ExtraBold.ttf
media/fonts/OpenSans-ExtraBoldItalic.ttf
media/fonts/OpenSans-Italic.ttf
media/fonts/OpenSans-Light.ttf
media/fonts/OpenSans-LightItalic.ttf
media/fonts/OpenSans-Regular.ttf
media/fonts/OpenSans-Semibold.ttf
media/fonts/OpenSans-SemiboldItalic.ttf
media/fonts/Ubuntu-B.ttf
media/fonts/Ubuntu-BI.ttf
media/fonts/Ubuntu-C.ttf
media/fonts/Ubuntu-L.ttf
media/fonts/Ubuntu-LI.ttf
media/fonts/Ubuntu-M.ttf
media/fonts/Ubuntu-MI.ttf
media/fonts/Ubuntu-R.ttf
media/fonts/Ubuntu-RI.ttf
media/fonts/UbuntuMono-B.ttf
media/fonts/UbuntuMono-BI.ttf
media/fonts/UbuntuMono-R.ttf
media/fonts/UbuntuMono-RI.ttf
media/fonts/doc/OpenSans/Apache License.txt
media/fonts/doc/Ubuntu/CONTRIBUTING.txt
media/fonts/doc/Ubuntu/FONTLOG.txt
media/fonts/doc/Ubuntu/LICENCE-FAQ.txt
media/fonts/doc/Ubuntu/LICENCE.txt
media/fonts/doc/Ubuntu/README.txt
media/fonts/doc/Ubuntu/TRADEMARKS.txt
media/fonts/doc/Ubuntu/copyright.txt
media/themes/lautus.msstyles/textfiles/ExtraLargeNormal.INI
ntoskrnl/config/cmapi.c
ntoskrnl/config/cminit.c
ntoskrnl/config/cmvalue.c
ntoskrnl/config/ntapi.c
ntoskrnl/include/internal/cm.h
ntoskrnl/lpc/complete.c
ntoskrnl/lpc/create.c
ntoskrnl/mm/ARM3/virtual.c
subsystems/ntvdm/dos/dos32krnl/dos.c
subsystems/ntvdm/dos/dos32krnl/dos.h
toolchain-msvc.cmake
win32ss/gdi/gdi32/misc/gdientry.c
win32ss/gdi/ntgdi/bitblt.c
win32ss/include/ntuser.h
win32ss/user/ntuser/desktop.h
win32ss/user/ntuser/menu.c
win32ss/user/ntuser/menu.h
win32ss/user/ntuser/window.c
win32ss/user/ntuser/winpos.c
win32ss/user/ntuser/winsta.c
win32ss/user/ntuser/winsta.h
win32ss/user/user32/lang/bg-BG.rc
win32ss/user/user32/lang/cs-CZ.rc
win32ss/user/user32/lang/da-DK.rc
win32ss/user/user32/lang/de-DE.rc
win32ss/user/user32/lang/el-GR.rc
win32ss/user/user32/lang/en-US.rc
win32ss/user/user32/lang/es-ES.rc
win32ss/user/user32/lang/fr-FR.rc
win32ss/user/user32/lang/he-IL.rc
win32ss/user/user32/lang/hu-HU.rc
win32ss/user/user32/lang/id-ID.rc
win32ss/user/user32/lang/it-IT.rc
win32ss/user/user32/lang/ja-JP.rc
win32ss/user/user32/lang/lt-LT.rc
win32ss/user/user32/lang/nl-NL.rc
win32ss/user/user32/lang/no-NO.rc
win32ss/user/user32/lang/pl-PL.rc
win32ss/user/user32/lang/pt-BR.rc
win32ss/user/user32/lang/ro-RO.rc
win32ss/user/user32/lang/ru-RU.rc
win32ss/user/user32/lang/sk-SK.rc
win32ss/user/user32/lang/sv-SE.rc
win32ss/user/user32/lang/tr-TR.rc
win32ss/user/user32/lang/uk-UA.rc
win32ss/user/user32/lang/zh-CN.rc
win32ss/user/user32/windows/menu.c

Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index bcb87bb,0000000..a7fd294
mode 100644,000000..100644
--- /dev/null
@@@ -1,1777 -1,0 +1,1777 @@@
- #define USE_CUSTOM_MENUBAND 1
 +/*
 + * ReactOS Explorer
 + *
 + * Copyright 2009 Andrew Hill <ash77 at domain reactos.org>
 + *
 + * This library is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * This library is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with this library; if not, write to the Free Software
 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + */
 +
 +/*
 +Implements a class that knows how to hold and manage the menu band, brand band,
 +toolbar, and address band for an explorer window
 +*/
 +
 +#include "precomp.h"
 +
 +/* FIXME, I can't include windowsx because it conflicts with some #defines */
 +#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
 +#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
 +
++#define USE_CUSTOM_MENUBAND 0
 +
 +// navigation controls and menubar just send a message to parent window
 +/*
 +TODO:
 +****Implement BandProxy methods
 +****Add QueryStatus handler for built-in bands
 +****Enable/Disable up, search, and folders commands appropriately
 +  **Why are explorer toolbar separators a nonstandard width?
 +  **Remove "(Empty)" item from Favorites menu. Probably something missing in CMenuCallback::CallbackSM
 +  **Chevron menu on menuband doesn't work
 +  **Fix CInternetToolbar::QueryBand to be generic
 +
 +****Fix context menu to strip divider when menu shown for menu band
 +****Fix context menu to have items checked appropriately
 +****Implement -1 command id update
 +****When bands are rearranged, resize the internet toolbar and fix height of brand band
 +****Right clicking on the browse back and forward toolbar buttons displays the same as pulldown menus
 +    Implement show/hide of bands
 +    Why is the background color of my toolbars different from explorer?
 +    Internet Toolbar command handler should get the target for the command and call Exec on the target.
 +        For commands built in to the Internet Toolbar, its Exec handles the command
 +    When window width is changed, brand band flashes badly
 +    Add all bands with correct ids (system bands now add with correct ids)
 +    Implement IBandSite
 +    Implement remaining IExplorerToolbar methods
 +    Fix toolbar buttons to enable/disable correctly
 +    After toolbar is customized, it may be necessary to patch the widths of separators
 +    Add theme support
 +    Check sizes and spacing of toolbars against Explorer
 +    Implement resizing of the dock bar
 +    Add missing icons for toolbar items
 +    Draw History item in forward/back dropdown menus with icon
 +    Fix toolbar customize dialog to not include separators as possible selections
 +    Implement save/restore of toolbar state
 +    Refactor drop down menu code to use a common function since code is so similar
 +*/
 +
 +extern HRESULT WINAPI SHBindToFolder(LPCITEMIDLIST path, IShellFolder **newFolder);
 +extern HRESULT CreateToolsBar(REFIID riid, void **ppv);
 +extern HRESULT CreateBrandBand(REFIID riid, void **ppv);
 +extern HRESULT CreateBandProxy(REFIID riid, void **ppv);
 +extern HRESULT CreateAddressBand(REFIID riid, void **ppv);
 +
 +typedef HRESULT(*PMENUBAND_CONSTRUCTOR)(REFIID riid, void **ppv);
 +
 +class CInternetToolbar;
 +
 +class CDockSite :
 +    public CComObjectRootEx<CComMultiThreadModelNoCS>,
 +    public IDockingWindowSite,
 +    public IInputObjectSite,
 +    public IOleCommandTarget,
 +    public IServiceProvider
 +{
 +public:
 +    enum {
 +        ITF_NOGRIPPER = 1,
 +        ITF_NOTITLE = 2,
 +        ITF_NEWBANDALWAYS = 4,
 +        ITF_GRIPPERALWAYS = 8,
 +        ITF_FIXEDSIZE = 16
 +    };
 +private:
 +    CComPtr<IUnknown>                       fContainedBand;         // the band inside us
 +    CInternetToolbar                        *fToolbar;              // our browser
 +    HWND                                    fRebarWindow;
 +    HWND                                    fChildWindow;
 +    int                                     fBandID;
 +public:
 +    int                                     fFlags;
 +private:
 +    bool                                    fInitialized;
 +    // fields of DESKBANDINFO must be preserved between calls to GetBandInfo
 +    DESKBANDINFO                            fDeskBandInfo;
 +public:
 +    CDockSite();
 +    ~CDockSite();
 +    HRESULT Initialize(IUnknown *containedBand, CInternetToolbar *browser, HWND hwnd, int bandID, int flags);
 +    HRESULT GetRBBandInfo(REBARBANDINFOW &bandInfo);
 +private:
 +
 +    // *** IOleWindow methods ***
 +    virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd);
 +    virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
 +
 +    // *** IDockingWindow methods ***
 +    virtual HRESULT STDMETHODCALLTYPE GetBorderDW(IUnknown* punkObj, LPRECT prcBorder);
 +    virtual HRESULT STDMETHODCALLTYPE RequestBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw);
 +    virtual HRESULT STDMETHODCALLTYPE SetBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw);
 +
 +    // *** IInputObjectSite specific methods ***
 +    virtual HRESULT STDMETHODCALLTYPE OnFocusChangeIS(IUnknown *punkObj, BOOL fSetFocus);
 +
 +    // *** IOleCommandTarget specific methods ***
 +    virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds,
 +        OLECMD prgCmds[  ], OLECMDTEXT *pCmdText);
 +    virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
 +        DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut);
 +
 +    // *** IServiceProvider methods ***
 +    virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
 +
 +BEGIN_COM_MAP(CDockSite)
 +    COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
 +    COM_INTERFACE_ENTRY_IID(IID_IDockingWindowSite, IDockingWindowSite)
 +    COM_INTERFACE_ENTRY_IID(IID_IInputObjectSite, IInputObjectSite)
 +    COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
 +    COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
 +END_COM_MAP()
 +};
 +
 +CDockSite::CDockSite()
 +{
 +    fToolbar = NULL;
 +    fRebarWindow = NULL;
 +    fChildWindow = NULL;
 +    fBandID = 0;
 +    fFlags = 0;
 +    fInitialized = false;
 +    memset(&fDeskBandInfo, 0, sizeof(fDeskBandInfo));
 +}
 +
 +CDockSite::~CDockSite()
 +{
 +}
 +
 +HRESULT CDockSite::Initialize(IUnknown *containedBand, CInternetToolbar *browser, HWND hwnd, int bandID, int flags)
 +{
 +    CComPtr<IObjectWithSite>                child;
 +    CComPtr<IOleWindow>                     oleWindow;
 +    CComPtr<IDeskBand>                      deskBand;
 +    TCHAR                                   textBuffer[40];
 +    REBARBANDINFOW                          bandInfo;
 +    HRESULT                                 hResult;
 +
 +    hResult = containedBand->QueryInterface(IID_PPV_ARG(IObjectWithSite, &child));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = containedBand->QueryInterface(IID_PPV_ARG(IOleWindow, &oleWindow));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = containedBand->QueryInterface(IID_PPV_ARG(IDeskBand, &deskBand));
 +    if (FAILED(hResult))
 +        return hResult;
 +    fContainedBand = containedBand;
 +    fToolbar = browser;
 +    fRebarWindow = hwnd;
 +    fBandID = bandID;
 +    fFlags = flags;
 +    hResult = child->SetSite(static_cast<IOleWindow *>(this));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = oleWindow->GetWindow(&fChildWindow);
 +    if (FAILED(hResult))
 +        return hResult;
 +
 +    memset(&bandInfo, 0, sizeof(bandInfo));
 +    bandInfo.cbSize = sizeof(bandInfo);
 +    bandInfo.lpText = textBuffer;
 +    bandInfo.cch = sizeof(textBuffer) / sizeof(TCHAR);
 +    hResult = GetRBBandInfo(bandInfo);
 +
 +    SendMessage(fRebarWindow, RB_GETBANDCOUNT, 0, 0);
 +    SendMessage(fRebarWindow, RB_INSERTBANDW, -1, (LPARAM)&bandInfo);
 +    fInitialized = true;
 +    return S_OK;
 +}
 +
 +HRESULT CDockSite::GetRBBandInfo(REBARBANDINFOW &bandInfo)
 +{
 +    CComPtr<IDeskBand>                      deskBand;
 +    HRESULT                                 hResult;
 +
 +    hResult = fContainedBand->QueryInterface(IID_PPV_ARG(IDeskBand, &deskBand));
 +    if (FAILED(hResult))
 +        return hResult;
 +
 +    fDeskBandInfo.dwMask = DBIM_BKCOLOR | DBIM_MODEFLAGS | DBIM_TITLE | DBIM_ACTUAL |
 +        DBIM_INTEGRAL | DBIM_MAXSIZE | DBIM_MINSIZE;
 +    hResult = deskBand->GetBandInfo(fBandID, 0, &fDeskBandInfo);
 +    // result of call is ignored
 +
 +    bandInfo.fMask = RBBIM_LPARAM | RBBIM_IDEALSIZE | RBBIM_ID | RBBIM_CHILDSIZE | RBBIM_CHILD |
 +        RBBIM_TEXT | RBBIM_STYLE;
 +
 +    bandInfo.fStyle = RBBS_FIXEDBMP;
 +    if (fDeskBandInfo.dwModeFlags & DBIMF_VARIABLEHEIGHT)
 +        bandInfo.fStyle |= RBBS_VARIABLEHEIGHT;
 +    if (fDeskBandInfo.dwModeFlags & DBIMF_USECHEVRON)
 +        bandInfo.fStyle |= RBBS_USECHEVRON;
 +    if (fDeskBandInfo.dwModeFlags & DBIMF_BREAK)
 +        bandInfo.fStyle |= RBBS_BREAK;
 +    if (fDeskBandInfo.dwModeFlags & DBIMF_TOPALIGN)
 +        bandInfo.fStyle |= RBBS_TOPALIGN;
 +    if (fFlags & ITF_NOGRIPPER || fToolbar->fLocked)
 +        bandInfo.fStyle |= RBBS_NOGRIPPER;
 +    if (fFlags & ITF_NOTITLE)
 +        bandInfo.fStyle |= RBBS_HIDETITLE;
 +    if (fFlags & ITF_GRIPPERALWAYS && !fToolbar->fLocked)
 +        bandInfo.fStyle |= RBBS_GRIPPERALWAYS;
 +    if (fFlags & ITF_FIXEDSIZE)
 +        bandInfo.fStyle |= RBBS_FIXEDSIZE;
 +
 +    if (fDeskBandInfo.dwModeFlags & DBIMF_BKCOLOR)
 +    {
 +        bandInfo.fMask |= RBBIM_COLORS;
 +        bandInfo.clrFore = CLR_DEFAULT;
 +        bandInfo.clrBack = fDeskBandInfo.crBkgnd;
 +    }
 +    wcsncpy(bandInfo.lpText, fDeskBandInfo.wszTitle, bandInfo.cch);
 +    bandInfo.hwndChild = fChildWindow;
 +    bandInfo.cxMinChild = fDeskBandInfo.ptMinSize.x;
 +    bandInfo.cyMinChild = fDeskBandInfo.ptMinSize.y;
 +    bandInfo.wID = fBandID;
 +    bandInfo.cyChild = fDeskBandInfo.ptActual.y;
 +    bandInfo.cyMaxChild = fDeskBandInfo.ptMaxSize.y;
 +    bandInfo.cyIntegral = fDeskBandInfo.ptIntegral.y;
 +    bandInfo.cxIdeal = fDeskBandInfo.ptActual.x;
 +    bandInfo.lParam = reinterpret_cast<LPARAM>(this);
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CDockSite::GetWindow(HWND *lphwnd)
 +{
 +    if (lphwnd == NULL)
 +        return E_POINTER;
 +    *lphwnd = fRebarWindow;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CDockSite::ContextSensitiveHelp(BOOL fEnterMode)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CDockSite::GetBorderDW(IUnknown* punkObj, LPRECT prcBorder)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CDockSite::RequestBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CDockSite::SetBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CDockSite::OnFocusChangeIS (IUnknown *punkObj, BOOL fSetFocus)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CDockSite::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds,
 +    OLECMD prgCmds[  ], OLECMDTEXT *pCmdText)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CDockSite::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt,
 +    VARIANT *pvaIn, VARIANT *pvaOut)
 +{
 +    TCHAR                                   textBuffer[40];
 +    REBARBANDINFOW                          bandInfo;
 +    int                                     index;
 +    HRESULT                                 hResult;
 +
 +    if (IsEqualIID(*pguidCmdGroup, CGID_DeskBand))
 +    {
 +        switch (nCmdID)
 +        {
 +            case DBID_BANDINFOCHANGED:
 +                if (fInitialized == false)
 +                    return S_OK;
 +                if (V_VT(pvaIn) != VT_I4)
 +                    return E_INVALIDARG;
 +                if (V_I4(pvaIn) != fBandID)
 +                    return E_FAIL;
 +                // deskband information changed
 +                // call GetBandInfo and refresh information in rebar
 +                memset(&bandInfo, 0, sizeof(bandInfo));
 +                bandInfo.cbSize = sizeof(bandInfo);
 +                bandInfo.lpText = textBuffer;
 +                bandInfo.cch = sizeof(textBuffer) / sizeof(TCHAR);
 +                hResult = GetRBBandInfo(bandInfo);
 +                if (FAILED(hResult))
 +                    return hResult;
 +                index = (int)SendMessage(fRebarWindow, RB_IDTOINDEX, fBandID, 0);
 +                SendMessage(fRebarWindow, RB_SETBANDINFOW, index, (LPARAM)&bandInfo);
 +                return S_OK;
 +        }
 +    }
 +    return E_FAIL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CDockSite::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
 +{
 +    if (IsEqualIID(guidService, SID_SMenuBandParent))
 +        return this->QueryInterface(riid, ppvObject);
 +
 +    return fToolbar->QueryService(guidService, riid, ppvObject);
 +}
 +
 +CMenuCallback::CMenuCallback()
 +{
 +}
 +
 +CMenuCallback::~CMenuCallback()
 +{
 +}
 +
 +HRESULT STDMETHODCALLTYPE CMenuCallback::GetObject(LPSMDATA psmd, REFIID riid, void **ppvObject)
 +{
 +    CComPtr<IShellMenu>                     parentMenu;
 +    CComPtr<IShellMenu>                     newMenu;
 +    CComPtr<IShellFolder>                   favoritesFolder;
 +    LPITEMIDLIST                            favoritesPIDL;
 +    HWND                                    ownerWindow;
 +    HMENU                                   parentHMenu;
 +    HMENU                                   favoritesHMenu;
 +    HKEY                                    orderRegKey;
 +    DWORD                                   disposition;
 +    HRESULT                                 hResult;
 +    static const TCHAR szFavoritesKey[] =
 +        _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MenuOrder\\Favorites");
 +
 +    if (!IsEqualIID(riid, IID_IShellMenu))
 +        return E_FAIL;
 +    if (psmd->uId != FCIDM_MENU_FAVORITES)
 +        return E_FAIL;
 +
 +    if (fFavoritesMenu.p == NULL)
 +    {
 +        // create favorites menu
 +        hResult = psmd->punk->QueryInterface(IID_PPV_ARG(IShellMenu, &parentMenu));
 +        if (FAILED(hResult))
 +            return hResult;
 +        hResult = parentMenu->GetMenu(&parentHMenu, &ownerWindow, NULL);
 +        if (FAILED(hResult))
 +            return hResult;
 +        favoritesHMenu = GetSubMenu(parentHMenu, 3);
 +        if (favoritesHMenu == NULL)
 +            return E_FAIL;
 +#if USE_CUSTOM_MENUBAND
 +        HMODULE hrs = LoadLibrary(L"rshell.dll");
 +
 +        PMENUBAND_CONSTRUCTOR func = (PMENUBAND_CONSTRUCTOR) GetProcAddress(hrs, "CMenuBand_Constructor");
 +        if (func)
 +        {
 +            hResult = func(IID_PPV_ARG(IShellMenu, &newMenu));
 +        }
 +        else
 +        {
 +            hResult = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER,
 +                IID_PPV_ARG(IShellMenu, &newMenu));
 +        }
 +#else
 +        hResult = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER,
 +            IID_PPV_ARG(IShellMenu, &newMenu));
 +#endif
 +        if (FAILED(hResult))
 +            return hResult;
 +        hResult = newMenu->Initialize(this, FCIDM_MENU_FAVORITES, -1, SMINIT_VERTICAL | SMINIT_CACHED);
 +        if (FAILED(hResult))
 +            return hResult;
 +        hResult = newMenu->SetMenu(favoritesHMenu, ownerWindow, SMSET_TOP | SMSET_DONTOWN);
 +        if (FAILED(hResult))
 +            return hResult;
 +        hResult = SHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &favoritesPIDL);
 +        if (FAILED(hResult))
 +            return hResult;
 +        hResult = SHBindToFolder(favoritesPIDL, &favoritesFolder);
 +        if (FAILED(hResult))
 +            return hResult;
 +        RegCreateKeyEx(HKEY_CURRENT_USER, szFavoritesKey,
 +                0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &orderRegKey, &disposition);
 +        hResult = newMenu->SetShellFolder(favoritesFolder, favoritesPIDL, orderRegKey, SMSET_BOTTOM | 0x18);
 +        ILFree(favoritesPIDL);
 +        if (SUCCEEDED(hResult))
 +            fFavoritesMenu.Attach(newMenu.Detach());
 +    }
 +    if (fFavoritesMenu.p == NULL)
 +        return E_FAIL;
 +    return fFavoritesMenu->QueryInterface(riid, ppvObject);
 +}
 +
 +HRESULT STDMETHODCALLTYPE CMenuCallback::CallbackSM(LPSMDATA psmd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 +{
 +    switch (uMsg)
 +    {
 +        case SMC_INITMENU:
 +            break;
 +        case SMC_CREATE:
 +            break;
 +        case SMC_EXITMENU:
 +            break;
 +        case SMC_GETINFO:
 +        {
 +            SMINFO *infoPtr = reinterpret_cast<SMINFO *>(lParam);
 +            if ((infoPtr->dwMask & SMIM_FLAGS) != 0)
 +            {
 +                if (psmd->uId == FCIDM_MENU_FAVORITES)
 +                {
 +                    infoPtr->dwFlags |= SMIF_DROPCASCADE;
 +                }
 +                else
 +                {
 +                    infoPtr->dwFlags |= SMIF_TRACKPOPUP;
 +                }
 +            }
 +            if ((infoPtr->dwMask & SMIM_ICON) != 0)
 +                infoPtr->iIcon = -1;
 +            return S_OK;
 +        }
 +        case SMC_GETSFINFO:
 +            break;
 +        case SMC_GETOBJECT:
 +            return GetObject(psmd, *reinterpret_cast<IID *>(wParam), reinterpret_cast<void **>(lParam));
 +        case SMC_GETSFOBJECT:
 +            break;
 +        case SMC_SFEXEC:
 +            break;
 +        case SMC_SFSELECTITEM:
 +            break;
 +        case 13:
 +            // return tooltip
 +            break;
 +        case SMC_REFRESH:
 +            break;
 +        case SMC_DEMOTE:
 +            break;
 +        case SMC_PROMOTE:
 +            break;
 +        case 0x13:
 +            break;
 +        case SMC_DEFAULTICON:
 +            break;
 +        case SMC_NEWITEM:
 +            break;
 +        case SMC_CHEVRONEXPAND:
 +            break;
 +        case SMC_DISPLAYCHEVRONTIP:
 +            break;
 +        case SMC_SETSFOBJECT:
 +            break;
 +        case SMC_SHCHANGENOTIFY:
 +            break;
 +        case SMC_CHEVRONGETTIP:
 +            break;
 +        case SMC_SFDDRESTRICTED:
 +            break;
 +        case 0x35:
 +            break;
 +        case 49:
 +            break;
 +        case 0x10000000:
 +            break;
 +    }
 +    return S_FALSE;
 +}
 +
 +CInternetToolbar::CInternetToolbar()
 +{
 +    fMainReBar = NULL;
 +    fLocked = false;
 +    fMenuBandWindow = NULL;
 +    fNavigationWindow = NULL;
 +    fMenuCallback.AddRef();
 +    fToolbarWindow = NULL;
 +    fAdviseCookie = 0;
 +}
 +
 +CInternetToolbar::~CInternetToolbar()
 +{
 +    fMenuCallback.Release();
 +}
 +
 +void CInternetToolbar::AddDockItem(IUnknown *newItem, int bandID, int flags)
 +{
 +    CDockSite           *newSite;
 +
 +    newSite = new CComObject<CDockSite>;
 +    newSite->AddRef();
 +    newSite->Initialize(newItem, this, fMainReBar, bandID, flags);
 +}
 +
 +HRESULT CInternetToolbar::ReserveBorderSpace(LONG maxHeight)
 +{
 +    CComPtr<IDockingWindowSite>             dockingWindowSite;
 +    RECT                                    availableBorderSpace;
 +
 +    HRESULT hResult = fSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &dockingWindowSite));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = dockingWindowSite->GetBorderDW(static_cast<IDockingWindow *>(this), &availableBorderSpace);
 +    if (FAILED(hResult))
 +        return hResult;
 +
 +    if (availableBorderSpace.top > maxHeight)
 +    {
 +        availableBorderSpace.top = maxHeight;
 +    }
 +
 +    return ResizeBorderDW(&availableBorderSpace, fSite, FALSE);
 +}
 +
 +HRESULT CInternetToolbar::CreateMenuBar(IShellMenu **menuBar)
 +{
 +    CComPtr<IOleCommandTarget>              siteCommandTarget;
 +    CComPtr<IOleWindow>                     oleWindow;
 +    CComPtr<IOleCommandTarget>              commandTarget;
 +    CComPtr<IShellMenuCallback>             callback;
 +    VARIANT                                 menuOut;
 +    HWND                                    ownerWindow;
 +    HRESULT                                 hResult;
 +
 +#if USE_CUSTOM_MENUBAND
 +    HMODULE hrs = LoadLibraryW(L"rshell.dll");
 +
 +    if (!hrs)
 +    {
 +        DbgPrint("Failed: %d\n", GetLastError());
 +        return E_FAIL;
 +    }
 +
 +    PMENUBAND_CONSTRUCTOR func = (PMENUBAND_CONSTRUCTOR) GetProcAddress(hrs, "CMenuBand_Constructor");
 +    if (func)
 +    {
 +        hResult = func(IID_PPV_ARG(IShellMenu, menuBar));
 +    }
 +    else
 +    {
 +        DbgPrint("Failed: %d\n", GetLastError());
 +        hResult = E_FAIL;
 +    }
 +    
 +    if (FAILED(hResult))
 +    {
 +        hResult = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER,
 +            IID_PPV_ARG(IShellMenu, menuBar));
 +    }
 +#else
 +    hResult = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER,
 +        IID_PPV_ARG(IShellMenu, menuBar));
 +#endif
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = fMenuCallback.QueryInterface(IID_PPV_ARG(IShellMenuCallback, &callback));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = (*menuBar)->Initialize(callback, -1, ANCESTORDEFAULT, SMINIT_HORIZONTAL | SMINIT_TOPLEVEL);
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = fSite->QueryInterface(IID_PPV_ARG(IOleWindow, &oleWindow));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = oleWindow->GetWindow(&ownerWindow);
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = fSite->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &siteCommandTarget));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = siteCommandTarget->Exec(&CGID_Explorer, 0x35, 0, NULL, &menuOut);
 +    if (FAILED(hResult))
 +        return hResult;
 +    if (V_VT(&menuOut) != VT_INT_PTR || V_INTREF(&menuOut) == NULL)
 +        return E_FAIL;
 +    hResult = (*menuBar)->SetMenu((HMENU)V_INTREF(&menuOut), ownerWindow, SMSET_DONTOWN);
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = (*menuBar)->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &commandTarget));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = commandTarget->Exec(&CGID_MenuBand, 3, 1, NULL, NULL);
 +    if (FAILED(hResult))
 +        return hResult;
 +    return S_OK;
 +}
 +
 +HRESULT CInternetToolbar::CreateBrandBand(IUnknown **logoBar)
 +{
 +    CComPtr<IUnknown>                       tempBand;
 +    HRESULT                                 hResult;
 +
 +#if 1
 +    hResult = ::CreateBrandBand(IID_PPV_ARG(IUnknown, logoBar));
 +#else
 +    hResult = CoCreateInstance(CLSID_BrandBand, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, logoBar));
 +#endif
 +    if (FAILED(hResult))
 +        return hResult;
 +    return S_OK;
 +}
 +
 +HRESULT CInternetToolbar::CreateToolsBar(IUnknown **toolsBar)
 +{
 +    HRESULT                                 hResult;
 +
 +    hResult = ::CreateToolsBar(IID_PPV_ARG(IUnknown, toolsBar));
 +    if (FAILED(hResult))
 +        return hResult;
 +    return S_OK;
 +}
 +
 +HRESULT CInternetToolbar::CreateAddressBand(IUnknown **toolsBar)
 +{
 +    CComPtr<IAddressBand>                   addressBand;
 +    HRESULT                                 hResult;
 +
 +#if 1
 +    hResult = ::CreateAddressBand(IID_PPV_ARG(IUnknown, toolsBar));
 +#else
 +    hResult = CoCreateInstance(CLSID_SH_AddressBand, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, toolsBar));
 +#endif
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = (*toolsBar)->QueryInterface(IID_PPV_ARG(IAddressBand, &addressBand));
 +    return S_OK;
 +}
 +
 +HRESULT CInternetToolbar::LockUnlockToolbars(bool locked)
 +{
 +    REBARBANDINFOW                          rebarBandInfo;
 +    int                                     bandCount;
 +    CDockSite                               *dockSite;
 +    HRESULT                                 hResult;
 +
 +    if (locked != fLocked)
 +    {
 +        fLocked = locked;
 +        rebarBandInfo.cbSize = sizeof(rebarBandInfo);
 +        rebarBandInfo.fMask = RBBIM_STYLE | RBBIM_LPARAM;
 +        bandCount = (int)SendMessage(fMainReBar, RB_GETBANDCOUNT, 0, 0);
 +        for (INT x  = 0; x < bandCount; x++)
 +        {
 +            SendMessage(fMainReBar, RB_GETBANDINFOW, x, (LPARAM)&rebarBandInfo);
 +            dockSite = reinterpret_cast<CDockSite *>(rebarBandInfo.lParam);
 +            if (dockSite != NULL)
 +            {
 +                rebarBandInfo.fStyle &= ~(RBBS_NOGRIPPER | RBBS_GRIPPERALWAYS);
 +                if (dockSite->fFlags & CDockSite::ITF_NOGRIPPER || fLocked)
 +                    rebarBandInfo.fStyle |= RBBS_NOGRIPPER;
 +                if (dockSite->fFlags & CDockSite::ITF_GRIPPERALWAYS && !fLocked)
 +                    rebarBandInfo.fStyle |= RBBS_GRIPPERALWAYS;
 +                SendMessage(fMainReBar, RB_SETBANDINFOW, x, (LPARAM)&rebarBandInfo);
 +            }
 +        }
 +        hResult = ReserveBorderSpace();
 +
 +        // TODO: refresh view menu?
 +    }
 +    return S_OK;
 +}
 +
 +HRESULT CInternetToolbar::CommandStateChanged(bool newValue, int commandID)
 +{
 +    HRESULT                                 hResult;
 +
 +    hResult = S_OK;
 +    switch (commandID)
 +    {
 +        case -1:
 +            // loop through buttons
 +            //for buttons in CLSID_CommonButtons
 +            //    if up, QueryStatus for up state and update it
 +            //
 +            //for buttons in fCommandCategory, update with QueryStatus of fCommandTarget
 +            break;
 +        case 1:
 +            // forward
 +            hResult = SetState(&CLSID_CommonButtons, IDM_GOTO_FORWARD, newValue ? TBSTATE_ENABLED : 0);
 +            break;
 +        case 2:
 +            // back
 +            hResult = SetState(&CLSID_CommonButtons, IDM_GOTO_BACK, newValue ? TBSTATE_ENABLED : 0);
 +            break;
 +    }
 +    return hResult;
 +}
 +
 +HRESULT CInternetToolbar::CreateAndInitBandProxy()
 +{
 +    CComPtr<IServiceProvider>               serviceProvider;
 +    HRESULT                                 hResult;
 +
 +    hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = serviceProvider->QueryService(SID_IBandProxy, IID_PPV_ARG(IBandProxy, &fBandProxy));
 +    if (FAILED(hResult))
 +    {
 +        hResult = CreateBandProxy(IID_PPV_ARG(IBandProxy, &fBandProxy));
 +        if (FAILED(hResult))
 +            return hResult;
 +        hResult = fBandProxy->SetSite(fSite);
 +        if (FAILED(hResult))
 +            return hResult;
 +    }
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::HasFocusIO()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::TranslateAcceleratorIO(LPMSG lpMsg)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::GetWindow(HWND *lphwnd)
 +{
 +    if (lphwnd == NULL)
 +        return E_POINTER;
 +    *lphwnd = m_hWnd;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::ContextSensitiveHelp(BOOL fEnterMode)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::ShowDW(BOOL fShow)
 +{
 +    CComPtr<IDockingWindow>     dockingWindow;
 +    HRESULT                     hResult;
 +
 +    // show the bar here
 +    hResult = ReserveBorderSpace();
 +    hResult = fMenuBar->QueryInterface(IID_PPV_ARG(IDockingWindow, &dockingWindow));
 +    hResult = dockingWindow->ShowDW(fShow);
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::CloseDW(DWORD dwReserved)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::ResizeBorderDW(LPCRECT prcBorder,
 +    IUnknown *punkToolbarSite, BOOL fReserved)
 +{
 +    RECT neededBorderSpace;
 +    RECT availableBorderSpace = *prcBorder;
 +
 +    SendMessage(fMainReBar, RB_SIZETORECT, RBSTR_CHANGERECT, reinterpret_cast<LPARAM>(&availableBorderSpace));
 +
 +    // RBSTR_CHANGERECT does not seem to set the proper size in the rect.
 +    // Let's make sure we fetch the actual size properly.
 +    GetWindowRect(fMainReBar, &availableBorderSpace);
 +    neededBorderSpace.left = 0;
 +    neededBorderSpace.top = availableBorderSpace.bottom - availableBorderSpace.top;
 +    if (!fLocked)
 +        neededBorderSpace.top += 3;
 +    neededBorderSpace.right = 0;
 +    neededBorderSpace.bottom = 0;
 +
 +    CComPtr<IDockingWindowSite> dockingWindowSite;
 +    
 +    HRESULT hResult = fSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &dockingWindowSite));
 +    if (FAILED(hResult))
 +        return hResult;
 +
 +    hResult = dockingWindowSite->RequestBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace);
 +    if (FAILED(hResult))
 +        return hResult;
 +
 +    hResult = dockingWindowSite->SetBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace);
 +    if (FAILED(hResult))
 +        return hResult;
 +
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::GetClassID(CLSID *pClassID)
 +{
 +    if (pClassID == NULL)
 +        return E_POINTER;
 +    *pClassID = CLSID_InternetToolbar;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::IsDirty()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::Load(IStream *pStm)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::Save(IStream *pStm, BOOL fClearDirty)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::GetSizeMax(ULARGE_INTEGER *pcbSize)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::InitNew()
 +{
 +    CComPtr<IShellMenu>                     menuBar;
 +    CComPtr<IUnknown>                       logoBar;
 +    CComPtr<IUnknown>                       toolsBar;
 +    CComPtr<IUnknown>                       navigationBar;
 +    CComPtr<IOleWindow>                     menuOleWindow;
 +    CComPtr<IOleWindow>                     toolbarOleWindow;
 +    CComPtr<IOleWindow>                     navigationOleWindow;
 +    HRESULT                                 hResult;
 +
 +    /* Create and attach the menubar to the rebar */
 +    hResult = CreateMenuBar(&menuBar);
 +    if (FAILED(hResult))
 +        return hResult;
 +    AddDockItem(menuBar, ITBBID_MENUBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
 +
 +    hResult = menuBar->QueryInterface(IID_PPV_ARG(IOleWindow, &menuOleWindow));
 +    hResult = menuOleWindow->GetWindow(&fMenuBandWindow);
 +    fMenuBar.Attach(menuBar.Detach());                  // transfer the ref count
 +
 +    // FIXME: The ros Rebar does not properly support fixed-size items such as the brandband,
 +    // and it will put them in their own row, sized to take up the whole row.
 +#if 0
 +    /* Create and attach the brand/logo to the rebar */
 +    hResult = CreateBrandBand(&logoBar);
 +    if (FAILED(hResult))
 +        return hResult;
 +    AddDockItem(logoBar, ITBBID_BRANDBAND, CDockSite::ITF_NOGRIPPER | CDockSite::ITF_NOTITLE | CDockSite::ITF_FIXEDSIZE);
 +    fLogoBar.Attach(logoBar.Detach());                  // transfer the ref count
 +#endif
 +
 +    /* Create and attach the standard toolbar to the rebar */
 +    hResult = CreateToolsBar(&toolsBar);
 +    if (FAILED(hResult))
 +        return hResult;
 +    AddDockItem(toolsBar, ITBBID_TOOLSBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
 +    fControlsBar.Attach(toolsBar.Detach());             // transfer the ref count
 +    hResult = fControlsBar->QueryInterface(IID_PPV_ARG(IOleWindow, &toolbarOleWindow));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = toolbarOleWindow->GetWindow(&fToolbarWindow);
 +    if (FAILED(hResult))
 +        return hResult;
 +
 +    /* Create and attach the address/navigation toolbar to the rebar */
 +    hResult = CreateAddressBand(&navigationBar);
 +    if (FAILED(hResult))
 +        return hResult;
 +    AddDockItem(navigationBar, ITBBID_ADDRESSBAND, CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
 +    hResult = navigationBar->QueryInterface(IID_PPV_ARG(IOleWindow, &navigationOleWindow));
 +    hResult = navigationOleWindow->GetWindow(&fNavigationWindow);
 +    fNavigationBar.Attach(navigationBar.Detach());
 +
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryStatus(const GUID *pguidCmdGroup,
 +    ULONG cCmds, OLECMD prgCmds[  ], OLECMDTEXT *pCmdText)
 +{
 +    if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands))
 +    {
 +        while (cCmds != 0)
 +        {
 +            switch (prgCmds->cmdID)
 +            {
 +                case ITID_TEXTLABELS:       // Text Labels state
 +                    prgCmds->cmdf = OLECMDF_SUPPORTED;
 +                    break;
 +                case ITID_TOOLBARBANDSHOWN: // toolbar visibility
 +                    prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
 +                    break;
 +                case ITID_ADDRESSBANDSHOWN: // address bar visibility
 +                    prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
 +                    break;
 +                case ITID_LINKSBANDSHOWN:   // links bar visibility
 +                    prgCmds->cmdf = 0;
 +                    break;
 +                case ITID_MENUBANDSHOWN:    // Menubar band visibility
 +                    prgCmds->cmdf = 0;
 +                    break;
 +                case ITID_AUTOHIDEENABLED:  // Auto hide enabled/disabled
 +                    prgCmds->cmdf = 0;
 +                    break;
 +                case ITID_CUSTOMIZEENABLED: // customize enabled
 +                    prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
 +                    break;
 +                case ITID_TOOLBARLOCKED:    // lock toolbars
 +                    prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
 +                    if (fLocked)
 +                        prgCmds->cmdf |= OLECMDF_LATCHED;
 +                    break;
 +                default:
 +                    prgCmds->cmdf = 0;
 +                    break;
 +            }
 +            prgCmds++;
 +            cCmds--;
 +        }
 +        return S_OK;
 +    }
 +    return E_FAIL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
 +    DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
 +{
 +    if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands))
 +    {
 +        switch (nCmdID)
 +        {
 +            case 1:
 +                // what do I do here?
 +                return S_OK;
 +            case ITID_TEXTLABELS:
 +                // toggle text labels
 +                return S_OK;
 +            case ITID_TOOLBARBANDSHOWN:
 +                // toggle toolbar band visibility
 +                return S_OK;
 +            case ITID_ADDRESSBANDSHOWN:
 +                // toggle address band visibility
 +                return S_OK;
 +            case ITID_LINKSBANDSHOWN:
 +                // toggle links band visibility
 +                return S_OK;
 +            case ITID_CUSTOMIZEENABLED:
 +                // run customize
 +                return S_OK;
 +            case ITID_TOOLBARLOCKED:
 +                return LockUnlockToolbars(!fLocked);
 +        }
 +    }
 +    return E_FAIL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::GetTypeInfoCount(UINT *pctinfo)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames,
 +    LCID lcid, DISPID *rgDispId)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
 +    WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
 +{
 +    HRESULT                                 hResult;
 +
 +    switch(dispIdMember)
 +    {
 +        case DISPID_BEFORENAVIGATE:
 +            hResult = S_OK;
 +            break;
 +        case DISPID_DOWNLOADCOMPLETE:
 +            hResult = S_OK;
 +            break;
 +        case DISPID_COMMANDSTATECHANGE:
 +            if (pDispParams->cArgs != 2)
 +                return E_INVALIDARG;
 +            if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL || V_VT(&pDispParams->rgvarg[1]) != VT_I4)
 +                return E_INVALIDARG;
 +            return CommandStateChanged(V_BOOL(&pDispParams->rgvarg[0]) != VARIANT_FALSE,
 +                V_I4(&pDispParams->rgvarg[1]));
 +        case DISPID_DOWNLOADBEGIN:
 +            hResult = S_OK;
 +            break;
 +        case DISPID_NAVIGATECOMPLETE2:
 +            hResult = S_OK;
 +            break;
 +        case DISPID_DOCUMENTCOMPLETE:
 +            hResult = S_OK;
 +            break;
 +    }
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::SetCommandTarget(IUnknown *theTarget, GUID *category, long param14)
 +{
 +    HRESULT                                 hResult;
 +
 +    fCommandTarget.Release();
 +    hResult = theTarget->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &fCommandTarget));
 +    if (FAILED(hResult))
 +        return hResult;
 +    fCommandCategory = *category;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::Unknown1()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::AddButtons(const GUID *pguidCmdGroup, long buttonCount, TBBUTTON *buttons)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::AddString(const GUID *pguidCmdGroup,
 +    HINSTANCE param10, LPCTSTR param14, long *param18)
 +{
 +    long                                    result;
 +
 +    result = (long)::SendMessage(fToolbarWindow, TB_ADDSTRINGW,
 +            reinterpret_cast<WPARAM>(param10), reinterpret_cast<LPARAM>(param14));
 +    *param18 = result;
 +    if (result == -1)
 +        return E_FAIL;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::GetButton(const GUID *pguidCmdGroup, long param10, long param14)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::GetState(const GUID *pguidCmdGroup, long commandID, long *theState)
 +{
 +    if (theState == NULL)
 +        return E_POINTER;
 +    // map the command id
 +    *theState = (long)::SendMessage(fToolbarWindow, TB_GETSTATE, commandID, 0);
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::SetState(const GUID *pguidCmdGroup, long commandID, long theState)
 +{
 +    // map the command id
 +    ::SendMessage(fToolbarWindow, TB_SETSTATE, commandID, MAKELONG(theState, 0));
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::AddBitmap(const GUID *pguidCmdGroup, long param10, long buttonCount,
 +    TBADDBITMAP *lParam, long *newIndex, COLORREF param20)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBitmapSize(long *paramC)
 +{
 +    if (paramC == NULL)
 +        return E_POINTER;
 +    *paramC = MAKELONG(24, 24);
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::SendToolbarMsg(const GUID *pguidCmdGroup, UINT uMsg,
 +    WPARAM wParam, LPARAM lParam, LRESULT *result)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::SetImageList(const GUID *pguidCmdGroup, HIMAGELIST param10,
 +    HIMAGELIST param14, HIMAGELIST param18)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::ModifyButton(const GUID *pguidCmdGroup, long param10, long param14)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::OnChange(LONG lEvent, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::SetSite(IUnknown *pUnkSite)
 +{
 +    CComPtr<IBrowserService>                browserService;
 +    CComPtr<IServiceProvider>               serviceProvider;
 +    CComPtr<IOleWindow>                     oleWindow;
 +    HWND                                    ownerWindow;
 +    HWND                                    dockContainer;
 +    HRESULT                                 hResult;
 +
 +    if (pUnkSite == NULL)
 +    {
 +        hResult = AtlUnadvise(fSite, DIID_DWebBrowserEvents, fAdviseCookie);
 +        ::DestroyWindow(fMainReBar);
 +        DestroyWindow();
 +        fSite.Release();
 +    }
 +    else
 +    {
 +        // get window handle of owner
 +        hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IOleWindow, &oleWindow));
 +        if (FAILED(hResult))
 +            return hResult;
 +        hResult = oleWindow->GetWindow(&ownerWindow);
 +        if (FAILED(hResult))
 +            return hResult;
 +        if (ownerWindow == NULL)
 +            return E_FAIL;
 +
 +        // create dock container
 +        fSite = pUnkSite;
 +        dockContainer = SHCreateWorkerWindowW(0, ownerWindow, 0,
 +            WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, NULL, 0);
 +        if (dockContainer == NULL)
 +            return E_FAIL;
 +        SubclassWindow(dockContainer);
 +
 +        // create rebar in dock container
 +        DWORD style = WS_VISIBLE | WS_BORDER | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
 +                      RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_REGISTERDROP | RBS_AUTOSIZE | RBS_DBLCLKTOGGLE |
 +                      CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_TOP;
 +        DWORD exStyle = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_TOOLWINDOW;
 +        fMainReBar = CreateWindowEx(exStyle, REBARCLASSNAMEW, NULL, style,
 +                            0, 0, 700, 60, dockContainer, NULL, _AtlBaseModule.GetModuleInstance(), NULL);
 +        if (fMainReBar == NULL)
 +            return E_FAIL;
 +
 +        // take advice to watch events
 +        hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
 +        hResult = serviceProvider->QueryService(
 +            SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
 +        hResult = AtlAdvise(browserService, static_cast<IDispatch *>(this), DIID_DWebBrowserEvents, &fAdviseCookie);
 +    }
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::GetSite(REFIID riid, void **ppvSite)
 +{
 +    if (ppvSite == NULL)
 +        return E_POINTER;
 +    if (fSite.p != NULL)
 +        return fSite->QueryInterface(riid, ppvSite);
 +    *ppvSite = NULL;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
 +{
 +    CComPtr<IServiceProvider>               serviceProvider;
 +    HRESULT                                 hResult;
 +
 +    if (IsEqualIID(guidService, IID_IBandSite))
 +        return this->QueryInterface(riid, ppvObject);
 +    if (IsEqualIID(guidService, SID_IBandProxy))
 +    {
 +        if (fBandProxy.p == NULL)
 +        {
 +            hResult = CreateAndInitBandProxy();
 +            if (FAILED(hResult))
 +                return hResult;
 +        }
 +        return fBandProxy->QueryInterface(riid, ppvObject);
 +    }
 +    return IUnknown_QueryService(fSite, guidService, riid, ppvObject);
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::OnWinEvent(
 +    HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
 +{
 +    CComPtr<IWinEventHandler>               menuWinEventHandler;
 +    HRESULT                                 hResult;
 +
 +    if (fMenuBar)
 +    {
 +        hResult = fMenuBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
 +        if (menuWinEventHandler->IsWindowOwner(hWnd) == S_OK)
 +        {
 +            return menuWinEventHandler->OnWinEvent(fMenuBandWindow, uMsg, wParam, lParam, theResult);
 +        }
 +    }
 +
 +    return S_FALSE;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::IsWindowOwner(HWND hWnd)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::AddBand(IUnknown *punk)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::EnumBands(UINT uBand, DWORD *pdwBandID)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryBand(DWORD dwBandID,
 +    IDeskBand **ppstb, DWORD *pdwState, LPWSTR pszName, int cchName)
 +{
 +    if (ppstb == NULL)
 +        return E_POINTER;
 +    if (dwBandID == ITBBID_MENUBAND && fMenuBar.p != NULL)
 +        return fMenuBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
 +    //if (dwBandID == ITBBID_BRANDBAND && fLogoBar.p != NULL)
 +    //    return fLogoBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
 +    *ppstb = NULL;
 +    return E_FAIL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::SetBandState(DWORD dwBandID, DWORD dwMask, DWORD dwState)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::RemoveBand(DWORD dwBandID)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBandObject(DWORD dwBandID, REFIID riid, void **ppv)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::SetBandSiteInfo(const BANDSITEINFO *pbsinfo)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBandSiteInfo(BANDSITEINFO *pbsinfo)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +LRESULT CInternetToolbar::OnTravelBack(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    CComPtr<IServiceProvider>               serviceProvider;
 +    CComPtr<IWebBrowser>                    webBrowser;
 +    HRESULT                                 hResult;
 +
 +    hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
 +    if (FAILED(hResult))
 +        return 0;
 +    hResult = serviceProvider->QueryService(SID_SShellBrowser,
 +        IID_PPV_ARG(IWebBrowser, &webBrowser));
 +    if (FAILED(hResult))
 +        return 0;
 +    hResult = webBrowser->GoBack();
 +    return 1;
 +}
 +
 +LRESULT CInternetToolbar::OnTravelForward(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    CComPtr<IServiceProvider>               serviceProvider;
 +    CComPtr<IWebBrowser>                    webBrowser;
 +    HRESULT                                 hResult;
 +
 +    hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
 +    if (FAILED(hResult))
 +        return 0;
 +    hResult = serviceProvider->QueryService(
 +        SID_SShellBrowser, IID_PPV_ARG(IWebBrowser, &webBrowser));
 +    if (FAILED(hResult))
 +        return 0;
 +    hResult = webBrowser->GoForward();
 +    return 1;
 +}
 +
 +LRESULT CInternetToolbar::OnUpLevel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    CComPtr<IOleCommandTarget>              oleCommandTarget;
 +    HRESULT                                 hResult;
 +
 +    hResult = fSite->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = oleCommandTarget->Exec(&CGID_ShellBrowser, IDM_GOTO_UPONELEVEL, 0, NULL, NULL);
 +    return 1;
 +}
 +
 +LRESULT CInternetToolbar::OnSearch(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    CComPtr<IObjectWithSite>                objectWithSite;
 +    CComPtr<IContextMenu>                   contextMenu;
 +    CMINVOKECOMMANDINFO                     commandInfo;
 +    const char                              *searchGUID = "{169A0691-8DF9-11d1-A1C4-00C04FD75D13}";
 +    HRESULT                                 hResult;
 +
 +    // TODO: Query shell if this command is enabled first
 +
 +    memset(&commandInfo, 0, sizeof(commandInfo));
 +    commandInfo.cbSize = sizeof(commandInfo);
 +    commandInfo.hwnd = m_hWnd;
 +    commandInfo.lpParameters = searchGUID;
 +    commandInfo.nShow = SW_SHOWNORMAL;
 +
 +    hResult = CoCreateInstance(CLSID_ShellSearchExt, NULL, CLSCTX_INPROC_SERVER,
 +        IID_PPV_ARG(IContextMenu, &contextMenu));
 +    if (FAILED(hResult))
 +        return 0;
 +    hResult = contextMenu->QueryInterface(IID_PPV_ARG(IObjectWithSite, &objectWithSite));
 +    if (FAILED(hResult))
 +        return 0;
 +    hResult = objectWithSite->SetSite(fSite);
 +    if (FAILED(hResult))
 +        return 0;
 +    hResult = contextMenu->InvokeCommand(&commandInfo);
 +    hResult = objectWithSite->SetSite(NULL);
 +    return 0;
 +}
 +
 +LRESULT CInternetToolbar::OnFolders(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    CComPtr<IOleCommandTarget>              oleCommandTarget;
 +    HRESULT                                 hResult;
 +
 +    hResult = fSite->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = oleCommandTarget->Exec(&CGID_Explorer, 0x23, 0, NULL, NULL);
 +    return 1;
 +}
 +
 +LRESULT CInternetToolbar::OnForwardToCommandTarget(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    HRESULT                                 hResult;
 +
 +    if (fCommandTarget.p != NULL)
 +    {
 +        hResult = fCommandTarget->Exec(&fCommandCategory, wID, 0, NULL, NULL);
 +    }
 +    return 1;
 +}
 +
 +LRESULT CInternetToolbar::OnMenuDropDown(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
 +{
 +    CComPtr<IServiceProvider>               serviceProvider;
 +    CComPtr<IBrowserService>                browserService;
 +    CComPtr<IOleCommandTarget>              commandTarget;
 +    CComPtr<ITravelLog>                     travelLog;
 +    NMTOOLBARW                              *notifyInfo;
 +    RECT                                    bounds;
 +    HMENU                                   newMenu;
 +    TPMPARAMS                               params;
 +    int                                     selectedItem;
 +    VARIANT                                 parmIn;
 +    OLECMD                                  commandInfo;
 +    HRESULT                                 hResult;
 +
 +    notifyInfo = (NMTOOLBARW *)pNMHDR;
 +    if (notifyInfo->hdr.hwndFrom != fToolbarWindow)
 +    {
 +        // not from the toolbar, keep looking for a message handler
 +        bHandled = FALSE;
 +        return 0;
 +    }
 +    SendMessage(fToolbarWindow, TB_GETRECT, notifyInfo->iItem, reinterpret_cast<LPARAM>(&bounds));
 +    ::MapWindowPoints(fToolbarWindow, NULL, reinterpret_cast<POINT *>(&bounds), 2);
 +    switch (notifyInfo->iItem)
 +    {
 +        case IDM_GOTO_BACK:
 +            newMenu = CreatePopupMenu();
 +            hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
 +            hResult = serviceProvider->QueryService(
 +                SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
 +            hResult = browserService->GetTravelLog(&travelLog);
 +            hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_BACK);
 +            hResult = browserService->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &commandTarget));
 +            commandInfo.cmdID = 0x1d;
 +            hResult = commandTarget->QueryStatus(&CGID_Explorer, 1, &commandInfo, NULL);
 +            if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED &&
 +                travelLog->CountEntries(browserService) > 1)
 +            {
 +                AppendMenu(newMenu, MF_SEPARATOR, -1, L"");
 +                AppendMenu(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, L"&History\tCtrl+H");
 +            }
 +            params.cbSize = sizeof (params);
 +            params.rcExclude = bounds;
 +            selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
 +                                    bounds.left, bounds.bottom, m_hWnd, &params);
 +            if (selectedItem == IDM_EXPLORERBAR_HISTORY)
 +            {
 +                V_VT(&parmIn) = VT_I4;
 +                V_I4(&parmIn) = 1;
 +                Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL);
 +            }
 +            else if (selectedItem != 0)
 +                hResult = travelLog->Travel(browserService, -selectedItem);
 +            DestroyMenu(newMenu);
 +            break;
 +        case IDM_GOTO_FORWARD:
 +            newMenu = CreatePopupMenu();
 +            hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
 +            hResult = serviceProvider->QueryService(SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
 +            hResult = browserService->GetTravelLog(&travelLog);
 +            hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_FORE);
 +            hResult = browserService->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &commandTarget));
 +            commandInfo.cmdID = 0x1d;
 +            hResult = commandTarget->QueryStatus(&CGID_Explorer, 1, &commandInfo, NULL);
 +            if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED &&
 +                travelLog->CountEntries(browserService) > 1)
 +            {
 +                AppendMenu(newMenu, MF_SEPARATOR, -1, L"");
 +                AppendMenu(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, L"&History\tCtrl+H");
 +            }
 +            params.cbSize = sizeof (params);
 +            params.rcExclude = bounds;
 +            selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
 +                                    bounds.left, bounds.bottom, m_hWnd, &params);
 +            if (selectedItem == IDM_EXPLORERBAR_HISTORY)
 +            {
 +                V_VT(&parmIn) = VT_I4;
 +                V_I4(&parmIn) = 1;
 +                Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL);
 +            }
 +            else if (selectedItem != 0)
 +                hResult = travelLog->Travel(browserService, -selectedItem);
 +            DestroyMenu(newMenu);
 +            break;
 +        case gViewsCommandID:
 +            VARIANT                     inValue;
 +            CComVariant                 outValue;
 +            HRESULT                     hResult;
 +
 +            V_VT(&inValue) = VT_INT_PTR;
 +            V_INTREF(&inValue) = reinterpret_cast<INT *>(&bounds);
 +
 +            if (fCommandTarget.p != NULL)
 +                hResult = fCommandTarget->Exec(&fCommandCategory, 0x7031, 1, &inValue, &outValue);
 +            // pvaOut is VT_I4 with value 0x403
 +            break;
 +    }
 +    return TBDDRET_DEFAULT;
 +}
 +
 +LRESULT CInternetToolbar::OnQueryInsert(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
 +{
 +    return 1;
 +}
 +
 +LRESULT CInternetToolbar::OnQueryDelete(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
 +{
 +    return 1;
 +}
 +
 +LRESULT CInternetToolbar::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    HMENU                                   contextMenuBar;
 +    HMENU                                   contextMenu;
 +    POINT                                   clickLocation;
 +    int                                     command;
 +    RBHITTESTINFO                           hitTestInfo;
 +    REBARBANDINFOW                          rebarBandInfo;
 +    int                                     bandID;
 +
 +    clickLocation.x = LOWORD(lParam);
 +    clickLocation.y = HIWORD(lParam);
 +    hitTestInfo.pt = clickLocation;
 +    ScreenToClient(&hitTestInfo.pt);
 +    SendMessage(fMainReBar, RB_HITTEST, 0, (LPARAM)&hitTestInfo);
 +    if (hitTestInfo.iBand == -1)
 +        return 0;
 +    rebarBandInfo.cbSize = sizeof(rebarBandInfo);
 +    rebarBandInfo.fMask = RBBIM_ID;
 +    SendMessage(fMainReBar, RB_GETBANDINFOW, hitTestInfo.iBand, (LPARAM)&rebarBandInfo);
 +    bandID = rebarBandInfo.wID;
 +    contextMenuBar = LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_CONTEXTMENU));
 +    contextMenu = GetSubMenu(contextMenuBar, 0);
 +    switch (bandID)
 +    {
 +        case ITBBID_MENUBAND:   // menu band
 +            DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
 +            DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
 +            DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
 +            break;
 +        case ITBBID_BRANDBAND:  // brand band
 +            DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
 +            DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
 +            DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
 +            break;
 +        case ITBBID_TOOLSBAND:  // tools band
 +            DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
 +            DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
 +            break;
 +        case ITBBID_ADDRESSBAND:    // navigation band
 +            DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
 +            DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
 +            break;
 +        default:
 +            break;
 +    }
 +
 +    MENUITEMINFO mii;
 +    mii.cbSize = sizeof(mii);
 +    mii.fMask = MIIM_STATE;
 +    mii.fState = fLocked ? MFS_CHECKED : MFS_UNCHECKED;
 +    command = SetMenuItemInfo(contextMenu, IDM_TOOLBARS_LOCKTOOLBARS, FALSE, &mii);
 +
 +    // TODO: use GetSystemMetrics(SM_MENUDROPALIGNMENT) to determine menu alignment
 +    command = TrackPopupMenu(contextMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
 +                clickLocation.x, clickLocation.y, 0, m_hWnd, NULL);
 +    switch (command)
 +    {
 +        case IDM_TOOLBARS_STANDARDBUTTONS:  // standard buttons
 +            break;
 +        case IDM_TOOLBARS_ADDRESSBAR:   // address bar
 +            break;
 +        case IDM_TOOLBARS_LINKSBAR: // links
 +            break;
 +        case IDM_TOOLBARS_LOCKTOOLBARS: // lock the toolbars
 +            LockUnlockToolbars(!fLocked);
 +            break;
 +        case IDM_TOOLBARS_CUSTOMIZE:    // customize
 +            SendMessage(fToolbarWindow, TB_CUSTOMIZE, 0, 0);
 +            break;
 +    }
 +    return 1;
 +}
 +
 +LRESULT CInternetToolbar::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    if (wParam != SIZE_MINIMIZED)
 +    {
 +        ::SetWindowPos(fMainReBar, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam),
 +            SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
 +    }
 +    return 1;
 +}
 +
 +LRESULT CInternetToolbar::OnSetCursor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    if ((short)lParam != HTCLIENT || (HWND)wParam != m_hWnd)
 +    {
 +        bHandled = FALSE;
 +        return 0;
 +    }
 +    SetCursor(LoadCursor(NULL, IDC_SIZENS));
 +    return 1;
 +}
 +
 +LRESULT CInternetToolbar::OnTipText(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
 +{
 +    CComPtr<IBrowserService>                browserService;
 +    CComPtr<ITravelLog>                     travelLog;
 +    TOOLTIPTEXTW                            *pTTTW;
 +    UINT                                    nID;
 +    wchar_t                                 tempString[300];
 +    HRESULT                                 hResult;
 +
 +    pTTTW = reinterpret_cast<TOOLTIPTEXTW *>(pNMHDR);
 +    if ((pTTTW->uFlags & TTF_IDISHWND) != 0)
 +        nID = ::GetDlgCtrlID((HWND)pNMHDR->idFrom);
 +    else
 +        nID = (UINT)pNMHDR->idFrom;
 +
 +    if (nID != 0)
 +    {
 +        if (nID == (UINT)IDM_GOTO_BACK || nID == (UINT)IDM_GOTO_FORWARD)
 +        {
 +            // TODO: Should this call QueryService?
 +            hResult = fSite->QueryInterface(IID_PPV_ARG(IBrowserService, &browserService));
 +            hResult = browserService->GetTravelLog(&travelLog);
 +            hResult = travelLog->GetToolTipText(browserService,
 +                (nID == (UINT)IDM_GOTO_BACK) ? TLOG_BACK : TLOG_FORE,
 +                0, tempString, 299);
 +            if (FAILED(hResult))
 +            {
 +                bHandled = FALSE;
 +                return 0;
 +            }
 +        }
 +        else
 +            tempString[0] = 0;
 +        wcsncpy (pTTTW->szText, tempString, sizeof (pTTTW->szText) / sizeof (wchar_t));
 +        ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
 +            SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
 +        return 0;
 +    }
 +    return 0;
 +}
 +
 +LRESULT CInternetToolbar::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    LRESULT theResult;
 +    HRESULT hResult;
 +    HWND    target = (HWND) lParam;
 +
 +    if (fMenuBar)
 +    {
 +        CComPtr<IWinEventHandler> menuWinEventHandler;
 +        hResult = fMenuBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
 +        if (SUCCEEDED(hResult))
 +        {
 +            if (menuWinEventHandler->IsWindowOwner(target) == S_OK)
 +            {
 +                hResult = menuWinEventHandler->OnWinEvent(target, uMsg, wParam, lParam, &theResult);
 +                return FAILED(hResult) ? 0 : theResult;
 +            }
 +        }
 +    }
 +
 +    if (fNavigationBar)
 +    {
 +        CComPtr<IWinEventHandler> menuWinEventHandler;
 +        hResult = fNavigationBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
 +        if (SUCCEEDED(hResult))
 +        {
 +            if (menuWinEventHandler->IsWindowOwner(target) == S_OK)
 +            {
 +                hResult = menuWinEventHandler->OnWinEvent(target, uMsg, wParam, lParam, &theResult);
 +                return FAILED(hResult) ? 0 : theResult;
 +            }
 +        }
 +    }
 +
 +    return 0;
 +}
 +LRESULT CInternetToolbar::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    NMHDR   *notifyHeader;
 +    LRESULT theResult;
 +    HRESULT hResult;
 +
 +    notifyHeader = (NMHDR *) lParam;
 +
 +    if (fMenuBar)
 +    {
 +        CComPtr<IWinEventHandler> menuWinEventHandler;
 +        hResult = fMenuBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
 +        if (SUCCEEDED(hResult))
 +        {
 +            if (menuWinEventHandler->IsWindowOwner(notifyHeader->hwndFrom) == S_OK)
 +            {
 +                hResult = menuWinEventHandler->OnWinEvent(notifyHeader->hwndFrom, uMsg, wParam, lParam, &theResult);
 +                return FAILED(hResult) ? 0 : theResult;
 +            }
 +        }
 +    }
 +
 +    if (fNavigationBar)
 +    {
 +        CComPtr<IWinEventHandler> menuWinEventHandler;
 +        hResult = fNavigationBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
 +        if (SUCCEEDED(hResult))
 +        {
 +            if (menuWinEventHandler->IsWindowOwner(notifyHeader->hwndFrom) == S_OK)
 +            {
 +                hResult = menuWinEventHandler->OnWinEvent(notifyHeader->hwndFrom, uMsg, wParam, lParam, &theResult);
 +                return FAILED(hResult) ? 0 : theResult;
 +            }
 +        }
 +    }
 +
 +    return 0;
 +}
 +
 +LRESULT CInternetToolbar::OnLDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    bHandled = FALSE;
 +    if (fLocked)
 +        return 0;
 +
 +    if (wParam & MK_CONTROL)
 +        return 0;
 +
 +    fSizing = TRUE;
 +
 +    DWORD msgp = GetMessagePos();
 +    
 +    fStartPosition.x = GET_X_LPARAM(msgp);
 +    fStartPosition.y = GET_Y_LPARAM(msgp);
 +    
 +    RECT rc;
 +    GetWindowRect(m_hWnd, &rc);
 +
 +    fStartHeight = rc.bottom - rc.top;
 +
 +    SetCapture();
 +
 +    bHandled = TRUE;
 +    return 0;
 +}
 +
 +LRESULT CInternetToolbar::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    bHandled = FALSE;
 +    if (!fSizing)
 +        return 0;
 +
 +    DWORD msgp = GetMessagePos();
 +
 +    POINT pt;
 +    pt.x = GET_X_LPARAM(msgp);
 +    pt.y = GET_Y_LPARAM(msgp);
 +
 +    ReserveBorderSpace(fStartHeight - fStartPosition.y + pt.y);
 +
 +    bHandled = TRUE;
 +    return 0;
 +}
 +
 +LRESULT CInternetToolbar::OnLUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    bHandled = FALSE;
 +    if (!fSizing)
 +        return 0;
 +
 +    OnMouseMove(uMsg, wParam, lParam, bHandled);
 +
 +    fSizing = FALSE;
 +
 +    ReleaseCapture();
 +
 +    return 0;
 +}
 +
 +HRESULT CreateInternetToolbar(REFIID riid, void **ppv)
 +{
 +    CComObject<CInternetToolbar>            *theToolbar;
 +    HRESULT                                 hResult;
 +
 +    if (ppv == NULL)
 +        return E_POINTER;
 +    *ppv = NULL;
 +    ATLTRY (theToolbar = new CComObject<CInternetToolbar>);
 +    if (theToolbar == NULL)
 +        return E_OUTOFMEMORY;
 +    hResult = theToolbar->QueryInterface (riid, reinterpret_cast<void **>(ppv));
 +    if (FAILED(hResult))
 +    {
 +        delete theToolbar;
 +        return hResult;
 +    }
 +    return S_OK;
 +}
index ceba070,0000000..2b09c10
mode 100644,000000..100644
--- /dev/null
@@@ -1,3355 -1,0 +1,3360 @@@
 +/*
 + * ReactOS Explorer
 + *
 + * Copyright 2009 Andrew Hill <ash77 at domain reactos.org>
 + *
 + * This library is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * This library is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with this library; if not, write to the Free Software
 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + */
 +
 +#include "precomp.h"
 +
 +#include <shellapi.h>
 +#include <htiframe.h>
 +
 +extern "C"
 +BOOL WINAPI Shell_GetImageLists(
 +    _Out_  HIMAGELIST *phiml,
 +    _Out_  HIMAGELIST *phimlSmall
 +    );
 +
 +#include "newatlinterfaces.h"
 +
 +/*
 +TODO:
 +  **Provide implementation of new and delete that use LocalAlloc
 +  **Persist history for shell view isn't working correctly, possibly because of the mismatch between traveling and updating the travel log. The
 +        view doesn't restore the selection correctly.
 +  **Build explorer.exe, browseui.dll, comctl32.dll, shdocvw.dll, shell32.dll, shlwapi.dll into a directory and run them for testing...
 +  **Add brand band bitmaps to shell32.dll
 +  **If Go button on address bar is clicked, each time a new duplicate entry is added to travel log
 +****The current entry is updated in travel log before doing the travel, which means when traveling back the update of the
 +        current state overwrites the wrong entry's contents. This needs to be changed.
 +****Fix close of browser window to release all objects
 +****Given only a GUID in ShowBrowserBar, what is the correct way to determine if the bar is vertical or horizontal?
 +  **When a new bar is added to base bar site, how is base bar told so it can resize?
 +  **Does the base bar site have a classid?
 +  **What should refresh command send to views to make them refresh?
 +  **When new bar is created, what status notifications need to be fired?
 +  **How does keyboard filtering dispatch?
 +  **For deferred persist history load, how does the view connect up and get the state?
 +    How does context menu send open, cut, rename commands to its site (the shell view)?
 +  **Fix browser to implement IProfferService and hold onto brand band correctly - this will allow animations.
 +
 +  **Route View->Toolbars commands to internet toolbar
 +  **Handle travel log items in View->Go
 +  **Fix ShowBrowserBar to pass correct size on when bar is shown
 +****Fix SetBorderSpaceDW to cascade resize to subsequent bars
 +****Make ShowToolbar check if bar is already created before creating it again
 +****Shell should fill in the list of explorer bars in the View submenus
 +  **Add folder menu in the file menu
 +  **Fix CShellBrowser::GetBorderDW to compute available size correctly
 +  **When a new bar is shown, re-fire the navigate event. This makes the explorer band select the correct folder
 +  **Implement support for refresh. Forward refresh to explorer bar (refresh on toolbar and in menu is dispatched different)
 +    Make folders toolbar item update state appropriately
 +    Read list of bands from registry on launch
 +    Read list of bars from registry on launch
 +    If the folders or search bars don't exist, disable the toolbar buttons
 +    If the favorites or history bars don't exist, disable the toolbar butons
 +    Fix Apply to all Folders in Folder Options
 +    Implement close command
 +    Add explorer band context menu to file menu
 +    Add code to allow restore of internet toolbar from registry
 +    Fix code that calls FireNavigateComplete to pass the correct new path
 +
 +    What are the other command ids for QueryStatus/FireCommandStateChange?
 +
 +    Add handler for cabinet settings change
 +    Add handler for system metrics change (renegotiate border space?)
 +    Add handler for theme change and forward to contained windows
 +
 +    When folders are shown, the status bar text should change
 +    Add code to save/restore shell view settings
 +    Implement tabbing between frames
 +    Fix handling of focus everywhere
 +    Most keyboard shortcuts don't work, such as F2 for rename, F5 for refresh (see list in "explorer keyboard shortcuts")
 +
 +    The status bar doesn't show help text for items owned by frame during menu tracking
 +    Stub out frame command handlers
 +    "Arrange icons by" group is not checked properly
 +
 +    When folders are hidden, icon is the same as the current shell object being displayed. When folders are shown,
 +        the icon is always an open folder with magnifying glass
 +    Fix bars to calculate height correctly
 +    Hookup policies for everything...
 +    Investigate toolbar message WM_USER+93
 +    Investigate toolbar message WM_USER+100 (Adds extra padding between parts of buttons with BTNS_DROPDOWN | BTNS_SHOWTEXT style
 +
 +    Vertical Explorer Bar             CATID_InfoBand
 +    Horizontal Explorer Bar           CATID_CommBand
 +    Desk Band                                 CATID_DeskBand
 +
 +    cache of bars
 +    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Discardable\PostSetup\Component Categories\{00021493-0000-0000-C000-000000000046}\Enum
 +    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Discardable\PostSetup\Component Categories\{00021494-0000-0000-C000-000000000046}\Enum
 +
 +    create key here with CLSID of bar to register tool band
 +    HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Toolbar
 +
 +*/
 +
 +#ifndef __GNUC__
 +#pragma comment(linker, \
 +    "\"/manifestdependency:type='Win32' "\
 +    "name='Microsoft.Windows.Common-Controls' "\
 +    "version='6.0.0.0' "\
 +    "processorArchitecture='*' "\
 +    "publicKeyToken='6595b64144ccf1df' "\
 +    "language='*'\"")
 +#endif // __GNUC__
 +
 +struct categoryCacheHeader
 +{
 +    long                dwSize;         // size of header only
 +    long                version;        // currently 1
 +    SYSTEMTIME          writeTime;      // time we were written to registry
 +    long                classCount;     // number of classes following
 +};
 +
 +static const unsigned int                   folderOptionsPageCountMax = 20;
 +static const long                           BTP_UPDATE_CUR_HISTORY = 1;
 +static const long                           BTP_UPDATE_NEXT_HISTORY = 2;
 +
 +BOOL                                        createNewStuff = false;
 +
 +
 +// this class is private to browseui.dll and is not registered externally?
 +//DEFINE_GUID(CLSID_ShellFldSetExt, 0x6D5313C0, 0x8C62, 0x11D1, 0xB2, 0xCD, 0x00, 0x60, 0x97, 0xDF, 0x8C, 0x11);
 +
 +
 +extern HRESULT CreateTravelLog(REFIID riid, void **ppv);
 +extern HRESULT CreateBaseBar(REFIID riid, void **ppv);
 +extern HRESULT CreateBaseBarSite(REFIID riid, void **ppv);
 +
 +// temporary
 +extern HRESULT CreateInternetToolbar(REFIID riid, void **ppv);
 +
 +
 +HMENU SHGetMenuFromID(HMENU topMenu, int theID)
 +{
 +    MENUITEMINFO                            menuItemInfo;
 +
 +    menuItemInfo.cbSize = sizeof(menuItemInfo);
 +    menuItemInfo.fMask = MIIM_SUBMENU;
 +    if (!GetMenuItemInfo(topMenu, theID, FALSE, &menuItemInfo))
 +        return NULL;
 +    return menuItemInfo.hSubMenu;
 +}
 +
 +void SHCheckMenuItem(HMENU theMenu, int theID, BOOL checked)
 +{
 +    MENUITEMINFO                            menuItemInfo;
 +
 +    menuItemInfo.cbSize = sizeof(menuItemInfo);
 +    menuItemInfo.fMask = MIIM_STATE;
 +    if (GetMenuItemInfo(theMenu, theID, FALSE, &menuItemInfo))
 +    {
 +        if (checked)
 +            menuItemInfo.fState |= MF_CHECKED;
 +        else
 +            menuItemInfo.fState &= ~MF_CHECKED;
 +        SetMenuItemInfo(theMenu, theID, FALSE, &menuItemInfo);
 +    }
 +}
 +
 +void DeleteMenuItems(HMENU theMenu, unsigned int firstIDToDelete, unsigned int lastIDToDelete)
 +{
 +    MENUITEMINFO                            menuItemInfo;
 +    int                                     menuItemCount;
 +    int                                     curIndex;
 +
 +    menuItemCount = GetMenuItemCount(theMenu);
 +    curIndex = 0;
 +    while (curIndex < menuItemCount)
 +    {
 +        menuItemInfo.cbSize = sizeof(menuItemInfo);
 +        menuItemInfo.fMask = MIIM_ID;
 +        if (GetMenuItemInfo(theMenu, curIndex, TRUE, &menuItemInfo) &&
 +            menuItemInfo.wID >= firstIDToDelete && menuItemInfo.wID <= lastIDToDelete)
 +        {
 +            DeleteMenu(theMenu, curIndex, MF_BYPOSITION);
 +            menuItemCount--;
 +        }
 +        else
 +            curIndex++;
 +    }
 +}
 +
 +HRESULT WINAPI SHBindToFolder(LPCITEMIDLIST path, IShellFolder **newFolder)
 +{
 +    CComPtr<IShellFolder>                   desktop;
 +
 +    HRESULT hr = ::SHGetDesktopFolder(&desktop);
 +    if (FAILED(hr))
 +        return E_FAIL;
 +    if (path == NULL || path->mkid.cb == 0)
 +    {
 +        *newFolder = desktop;
 +        desktop.p->AddRef ();
 +        return S_OK;
 +    }
 +    return desktop->BindToObject (path, NULL, IID_PPV_ARG(IShellFolder, newFolder));
 +}
 +
 +static const TCHAR szCabinetWndClass[] = TEXT("CabinetWClassX");
 +static const TCHAR szExploreWndClass[] = TEXT("ExploreWClassX");
 +
 +class CDockManager;
 +class CShellBrowser;
 +
 +class CToolbarProxy :
 +    public CWindowImpl<CToolbarProxy, CWindow, CControlWinTraits>
 +{
 +private:
 +    CComPtr<IExplorerToolbar>               fExplorerToolbar;
 +public:
 +    void Initialize(HWND parent, IUnknown *explorerToolbar);
 +
 +private:
 +
 +    // message handlers
 +    LRESULT OnAddBitmap(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
 +    LRESULT OnForwardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
 +
 +    BEGIN_MSG_MAP(CToolbarProxy)
 +        MESSAGE_HANDLER(TB_ADDBITMAP, OnAddBitmap)
 +        MESSAGE_RANGE_HANDLER(WM_USER, 0x7fff, OnForwardMessage)
 +    END_MSG_MAP()
 +};
 +
 +void CToolbarProxy::Initialize(HWND parent, IUnknown *explorerToolbar)
 +{
 +    HWND                                    myWindow;
 +    HRESULT                                 hResult;
 +
 +    myWindow = SHCreateWorkerWindowW(0, parent, 0, WS_CHILD, NULL, 0);
 +    if (myWindow != NULL)
 +    {
 +        SubclassWindow(myWindow);
 +        SetWindowPos(NULL, -32000, -32000, 0, 0, SWP_NOOWNERZORDER | SWP_NOZORDER);
 +        hResult = explorerToolbar->QueryInterface(
 +            IID_PPV_ARG(IExplorerToolbar, &fExplorerToolbar));
 +    }
 +}
 +
 +LRESULT CToolbarProxy::OnAddBitmap(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    long int                                result;
 +    HRESULT                                 hResult;
 +
 +    result = 0;
 +    if (fExplorerToolbar.p != NULL)
 +    {
 +        hResult = fExplorerToolbar->AddBitmap(&CGID_ShellBrowser, 1, (long)wParam,
 +            reinterpret_cast<TBADDBITMAP *>(lParam), &result, RGB(192, 192, 192));
 +        hResult = fExplorerToolbar->AddBitmap(&CGID_ShellBrowser, 2, (long)wParam,
 +            reinterpret_cast<TBADDBITMAP *>(lParam), &result, RGB(192, 192, 192));
 +    }
 +    return result;
 +}
 +
 +LRESULT CToolbarProxy::OnForwardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    LRESULT                                 result;
 +    HRESULT                                 hResult;
 +
 +    result = 0;
 +    if (fExplorerToolbar.p != NULL)
 +        hResult = fExplorerToolbar->SendToolbarMsg(&CGID_ShellBrowser, uMsg, wParam, lParam, &result);
 +    return result;
 +}
 +
 +/*
 +Switch to a new bar when it receives an Exec(CGID_IDeskBand, 1, 1, vaIn, NULL);
 +    where vaIn will be a VT_UNKNOWN with the new bar. It also sends a RB_SHOWBAND to the
 +    rebar
 +*/
 +
 +class CShellBrowser :
 +    public CWindowImpl<CShellBrowser, CWindow, CFrameWinTraits>,
 +    public CComObjectRootEx<CComMultiThreadModelNoCS>,
 +    public IShellBrowser,
 +    public IDropTarget,
 +    public IServiceProvider,
 +    public IProfferServiceImpl<CShellBrowser>,
 +    public IShellBrowserService,
 +    public IWebBrowser2,
 +    public ITravelLogClient,
 +    public IPersistHistory,
 +    public IDockingWindowSite,
 +    public IOleCommandTarget,
 +    public IBrowserService2,
 +    public IConnectionPointContainerImpl<CShellBrowser>,
 +    public MyIConnectionPointImpl<CShellBrowser, &DIID_DWebBrowserEvents2>,
 +    public MyIConnectionPointImpl<CShellBrowser, &DIID_DWebBrowserEvents>
 +{
 +private:
 +    class barInfo
 +    {
 +    public:
 +        RECT                                borderSpace;
 +        CComPtr<IUnknown>                   clientBar;
 +        HWND                                hwnd;
 +    };
 +    static const int                        BIInternetToolbar = 0;
 +    static const int                        BIVerticalBaseBar = 1;
 +    static const int                        BIHorizontalBaseBar = 2;
 +
 +    HWND                                    fCurrentShellViewWindow;    // our currently hosted shell view window
 +    CComPtr<IShellFolder>                   fCurrentShellFolder;        //
 +    CComPtr<IShellView>                     fCurrentShellView;          //
 +    LPITEMIDLIST                            fCurrentDirectoryPIDL;      //
 +    HWND                                    fStatusBar;
 +    bool                                    fStatusBarVisible;
 +    CToolbarProxy                           fToolbarProxy;
 +    barInfo                                 fClientBars[3];
 +    CComPtr<ITravelLog>                     fTravelLog;
 +    HMENU                                   fCurrentMenuBar;
 +    CABINETSTATE                            fCabinetState;
 +    // The next three fields support persisted history for shell views.
 +    // They do not need to be reference counted.
 +    IOleObject                              *fHistoryObject;
 +    IStream                                 *fHistoryStream;
 +    IBindCtx                                *fHistoryBindContext;
 +    HACCEL m_hAccel;
 +public:
 +#if 0
 +    ULONG InternalAddRef()
 +    {
 +        OutputDebugString(_T("AddRef\n"));
 +        return CComObjectRootEx<CComMultiThreadModelNoCS>::InternalAddRef();
 +    }
 +    ULONG InternalRelease()
 +    {
 +        OutputDebugString(_T("Release\n"));
 +        return CComObjectRootEx<CComMultiThreadModelNoCS>::InternalRelease();
 +    }
 +#endif
 +
 +    CShellBrowser();
 +    ~CShellBrowser();
 +    HRESULT Initialize(LPITEMIDLIST pidl, long b, long c, long d);
 +public:
 +    HRESULT BrowseToPIDL(LPCITEMIDLIST pidl, long flags);
 +    HRESULT BrowseToPath(IShellFolder *newShellFolder, LPCITEMIDLIST absolutePIDL,
 +        FOLDERSETTINGS *folderSettings, long flags);
 +    HRESULT GetMenuBand(REFIID riid, void **shellMenu);
 +    HRESULT GetBaseBar(bool vertical, IUnknown **theBaseBar);
 +    HRESULT ShowBand(const CLSID &classID, bool vertical);
 +    HRESULT NavigateToParent();
 +    HRESULT DoFolderOptions();
 +    static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 +    void RepositionBars();
 +    virtual WNDPROC GetWindowProc()
 +    {
 +        return WindowProc;
 +    }
 +    HRESULT FireEvent(DISPID dispIdMember, int argCount, VARIANT *arguments);
 +    HRESULT FireNavigateComplete(const wchar_t *newDirectory);
 +    HRESULT FireCommandStateChange(bool newState, int commandID);
 +    HRESULT FireCommandStateChangeAll();
 +    HRESULT UpdateForwardBackState();
 +    void UpdateGotoMenu(HMENU theMenu);
 +    void UpdateViewMenu(HMENU theMenu);
 +
 +/*    // *** IDockingWindowFrame methods ***
 +    virtual HRESULT STDMETHODCALLTYPE AddToolbar(IUnknown *punkSrc, LPCWSTR pwszItem, DWORD dwAddFlags);
 +    virtual HRESULT STDMETHODCALLTYPE RemoveToolbar(IUnknown *punkSrc, DWORD dwRemoveFlags);
 +    virtual HRESULT STDMETHODCALLTYPE FindToolbar(LPCWSTR pwszItem, REFIID riid, void **ppv);
 +    */
 +
 +    // *** IDockingWindowSite methods ***
 +    virtual HRESULT STDMETHODCALLTYPE GetBorderDW(IUnknown* punkObj, LPRECT prcBorder);
 +    virtual HRESULT STDMETHODCALLTYPE RequestBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw);
 +    virtual HRESULT STDMETHODCALLTYPE SetBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw);
 +
 +    // *** IOleCommandTarget methods ***
 +    virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds,
 +        OLECMD prgCmds[  ], OLECMDTEXT *pCmdText);
 +    virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
 +        DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut);
 +
 +    // *** IOleWindow methods ***
 +    virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd);
 +    virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
 +
 +    // *** IShellBrowser methods ***
 +    virtual HRESULT STDMETHODCALLTYPE InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths);
 +    virtual HRESULT STDMETHODCALLTYPE SetMenuSB(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject);
 +    virtual HRESULT STDMETHODCALLTYPE RemoveMenusSB(HMENU hmenuShared);
 +    virtual HRESULT STDMETHODCALLTYPE SetStatusTextSB(LPCOLESTR pszStatusText);
 +    virtual HRESULT STDMETHODCALLTYPE EnableModelessSB(BOOL fEnable);
 +    virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorSB(MSG *pmsg, WORD wID);
 +    virtual HRESULT STDMETHODCALLTYPE BrowseObject(LPCITEMIDLIST pidl, UINT wFlags);
 +    virtual HRESULT STDMETHODCALLTYPE GetViewStateStream(DWORD grfMode, IStream **ppStrm);
 +    virtual HRESULT STDMETHODCALLTYPE GetControlWindow(UINT id, HWND *lphwnd);
 +    virtual HRESULT STDMETHODCALLTYPE SendControlMsg(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret);
 +    virtual HRESULT STDMETHODCALLTYPE QueryActiveShellView(IShellView **ppshv);
 +    virtual HRESULT STDMETHODCALLTYPE OnViewWindowActive(IShellView *ppshv);
 +    virtual HRESULT STDMETHODCALLTYPE SetToolbarItems(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags);
 +
 +    // *** IDropTarget methods ***
 +    virtual HRESULT STDMETHODCALLTYPE DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
 +    virtual HRESULT STDMETHODCALLTYPE DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
 +    virtual HRESULT STDMETHODCALLTYPE DragLeave();
 +    virtual HRESULT STDMETHODCALLTYPE Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
 +
 +    // *** IServiceProvider methods ***
 +    virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
 +
 +    // *** IShellBowserService methods ***
 +    virtual HRESULT STDMETHODCALLTYPE GetPropertyBag(long flags, REFIID riid, void **ppvObject);
 +
 +    // *** IDispatch methods ***
 +    virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo);
 +    virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo);
 +    virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(
 +        REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId);
 +    virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
 +        DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr);
 +
 +    // *** IBrowserService methods ***
 +    virtual HRESULT STDMETHODCALLTYPE GetParentSite(IOleInPlaceSite **ppipsite);
 +    virtual HRESULT STDMETHODCALLTYPE SetTitle(IShellView *psv, LPCWSTR pszName);
 +    virtual HRESULT STDMETHODCALLTYPE GetTitle(IShellView *psv, LPWSTR pszName, DWORD cchName);
 +    virtual HRESULT STDMETHODCALLTYPE GetOleObject(IOleObject **ppobjv);
 +    virtual HRESULT STDMETHODCALLTYPE GetTravelLog(ITravelLog **pptl);
 +    virtual HRESULT STDMETHODCALLTYPE ShowControlWindow(UINT id, BOOL fShow);
 +    virtual HRESULT STDMETHODCALLTYPE IsControlWindowShown(UINT id, BOOL *pfShown);
 +    virtual HRESULT STDMETHODCALLTYPE IEGetDisplayName(LPCITEMIDLIST pidl, LPWSTR pwszName, UINT uFlags);
 +    virtual HRESULT STDMETHODCALLTYPE IEParseDisplayName(UINT uiCP, LPCWSTR pwszPath, LPITEMIDLIST *ppidlOut);
 +    virtual HRESULT STDMETHODCALLTYPE DisplayParseError(HRESULT hres, LPCWSTR pwszPath);
 +    virtual HRESULT STDMETHODCALLTYPE NavigateToPidl(LPCITEMIDLIST pidl, DWORD grfHLNF);
 +    virtual HRESULT STDMETHODCALLTYPE SetNavigateState(BNSTATE bnstate);
 +    virtual HRESULT STDMETHODCALLTYPE GetNavigateState(BNSTATE *pbnstate);
 +    virtual HRESULT STDMETHODCALLTYPE NotifyRedirect(IShellView *psv, LPCITEMIDLIST pidl, BOOL *pfDidBrowse);
 +    virtual HRESULT STDMETHODCALLTYPE UpdateWindowList();
 +    virtual HRESULT STDMETHODCALLTYPE UpdateBackForwardState();
 +    virtual HRESULT STDMETHODCALLTYPE SetFlags(DWORD dwFlags, DWORD dwFlagMask);
 +    virtual HRESULT STDMETHODCALLTYPE GetFlags(DWORD *pdwFlags);
 +    virtual HRESULT STDMETHODCALLTYPE CanNavigateNow( void);
 +    virtual HRESULT STDMETHODCALLTYPE GetPidl(LPITEMIDLIST *ppidl);
 +    virtual HRESULT STDMETHODCALLTYPE SetReferrer(LPCITEMIDLIST pidl);
 +    virtual DWORD STDMETHODCALLTYPE GetBrowserIndex();
 +    virtual HRESULT STDMETHODCALLTYPE GetBrowserByIndex(DWORD dwID, IUnknown **ppunk);
 +    virtual HRESULT STDMETHODCALLTYPE GetHistoryObject(IOleObject **ppole, IStream **pstm, IBindCtx **ppbc);
 +    virtual HRESULT STDMETHODCALLTYPE SetHistoryObject(IOleObject *pole, BOOL fIsLocalAnchor);
 +    virtual HRESULT STDMETHODCALLTYPE CacheOLEServer(IOleObject *pole);
 +    virtual HRESULT STDMETHODCALLTYPE GetSetCodePage(VARIANT *pvarIn, VARIANT *pvarOut);
 +    virtual HRESULT STDMETHODCALLTYPE OnHttpEquiv(IShellView *psv, BOOL fDone, VARIANT *pvarargIn, VARIANT *pvarargOut);
 +    virtual HRESULT STDMETHODCALLTYPE GetPalette(HPALETTE *hpal);
 +    virtual HRESULT STDMETHODCALLTYPE RegisterWindow(BOOL fForceRegister, int swc);
 +
 +    // *** IBrowserService2 methods ***
 +    virtual LRESULT STDMETHODCALLTYPE WndProcBS(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 +    virtual HRESULT STDMETHODCALLTYPE SetAsDefFolderSettings();
 +    virtual HRESULT STDMETHODCALLTYPE GetViewRect(RECT *prc);
 +    virtual HRESULT STDMETHODCALLTYPE OnSize(WPARAM wParam);
 +    virtual HRESULT STDMETHODCALLTYPE OnCreate(struct tagCREATESTRUCTW *pcs);
 +    virtual LRESULT STDMETHODCALLTYPE OnCommand(WPARAM wParam, LPARAM lParam);
 +    virtual HRESULT STDMETHODCALLTYPE OnDestroy();
 +    virtual LRESULT STDMETHODCALLTYPE OnNotify(struct tagNMHDR *pnm);
 +    virtual HRESULT STDMETHODCALLTYPE OnSetFocus();
 +    virtual HRESULT STDMETHODCALLTYPE OnFrameWindowActivateBS(BOOL fActive);
 +    virtual HRESULT STDMETHODCALLTYPE ReleaseShellView();
 +    virtual HRESULT STDMETHODCALLTYPE ActivatePendingView();
 +    virtual HRESULT STDMETHODCALLTYPE CreateViewWindow(IShellView *psvNew, IShellView *psvOld, LPRECT prcView, HWND *phwnd);
 +    virtual HRESULT STDMETHODCALLTYPE CreateBrowserPropSheetExt(REFIID riid, void **ppv);
 +    virtual HRESULT STDMETHODCALLTYPE GetViewWindow(HWND *phwndView);
 +    virtual HRESULT STDMETHODCALLTYPE GetBaseBrowserData(LPCBASEBROWSERDATA *pbbd);
 +    virtual LPBASEBROWSERDATA STDMETHODCALLTYPE PutBaseBrowserData( void);
 +    virtual HRESULT STDMETHODCALLTYPE InitializeTravelLog(ITravelLog *ptl, DWORD dw);
 +    virtual HRESULT STDMETHODCALLTYPE SetTopBrowser();
 +    virtual HRESULT STDMETHODCALLTYPE Offline(int iCmd);
 +    virtual HRESULT STDMETHODCALLTYPE AllowViewResize(BOOL f);
 +    virtual HRESULT STDMETHODCALLTYPE SetActivateState(UINT u);
 +    virtual HRESULT STDMETHODCALLTYPE UpdateSecureLockIcon(int eSecureLock);
 +    virtual HRESULT STDMETHODCALLTYPE InitializeDownloadManager();
 +    virtual HRESULT STDMETHODCALLTYPE InitializeTransitionSite();
 +    virtual HRESULT STDMETHODCALLTYPE _Initialize(HWND hwnd, IUnknown *pauto);
 +    virtual HRESULT STDMETHODCALLTYPE _CancelPendingNavigationAsync( void);
 +    virtual HRESULT STDMETHODCALLTYPE _CancelPendingView();
 +    virtual HRESULT STDMETHODCALLTYPE _MaySaveChanges();
 +    virtual HRESULT STDMETHODCALLTYPE _PauseOrResumeView(BOOL fPaused);
 +    virtual HRESULT STDMETHODCALLTYPE _DisableModeless();
 +    virtual HRESULT STDMETHODCALLTYPE _NavigateToPidl(LPCITEMIDLIST pidl, DWORD grfHLNF, DWORD dwFlags);
 +    virtual HRESULT STDMETHODCALLTYPE _TryShell2Rename(IShellView *psv, LPCITEMIDLIST pidlNew);
 +    virtual HRESULT STDMETHODCALLTYPE _SwitchActivationNow();
 +    virtual HRESULT STDMETHODCALLTYPE _ExecChildren(IUnknown *punkBar, BOOL fBroadcast, const GUID *pguidCmdGroup,
 +        DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut);
 +    virtual HRESULT STDMETHODCALLTYPE _SendChildren(
 +        HWND hwndBar, BOOL fBroadcast, UINT uMsg, WPARAM wParam, LPARAM lParam);
 +    virtual HRESULT STDMETHODCALLTYPE GetFolderSetData(struct tagFolderSetData *pfsd);
 +    virtual HRESULT STDMETHODCALLTYPE _OnFocusChange(UINT itb);
 +    virtual HRESULT STDMETHODCALLTYPE v_ShowHideChildWindows(BOOL fChildOnly);
 +    virtual UINT STDMETHODCALLTYPE _get_itbLastFocus();
 +    virtual HRESULT STDMETHODCALLTYPE _put_itbLastFocus(UINT itbLastFocus);
 +    virtual HRESULT STDMETHODCALLTYPE _UIActivateView(UINT uState);
 +    virtual HRESULT STDMETHODCALLTYPE _GetViewBorderRect(RECT *prc);
 +    virtual HRESULT STDMETHODCALLTYPE _UpdateViewRectSize();
 +    virtual HRESULT STDMETHODCALLTYPE _ResizeNextBorder(UINT itb);
 +    virtual HRESULT STDMETHODCALLTYPE _ResizeView();
 +    virtual HRESULT STDMETHODCALLTYPE _GetEffectiveClientArea(LPRECT lprectBorder, HMONITOR hmon);
 +    virtual IStream *STDMETHODCALLTYPE v_GetViewStream(LPCITEMIDLIST pidl, DWORD grfMode, LPCWSTR pwszName);
 +    virtual LRESULT STDMETHODCALLTYPE ForwardViewMsg(UINT uMsg, WPARAM wParam, LPARAM lParam);
 +    virtual HRESULT STDMETHODCALLTYPE SetAcceleratorMenu(HACCEL hacc);
 +    virtual int STDMETHODCALLTYPE _GetToolbarCount();
 +    virtual LPTOOLBARITEM STDMETHODCALLTYPE _GetToolbarItem(int itb);
 +    virtual HRESULT STDMETHODCALLTYPE _SaveToolbars(IStream *pstm);
 +    virtual HRESULT STDMETHODCALLTYPE _LoadToolbars(IStream *pstm);
 +    virtual HRESULT STDMETHODCALLTYPE _CloseAndReleaseToolbars(BOOL fClose);
 +    virtual HRESULT STDMETHODCALLTYPE v_MayGetNextToolbarFocus(LPMSG lpMsg, UINT itbNext,
 +        int citb, LPTOOLBARITEM *pptbi, HWND *phwnd);
 +    virtual HRESULT STDMETHODCALLTYPE _ResizeNextBorderHelper(UINT itb, BOOL bUseHmonitor);
 +    virtual UINT STDMETHODCALLTYPE _FindTBar(IUnknown *punkSrc);
 +    virtual HRESULT STDMETHODCALLTYPE _SetFocus(LPTOOLBARITEM ptbi, HWND hwnd, LPMSG lpMsg);
 +    virtual HRESULT STDMETHODCALLTYPE v_MayTranslateAccelerator(MSG *pmsg);
 +    virtual HRESULT STDMETHODCALLTYPE _GetBorderDWHelper(IUnknown *punkSrc, LPRECT lprectBorder, BOOL bUseHmonitor);
 +    virtual HRESULT STDMETHODCALLTYPE v_CheckZoneCrossing(LPCITEMIDLIST pidl);
 +
 +    // *** IWebBrowser methods ***
 +    virtual HRESULT STDMETHODCALLTYPE GoBack();
 +    virtual HRESULT STDMETHODCALLTYPE GoForward();
 +    virtual HRESULT STDMETHODCALLTYPE GoHome();
 +    virtual HRESULT STDMETHODCALLTYPE GoSearch();
 +    virtual HRESULT STDMETHODCALLTYPE Navigate(BSTR URL, VARIANT *Flags, VARIANT *TargetFrameName,
 +        VARIANT *PostData, VARIANT *Headers);
 +    virtual HRESULT STDMETHODCALLTYPE Refresh();
 +    virtual HRESULT STDMETHODCALLTYPE Refresh2(VARIANT *Level);
 +    virtual HRESULT STDMETHODCALLTYPE Stop();
 +    virtual HRESULT STDMETHODCALLTYPE get_Application(IDispatch **ppDisp);
 +    virtual HRESULT STDMETHODCALLTYPE get_Parent(IDispatch **ppDisp);
 +    virtual HRESULT STDMETHODCALLTYPE get_Container(IDispatch **ppDisp);
 +    virtual HRESULT STDMETHODCALLTYPE get_Document(IDispatch **ppDisp);
 +    virtual HRESULT STDMETHODCALLTYPE get_TopLevelContainer(VARIANT_BOOL *pBool);
 +    virtual HRESULT STDMETHODCALLTYPE get_Type(BSTR *Type);
 +    virtual HRESULT STDMETHODCALLTYPE get_Left(long *pl);
 +    virtual HRESULT STDMETHODCALLTYPE put_Left(long Left);
 +    virtual HRESULT STDMETHODCALLTYPE get_Top(long *pl);
 +    virtual HRESULT STDMETHODCALLTYPE put_Top(long Top);
 +    virtual HRESULT STDMETHODCALLTYPE get_Width(long *pl);
 +    virtual HRESULT STDMETHODCALLTYPE put_Width(long Width);
 +    virtual HRESULT STDMETHODCALLTYPE get_Height(long *pl);
 +    virtual HRESULT STDMETHODCALLTYPE put_Height(long Height);
 +    virtual HRESULT STDMETHODCALLTYPE get_LocationName(BSTR *LocationName);
 +    virtual HRESULT STDMETHODCALLTYPE get_LocationURL(BSTR *LocationURL);
 +    virtual HRESULT STDMETHODCALLTYPE get_Busy(VARIANT_BOOL *pBool);
 +
 +    // *** IWebBrowserApp methods ***
 +    virtual HRESULT STDMETHODCALLTYPE Quit();
 +    virtual HRESULT STDMETHODCALLTYPE ClientToWindow(int *pcx, int *pcy);
 +    virtual HRESULT STDMETHODCALLTYPE PutProperty(BSTR Property, VARIANT vtValue);
 +    virtual HRESULT STDMETHODCALLTYPE GetProperty(BSTR Property, VARIANT *pvtValue);
 +    virtual HRESULT STDMETHODCALLTYPE get_Name(BSTR *Name);
 +    virtual HRESULT STDMETHODCALLTYPE get_HWND(SHANDLE_PTR *pHWND);
 +    virtual HRESULT STDMETHODCALLTYPE get_FullName(BSTR *FullName);
 +    virtual HRESULT STDMETHODCALLTYPE get_Path(BSTR *Path);
 +    virtual HRESULT STDMETHODCALLTYPE get_Visible(VARIANT_BOOL *pBool);
 +    virtual HRESULT STDMETHODCALLTYPE put_Visible(VARIANT_BOOL Value);
 +    virtual HRESULT STDMETHODCALLTYPE get_StatusBar(VARIANT_BOOL *pBool);
 +    virtual HRESULT STDMETHODCALLTYPE put_StatusBar(VARIANT_BOOL Value);
 +    virtual HRESULT STDMETHODCALLTYPE get_StatusText(BSTR *StatusText);
 +    virtual HRESULT STDMETHODCALLTYPE put_StatusText(BSTR StatusText);
 +    virtual HRESULT STDMETHODCALLTYPE get_ToolBar(int *Value);
 +    virtual HRESULT STDMETHODCALLTYPE put_ToolBar(int Value);
 +    virtual HRESULT STDMETHODCALLTYPE get_MenuBar(VARIANT_BOOL *Value);
 +    virtual HRESULT STDMETHODCALLTYPE put_MenuBar(VARIANT_BOOL Value);
 +    virtual HRESULT STDMETHODCALLTYPE get_FullScreen(VARIANT_BOOL *pbFullScreen);
 +    virtual HRESULT STDMETHODCALLTYPE put_FullScreen(VARIANT_BOOL bFullScreen);
 +
 +    // *** IWebBrowser2 methods ***
 +    virtual HRESULT STDMETHODCALLTYPE Navigate2(VARIANT *URL, VARIANT *Flags, VARIANT *TargetFrameName,
 +        VARIANT *PostData, VARIANT *Headers);
 +    virtual HRESULT STDMETHODCALLTYPE QueryStatusWB(OLECMDID cmdID, OLECMDF *pcmdf);
 +    virtual HRESULT STDMETHODCALLTYPE ExecWB(OLECMDID cmdID, OLECMDEXECOPT cmdexecopt,
 +        VARIANT *pvaIn, VARIANT *pvaOut);
 +    virtual HRESULT STDMETHODCALLTYPE ShowBrowserBar(VARIANT *pvaClsid, VARIANT *pvarShow, VARIANT *pvarSize);
 +    virtual HRESULT STDMETHODCALLTYPE get_ReadyState(READYSTATE *plReadyState);
 +    virtual HRESULT STDMETHODCALLTYPE get_Offline(VARIANT_BOOL *pbOffline);
 +    virtual HRESULT STDMETHODCALLTYPE put_Offline(VARIANT_BOOL bOffline);
 +    virtual HRESULT STDMETHODCALLTYPE get_Silent(VARIANT_BOOL *pbSilent);
 +    virtual HRESULT STDMETHODCALLTYPE put_Silent(VARIANT_BOOL bSilent);
 +    virtual HRESULT STDMETHODCALLTYPE get_RegisterAsBrowser(VARIANT_BOOL *pbRegister);
 +    virtual HRESULT STDMETHODCALLTYPE put_RegisterAsBrowser(VARIANT_BOOL bRegister);
 +    virtual HRESULT STDMETHODCALLTYPE get_RegisterAsDropTarget(VARIANT_BOOL *pbRegister);
 +    virtual HRESULT STDMETHODCALLTYPE put_RegisterAsDropTarget(VARIANT_BOOL bRegister);
 +    virtual HRESULT STDMETHODCALLTYPE get_TheaterMode(VARIANT_BOOL *pbRegister);
 +    virtual HRESULT STDMETHODCALLTYPE put_TheaterMode(VARIANT_BOOL bRegister);
 +    virtual HRESULT STDMETHODCALLTYPE get_AddressBar(VARIANT_BOOL *Value);
 +    virtual HRESULT STDMETHODCALLTYPE put_AddressBar(VARIANT_BOOL Value);
 +    virtual HRESULT STDMETHODCALLTYPE get_Resizable(VARIANT_BOOL *Value);
 +    virtual HRESULT STDMETHODCALLTYPE put_Resizable(VARIANT_BOOL Value);
 +
 +    // *** ITravelLogClient methods ***
 +    virtual HRESULT STDMETHODCALLTYPE FindWindowByIndex(DWORD dwID, IUnknown **ppunk);
 +    virtual HRESULT STDMETHODCALLTYPE GetWindowData(IStream *pStream, LPWINDOWDATA pWinData);
 +    virtual HRESULT STDMETHODCALLTYPE LoadHistoryPosition(LPWSTR pszUrlLocation, DWORD dwPosition);
 +
 +    // *** IPersist methods ***
 +    virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID);
 +
 +    // *** IPersistHistory methods ***
 +    virtual HRESULT STDMETHODCALLTYPE LoadHistory(IStream *pStream, IBindCtx *pbc);
 +    virtual HRESULT STDMETHODCALLTYPE SaveHistory(IStream *pStream);
 +    virtual HRESULT STDMETHODCALLTYPE SetPositionCookie(DWORD dwPositioncookie);
 +    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);
 +    LRESULT RelayMsgToShellView(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
 +    LRESULT OnClose(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnFolderOptions(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnMapNetworkDrive(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnDisconnectNetworkDrive(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnAboutReactOS(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    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);
 +    LRESULT OnToggleToolbarLock(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnToggleToolbarBandVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnToggleAddressBandVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnToggleLinksBandVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnToggleTextLabels(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnToolbarCustomize(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnGoTravel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT RelayCommands(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
 +
 +    static ATL::CWndClassInfo& GetWndClassInfo()
 +    {
 +        static ATL::CWndClassInfo wc =
 +        {
 +            { sizeof(WNDCLASSEX), CS_DBLCLKS, StartWindowProc,
 +              0, 0, NULL, LoadIcon(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDI_CABINET)),
 +              LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_WINDOW + 1), NULL, szCabinetWndClass, NULL },
 +            NULL, NULL, IDC_ARROW, TRUE, 0, _T("")
 +        };
 +        return wc;
 +    }
 +
 +    BEGIN_MSG_MAP(CShellBrowser)
 +        MESSAGE_HANDLER(WM_CREATE, OnCreate)
 +        MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
 +        MESSAGE_HANDLER(WM_SIZE, OnSize)
 +        MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup)
 +        MESSAGE_HANDLER(WM_MEASUREITEM, RelayMsgToShellView)
 +        MESSAGE_HANDLER(WM_DRAWITEM, RelayMsgToShellView)
 +        MESSAGE_HANDLER(WM_MENUSELECT, RelayMsgToShellView)
 +        COMMAND_ID_HANDLER(IDM_FILE_CLOSE, OnClose)
 +        COMMAND_ID_HANDLER(IDM_TOOLS_FOLDEROPTIONS, OnFolderOptions)
 +        COMMAND_ID_HANDLER(IDM_TOOLS_MAPNETWORKDRIVE, OnMapNetworkDrive)
 +        COMMAND_ID_HANDLER(IDM_TOOLS_DISCONNECTNETWORKDRIVE, OnDisconnectNetworkDrive)
 +        COMMAND_ID_HANDLER(IDM_HELP_ABOUT, OnAboutReactOS)
 +        COMMAND_ID_HANDLER(IDM_GOTO_BACK, OnGoBack)
 +        COMMAND_ID_HANDLER(IDM_GOTO_FORWARD, OnGoForward)
 +        COMMAND_ID_HANDLER(IDM_GOTO_UPONELEVEL, OnGoUpLevel)
 +        COMMAND_ID_HANDLER(IDM_GOTO_HOMEPAGE, OnGoHome)
 +        COMMAND_ID_HANDLER(IDM_HELP_ISTHISCOPYLEGAL, OnIsThisLegal)
 +        COMMAND_ID_HANDLER(IDM_VIEW_STATUSBAR, OnToggleStatusBarVisible)
 +        COMMAND_ID_HANDLER(IDM_TOOLBARS_LOCKTOOLBARS, OnToggleToolbarLock)
 +        COMMAND_ID_HANDLER(IDM_TOOLBARS_STANDARDBUTTONS, OnToggleToolbarBandVisible)
 +        COMMAND_ID_HANDLER(IDM_TOOLBARS_ADDRESSBAR, OnToggleAddressBandVisible)
 +        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()
 +
 +    BEGIN_CONNECTION_POINT_MAP(CShellBrowser)
 +        CONNECTION_POINT_ENTRY(DIID_DWebBrowserEvents2)
 +        CONNECTION_POINT_ENTRY(DIID_DWebBrowserEvents)
 +    END_CONNECTION_POINT_MAP()
 +
 +    BEGIN_COM_MAP(CShellBrowser)
 +        COM_INTERFACE_ENTRY_IID(IID_IDockingWindowSite, IDockingWindowSite)
 +        COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
 +        COM_INTERFACE_ENTRY2_IID(IID_IOleWindow, IOleWindow, IDockingWindowSite)
 +        COM_INTERFACE_ENTRY_IID(IID_IShellBrowser, IShellBrowser)
 +        COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
 +        COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
 +        COM_INTERFACE_ENTRY_IID(IID_IProfferService, IProfferService)
 +        COM_INTERFACE_ENTRY_IID(IID_IShellBrowserService, IShellBrowserService)
 +        COM_INTERFACE_ENTRY_IID(IID_IDispatch, IDispatch)
 +        COM_INTERFACE_ENTRY_IID(IID_IConnectionPointContainer, IConnectionPointContainer)
 +        COM_INTERFACE_ENTRY_IID(IID_IWebBrowser, IWebBrowser)
 +        COM_INTERFACE_ENTRY_IID(IID_IWebBrowserApp, IWebBrowserApp)
 +        COM_INTERFACE_ENTRY_IID(IID_IWebBrowser2, IWebBrowser2)
 +        COM_INTERFACE_ENTRY_IID(IID_ITravelLogClient, ITravelLogClient)
 +        COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
 +        COM_INTERFACE_ENTRY_IID(IID_IPersistHistory, IPersistHistory)
 +        COM_INTERFACE_ENTRY_IID(IID_IBrowserService, IBrowserService)
 +        COM_INTERFACE_ENTRY_IID(IID_IBrowserService2, IBrowserService2)
 +    END_COM_MAP()
 +};
 +
 +extern HRESULT CreateProgressDialog(REFIID riid, void **ppv);
 +
 +CShellBrowser::CShellBrowser()
 +{
 +    fCurrentShellViewWindow = NULL;
 +    fCurrentDirectoryPIDL = NULL;
 +    fStatusBar = NULL;
 +    fStatusBarVisible = true;
 +    memset(fClientBars, 0, sizeof(fClientBars));
 +    fCurrentMenuBar = NULL;
 +    fHistoryObject = NULL;
 +    fHistoryStream = NULL;
 +    fHistoryBindContext = NULL;
 +}
 +
 +CShellBrowser::~CShellBrowser()
 +{
 +}
 +
 +HRESULT CShellBrowser::Initialize(LPITEMIDLIST pidl, long b, long c, long d)
 +{
 +    CComPtr<IDockingWindow>                 dockingWindow;
 +    CComPtr<IStream>                        settingsStream;
 +    CComPtr<IPersistStreamInit>             persistStreamInit;
 +    CComPtr<IOleCommandTarget>              commandTarget;
 +    CComPtr<IObjectWithSite>                objectSite;
 +    HRESULT                                 hResult;
 +
 +    _AtlInitialConstruct();
 +
 +    fCabinetState.cLength = sizeof(fCabinetState);
 +    if (ReadCabinetState(&fCabinetState, sizeof(fCabinetState)) == FALSE)
 +    {
 +    }
 +
 +    // create window
 +    Create(HWND_DESKTOP);
 +    if (m_hWnd == NULL)
 +        return E_FAIL;
 +
 +#if 0
 +    hResult = CoCreateInstance(CLSID_InternetToolbar, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, &fClientBars[BIInternetToolbar].clientBar));
 +    if (FAILED(hResult))
 +        return hResult;
 +#else
 +    hResult = CreateInternetToolbar(IID_PPV_ARG(IUnknown, &fClientBars[BIInternetToolbar].clientBar));
 +    if (FAILED(hResult))
 +        return hResult;
 +#endif
 +
 +    // create interfaces
 +    hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
 +        IID_PPV_ARG(IDockingWindow, &dockingWindow));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
 +        IID_PPV_ARG(IPersistStreamInit, &persistStreamInit));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
 +        IID_PPV_ARG(IOleCommandTarget, &commandTarget));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
 +        IID_PPV_ARG(IObjectWithSite, &objectSite));
 +    if (FAILED(hResult))
 +        return hResult;
 +
 +    hResult = objectSite->SetSite(static_cast<IShellBrowser *>(this));
 +    if (FAILED(hResult))
 +        return hResult;
 +
 +    hResult = commandTarget->Exec(&CGID_PrivCITCommands, 1, 1 /* or 0 */, NULL, NULL);
 +    if (FAILED(hResult))
 +        return hResult;
 +
 +    // TODO: create settingsStream from registry entry
 +    if (settingsStream.p == NULL)
 +    {
 +        hResult = persistStreamInit->InitNew();
 +        if (FAILED(hResult))
 +            return hResult;
 +    }
 +    else
 +    {
 +        hResult = persistStreamInit->Load(settingsStream);
 +        if (FAILED(hResult))
 +            return hResult;
 +    }
 +    hResult = dockingWindow->ShowDW(TRUE);
 +    if (FAILED(hResult))
 +        return hResult;
 +
 +    fToolbarProxy.Initialize(m_hWnd, fClientBars[BIInternetToolbar].clientBar);
 +
 +    // create status bar
 +    fStatusBar = CreateWindow(STATUSCLASSNAMEW, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
 +                    SBT_NOBORDERS | SBT_TOOLTIPS, 0, 0, 500, 20, m_hWnd, (HMENU)0xa001,
 +                    _AtlBaseModule.GetModuleInstance(), 0);
 +    fStatusBarVisible = true;
 +
 +    // browse 
 +    hResult = BrowseToPIDL(pidl, BTP_UPDATE_NEXT_HISTORY);
 +    if (FAILED(hResult))
 +        return hResult;
 +
 +    ShowWindow(SW_SHOWNORMAL);
 +
 +    return S_OK;
 +}
 +
 +HRESULT CShellBrowser::BrowseToPIDL(LPCITEMIDLIST pidl, long flags)
 +{
 +    CComPtr<IShellFolder>                   newFolder;
 +    FOLDERSETTINGS                          newFolderSettings;
 +    HRESULT                                 hResult;
 +
 +    // called by shell view to browse to new folder
 +    // also called by explorer band to navigate to new folder
 +    hResult = SHBindToFolder(pidl, &newFolder);
 +    if (FAILED(hResult))
 +        return hResult;
 +
 +    newFolderSettings.ViewMode = FVM_ICON;
 +    newFolderSettings.fFlags = 0;
 +    hResult = BrowseToPath(newFolder, pidl, &newFolderSettings, flags);
 +    if (FAILED(hResult))
 +        return hResult;
 +    return S_OK;
 +}
 +
 +BOOL WINAPI _ILIsDesktop(LPCITEMIDLIST pidl)
 +{
 +    return (pidl == NULL || pidl->mkid.cb == 0);
 +}
 +
 +BOOL WINAPI _ILIsPidlSimple(LPCITEMIDLIST pidl)
 +{
 +    LPCITEMIDLIST                           pidlnext;
 +    WORD                                    length;
 +    BOOL                                    ret;
 +
 +    ret = TRUE;
 +    if (! _ILIsDesktop(pidl))
 +    {
 +        length = pidl->mkid.cb;
 +        pidlnext =
 +            reinterpret_cast<LPCITEMIDLIST>(
 +                reinterpret_cast<const BYTE *>(pidl) + length);
 +        if (pidlnext->mkid.cb != 0)
 +            ret = FALSE;
 +    }
 +    return ret;
 +}
 +
 +HRESULT WINAPI SHBindToFolderIDListParent(IShellFolder *unused, LPCITEMIDLIST pidl,
 +    const IID *riid, LPVOID *ppv, LPITEMIDLIST *ppidlLast)
 +{
 +    CComPtr<IShellFolder>                   psf;
 +    LPITEMIDLIST                            pidlChild;
 +    LPITEMIDLIST                            pidlParent;
 +    HRESULT                                 hResult;
 +
 +    hResult = E_FAIL;
 +    if (ppv == NULL)
 +        return E_POINTER;
 +    *ppv = NULL;
 +    if (ppidlLast != NULL)
 +        *ppidlLast = NULL;
 +    if (_ILIsPidlSimple(pidl))
 +    {
 +        if (ppidlLast != NULL)
 +            *ppidlLast = ILClone(pidl);
 +        hResult = SHGetDesktopFolder((IShellFolder **)ppv);
 +    }
 +    else
 +    {
 +        pidlChild = ILClone(ILFindLastID(pidl));
 +        pidlParent = ILClone(pidl);
 +        ILRemoveLastID(pidlParent);
 +        hResult = SHGetDesktopFolder(&psf);
 +        if (SUCCEEDED(hResult))
 +            hResult = psf->BindToObject(pidlParent, NULL, *riid, ppv);
 +        if (SUCCEEDED(hResult) && ppidlLast != NULL)
 +            *ppidlLast = pidlChild;
 +        else
 +            ILFree(pidlChild);
 +        ILFree(pidlParent);
 +    }
 +    return hResult;
 +}
 +
 +HRESULT IEGetNameAndFlagsEx(LPITEMIDLIST pidl, SHGDNF uFlags, long param10,
 +    LPWSTR pszBuf, UINT cchBuf, SFGAOF *rgfInOut)
 +{
 +    CComPtr<IShellFolder>                   parentFolder;
 +    LPITEMIDLIST                            childPIDL;
 +    STRRET                                  L108;
 +    HRESULT                                 hResult;
 +
 +    hResult = SHBindToFolderIDListParent(NULL, pidl, &IID_PPV_ARG(IShellFolder, &parentFolder), &childPIDL);
 +    hResult = parentFolder->GetDisplayNameOf(childPIDL, uFlags, &L108);
 +    StrRetToBufW(&L108, childPIDL, pszBuf, cchBuf);
 +    if (rgfInOut)
 +        hResult = parentFolder->GetAttributesOf(1, const_cast<LPCITEMIDLIST *>(&childPIDL), rgfInOut);
 +    ILFree(childPIDL);
 +    return S_OK;
 +}
 +
 +long IEGetNameAndFlags(LPITEMIDLIST pidl, SHGDNF uFlags, LPWSTR pszBuf, UINT cchBuf, SFGAOF *rgfInOut)
 +{
 +    return IEGetNameAndFlagsEx(pidl, uFlags, 0, pszBuf, cchBuf, rgfInOut);
 +}
 +
 +HRESULT CShellBrowser::BrowseToPath(IShellFolder *newShellFolder,
 +    LPCITEMIDLIST absolutePIDL, FOLDERSETTINGS *folderSettings, long flags)
 +{
 +    CComPtr<IObjectWithSite>                objectWithSite;
 +    CComPtr<IShellFolder>                   saveCurrentShellFolder;
 +    CComPtr<IShellView>                     saveCurrentShellView;
 +    CComPtr<IShellView>                     newShellView;
 +    CComPtr<ITravelLog>                     travelLog;
 +    HWND                                    newShellViewWindow;
 +    BOOL                                    windowUpdateIsLocked;
 +    RECT                                    shellViewWindowBounds;
 +    HWND                                    previousView;
 +    HCURSOR                                 saveCursor;
 +    wchar_t                                 newTitle[MAX_PATH];
 +    SHGDNF                                  nameFlags;
 +    HRESULT                                 hResult;
 +
 +    if (newShellFolder == NULL)
 +        return E_INVALIDARG;
 +
 +    hResult = GetTravelLog(&travelLog);
 +    if (FAILED(hResult))
 +        return hResult;
 +
 +    // update history
 +    if (flags & BTP_UPDATE_CUR_HISTORY)
 +    {
 +        if (travelLog->CountEntries(static_cast<IDropTarget *>(this)) > 0)
 +            hResult = travelLog->UpdateEntry(static_cast<IDropTarget *>(this), FALSE);
 +        // what to do with error? Do we want to halt browse because state save failed?
 +    }
 +
++    if (fCurrentShellView)
++    {
++        fCurrentShellView->UIActivate(SVUIA_DEACTIVATE);
++    }
++
 +    // create view object
 +    hResult = newShellFolder->CreateViewObject(m_hWnd, IID_PPV_ARG(IShellView, &newShellView));
 +    if (FAILED(hResult))
 +        return hResult;
 +    previousView = fCurrentShellViewWindow;
 +
 +    // enter updating section
 +    saveCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
 +    windowUpdateIsLocked = LockWindowUpdate(TRUE);
 +    if (fCurrentShellView != NULL)
 +        ::SendMessage(fCurrentShellViewWindow, WM_SETREDRAW, 0, 0);
 +
 +    // set site
 +    hResult = newShellView->QueryInterface(IID_PPV_ARG(IObjectWithSite, &objectWithSite));
 +    if (SUCCEEDED(hResult) && objectWithSite.p != NULL)
 +        hResult = objectWithSite->SetSite(static_cast<IDropTarget *>(this));
 +
 +    // update folder and view
 +    saveCurrentShellFolder = fCurrentShellFolder;
 +    saveCurrentShellView = fCurrentShellView;
 +    fCurrentShellFolder = newShellFolder;
 +    fCurrentShellView = newShellView;
 +
 +    // get boundary
 +    if (previousView != NULL)
 +        ::GetWindowRect(previousView, &shellViewWindowBounds);
 +    else
 +        ZeroMemory(&shellViewWindowBounds, sizeof(shellViewWindowBounds));
 +    ::MapWindowPoints(0, m_hWnd, reinterpret_cast<POINT *>(&shellViewWindowBounds), 2);
 +
 +    // create view window
 +    hResult = newShellView->CreateViewWindow(saveCurrentShellView, folderSettings,
 +        this, &shellViewWindowBounds, &newShellViewWindow);
 +    if (FAILED(hResult) || newShellViewWindow == NULL)
 +    {
 +        fCurrentShellView = saveCurrentShellView;
 +        fCurrentShellFolder = saveCurrentShellFolder;
 +        ::SendMessage(fCurrentShellViewWindow, WM_SETREDRAW, 1, 0);
 +        if (windowUpdateIsLocked)
 +            LockWindowUpdate(FALSE);
 +        SetCursor(saveCursor);
 +        return hResult;
 +    }
 +
 +    if (objectWithSite.p != NULL)
 +        hResult = objectWithSite->SetSite(NULL);
 +
 +    // update current pidl
 +    ILFree(fCurrentDirectoryPIDL);
 +    fCurrentDirectoryPIDL = ILClone(absolutePIDL);
 +
 +    // update view window
 +    if (saveCurrentShellView != NULL)
 +        saveCurrentShellView->DestroyViewWindow();
 +    fCurrentShellViewWindow = newShellViewWindow;
 +
 +    // no use
 +    saveCurrentShellView.Release();
 +    saveCurrentShellFolder.Release();
 +
 +    hResult = newShellView->UIActivate(SVUIA_ACTIVATE_FOCUS);
 +
 +    // leave updating section
 +    if (windowUpdateIsLocked)
 +        LockWindowUpdate(FALSE);
 +    SetCursor(saveCursor);
 +
 +    // update history
 +    if (flags & BTP_UPDATE_NEXT_HISTORY)
 +    {
 +        hResult = travelLog->AddEntry(static_cast<IDropTarget *>(this), FALSE);
 +        hResult = travelLog->UpdateEntry(static_cast<IDropTarget *>(this), FALSE);
 +    }
 +
 +    // completed
 +    nameFlags = SHGDN_FORADDRESSBAR | SHGDN_FORPARSING;
 +    hResult = IEGetNameAndFlags(fCurrentDirectoryPIDL, nameFlags, newTitle,
 +        sizeof(newTitle) / sizeof(wchar_t), NULL);
 +    if (SUCCEEDED(hResult))
 +    {
 +        FireNavigateComplete(newTitle);
 +    }
 +    else
 +    {
 +        FireNavigateComplete(L"ERROR");
 +    }
 +
 +    if (fCabinetState.fFullPathTitle)
 +        nameFlags = SHGDN_FORADDRESSBAR | SHGDN_FORPARSING;
 +    else
 +        nameFlags = SHGDN_FORADDRESSBAR;
 +    hResult = IEGetNameAndFlags(fCurrentDirectoryPIDL, nameFlags, newTitle,
 +        sizeof(newTitle) / sizeof(wchar_t), NULL);
 +    if (SUCCEEDED(hResult))
 +    {
 +        SetWindowText(newTitle);
 +
 +        LPCITEMIDLIST pidlChild;
 +        INT index, indexOpen;
 +        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);
 +
 +        SendMessage(WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(icSmall));
 +        SendMessage(WM_SETICON, ICON_BIG,   reinterpret_cast<LPARAM>(icLarge));
 +    }
 +
 +    // TODO: Update the window icon
 +
 +    FireCommandStateChangeAll();
 +    hResult = UpdateForwardBackState();
 +    return S_OK;
 +}
 +
 +HRESULT CShellBrowser::GetMenuBand(REFIID riid, void **shellMenu)
 +{
 +    CComPtr<IServiceProvider>               serviceProvider;
 +    CComPtr<IBandSite>                      bandSite;
 +    CComPtr<IDeskBand>                      deskBand;
 +    HRESULT                                 hResult;
 +
 +    if (fClientBars[BIInternetToolbar].clientBar.p == NULL)
 +        return E_FAIL;
 +    hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
 +        IID_PPV_ARG(IServiceProvider, &serviceProvider));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = serviceProvider->QueryService(SID_IBandSite, IID_PPV_ARG(IBandSite, &bandSite));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = bandSite->QueryBand(1, &deskBand, NULL, NULL, 0);
 +    if (FAILED(hResult))
 +        return hResult;
 +    return deskBand->QueryInterface(riid, shellMenu);
 +}
 +
 +HRESULT CShellBrowser::GetBaseBar(bool vertical, IUnknown **theBaseBar)
 +{
 +    CComPtr<IUnknown>                       newBaseBar;
 +    CComPtr<IDeskBar>                       deskBar;
 +    CComPtr<IUnknown>                       newBaseBarSite;
 +    CComPtr<IObjectWithSite>                objectWithSite;
 +    CComPtr<IDeskBarClient>                 deskBarClient;
 +    IUnknown                                **cache;
 +    HRESULT                                 hResult;
 +
 +    if (vertical)
 +        cache = &fClientBars[BIVerticalBaseBar].clientBar.p;
 +    else
 +        cache = &fClientBars[BIHorizontalBaseBar].clientBar.p;
 +    if (*cache == NULL)
 +    {
 +        hResult = CreateBaseBar(IID_PPV_ARG(IUnknown, &newBaseBar));
 +        if (FAILED(hResult))
 +            return hResult;
 +        hResult = CreateBaseBarSite(IID_PPV_ARG(IUnknown, &newBaseBarSite));
 +        if (FAILED(hResult))
 +            return hResult;
 +
 +        // tell the new base bar about the shell browser
 +        hResult = newBaseBar->QueryInterface(IID_PPV_ARG(IObjectWithSite, &objectWithSite));
 +        if (FAILED(hResult))
 +            return hResult;
 +        hResult = objectWithSite->SetSite(static_cast<IDropTarget *>(this));
 +        if (FAILED(hResult))
 +            return hResult;
 +
 +        // tell the new base bar about the new base bar site
 +        hResult = newBaseBar->QueryInterface(IID_PPV_ARG(IDeskBar, &deskBar));
 +        if (FAILED(hResult))
 +            return hResult;
 +        hResult = deskBar->SetClient(newBaseBarSite);
 +        if (FAILED(hResult))
 +            return hResult;
 +
 +        // tell the new base bar site about the new base bar
 +        hResult = newBaseBarSite->QueryInterface(IID_PPV_ARG(IDeskBarClient, &deskBarClient));
 +        if (FAILED(hResult))
 +            return hResult;
 +        hResult = deskBarClient->SetDeskBarSite(newBaseBar);
 +        if (FAILED(hResult))
 +            return hResult;
 +
 +        *cache = newBaseBar.Detach();
 +    }
 +    return (*cache)->QueryInterface(IID_PPV_ARG(IUnknown, theBaseBar));
 +}
 +
 +HRESULT CShellBrowser::ShowBand(const CLSID &classID, bool vertical)
 +{
 +    CComPtr<IDockingWindow>                 dockingWindow;
 +    CComPtr<IOleCommandTarget>              oleCommandTarget;
 +    CComPtr<IUnknown>                       baseBarSite;
 +    CComPtr<IUnknown>                       newBand;
 +    CComPtr<IUnknown>                       theBaseBar;
 +    CComPtr<IDeskBar>                       deskBar;
 +    VARIANT                                 vaIn;
 +    HRESULT                                 hResult;
 +
 +    __debugbreak();
 +
 +    hResult = GetBaseBar(vertical, (IUnknown **)&theBaseBar);
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = CoCreateInstance(classID, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, &newBand));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = theBaseBar->QueryInterface(IID_PPV_ARG(IDeskBar, &deskBar));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = deskBar->GetClient(&baseBarSite);
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = theBaseBar->QueryInterface(IID_PPV_ARG(IDockingWindow, &dockingWindow));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = baseBarSite->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
 +    if (FAILED(hResult))
 +        return hResult;
 +    V_VT(&vaIn) = VT_UNKNOWN;
 +    V_UNKNOWN(&vaIn) = newBand.p;
 +    hResult = oleCommandTarget->Exec(&CGID_IDeskBand, 1, 1, &vaIn, NULL);
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = dockingWindow->ShowDW(TRUE);
 +    if (FAILED(hResult))
 +        return hResult;
 +    return S_OK;
 +}
 +
 +HRESULT CShellBrowser::NavigateToParent()
 +{
 +    LPITEMIDLIST                            newDirectory;
 +    HRESULT                                 hResult;
 +
 +    newDirectory = ILClone(fCurrentDirectoryPIDL);
 +    if (newDirectory == NULL)
 +        return E_OUTOFMEMORY;
 +    ILRemoveLastID(newDirectory);
 +    hResult = BrowseToPIDL(newDirectory, BTP_UPDATE_CUR_HISTORY | BTP_UPDATE_NEXT_HISTORY);
 +    ILFree(newDirectory);
 +    if (FAILED(hResult))
 +        return hResult;
 +    return S_OK;
 +}
 +
 +BOOL CALLBACK AddFolderOptionsPage(HPROPSHEETPAGE thePage, LPARAM lParam)
 +{
 +    PROPSHEETHEADER                         *sheetInfo;
 +
 +    sheetInfo = (PROPSHEETHEADER *)lParam;
 +    if (sheetInfo->nPages >= folderOptionsPageCountMax)
 +        return FALSE;
 +    sheetInfo->phpage[sheetInfo->nPages] = thePage;
 +    sheetInfo->nPages++;
 +    return TRUE;
 +}
 +
 +HRESULT CShellBrowser::DoFolderOptions()
 +{
 +    CComPtr<IShellPropSheetExt>             folderOptionsSheet;
 +    CComPtr<IObjectWithSite>                objectWithSite;
 +    PROPSHEETHEADER                         m_PropSheet;
 +    HPROPSHEETPAGE                          m_psp[folderOptionsPageCountMax];
 +//    CComPtr<IGlobalFolderSettings>          globalSettings;
 +//    SHELLSTATE2                             shellState;
 +    HRESULT                                 hResult;
 +
 +    memset(m_psp, 0, sizeof(m_psp));
 +    memset(&m_PropSheet, 0, sizeof(m_PropSheet));
 +
 +    // create sheet object
 +    hResult = CoCreateInstance(CLSID_ShellFldSetExt, NULL, CLSCTX_INPROC_SERVER,
 +        IID_PPV_ARG(IShellPropSheetExt, &folderOptionsSheet));
 +    if (FAILED(hResult))
 +        return E_FAIL;
 +
 +    // must set site in order for Apply to all Folders on Advanced page to be enabled
 +    hResult = folderOptionsSheet->QueryInterface(IID_PPV_ARG(IObjectWithSite, &objectWithSite));
 +    if (SUCCEEDED(hResult) && objectWithSite.p != NULL)
 +        hResult = objectWithSite->SetSite(static_cast<IDispatch *>(this));
 +    m_PropSheet.phpage = m_psp;
 +
 +#if 0
 +    hResult = CoCreateInstance(CLSID_GlobalFolderSettings, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IGlobalFolderSettings, &globalSettings));
 +    if (FAILED(hResult))
 +        return E_FAIL;
 +    hResult = globalSettings->Get(&shellState, sizeof(shellState));
 +    if (FAILED(hResult))
 +        return E_FAIL;
 +#endif
 +
 +    // add pages
 +    hResult = folderOptionsSheet->AddPages(AddFolderOptionsPage, reinterpret_cast<LPARAM>(&m_PropSheet));
 +    if (FAILED(hResult))
 +        return E_FAIL;
 +
 +    if (fCurrentShellView != NULL)
 +    {
 +        hResult = fCurrentShellView->AddPropertySheetPages(
 +            0, AddFolderOptionsPage, reinterpret_cast<LPARAM>(&m_PropSheet));
 +        if (FAILED(hResult))
 +            return E_FAIL;
 +    }
 +
 +    // show sheet
 +    m_PropSheet.dwSize = sizeof(PROPSHEETHEADER);
 +    m_PropSheet.dwFlags = 0;
 +    m_PropSheet.hwndParent = m_hWnd;
 +    m_PropSheet.hInstance = _AtlBaseModule.GetResourceInstance();
 +    m_PropSheet.pszCaption = _T("Folder Options");
 +    m_PropSheet.nStartPage = 0;
 +    PropertySheet(&m_PropSheet);
 +    return S_OK;
 +}
 +
 +LRESULT CALLBACK CShellBrowser::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 +{
 +    CShellBrowser                           *pThis = reinterpret_cast<CShellBrowser *>(hWnd);
 +    _ATL_MSG                                msg(pThis->m_hWnd, uMsg, wParam, lParam);
 +    LRESULT                                 lResult;
 +    CComPtr<IMenuBand>                      menuBand;
 +    const _ATL_MSG                          *previousMessage;
 +    BOOL                                    handled;
 +    WNDPROC                                 saveWindowProc;
 +    HRESULT                                 hResult;
 +
 +    hWnd = pThis->m_hWnd;
 +    previousMessage = pThis->m_pCurrentMsg;
 +    pThis->m_pCurrentMsg = &msg;
 +
 +    hResult = pThis->GetMenuBand(IID_PPV_ARG(IMenuBand, &menuBand));
 +    if (SUCCEEDED(hResult) && menuBand.p != NULL)
 +    {
 +        hResult = menuBand->TranslateMenuMessage(&msg, &lResult);
 +        if (hResult == S_OK)
 +            return lResult;
 +        uMsg = msg.message;
 +        wParam = msg.wParam;
 +        lParam = msg.lParam;
 +    }
 +
 +    handled = pThis->ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, 0);
 +    ATLASSERT(pThis->m_pCurrentMsg == &msg);
 +    if (handled == FALSE)
 +    {
 +        if (uMsg == WM_NCDESTROY)
 +        {
 +            saveWindowProc = reinterpret_cast<WNDPROC>(GetWindowLongPtr(hWnd, GWL_WNDPROC));
 +            lResult = pThis->DefWindowProc(uMsg, wParam, lParam);
 +            if (saveWindowProc == reinterpret_cast<WNDPROC>(GetWindowLongPtr(hWnd, GWL_WNDPROC)))
 +                SetWindowLongPtr(hWnd, GWL_WNDPROC, (LONG_PTR)pThis->m_pfnSuperWindowProc);
 +            pThis->m_dwState |= WINSTATE_DESTROYED;
 +        }
 +        else
 +            lResult = pThis->DefWindowProc(uMsg, wParam, lParam);
 +    }
 +    pThis->m_pCurrentMsg = previousMessage;
 +    if (previousMessage == NULL && (pThis->m_dwState & WINSTATE_DESTROYED) != 0)
 +    {
 +        pThis->m_dwState &= ~WINSTATE_DESTROYED;
 +        pThis->m_hWnd = NULL;
 +        pThis->OnFinalMessage(hWnd);
 +    }
 +    return lResult;
 +}
 +
 +void CShellBrowser::RepositionBars()
 +{
 +    RECT                                    clientRect;
 +    RECT                                    statusRect;
 +    int                                     x;
 +
 +    GetClientRect(&clientRect);
 +
 +    if (fStatusBarVisible && fStatusBar)
 +    {
 +        ::GetWindowRect(fStatusBar, &statusRect);
 +        ::SetWindowPos(fStatusBar, NULL, clientRect.left, clientRect.bottom - (statusRect.bottom - statusRect.top),
 +                            clientRect.right - clientRect.left,
 +                            statusRect.bottom - statusRect.top, SWP_NOOWNERZORDER | SWP_NOZORDER);
 +        clientRect.bottom -= statusRect.bottom - statusRect.top;
 +    }
 +
 +    for (x = 0; x < 3; x++)
 +    {
 +        HWND hwnd = fClientBars[x].hwnd;
 +        RECT borderSpace = fClientBars[x].borderSpace;
 +        if (hwnd == NULL && fClientBars[x].clientBar != NULL)
 +        {
 +            IUnknown_GetWindow(fClientBars[x].clientBar, &hwnd);
 +            fClientBars[x].hwnd = hwnd;
 +        }
 +        if (hwnd != NULL)
 +        {
 +            RECT toolbarRect = clientRect;
 +            if (borderSpace.top != 0)
 +            {
 +                toolbarRect.bottom = toolbarRect.top + borderSpace.top;
 +            }
 +            else if (borderSpace.bottom != 0)
 +            {
 +                toolbarRect.top = toolbarRect.bottom - borderSpace.bottom;
 +            }
 +            else if (borderSpace.left != 0)
 +            {
 +                toolbarRect.right = toolbarRect.left + borderSpace.left;
 +            }
 +            else if (borderSpace.right != 0)
 +            {
 +                toolbarRect.left = toolbarRect.right - borderSpace.right;
 +            }
 +
 +            ::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,
 +                        clientRect.right - clientRect.left,
 +                        clientRect.bottom - clientRect.top, SWP_NOOWNERZORDER | SWP_NOZORDER);
 +}
 +
 +HRESULT CShellBrowser::FireEvent(DISPID dispIdMember, int argCount, VARIANT *arguments)
 +{
 +    DISPPARAMS                          params;
 +    CComDynamicUnkArray                 &vec = IConnectionPointImpl<CShellBrowser, &DIID_DWebBrowserEvents2>::m_vec;
 +    CComDynamicUnkArray                 &vec2 = IConnectionPointImpl<CShellBrowser, &DIID_DWebBrowserEvents>::m_vec;
 +    HRESULT                             hResult;
 +
 +    params.rgvarg = arguments;
 +    params.rgdispidNamedArgs = NULL;
 +    params.cArgs = argCount;
 +    params.cNamedArgs = 0;
 +    IUnknown** pp = vec.begin();
 +    while (pp < vec.end())
 +    {
 +        if (*pp != NULL)
 +        {
 +            CComPtr<IDispatch>          theDispatch;
 +
 +            hResult = (*pp)->QueryInterface(IID_PPV_ARG(IDispatch, &theDispatch));
 +            hResult = theDispatch->Invoke(dispIdMember, GUID_NULL, 0, DISPATCH_METHOD, &params, NULL, NULL, NULL);
 +        }
 +        pp++;
 +    }
 +    pp = vec2.begin();
 +    while (pp < vec2.end())
 +    {
 +        if (*pp != NULL)
 +        {
 +            CComPtr<IDispatch>          theDispatch;
 +
 +            hResult = (*pp)->QueryInterface(IID_PPV_ARG(IDispatch, &theDispatch));
 +            hResult = theDispatch->Invoke(dispIdMember, GUID_NULL, 0, DISPATCH_METHOD, &params, NULL, NULL, NULL);
 +        }
 +        pp++;
 +    }
 +    return S_OK;
 +}
 +
 +HRESULT CShellBrowser::FireNavigateComplete(const wchar_t *newDirectory)
 +{
 +    // these two variants intentionally to do use CComVariant because it would double free/release
 +    // or does not need to dispose at all
 +    VARIANT                             varArg[2];
 +    VARIANT                             varArgs;
 +    CComBSTR                            tempString(newDirectory);
 +
 +    V_VT(&varArgs) = VT_BSTR;
 +    V_BSTR(&varArgs) = tempString.m_str;
 +
 +    V_VT(&varArg[0]) = VT_VARIANT | VT_BYREF;
 +    V_VARIANTREF(&varArg[0]) = &varArgs;
 +    V_VT(&varArg[1]) = VT_DISPATCH;
 +    V_DISPATCH(&varArg[1]) = (IDispatch *)this;
 +
 +    return FireEvent(DISPID_NAVIGATECOMPLETE2, 2, varArg);
 +}
 +
 +HRESULT CShellBrowser::FireCommandStateChange(bool newState, int commandID)
 +{
 +    VARIANT                             varArg[2];
 +
 +    V_VT(&varArg[0]) = VT_BOOL;
 +    V_BOOL(&varArg[0]) = newState ? VARIANT_TRUE : VARIANT_FALSE;
 +    V_VT(&varArg[1]) = VT_I4;
 +    V_I4(&varArg[1]) = commandID;
 +
 +    return FireEvent(DISPID_COMMANDSTATECHANGE, 2, varArg);
 +}
 +
 +HRESULT CShellBrowser::FireCommandStateChangeAll()
 +{
 +    return FireCommandStateChange(false, -1);
 +}
 +
 +HRESULT CShellBrowser::UpdateForwardBackState()
 +{
 +    CComPtr<ITravelLog>                     travelLog;
 +    CComPtr<ITravelEntry>                   unusedEntry;
 +    bool                                    canGoBack;
 +    bool                                    canGoForward;
 +    HRESULT                                 hResult;
 +
 +    canGoBack = false;
 +    canGoForward = false;
 +    hResult = GetTravelLog(&travelLog);
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = travelLog->GetTravelEntry(static_cast<IDropTarget *>(this), TLOG_BACK, &unusedEntry);
 +    if (SUCCEEDED(hResult))
 +    {
 +        canGoBack = true;
 +        unusedEntry.Release();
 +    }
 +    hResult = travelLog->GetTravelEntry(static_cast<IDropTarget *>(this), TLOG_FORE, &unusedEntry);
 +    if (SUCCEEDED(hResult))
 +    {
 +        canGoForward = true;
 +        unusedEntry.Release();
 +    }
 +    hResult = FireCommandStateChange(canGoBack, 2);
 +    hResult = FireCommandStateChange(canGoForward, 1);
 +    return S_OK;
 +}
 +
 +void CShellBrowser::UpdateGotoMenu(HMENU theMenu)
 +{
 +    CComPtr<ITravelLog>                     travelLog;
 +    int                                     position;
 +    MENUITEMINFO                            menuItemInfo;
 +    HRESULT                                 hResult;
 +
 +    DeleteMenuItems(theMenu, IDM_GOTO_TRAVEL_FIRST, IDM_GOTO_TRAVEL_LAST);
 +
 +    position = GetMenuItemCount(theMenu);
 +    hResult = GetTravelLog(&travelLog);
 +    if (FAILED(hResult))
 +        return;
 +    hResult = travelLog->InsertMenuEntries(static_cast<IDropTarget *>(this), theMenu, position,
 +        IDM_GOTO_TRAVEL_FIRSTTARGET, IDM_GOTO_TRAVEL_LASTTARGET, TLMENUF_BACKANDFORTH | TLMENUF_CHECKCURRENT);
 +    if (SUCCEEDED(hResult))
 +    {
 +        menuItemInfo.cbSize = sizeof(menuItemInfo);
 +        menuItemInfo.fMask = MIIM_TYPE | MIIM_ID;
 +        menuItemInfo.fType = MF_SEPARATOR;
 +        menuItemInfo.wID = IDM_GOTO_TRAVEL_SEP;
 +        InsertMenuItem(theMenu, position, TRUE, &menuItemInfo);
 +    }
 +}
 +
 +void CShellBrowser::UpdateViewMenu(HMENU theMenu)
 +{
 +    CComPtr<IOleCommandTarget>              oleCommandTarget;
 +    CComPtr<ITravelLog>                     travelLog;
 +    HMENU                                   gotoMenu;
 +    OLECMD                                  commandList[5];
 +    HMENU                                   toolbarMenuBar;
 +    HMENU                                   toolbarMenu;
 +    MENUITEMINFO                            menuItemInfo;
 +    HRESULT                                 hResult;
 +
 +    gotoMenu = SHGetMenuFromID(theMenu, FCIDM_MENU_EXPLORE);
 +    if (gotoMenu != NULL)
 +        UpdateGotoMenu(gotoMenu);
 +
 +    commandList[0].cmdID = ITID_TOOLBARBANDSHOWN;
 +    commandList[1].cmdID = ITID_ADDRESSBANDSHOWN;
 +    commandList[2].cmdID = ITID_LINKSBANDSHOWN;
 +    commandList[3].cmdID = ITID_TOOLBARLOCKED;
 +    commandList[4].cmdID = ITID_CUSTOMIZEENABLED;
 +
 +    hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
 +        IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
 +    if (SUCCEEDED(hResult))
 +        hResult = oleCommandTarget->QueryStatus(&CGID_PrivCITCommands, 5, commandList, NULL);
 +    if (FAILED(hResult))
 +        DeleteMenu(theMenu, IDM_VIEW_TOOLBARS, MF_BYCOMMAND);
 +    else
 +    {
 +        toolbarMenuBar = LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_CONTEXTMENU));
 +        toolbarMenu = GetSubMenu(toolbarMenuBar, 0);
 +
 +        SHCheckMenuItem(toolbarMenu, IDM_TOOLBARS_STANDARDBUTTONS, commandList[0].cmdf);
 +        SHCheckMenuItem(toolbarMenu, IDM_TOOLBARS_ADDRESSBAR, commandList[1].cmdf & OLECMDF_ENABLED);
 +        SHCheckMenuItem(toolbarMenu, IDM_TOOLBARS_LINKSBAR, commandList[2].cmdf & OLECMDF_ENABLED);
 +        SHCheckMenuItem(toolbarMenu, IDM_TOOLBARS_LOCKTOOLBARS, commandList[3].cmdf & OLECMDF_ENABLED);
 +        if ((commandList[4].cmdf & OLECMDF_ENABLED) == 0)
 +            DeleteMenu(toolbarMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
 +        DeleteMenu(toolbarMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
 +        DeleteMenu(toolbarMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
 +
 +        menuItemInfo.cbSize = sizeof(menuItemInfo);
 +        menuItemInfo.fMask = MIIM_SUBMENU;
 +        menuItemInfo.hSubMenu = toolbarMenu;
 +        SetMenuItemInfo(theMenu, IDM_VIEW_TOOLBARS, FALSE, &menuItemInfo);
 +    }
 +    SHCheckMenuItem(theMenu, IDM_VIEW_STATUSBAR, fStatusBarVisible ? TRUE : FALSE);
 +}
 +
 +bool IUnknownIsEqual(IUnknown *int1, IUnknown *int2)
 +{
 +    CComPtr<IUnknown>                       int1Retry;
 +    CComPtr<IUnknown>                       int2Retry;
 +    HRESULT                                 hResult;
 +
 +    if (int1 == int2)
 +        return true;
 +    if (int1 == NULL || int2 == NULL)
 +        return false;
 +    hResult = int1->QueryInterface(IID_PPV_ARG(IUnknown, &int1Retry));
 +    if (FAILED(hResult))
 +        return false;
 +    hResult = int2->QueryInterface(IID_PPV_ARG(IUnknown, &int2Retry));
 +    if (FAILED(hResult))
 +        return false;
 +    if (int1Retry == int2Retry)
 +        return true;
 +    return false;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetBorderDW(IUnknown *punkObj, LPRECT prcBorder)
 +{
 +    static const INT excludeItems[] = { 1, 1, 1, 0xa001, 0, 0 };
 +
 +    RECT availableBounds;
 +
 +    GetEffectiveClientRect(m_hWnd, &availableBounds, excludeItems);
 +    for (INT x = 0; x < 3; x++)
 +    {
 +        if (fClientBars[x].clientBar.p != NULL && !IUnknownIsEqual(fClientBars[x].clientBar, punkObj))
 +        {
 +            availableBounds.top += fClientBars[x].borderSpace.top;
 +            availableBounds.left += fClientBars[x].borderSpace.left;
 +            availableBounds.bottom -= fClientBars[x].borderSpace.bottom;
 +            availableBounds.right -= fClientBars[x].borderSpace.right;
 +        }
 +    }
 +    *prcBorder = availableBounds;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::RequestBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw)
 +{
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw)
 +{
 +    for (INT x = 0; x < 3; x++)
 +    {
 +        if (IUnknownIsEqual(fClientBars[x].clientBar, punkObj))
 +        {
 +            fClientBars[x].borderSpace = *pbw;
 +            // if this bar changed size, it cascades and forces all subsequent bars to resize
 +            RepositionBars();
 +            return S_OK;
 +        }
 +    }
 +    return E_INVALIDARG;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::QueryStatus(const GUID *pguidCmdGroup,
 +    ULONG cCmds, OLECMD prgCmds[  ], OLECMDTEXT *pCmdText)
 +{
 +    CComPtr<IOleCommandTarget>              commandTarget;
 +    HRESULT                                 hResult;
 +
 +    if (prgCmds == NULL)
 +        return E_INVALIDARG;
 +    if (pguidCmdGroup == NULL)
 +    {
 +        if (fCurrentShellView.p != NULL)
 +        {
 +            hResult = fCurrentShellView->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &commandTarget));
 +            if (SUCCEEDED(hResult) && commandTarget.p != NULL)
 +                return commandTarget->QueryStatus(NULL, 1, prgCmds, pCmdText);
 +        }
 +        while (cCmds != 0)
 +        {
 +            prgCmds->cmdf = 0;
 +            prgCmds++;
 +            cCmds--;
 +        }
 +    }
 +    else if (IsEqualIID(*pguidCmdGroup, CGID_Explorer))
 +    {
 +        while (cCmds != 0)
 +        {
 +            switch (prgCmds->cmdID)
 +            {
 +                case 0x1c:  // search
 +                    prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
 +                    break;
 +                case 0x1d:  // history
 +                    prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
 +                    break;
 +                case 0x1e:  // favorites
 +                    prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
 +                    break;
 +                case 0x23:  // folders
 +                    prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED | OLECMDF_LATCHED;
 +                    break;
 +                default:
 +                    prgCmds->cmdf = 0;
 +                    break;
 +            }
 +            prgCmds++;
 +            cCmds--;
 +        }
 +    }
 +    else if (IsEqualIID(*pguidCmdGroup, CGID_ShellBrowser))
 +    {
 +        while (cCmds != 0)
 +        {
 +            switch (prgCmds->cmdID)
 +            {
 +                case 0xa022:    // up level
 +                    prgCmds->cmdf = OLECMDF_SUPPORTED;
 +                    if (fCurrentDirectoryPIDL->mkid.cb != 0)
 +                        prgCmds->cmdf |= OLECMDF_ENABLED;
 +                    break;
 +            }
 +            prgCmds++;
 +            cCmds--;
 +        }
 +    }
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
 +    DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
 +{
 +    HRESULT                                 hResult;
 +
 +    if (IsEqualIID(*pguidCmdGroup, CGID_Explorer))
 +    {
 +        switch (nCmdID)
 +        {
 +            case 0x23:
 +                hResult = ShowBand(CLSID_ExplorerBand, true);
 +                return S_OK;
 +            case 0x27:
 +                if (nCmdexecopt == 1)
 +                {
 +                    // pvaIn is a VT_UNKNOWN with a band that is being hidden
 +                }
 +                else
 +                {
 +                    // update zones part of the status bar
 +                }
 +                return S_OK;
 +            case 0x35: // don't do this, and the internet toolbar doesn't create a menu band
 +                V_VT(pvaOut) = VT_INT_PTR;
 +                V_INTREF(pvaOut) = reinterpret_cast<INT *>(
 +                    LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_MAINMENU)));
 +                return S_OK;
 +            case 0x38:
 +                // indicate if this cabinet was opened as a browser
 +                return S_FALSE;
 +            default:
 +                return E_NOTIMPL;
 +        }
 +    }
 +    else if (IsEqualIID(*pguidCmdGroup, CGID_InternetButtons))
 +    {
 +        switch (nCmdID)
 +        {
 +            case 0x23:
 +                // placeholder
 +                return S_OK;
 +        }
 +    }
 +    else if (IsEqualIID(*pguidCmdGroup, CGID_Theater))
 +    {
 +        switch (nCmdID)
 +        {
 +            case 6:
 +                // what is theater mode and why do we receive this?
 +                return E_NOTIMPL;
 +        }
 +    }
 +    else if (IsEqualIID(*pguidCmdGroup, CGID_MenuBand))
 +    {
 +        switch (nCmdID)
 +        {
 +            case 14:
 +                // initialize favorites menu
 +                return S_OK;
 +        }
 +    }
 +    else if (IsEqualIID(*pguidCmdGroup, CGID_ShellDocView))
 +    {
 +        switch (nCmdID)
 +        {
 +            case 0x12:
 +                // refresh on toolbar clicked
 +                return S_OK;
 +            case 0x4d:
 +                // tell the view if it should hide the task pane or not
 +                return (fClientBars[BIVerticalBaseBar].clientBar.p == NULL) ? S_FALSE : S_OK;
 +        }
 +    }
 +    else if (IsEqualIID(*pguidCmdGroup, CGID_ShellBrowser))
 +    {
 +        switch (nCmdID)
 +        {
 +            case 40994:
 +                return NavigateToParent();
 +        }
 +    }
 +    else if (IsEqualIID(*pguidCmdGroup, CGID_IExplorerToolbar))
 +    {
 +        switch (nCmdID)
 +        {
 +            case 0x7063:
 +                return DoFolderOptions();
 +        }
 +    }
 +    else if (IsEqualIID(*pguidCmdGroup, CGID_DefView))
 +    {
 +        switch (nCmdID)
 +        {
 +            case 1:
 +                // Reset All Folders option in Folder Options
 +                break;
 +        }
 +    }
 +    else
 +    {
 +        return E_NOTIMPL;
 +    }
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetWindow(HWND *lphwnd)
 +{
 +    if (lphwnd == NULL)
 +        return E_POINTER;
 +    *lphwnd = m_hWnd;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::ContextSensitiveHelp(BOOL fEnterMode)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
 +{
 +    HMENU mainMenu = LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_MAINMENU));
 +    Shell_MergeMenus(hmenuShared, mainMenu, 0, 0, FCIDM_BROWSERLAST, MM_SUBMENUSHAVEIDS);
 +
 +    int GCCU(itemCount3) = GetMenuItemCount(hmenuShared);
 +    Unused(itemCount3);
 +
 +    lpMenuWidths->width[0] = 2;
 +    lpMenuWidths->width[2] = 3;
 +    lpMenuWidths->width[4] = 1;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetMenuSB(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject)
 +{
 +    CComPtr<IShellMenu>                     shellMenu;
 +    HRESULT                                 hResult;
 +
 +    if (IsMenu(hmenuShared) == FALSE)
 +        return E_FAIL;
 +    hResult = GetMenuBand(IID_PPV_ARG(IShellMenu, &shellMenu));
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = shellMenu->SetMenu(hmenuShared, NULL, SMSET_DONTOWN);
 +    if (FAILED(hResult))
 +        return hResult;
 +    fCurrentMenuBar = hmenuShared;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::RemoveMenusSB(HMENU hmenuShared)
 +{
 +    if (hmenuShared == fCurrentMenuBar)
 +        fCurrentMenuBar = NULL;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetStatusTextSB(LPCOLESTR pszStatusText)
 +{
 +    //
 +    if (pszStatusText)
 +    {
 +        ::SetWindowText(fStatusBar, pszStatusText);
 +    }
 +    else
 +    {
 +
 +    }
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::EnableModelessSB(BOOL fEnable)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::TranslateAcceleratorSB(MSG *pmsg, WORD wID)
 +{
 +    if (!::TranslateAcceleratorW(m_hWnd, m_hAccel, pmsg))
 +        return S_FALSE;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::BrowseObject(LPCITEMIDLIST pidl, UINT wFlags)
 +{
 +    return BrowseToPIDL(pidl, BTP_UPDATE_CUR_HISTORY | BTP_UPDATE_NEXT_HISTORY);
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetViewStateStream(DWORD grfMode, IStream **ppStrm)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetControlWindow(UINT id, HWND *lphwnd)
 +{
 +    if (lphwnd == NULL)
 +        return E_POINTER;
 +    *lphwnd = NULL;
 +    switch(id)
 +    {
 +        case FCW_TOOLBAR:
 +            *lphwnd = fToolbarProxy.m_hWnd;
 +            return S_OK;
 +        case FCW_STATUS:
 +            *lphwnd = fStatusBar;
 +            return S_OK;
 +        case FCW_TREE:
 +            // find the directory browser and return it
 +            // this should be used only to determine if a tree is present
 +            return S_OK;
 +        case FCW_PROGRESS:
 +            // is this a progress dialog?
 +            return S_OK;
 +    }
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SendControlMsg(
 +    UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret)
 +{
 +    LPARAM                                  result;
 +
 +    if (pret != NULL)
 +        *pret = 0;
 +    switch(id)
 +    {
 +        case FCW_TOOLBAR:
 +            result = fToolbarProxy.SendMessage(uMsg, wParam, lParam);
 +            if (pret != NULL)
 +                *pret = result;
 +            break;
 +        case FCW_STATUS:
 +            result = SendMessage(fStatusBar, uMsg, wParam, lParam);
 +            if (pret != NULL)
 +                *pret = result;
 +            break;
 +    }
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::QueryActiveShellView(IShellView **ppshv)
 +{
 +    if (ppshv == NULL)
 +        return E_POINTER;
 +    *ppshv = fCurrentShellView;
 +    if (fCurrentShellView.p != NULL)
 +        fCurrentShellView.p->AddRef();
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::OnViewWindowActive(IShellView *ppshv)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetToolbarItems(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::DragEnter(
 +    IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::DragLeave()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::Drop(
 +    IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
 +{
 +    // view does a query for SID_STopLevelBrowser, IID_IShellBrowserService
 +    // the returned interface has a method GetPropertyBag on it
 +    if (IsEqualIID(guidService, SID_STopLevelBrowser))
 +        return this->QueryInterface(riid, ppvObject);
 +    if (IsEqualIID(guidService, SID_SShellBrowser))
 +        return this->QueryInterface(riid, ppvObject);
 +    if (IsEqualIID(guidService, SID_ITargetFrame2))
 +        return this->QueryInterface(riid, ppvObject);
 +    if (IsEqualIID(guidService, SID_IWebBrowserApp))        // without this, the internet toolbar won't reflect notifications
 +        return this->QueryInterface(riid, ppvObject);
 +    if (IsEqualIID(guidService, SID_SProxyBrowser))
 +        return this->QueryInterface(riid, ppvObject);
 +    if (IsEqualIID(guidService, SID_IExplorerToolbar))
 +        return fClientBars[BIInternetToolbar].clientBar->QueryInterface(riid, ppvObject);
 +    if (IsEqualIID(riid, IID_IShellBrowser))
 +        return this->QueryInterface(riid, ppvObject);
 +    return E_NOINTERFACE;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetPropertyBag(long flags, REFIID riid, void **ppvObject)
 +{
 +    if (ppvObject == NULL)
 +        return E_POINTER;
 +    *ppvObject = NULL;
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetTypeInfoCount(UINT *pctinfo)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames,
 +    UINT cNames, LCID lcid, DISPID *rgDispId)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
 +    WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetParentSite(IOleInPlaceSite **ppipsite)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetTitle(IShellView *psv, LPCWSTR pszName)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetTitle(IShellView *psv, LPWSTR pszName, DWORD cchName)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetOleObject(IOleObject **ppobjv)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetTravelLog(ITravelLog **pptl)
 +{
 +    HRESULT                                 hResult;
 +
 +    // called by toolbar when displaying tooltips
 +    if (pptl == NULL)
 +        return E_FAIL;
 +
 +    *pptl = NULL;
 +    if (fTravelLog.p == NULL)
 +    {
 +        hResult = CreateTravelLog(IID_PPV_ARG(ITravelLog, &fTravelLog));
 +        if (FAILED(hResult))
 +            return hResult;
 +    }
 +    *pptl = fTravelLog.p;
 +    fTravelLog.p->AddRef();
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::ShowControlWindow(UINT id, BOOL fShow)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::IsControlWindowShown(UINT id, BOOL *pfShown)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::IEGetDisplayName(LPCITEMIDLIST pidl, LPWSTR pwszName, UINT uFlags)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::IEParseDisplayName(UINT uiCP, LPCWSTR pwszPath, LPITEMIDLIST *ppidlOut)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::DisplayParseError(HRESULT hres, LPCWSTR pwszPath)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::NavigateToPidl(LPCITEMIDLIST pidl, DWORD grfHLNF)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetNavigateState(BNSTATE bnstate)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetNavigateState(BNSTATE *pbnstate)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::NotifyRedirect(IShellView *psv, LPCITEMIDLIST pidl, BOOL *pfDidBrowse)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::UpdateWindowList()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::UpdateBackForwardState()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetFlags(DWORD dwFlags, DWORD dwFlagMask)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetFlags(DWORD *pdwFlags)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::CanNavigateNow()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetPidl(LPITEMIDLIST *ppidl)
 +{
 +    // called by explorer bar to get current pidl
 +    if (ppidl == NULL)
 +        return E_POINTER;
 +    *ppidl = ILClone(fCurrentDirectoryPIDL);
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetReferrer(LPCITEMIDLIST pidl)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +DWORD STDMETHODCALLTYPE CShellBrowser::GetBrowserIndex()
 +{
 +    return -1;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetBrowserByIndex(DWORD dwID, IUnknown **ppunk)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetHistoryObject(IOleObject **ppole, IStream **pstm, IBindCtx **ppbc)
 +{
 +    if (ppole == NULL || pstm == NULL || ppbc == NULL)
 +        return E_INVALIDARG;
 +    *ppole = fHistoryObject;
 +    if (fHistoryObject != NULL)
 +        fHistoryObject->AddRef();
 +    *pstm = fHistoryStream;
 +    if (fHistoryStream != NULL)
 +        fHistoryStream->AddRef();
 +    *ppbc = fHistoryBindContext;
 +    if (fHistoryBindContext != NULL)
 +        fHistoryBindContext->AddRef();
 +    fHistoryObject = NULL;
 +    fHistoryStream = NULL;
 +    fHistoryBindContext = NULL;
 +    if (*ppole == NULL)
 +        return E_FAIL;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetHistoryObject(IOleObject *pole, BOOL fIsLocalAnchor)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::CacheOLEServer(IOleObject *pole)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetSetCodePage(VARIANT *pvarIn, VARIANT *pvarOut)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::OnHttpEquiv(
 +    IShellView *psv, BOOL fDone, VARIANT *pvarargIn, VARIANT *pvarargOut)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetPalette(HPALETTE *hpal)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::RegisterWindow(BOOL fForceRegister, int swc)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +LRESULT STDMETHODCALLTYPE CShellBrowser::WndProcBS(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetAsDefFolderSettings()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetViewRect(RECT *prc)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::OnSize(WPARAM wParam)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::OnCreate(struct tagCREATESTRUCTW *pcs)
 +{
 +    m_hAccel = LoadAcceleratorsW(GetModuleHandle(L"browseui.dll"), MAKEINTRESOURCEW(256));
 +    return S_OK;
 +}
 +
 +LRESULT STDMETHODCALLTYPE CShellBrowser::OnCommand(WPARAM wParam, LPARAM lParam)
 +{
 +    return 0;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::OnDestroy()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +LRESULT STDMETHODCALLTYPE CShellBrowser::OnNotify(struct tagNMHDR *pnm)
 +{
 +    return 0;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::OnSetFocus()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::OnFrameWindowActivateBS(BOOL fActive)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::ReleaseShellView()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::ActivatePendingView()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::CreateViewWindow(
 +    IShellView *psvNew, IShellView *psvOld, LPRECT prcView, HWND *phwnd)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::CreateBrowserPropSheetExt(REFIID riid, void **ppv)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetViewWindow(HWND *phwndView)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetBaseBrowserData(LPCBASEBROWSERDATA *pbbd)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +LPBASEBROWSERDATA STDMETHODCALLTYPE CShellBrowser::PutBaseBrowserData()
 +{
 +    return NULL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::InitializeTravelLog(ITravelLog *ptl, DWORD dw)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetTopBrowser()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::Offline(int iCmd)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::AllowViewResize(BOOL f)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetActivateState(UINT u)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::UpdateSecureLockIcon(int eSecureLock)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::InitializeDownloadManager()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::InitializeTransitionSite()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_Initialize(HWND hwnd, IUnknown *pauto)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_CancelPendingNavigationAsync()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_CancelPendingView()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_MaySaveChanges()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_PauseOrResumeView(BOOL fPaused)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_DisableModeless()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_NavigateToPidl(LPCITEMIDLIST pidl, DWORD grfHLNF, DWORD dwFlags)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_TryShell2Rename(IShellView *psv, LPCITEMIDLIST pidlNew)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_SwitchActivationNow()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_ExecChildren(IUnknown *punkBar, BOOL fBroadcast,
 +    const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_SendChildren(
 +    HWND hwndBar, BOOL fBroadcast, UINT uMsg, WPARAM wParam, LPARAM lParam)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetFolderSetData(struct tagFolderSetData *pfsd)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_OnFocusChange(UINT itb)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::v_ShowHideChildWindows(BOOL fChildOnly)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +UINT STDMETHODCALLTYPE CShellBrowser::_get_itbLastFocus()
 +{
 +    return 0;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_put_itbLastFocus(UINT itbLastFocus)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_UIActivateView(UINT uState)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_GetViewBorderRect(RECT *prc)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_UpdateViewRectSize()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_ResizeNextBorder(UINT itb)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_ResizeView()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_GetEffectiveClientArea(LPRECT lprectBorder, HMONITOR hmon)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +IStream *STDMETHODCALLTYPE CShellBrowser::v_GetViewStream(LPCITEMIDLIST pidl, DWORD grfMode, LPCWSTR pwszName)
 +{
 +    return NULL;
 +}
 +
 +LRESULT STDMETHODCALLTYPE CShellBrowser::ForwardViewMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
 +{
 +    return 0;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetAcceleratorMenu(HACCEL hacc)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +int STDMETHODCALLTYPE CShellBrowser::_GetToolbarCount()
 +{
 +    return 0;
 +}
 +
 +LPTOOLBARITEM STDMETHODCALLTYPE CShellBrowser::_GetToolbarItem(int itb)
 +{
 +    return NULL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_SaveToolbars(IStream *pstm)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_LoadToolbars(IStream *pstm)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_CloseAndReleaseToolbars(BOOL fClose)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::v_MayGetNextToolbarFocus(
 +    LPMSG lpMsg, UINT itbNext, int citb, LPTOOLBARITEM *pptbi, HWND *phwnd)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_ResizeNextBorderHelper(UINT itb, BOOL bUseHmonitor)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +UINT STDMETHODCALLTYPE CShellBrowser::_FindTBar(IUnknown *punkSrc)
 +{
 +    return 0;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_SetFocus(LPTOOLBARITEM ptbi, HWND hwnd, LPMSG lpMsg)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::v_MayTranslateAccelerator(MSG *pmsg)
 +{
 +    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)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::v_CheckZoneCrossing(LPCITEMIDLIST pidl)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GoBack()
 +{
 +    CComPtr<ITravelLog>                     travelLog;
 +    HRESULT                                 hResult;
 +
 +    hResult = GetTravelLog(&travelLog);
 +    if (FAILED(hResult))
 +        return hResult;
 +    return travelLog->Travel(static_cast<IDropTarget *>(this), TLOG_BACK);
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GoForward()
 +{
 +    CComPtr<ITravelLog>                     travelLog;
 +    HRESULT                                 hResult;
 +
 +    hResult = GetTravelLog(&travelLog);
 +    if (FAILED(hResult))
 +        return hResult;
 +    return travelLog->Travel(static_cast<IDropTarget *>(this), TLOG_FORE);
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GoHome()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GoSearch()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::Navigate(BSTR URL, VARIANT *Flags,
 +    VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::Refresh()
 +{
 +    VARIANT                                 level;
 +
 +    V_VT(&level) = VT_I4;
 +    V_I4(&level) = 4;
 +    return Refresh2(&level);
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::Refresh2(VARIANT *Level)
 +{
 +    CComPtr<IOleCommandTarget>              oleCommandTarget;
 +    HRESULT                                 hResult;
 +
 +    hResult = fCurrentShellView->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
 +    if (FAILED(hResult))
 +        return hResult;
 +    return oleCommandTarget->Exec(NULL, 22, 1, Level, NULL);
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::Stop()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Application(IDispatch **ppDisp)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Parent(IDispatch **ppDisp)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Container(IDispatch **ppDisp)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Document(IDispatch **ppDisp)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_TopLevelContainer(VARIANT_BOOL *pBool)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Type(BSTR *Type)
 +{
 +    return E_NOTIMPL;
 +}
 +#ifdef __exdisp_h__
 +#define long LONG
 +#endif
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Left(long *pl)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_Left(long Left)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Top(long *pl)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_Top(long Top)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Width(long *pl)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_Width(long Width)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Height(long *pl)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_Height(long Height)
 +{
 +    return E_NOTIMPL;
 +}
 +#ifdef __exdisp_h__
 +#undef long
 +#endif
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_LocationName(BSTR *LocationName)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_LocationURL(BSTR *LocationURL)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Busy(VARIANT_BOOL *pBool)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::Quit()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::ClientToWindow(int *pcx, int *pcy)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::PutProperty(BSTR Property, VARIANT vtValue)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetProperty(BSTR Property, VARIANT *pvtValue)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Name(BSTR *Name)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_HWND(SHANDLE_PTR *pHWND)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_FullName(BSTR *FullName)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Path(BSTR *Path)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Visible(VARIANT_BOOL *pBool)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_Visible(VARIANT_BOOL Value)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_StatusBar(VARIANT_BOOL *pBool)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_StatusBar(VARIANT_BOOL Value)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_StatusText(BSTR *StatusText)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_StatusText(BSTR StatusText)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_ToolBar(int *Value)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_ToolBar(int Value)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_MenuBar(VARIANT_BOOL *Value)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_MenuBar(VARIANT_BOOL Value)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_FullScreen(VARIANT_BOOL *pbFullScreen)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_FullScreen(VARIANT_BOOL bFullScreen)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::Navigate2(VARIANT *URL, VARIANT *Flags,
 +    VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers)
 +{
 +    LPITEMIDLIST                            pidl;
 +    HRESULT                                 hResult;
 +
 +    // called from drive combo box to navigate to a directory
 +    if (V_VT(URL) != (VT_ARRAY | VT_UI1))
 +        return E_INVALIDARG;
 +    if (V_ARRAY(URL)->cDims != 1 || V_ARRAY(URL)->cbElements != 1)
 +        return E_INVALIDARG;
 +    pidl = (LPITEMIDLIST)V_ARRAY(URL)->pvData;
 +    hResult = BrowseToPIDL((LPITEMIDLIST)pidl, BTP_UPDATE_CUR_HISTORY | BTP_UPDATE_NEXT_HISTORY);
 +    if (FAILED(hResult))
 +        return hResult;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::QueryStatusWB(OLECMDID cmdID, OLECMDF *pcmdf)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::ExecWB(OLECMDID cmdID, OLECMDEXECOPT cmdexecopt,
 +    VARIANT *pvaIn, VARIANT *pvaOut)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::ShowBrowserBar(VARIANT *pvaClsid, VARIANT *pvarShow, VARIANT *pvarSize)
 +{
 +    CLSID                                   classID;
 +    bool                                    vertical;
 +
 +    // called to show search bar
 +    if (V_VT(pvaClsid) != VT_BSTR)
 +        return E_INVALIDARG;
 +    CLSIDFromString(V_BSTR(pvaClsid), &classID);
 +    // TODO: properly compute the value of vertical
 +    vertical = true;
 +    return ShowBand(classID, vertical);
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_ReadyState(READYSTATE *plReadyState)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Offline(VARIANT_BOOL *pbOffline)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_Offline(VARIANT_BOOL bOffline)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Silent(VARIANT_BOOL *pbSilent)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_Silent(VARIANT_BOOL bSilent)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_RegisterAsBrowser(VARIANT_BOOL *pbRegister)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_RegisterAsBrowser(VARIANT_BOOL bRegister)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_RegisterAsDropTarget(VARIANT_BOOL *pbRegister)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_RegisterAsDropTarget(VARIANT_BOOL bRegister)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_TheaterMode(VARIANT_BOOL *pbRegister)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_TheaterMode(VARIANT_BOOL bRegister)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_AddressBar(VARIANT_BOOL *Value)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_AddressBar(VARIANT_BOOL Value)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Resizable(VARIANT_BOOL *Value)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_Resizable(VARIANT_BOOL Value)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::FindWindowByIndex(DWORD dwID, IUnknown **ppunk)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetWindowData(IStream *pStream, LPWINDOWDATA pWinData)
 +{
 +    if (pWinData == NULL)
 +        return E_POINTER;
 +
 +    pWinData->dwWindowID = -1;
 +    pWinData->uiCP = 0;
 +    pWinData->pidl = ILClone(fCurrentDirectoryPIDL);
 +    pWinData->lpszUrl = NULL;
 +    pWinData->lpszUrlLocation = NULL;
 +    pWinData->lpszTitle = NULL;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::LoadHistoryPosition(LPWSTR pszUrlLocation, DWORD dwPosition)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetClassID(CLSID *pClassID)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::LoadHistory(IStream *pStream, IBindCtx *pbc)
 +{
 +    CComPtr<IPersistHistory>                viewPersistHistory;
 +    CComPtr<IOleObject>                     viewHistoryObject;
 +    persistState                            oldState;
 +    ULONG                                   numRead;
 +    LPITEMIDLIST                            pidl;
 +    HRESULT                                 hResult;
 +
 +    hResult = pStream->Read(&oldState, sizeof(oldState), &numRead);
 +    if (FAILED(hResult))
 +        return hResult;
 +    if (numRead != sizeof(oldState) || oldState.dwSize != sizeof(oldState))
 +        return E_FAIL;
 +    if (oldState.browseType != 2)
 +        return E_FAIL;
 +    pidl = static_cast<LPITEMIDLIST>(CoTaskMemAlloc(oldState.pidlSize));
 +    if (pidl == NULL)
 +        return E_OUTOFMEMORY;
 +    hResult = pStream->Read(pidl, oldState.pidlSize, &numRead);
 +    if (FAILED(hResult))
 +    {
 +        ILFree(pidl);
 +        return hResult;
 +    }
 +    if (numRead != oldState.pidlSize)
 +    {
 +        ILFree(pidl);
 +        return E_FAIL;
 +    }
 +    hResult = CoCreateInstance(oldState.persistClass, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_SERVER,
 +        IID_PPV_ARG(IOleObject, &viewHistoryObject));
 +    fHistoryObject = viewHistoryObject;
 +    fHistoryStream = pStream;
 +    fHistoryBindContext = pbc;
 +    hResult = BrowseToPIDL(pidl, BTP_UPDATE_CUR_HISTORY);
 +    fHistoryObject = NULL;
 +    fHistoryStream = NULL;
 +    fHistoryBindContext = NULL;
 +    ILFree(pidl);
 +    if (FAILED(hResult))
 +        return hResult;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SaveHistory(IStream *pStream)
 +{
 +    CComPtr<IPersistHistory>                viewPersistHistory;
 +    persistState                            newState;
 +    HRESULT                                 hResult;
 +
 +    hResult = fCurrentShellView->GetItemObject(
 +        SVGIO_BACKGROUND, IID_PPV_ARG(IPersistHistory, &viewPersistHistory));
 +    memset(&newState, 0, sizeof(newState));
 +    newState.dwSize = sizeof(newState);
 +    newState.browseType = 2;
 +    newState.browserIndex = GetBrowserIndex();
 +    if (viewPersistHistory.p != NULL)
 +    {
 +        hResult = viewPersistHistory->GetClassID(&newState.persistClass);
 +        if (FAILED(hResult))
 +            return hResult;
 +    }
 +    newState.pidlSize = ILGetSize(fCurrentDirectoryPIDL);
 +    hResult = pStream->Write(&newState, sizeof(newState), NULL);
 +    if (FAILED(hResult))
 +        return hResult;
 +    hResult = pStream->Write(fCurrentDirectoryPIDL, newState.pidlSize, NULL);
 +    if (FAILED(hResult))
 +        return hResult;
 +    if (viewPersistHistory.p != NULL)
 +    {
 +        hResult = viewPersistHistory->SaveHistory(pStream);
 +        if (FAILED(hResult))
 +            return hResult;
 +    }
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetPositionCookie(DWORD dwPositioncookie)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetPositionCookie(DWORD *pdwPositioncookie)
 +{
 +    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
 +    PostQuitMessage(0);
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    CComPtr<IDockingWindow>                 dockingWindow;
 +    RECT                                    availableBounds;
 +    static const INT                        excludeItems[] = {1, 1, 1, 0xa001, 0, 0};
 +    HRESULT                                 hResult;
 +
 +    if (wParam != SIZE_MINIMIZED)
 +    {
 +        GetEffectiveClientRect(m_hWnd, &availableBounds, excludeItems);
 +        for (INT x = 0; x < 3; x++)
 +        {
 +            if (fClientBars[x].clientBar != NULL)
 +            {
 +                hResult = fClientBars[x].clientBar->QueryInterface(
 +                    IID_PPV_ARG(IDockingWindow, &dockingWindow));
 +                if (SUCCEEDED(hResult) && dockingWindow != NULL)
 +                {
 +                    hResult = dockingWindow->ResizeBorderDW(
 +                        &availableBounds, static_cast<IDropTarget *>(this), TRUE);
 +                    break;
 +                }
 +            }
 +        }
 +        RepositionBars();
 +    }
 +    return 1;
 +}
 +
 +LRESULT CShellBrowser::OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    HMENU                                   theMenu;
 +
 +    theMenu = reinterpret_cast<HMENU>(wParam);
 +    if (theMenu == SHGetMenuFromID(fCurrentMenuBar, FCIDM_MENU_VIEW))
 +        UpdateViewMenu(theMenu);
 +    return RelayMsgToShellView(uMsg, wParam, lParam, bHandled);
 +}
 +
 +LRESULT CShellBrowser::RelayMsgToShellView(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    if (fCurrentShellViewWindow != NULL)
 +        return SendMessage(fCurrentShellViewWindow, uMsg, wParam, lParam);
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnClose(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnFolderOptions(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    HRESULT                                 hResult;
 +
 +    hResult = DoFolderOptions();
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnMapNetworkDrive(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +#ifndef __REACTOS__
 +    WNetConnectionDialog(m_hWnd, RESOURCETYPE_DISK);
 +#endif /* __REACTOS__ */
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnDisconnectNetworkDrive(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +#ifndef __REACTOS__
 +    WNetDisconnectDialog(m_hWnd, RESOURCETYPE_DISK);
 +#endif /* __REACTOS__ */
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnAboutReactOS(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    ShellAbout(m_hWnd, _T("ReactOS"), _T(""), NULL);
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnGoBack(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    HRESULT                                 hResult;
 +
 +    hResult = GoBack();
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnGoForward(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    HRESULT                                 hResult;
 +
 +    hResult = GoForward();
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnGoUpLevel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    HRESULT                                 hResult;
 +
 +    hResult = NavigateToParent();
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnGoHome(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    HRESULT                                 hResult;
 +
 +    hResult = GoHome();
 +    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 = NULL;
 +    HMODULE Module = GetModuleHandle(TEXT("browseui.dll"));
 +    if (Module != NULL)
 +        Func = reinterpret_cast<PSHOpenNewFrame>(GetProcAddress(Module, (LPCSTR) 103));
 +    if (Func != NULL)
 +    {
 +        LPITEMIDLIST                        desktopPIDL;
 +
 +        hResult = SHGetFolderLocation(NULL, CSIDL_DESKTOP, NULL, 0, &desktopPIDL);
 +        if (SUCCEEDED(hResult))
 +        {
 +            hResult = Func(desktopPIDL, NULL, -1, 1);
 +        }
 +    }
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnToggleStatusBarVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    fStatusBarVisible = !fStatusBarVisible;
 +    // TODO: trigger a relayout of contained items
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnToggleToolbarLock(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    CComPtr<IOleCommandTarget>              commandTarget;
 +    HRESULT                                 hResult;
 +
 +    hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
 +        IID_PPV_ARG(IOleCommandTarget, &commandTarget));
 +    if (FAILED(hResult))
 +        return 0;
 +    hResult = commandTarget->Exec(&CGID_PrivCITCommands, ITID_TOOLBARLOCKED, 0, NULL, NULL);
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnToggleToolbarBandVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    CComPtr<IOleCommandTarget>              commandTarget;
 +    HRESULT                                 hResult;
 +
 +    hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
 +        IID_PPV_ARG(IOleCommandTarget, &commandTarget));
 +    if (FAILED(hResult))
 +        return 0;
 +    hResult = commandTarget->Exec(&CGID_PrivCITCommands, ITID_TOOLBARBANDSHOWN, 0, NULL, NULL);
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnToggleAddressBandVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    CComPtr<IOleCommandTarget>              commandTarget;
 +    HRESULT                                 hResult;
 +
 +    hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
 +        IID_PPV_ARG(IOleCommandTarget, &commandTarget));
 +    if (FAILED(hResult))
 +        return 0;
 +    hResult = commandTarget->Exec(&CGID_PrivCITCommands, ITID_ADDRESSBANDSHOWN, 0, NULL, NULL);
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnToggleLinksBandVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    CComPtr<IOleCommandTarget>              commandTarget;
 +    HRESULT                                 hResult;
 +
 +    hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
 +        IID_PPV_ARG(IOleCommandTarget, &commandTarget));
 +    if (FAILED(hResult))
 +        return 0;
 +    hResult = commandTarget->Exec(&CGID_PrivCITCommands, ITID_LINKSBANDSHOWN, 0, NULL, NULL);
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnToggleTextLabels(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    CComPtr<IOleCommandTarget>              commandTarget;
 +    HRESULT                                 hResult;
 +
 +    hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
 +        IID_PPV_ARG(IOleCommandTarget, &commandTarget));
 +    if (FAILED(hResult))
 +        return 0;
 +    hResult = commandTarget->Exec(&CGID_PrivCITCommands, ITID_TEXTLABELS, 0, NULL, NULL);
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnToolbarCustomize(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    CComPtr<IOleCommandTarget>              commandTarget;
 +    HRESULT                                 hResult;
 +
 +    hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
 +        IID_PPV_ARG(IOleCommandTarget, &commandTarget));
 +    if (FAILED(hResult))
 +        return 0;
 +    hResult = commandTarget->Exec(&CGID_PrivCITCommands, ITID_CUSTOMIZEENABLED, 0, NULL, NULL);
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnGoTravel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::RelayCommands(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    if (HIWORD(wParam) == 0 && LOWORD(wParam) < FCIDM_SHVIEWLAST && fCurrentShellViewWindow != NULL)
 +        return SendMessage(fCurrentShellViewWindow, uMsg, wParam, lParam);
 +    return 0;
 +}
 +
 +static HRESULT ExplorerMessageLoop(IEThreadParamBlock * parameters)
 +{
 +    CComPtr<IShellBrowser>                  shellBrowser;
 +    CComObject<CShellBrowser>               *theCabinet;
 +    HRESULT                                 hResult;
 +    MSG Msg;
 +    BOOL Ret;
 +
 +    OleInitialize(NULL);
 +
 +    ATLTRY(theCabinet = new CComObject<CShellBrowser>);
 +    if (theCabinet == NULL)
 +    {
 +        hResult = E_OUTOFMEMORY;
 +        goto uninitialize;
 +    }
 +
 +    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)
 +        {
 +            // Error: continue or exit?
 +            break;
 +        }
 +
 +        if (theCabinet->v_MayTranslateAccelerator(&Msg) != S_OK)
 +        {
 +            TranslateMessage(&Msg);
 +            DispatchMessage(&Msg);
 +        }
 +
 +        if (Msg.message == WM_QUIT)
 +            break;
 +    }
 +
 +uninitialize:
 +    OleUninitialize();
 +    return hResult;
 +}
 +
 +DWORD WINAPI BrowserThreadProc(LPVOID lpThreadParameter)
 +{
 +    IEThreadParamBlock * parameters = (IEThreadParamBlock *) lpThreadParameter;
 +    return ExplorerMessageLoop(parameters);
 +}
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 0000000,28533f6..28533f6
mode 000000,100644..100644
--- /dev/null
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 0000000,860fe85..860fe85
mode 000000,100644..100644
--- /dev/null
index 0000000,7bc3ed7..7bc3ed7
mode 000000,100644..100644
--- /dev/null
Simple merge
Simple merge
index 0000000,fd79d43..fd79d43
mode 000000,100644..100644
Binary files differ
index 0000000,9bc8009..9bc8009
mode 000000,100644..100644
Binary files differ
index 0000000,83966f2..83966f2
mode 000000,100644..100644
Binary files differ
index 0000000,97c355b..97c355b
mode 000000,100644..100644
Binary files differ
index 0000000,0b45898..0b45898
mode 000000,100644..100644
Binary files differ
index 0000000,21f6f84..21f6f84
mode 000000,100644..100644
Binary files differ
index 0000000,31cb688..31cb688
mode 000000,100644..100644
Binary files differ
index 0000000,c90da48..c90da48
mode 000000,100644..100644
Binary files differ
index 0000000,0d38189..0d38189
mode 000000,100644..100644
Binary files differ
index 0000000,68299c4..68299c4
mode 000000,100644..100644
Binary files differ
index 0000000,db43334..db43334
mode 000000,100644..100644
Binary files differ
index 0000000,1a7679e..1a7679e
mode 000000,100644..100644
Binary files differ
index 0000000,59b6d16..59b6d16
mode 000000,100644..100644
Binary files differ
index 0000000,c0142fe..c0142fe
mode 000000,100644..100644
Binary files differ
index 0000000,12e4c7d..12e4c7d
mode 000000,100644..100644
Binary files differ
index 0000000,8d3e867..8d3e867
mode 000000,100644..100644
Binary files differ
index 0000000,7b7ac7d..7b7ac7d
mode 000000,100644..100644
Binary files differ
index 0000000,e36de45..e36de45
mode 000000,100644..100644
Binary files differ
index 0000000,443ec8b..443ec8b
mode 000000,100644..100644
Binary files differ
index 0000000,321eccf..321eccf
mode 000000,100644..100644
Binary files differ
index 0000000,45a038b..45a038b
mode 000000,100644..100644
Binary files differ
index 0000000,6f819f6..6f819f6
mode 000000,100644..100644
Binary files differ
index 0000000,7bd6665..7bd6665
mode 000000,100644..100644
Binary files differ
index 0000000,6c5b8ba..6c5b8ba
mode 000000,100644..100644
Binary files differ
index 0000000,fdd309d..fdd309d
mode 000000,100644..100644
Binary files differ
index 0000000,18f81a2..18f81a2
mode 000000,100644..100644
Binary files differ
index 0000000,292d4ad..292d4ad
mode 000000,100644..100644
--- /dev/null
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 13d2732,0000000..fe3483c
mode 100644,000000..100644
--- /dev/null
@@@ -1,4517 -1,0 +1,4240 @@@
- PMENU FASTCALL
- IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu)
- {
-    PMENU Menu, NewMenu = NULL, SysMenu = NULL, ret = NULL;
-    PTHREADINFO W32Thread;
-    HMENU hNewMenu, hSysMenu;
-    ROSMENUITEMINFO ItemInfoSet = {0};
-    ROSMENUITEMINFO ItemInfo = {0};
-    UNICODE_STRING MenuName;
-    if(bRevert)
-    {
-       W32Thread = PsGetCurrentThreadWin32Thread();
-       if(!W32Thread->rpdesk)
-          return NULL;
-       if(Window->SystemMenu)
-       {
-          Menu = UserGetMenuObject(Window->SystemMenu);
-          if(Menu)
-          {
-             IntDestroyMenuObject(Menu, TRUE, TRUE);
-             Window->SystemMenu = (HMENU)0;
-          }
-       }
-       if(W32Thread->rpdesk->rpwinstaParent->SystemMenuTemplate)
-       {
-          /* Clone system menu */
-          Menu = UserGetMenuObject(W32Thread->rpdesk->rpwinstaParent->SystemMenuTemplate);
-          if(!Menu)
-             return NULL;
-          NewMenu = IntCloneMenu(Menu);
-          if(NewMenu)
-          {  // Use spmenuSys
-             Window->SystemMenu = NewMenu->head.h;
-             NewMenu->fFlags |= MNF_SYSDESKMN;
-             NewMenu->hWnd = Window->head.h;
-             ret = NewMenu;
-             //IntReleaseMenuObject(NewMenu);
-          }
-       }
-       else
-       {
-          hSysMenu = UserCreateMenu(FALSE);
-          if (NULL == hSysMenu)
-          {
-             return NULL;
-          }
-          SysMenu = IntGetMenuObject(hSysMenu);
-          if (NULL == SysMenu)
-          {
-             UserDestroyMenu(hSysMenu);
-             return NULL;
-          }
-          SysMenu->fFlags |= MNF_SYSDESKMN;
-          SysMenu->hWnd = Window->head.h;
-          //hNewMenu = co_IntLoadSysMenuTemplate();
-          //if ( Window->ExStyle & WS_EX_MDICHILD )
-          //{
-          //   RtlInitUnicodeString( &MenuName, L"SYSMENUMDI");
-          //   hNewMenu = co_IntCallLoadMenu( hModClient, &MenuName);
-          //}
-          //else
-          {
-             RtlInitUnicodeString( &MenuName, L"SYSMENU");
-             hNewMenu = co_IntCallLoadMenu( hModClient, &MenuName);
-             //ERR("%wZ\n",&MenuName);
-          }
-          if(!hNewMenu)
-          {
-             ERR("No Menu!!\n");
-             IntReleaseMenuObject(SysMenu);
-             UserDestroyMenu(hSysMenu);
-             return NULL;
-          }
-          Menu = IntGetMenuObject(hNewMenu);
-          if(!Menu)
-          {
-             IntReleaseMenuObject(SysMenu);
-             UserDestroyMenu(hSysMenu);
-             return NULL;
-          }
-          // Do the rest in here.
-          Menu->fFlags |= MNS_CHECKORBMP | MNF_SYSDESKMN | MNF_POPUP;
-          ItemInfoSet.cbSize = sizeof( MENUITEMINFOW);
-          ItemInfoSet.fMask = MIIM_BITMAP;
-          ItemInfoSet.hbmpItem = HBMMENU_POPUP_CLOSE;
-          IntMenuItemInfo(Menu, SC_CLOSE, FALSE, &ItemInfoSet, TRUE, NULL);
-          ItemInfoSet.hbmpItem = HBMMENU_POPUP_RESTORE;
-          IntMenuItemInfo(Menu, SC_RESTORE, FALSE, &ItemInfoSet, TRUE, NULL);
-          ItemInfoSet.hbmpItem = HBMMENU_POPUP_MAXIMIZE;
-          IntMenuItemInfo(Menu, SC_MAXIMIZE, FALSE, &ItemInfoSet, TRUE, NULL);
-          ItemInfoSet.hbmpItem = HBMMENU_POPUP_MINIMIZE;
-          IntMenuItemInfo(Menu, SC_MINIMIZE, FALSE, &ItemInfoSet, TRUE, NULL);
-          NewMenu = IntCloneMenu(Menu);
-          if(NewMenu)
-          {
-             NewMenu->fFlags |= MNF_SYSDESKMN | MNF_POPUP;
-             // Do not set MNS_CHECKORBMP it breaks menus, also original code destroyed the style anyway.
-             IntReleaseMenuObject(NewMenu);
-             UserSetMenuDefaultItem(NewMenu, SC_CLOSE, FALSE);
-             if (Window->pcls->style & CS_NOCLOSE)
-                IntRemoveMenuItem(NewMenu, SC_CLOSE, MF_BYCOMMAND, TRUE);
-             ItemInfo.cbSize = sizeof(MENUITEMINFOW);
-             ItemInfo.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE | MIIM_SUBMENU;
-             ItemInfo.fType = 0;
-             ItemInfo.fState = MFS_ENABLED;
-             ItemInfo.dwTypeData = NULL;
-             ItemInfo.cch = 0;
-             ItemInfo.hSubMenu = NewMenu->head.h;
-             IntInsertMenuItem(SysMenu, (UINT) -1, TRUE, &ItemInfo, NULL);
-             Window->SystemMenu = SysMenu->head.h;
-             ret = SysMenu;
-          }
-          IntDestroyMenuObject(Menu, FALSE, TRUE);
-       }
-       if(RetMenu)
-          return ret;
-       else
-          return NULL;
-    }
-    else
-    {
-       if(Window->SystemMenu)
-          return IntGetMenuObject((HMENU)Window->SystemMenu);
-       else
-          return NULL;
-    }
- }
 +/*
 + * COPYRIGHT:        See COPYING in the top level directory
 + * PROJECT:          ReactOS Win32k subsystem
 + * PURPOSE:          Windows
 + * FILE:             subsystems/win32/win32k/ntuser/window.c
 + * PROGRAMER:        Casper S. Hornstrup (chorns@users.sourceforge.net)
 + */
 +
 +#include <win32k.h>
 +DBG_DEFAULT_CHANNEL(UserWnd);
 +
 +INT gNestedWindowLimit = 50;
 +
 +/* HELPER FUNCTIONS ***********************************************************/
 +
 +BOOL FASTCALL UserUpdateUiState(PWND Wnd, WPARAM wParam)
 +{
 +    WORD Action = LOWORD(wParam);
 +    WORD Flags = HIWORD(wParam);
 +
 +    if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
 +    {
 +        EngSetLastError(ERROR_INVALID_PARAMETER);
 +        return FALSE;
 +    }
 +
 +    switch (Action)
 +    {
 +        case UIS_INITIALIZE:
 +            EngSetLastError(ERROR_INVALID_PARAMETER);
 +            return FALSE;
 +
 +        case UIS_SET:
 +            if (Flags & UISF_HIDEFOCUS)
 +                Wnd->HideFocus = TRUE;
 +            if (Flags & UISF_HIDEACCEL)
 +                Wnd->HideAccel = TRUE;
 +            break;
 +
 +        case UIS_CLEAR:
 +            if (Flags & UISF_HIDEFOCUS)
 +                Wnd->HideFocus = FALSE;
 +            if (Flags & UISF_HIDEACCEL)
 +                Wnd->HideAccel = FALSE;
 +            break;
 +    }
 +
 +    return TRUE;
 +}
 +
 +PWND FASTCALL IntGetWindowObject(HWND hWnd)
 +{
 +   PWND Window;
 +
 +   if (!hWnd) return NULL;
 +
 +   Window = UserGetWindowObject(hWnd);
 +   if (Window)
 +      Window->head.cLockObj++;
 +
 +   return Window;
 +}
 +
 +PWND FASTCALL VerifyWnd(PWND pWnd)
 +{
 +   HWND hWnd;
 +   UINT State, State2;
 +
 +   if (!pWnd) return NULL;
 +
 +   _SEH2_TRY
 +   {
 +      hWnd = UserHMGetHandle(pWnd);
 +      State = pWnd->state;
 +      State2 = pWnd->state2;
 +   }
 +   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
 +   {
 +      _SEH2_YIELD(return NULL);
 +   }
 +   _SEH2_END
 +
 +   if ( UserObjectInDestroy(hWnd) ||
 +        State & WNDS_DESTROYED ||
 +        State2 & WNDS2_INDESTROY )
 +      return NULL;
 +
 +   return pWnd;
 +}
 +
 +PWND FASTCALL ValidateHwndNoErr(HWND hWnd)
 +{
 +   if (hWnd) return (PWND)UserGetObjectNoErr(gHandleTable, hWnd, TYPE_WINDOW);
 +   return NULL;
 +}
 +
 +/* Temp HACK */
 +PWND FASTCALL UserGetWindowObject(HWND hWnd)
 +{
 +    PWND Window;
 +
 +   if (!hWnd)
 +   {
 +      EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
 +      return NULL;
 +   }
 +
 +   Window = (PWND)UserGetObject(gHandleTable, hWnd, TYPE_WINDOW);
 +   if (!Window || 0 != (Window->state & WNDS_DESTROYED))
 +   {
 +      EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
 +      return NULL;
 +   }
 +
 +   return Window;
 +}
 +
 +ULONG FASTCALL
 +IntSetStyle( PWND pwnd, ULONG set_bits, ULONG clear_bits )
 +{
 +    ULONG styleOld, styleNew;
 +    styleOld = pwnd->style;
 +    styleNew = (pwnd->style | set_bits) & ~clear_bits;
 +    if (styleNew == styleOld) return styleNew;
 +    pwnd->style = styleNew;
 +    if ((styleOld ^ styleNew) & WS_VISIBLE) // State Change.
 +    {
 +       if (styleOld & WS_VISIBLE) pwnd->head.pti->cVisWindows--; 
 +       if (styleNew & WS_VISIBLE) pwnd->head.pti->cVisWindows++;
 +       DceResetActiveDCEs( pwnd );
 +    }
 +    return styleOld;
 +}
 +
 +/*
 + * IntIsWindow
 + *
 + * The function determines whether the specified window handle identifies
 + * an existing window.
 + *
 + * Parameters
 + *    hWnd
 + *       Handle to the window to test.
 + *
 + * Return Value
 + *    If the window handle identifies an existing window, the return value
 + *    is TRUE. If the window handle does not identify an existing window,
 + *    the return value is FALSE.
 + */
 +
 +BOOL FASTCALL
 +IntIsWindow(HWND hWnd)
 +{
 +   PWND Window;
 +
 +   if (!(Window = UserGetWindowObject(hWnd)))
 +   {
 +      return FALSE;
 +   }
 +
 +   return TRUE;
 +}
 +
 +BOOL FASTCALL
 +IntIsWindowVisible(PWND Wnd)
 +{
 +   PWND Temp = Wnd;
 +   for (;;)
 +   {
 +      if (!Temp) return TRUE;
 +      if (!(Temp->style & WS_VISIBLE)) break;
 +      if (Temp->style & WS_MINIMIZE && Temp != Wnd) break;
 +      if (Temp->fnid == FNID_DESKTOP) return TRUE;
 +      Temp = Temp->spwndParent;
 +   }
 +   return FALSE;
 +}
 +
 +PWND FASTCALL
 +IntGetParent(PWND Wnd)
 +{
 +   if (Wnd->style & WS_POPUP)
 +   {
 +      return Wnd->spwndOwner;
 +   }
 +   else if (Wnd->style & WS_CHILD)
 +   {
 +      return Wnd->spwndParent;
 +   }
 +
 +   return NULL;
 +}
 +
 +BOOL
 +FASTCALL
 +IntEnableWindow( HWND hWnd, BOOL bEnable )
 +{
 +   BOOL Update;
 +   PWND pWnd;
 +   UINT bIsDisabled;
 +
 +   if(!(pWnd = UserGetWindowObject(hWnd)))
 +   {
 +      return FALSE;
 +   }
 +
 +   /* check if updating is needed */
 +   bIsDisabled = !!(pWnd->style & WS_DISABLED);
 +   Update = bIsDisabled;
 +
 +    if (bEnable)
 +    {
 +       IntSetStyle( pWnd, 0, WS_DISABLED );
 +    }
 +    else
 +    {
 +       Update = !bIsDisabled;
 +
 +       co_IntSendMessage( hWnd, WM_CANCELMODE, 0, 0);
 +
 +       /* Remove keyboard focus from that window if it had focus */
 +       if (hWnd == IntGetThreadFocusWindow())
 +       {
 +          TRACE("IntEnableWindow SF NULL\n");
 +          co_UserSetFocus(NULL);
 +       }
 +       IntSetStyle( pWnd, WS_DISABLED, 0 );
 +    }
 +
 +    if (Update)
 +    {
 +        IntNotifyWinEvent(EVENT_OBJECT_STATECHANGE, pWnd, OBJID_WINDOW, CHILDID_SELF, 0);
 +        co_IntSendMessage(hWnd, WM_ENABLE, (LPARAM)bEnable, 0);
 +    }
 +    // Return nonzero if it was disabled, or zero if it wasn't:
 +    return bIsDisabled;
 +}
 +
 +/*
 + * IntWinListChildren
 + *
 + * Compile a list of all child window handles from given window.
 + *
 + * Remarks
 + *    This function is similar to Wine WIN_ListChildren. The caller
 + *    must free the returned list with ExFreePool.
 + */
 +
 +HWND* FASTCALL
 +IntWinListChildren(PWND Window)
 +{
 +   PWND Child;
 +   HWND *List;
 +   UINT Index, NumChildren = 0;
 +
 +   if (!Window) return NULL;
 +
 +   for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
 +      ++NumChildren;
 +
 +   List = ExAllocatePoolWithTag(PagedPool, (NumChildren + 1) * sizeof(HWND), USERTAG_WINDOWLIST);
 +   if(!List)
 +   {
 +      ERR("Failed to allocate memory for children array\n");
 +      EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
 +      return NULL;
 +   }
 +   for (Child = Window->spwndChild, Index = 0;
 +         Child != NULL;
 +         Child = Child->spwndNext, ++Index)
 +      List[Index] = Child->head.h;
 +   List[Index] = NULL;
 +
 +   return List;
 +}
 +
 +PWND FASTCALL
 +IntGetNonChildAncestor(PWND pWnd)
 +{
 +   while(pWnd && (pWnd->style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
 +      pWnd = pWnd->spwndParent;
 +   return pWnd;
 +}
 +
 +BOOL FASTCALL
 +IntIsTopLevelWindow(PWND pWnd)
 +{
 +   if ( pWnd->spwndParent &&
 +        pWnd->spwndParent == co_GetDesktopWindow(pWnd) ) return TRUE;
 +   return FALSE;
 +}
 +
 +BOOL FASTCALL
 +IntValidateOwnerDepth(PWND Wnd, PWND Owner)
 +{
 +   INT Depth = 1;
 +   for (;;)
 +   {
 +      if ( !Owner ) return gNestedWindowLimit >= Depth;
 +      if (Owner == Wnd) break;
 +      Owner = Owner->spwndOwner;
 +      Depth++;
 +   }
 +   return FALSE;
 +}
 +
 +HWND FASTCALL
 +IntGetWindow(HWND hWnd,
 +          UINT uCmd)
 +{
 +    PWND Wnd, FoundWnd;
 +    HWND Ret = NULL;
 +
 +    Wnd = ValidateHwndNoErr(hWnd);
 +    if (!Wnd)
 +        return NULL;
 +
 +    FoundWnd = NULL;
 +    switch (uCmd)
 +    {
 +            case GW_OWNER:
 +                if (Wnd->spwndOwner != NULL)
 +                    FoundWnd = Wnd->spwndOwner;
 +                break;
 +
 +            case GW_HWNDFIRST:
 +                if(Wnd->spwndParent != NULL)
 +                {
 +                    FoundWnd = Wnd->spwndParent;
 +                    if (FoundWnd->spwndChild != NULL)
 +                        FoundWnd = FoundWnd->spwndChild;
 +                }
 +                break;
 +            case GW_HWNDNEXT:
 +                if (Wnd->spwndNext != NULL)
 +                    FoundWnd = Wnd->spwndNext;
 +                break;
 +
 +            case GW_HWNDPREV:
 +                if (Wnd->spwndPrev != NULL)
 +                    FoundWnd = Wnd->spwndPrev;
 +                break;
 +   
 +            case GW_CHILD:
 +                if (Wnd->spwndChild != NULL)
 +                    FoundWnd = Wnd->spwndChild;
 +                break;
 +
 +            case GW_HWNDLAST:
 +                FoundWnd = Wnd;
 +                while ( FoundWnd->spwndNext != NULL)
 +                    FoundWnd = FoundWnd->spwndNext;
 +                break;
 +
 +            default:
 +                Wnd = NULL;
 +                break;
 +    }
 +
 +    if (FoundWnd != NULL)
 +        Ret = UserHMGetHandle(FoundWnd);
 +    return Ret;
 +}
 +
 +/***********************************************************************
 + *           IntSendDestroyMsg
 + */
 +static void IntSendDestroyMsg(HWND hWnd)
 +{
 +
 +   PWND Window;
 +#if 0 /* FIXME */
 +
 +   GUITHREADINFO info;
 +
 +   if (GetGUIThreadInfo(GetCurrentThreadId(), &info))
 +   {
 +      if (hWnd == info.hwndCaret)
 +      {
 +         DestroyCaret();
 +      }
 +   }
 +#endif
 +
 +   Window = UserGetWindowObject(hWnd);
 +   if (Window)
 +   {
 +//      USER_REFERENCE_ENTRY Ref;
 +//      UserRefObjectCo(Window, &Ref);
 +
 +      if (!Window->spwndOwner && !IntGetParent(Window))
 +      {
 +         co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (WPARAM) hWnd, 0);
 +      }
 +
 +//      UserDerefObjectCo(Window);
 +   }
 +
 +   /* The window could already be destroyed here */
 +
 +   /*
 +    * Send the WM_DESTROY to the window.
 +    */
 +
 +   co_IntSendMessage(hWnd, WM_DESTROY, 0, 0);
 +
 +   /*
 +    * This WM_DESTROY message can trigger re-entrant calls to DestroyWindow
 +    * make sure that the window still exists when we come back.
 +    */
 +#if 0 /* FIXME */
 +
 +   if (IsWindow(Wnd))
 +   {
 +      HWND* pWndArray;
 +      int i;
 +
 +      if (!(pWndArray = WIN_ListChildren( hwnd )))
 +         return;
 +
 +      /* start from the end (FIXME: is this needed?) */
 +      for (i = 0; pWndArray[i]; i++)
 +         ;
 +
 +      while (--i >= 0)
 +      {
 +         if (IsWindow( pWndArray[i] ))
 +            WIN_SendDestroyMsg( pWndArray[i] );
 +      }
 +      HeapFree(GetProcessHeap(), 0, pWndArray);
 +   }
 +   else
 +   {
 +      TRACE("destroyed itself while in WM_DESTROY!\n");
 +   }
 +#endif
 +}
 +
 +static VOID
 +UserFreeWindowInfo(PTHREADINFO ti, PWND Wnd)
 +{
 +    PCLIENTINFO ClientInfo = GetWin32ClientInfo();
 +
 +    if (!Wnd) return;
 +
 +    if (ClientInfo->CallbackWnd.pWnd == DesktopHeapAddressToUser(Wnd))
 +    {
 +        ClientInfo->CallbackWnd.hWnd = NULL;
 +        ClientInfo->CallbackWnd.pWnd = NULL;
 +    }
 +
 +   if (Wnd->strName.Buffer != NULL)
 +   {
 +       Wnd->strName.Length = 0;
 +       Wnd->strName.MaximumLength = 0;
 +       DesktopHeapFree(Wnd->head.rpdesk,
 +                       Wnd->strName.Buffer);
 +       Wnd->strName.Buffer = NULL;
 +   }
 +
 +//    DesktopHeapFree(Wnd->head.rpdesk, Wnd);
 +//    WindowObject->hWnd = NULL;
 +}
 +
 +/***********************************************************************
 + *           IntDestroyWindow
 + *
 + * Destroy storage associated to a window. "Internals" p.358
 + *
 + * This is the "functional" DestroyWindows function ei. all stuff
 + * done in CreateWindow is undone here and not in DestroyWindow:-P
 +
 + */
 +static LRESULT co_UserFreeWindow(PWND Window,
 +                                   PPROCESSINFO ProcessData,
 +                                   PTHREADINFO ThreadData,
 +                                   BOOLEAN SendMessages)
 +{
 +   HWND *Children;
 +   HWND *ChildHandle;
 +   PWND Child;
 +   PMENU Menu;
 +   BOOLEAN BelongsToThreadData;
 +
 +   ASSERT(Window);
 +
 +   if(Window->state2 & WNDS2_INDESTROY)
 +   {
 +      TRACE("Tried to call IntDestroyWindow() twice\n");
 +      return 0;
 +   }
 +   Window->state2 |= WNDS2_INDESTROY;
 +   Window->style &= ~WS_VISIBLE;
 +   Window->head.pti->cVisWindows--;
 +
 +   IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Window, OBJID_WINDOW, CHILDID_SELF, 0);
 +
 +   /* remove the window already at this point from the thread window list so we
 +      don't get into trouble when destroying the thread windows while we're still
 +      in IntDestroyWindow() */
 +   RemoveEntryList(&Window->ThreadListEntry);
 +
 +   BelongsToThreadData = IntWndBelongsToThread(Window, ThreadData);
 +
 +   IntDeRegisterShellHookWindow(Window->head.h);
 +
 +   if(SendMessages)
 +   {
 +      /* Send destroy messages */
 +      IntSendDestroyMsg(Window->head.h);
 +   }
 +
 +   /* free child windows */
 +   Children = IntWinListChildren(Window);
 +   if (Children)
 +   {
 +      for (ChildHandle = Children; *ChildHandle; ++ChildHandle)
 +      {
 +         if ((Child = IntGetWindowObject(*ChildHandle)))
 +         {
 +            if(!IntWndBelongsToThread(Child, ThreadData))
 +            {
 +               /* send WM_DESTROY messages to windows not belonging to the same thread */
 +               IntSendDestroyMsg(Child->head.h);
 +            }
 +            else
 +               co_UserFreeWindow(Child, ProcessData, ThreadData, SendMessages);
 +
 +            UserDereferenceObject(Child);
 +         }
 +      }
 +      ExFreePoolWithTag(Children, USERTAG_WINDOWLIST);
 +   }
 +
 +   if(SendMessages)
 +   {
 +      /*
 +       * Clear the update region to make sure no WM_PAINT messages will be
 +       * generated for this window while processing the WM_NCDESTROY.
 +       */
 +      co_UserRedrawWindow(Window, NULL, 0,
 +                          RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE |
 +                          RDW_NOINTERNALPAINT | RDW_NOCHILDREN);
 +      if(BelongsToThreadData)
 +         co_IntSendMessage(Window->head.h, WM_NCDESTROY, 0, 0);
 +   }
 +
 +   DestroyTimersForWindow(ThreadData, Window);
 +
 +   /* Unregister hot keys */
 +   UnregisterWindowHotKeys (Window);
 +
 +   /* flush the message queue */
 +   MsqRemoveWindowMessagesFromQueue(Window);
 +
 +   /* from now on no messages can be sent to this window anymore */
 +   Window->state |= WNDS_DESTROYED;
 +   Window->fnid |= FNID_FREED;
 +
 +   /* don't remove the WINDOWSTATUS_DESTROYING bit */
 +
 +   /* reset shell window handles */
 +   if(ThreadData->rpdesk)
 +   {
 +      if (Window->head.h == ThreadData->rpdesk->rpwinstaParent->ShellWindow)
 +         ThreadData->rpdesk->rpwinstaParent->ShellWindow = NULL;
 +
 +      if (Window->head.h == ThreadData->rpdesk->rpwinstaParent->ShellListView)
 +         ThreadData->rpdesk->rpwinstaParent->ShellListView = NULL;
 +   }
 +
 +   /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
 +
 +#if 0 /* FIXME */
 +
 +   WinPosCheckInternalPos(Window->head.h);
 +   if (Window->head.h == GetCapture())
 +   {
 +      ReleaseCapture();
 +   }
 +
 +   /* free resources associated with the window */
 +   TIMER_RemoveWindowTimers(Window->head.h);
 +#endif
 +
 +   if ( ((Window->style & (WS_CHILD|WS_POPUP)) != WS_CHILD) &&
 +        Window->IDMenu &&
 +        (Menu = UserGetMenuObject((HMENU)Window->IDMenu)))
 +   {
 +      IntDestroyMenuObject(Menu, TRUE, TRUE);
 +      Window->IDMenu = 0;
 +   }
 +
 +   if(Window->SystemMenu
 +         && (Menu = UserGetMenuObject(Window->SystemMenu)))
 +   {
 +      IntDestroyMenuObject(Menu, TRUE, TRUE);
 +      Window->SystemMenu = (HMENU)0;
 +   }
 +
 +   DceFreeWindowDCE(Window);    /* Always do this to catch orphaned DCs */
 +#if 0 /* FIXME */
 +
 +   WINPROC_FreeProc(Window->winproc, WIN_PROC_WINDOW);
 +   CLASS_RemoveWindow(Window->Class);
 +#endif
 +
 +   IntUnlinkWindow(Window);
 +
 +   if (Window->PropListItems)
 +   {
 +      IntRemoveWindowProp(Window);
 +      TRACE("Window->PropListItems %d\n",Window->PropListItems);
 +      ASSERT(Window->PropListItems==0);
 +   }
 +
 +   UserReferenceObject(Window);
 +   UserDeleteObject(Window->head.h, TYPE_WINDOW);
 +
 +   IntDestroyScrollBars(Window);
 +
 +   /* dereference the class */
 +   IntDereferenceClass(Window->pcls,
 +                       Window->head.pti->pDeskInfo,
 +                       Window->head.pti->ppi);
 +   Window->pcls = NULL;
 +
 +   if(Window->hrgnClip)
 +   {
 +      IntGdiSetRegionOwner(Window->hrgnClip, GDI_OBJ_HMGR_POWNED);
 +      GreDeleteObject(Window->hrgnClip);
 +      Window->hrgnClip = NULL;
 +   }
 +   Window->head.pti->cWindows--;
 +
 +//   ASSERT(Window != NULL);
 +   UserFreeWindowInfo(Window->head.pti, Window);
 +
 +   UserDereferenceObject(Window);
 +
 +   UserClipboardFreeWindow(Window);
 +
 +   return 0;
 +}
 +
 +//
 +// Same as User32:IntGetWndProc.
 +//
 +WNDPROC FASTCALL
 +IntGetWindowProc(PWND pWnd,
 +                 BOOL Ansi)
 +{
 +   INT i;
 +   PCLS Class;
 +   WNDPROC gcpd, Ret = 0;
 +
 +   ASSERT(UserIsEnteredExclusive() == TRUE);
 +
 +   Class = pWnd->pcls;
 +
 +   if (pWnd->state & WNDS_SERVERSIDEWINDOWPROC)
 +   {
 +      for ( i = FNID_FIRST; i <= FNID_SWITCH; i++)
 +      {
 +         if (GETPFNSERVER(i) == pWnd->lpfnWndProc)
 +         {
 +            if (Ansi)
 +               Ret = GETPFNCLIENTA(i);
 +            else
 +               Ret = GETPFNCLIENTW(i);
 +         }
 +      }
 +      return Ret;
 +   }
 +
 +   if (Class->fnid == FNID_EDIT)
 +      Ret = pWnd->lpfnWndProc;
 +   else
 +   {
 +      Ret = pWnd->lpfnWndProc;
 +
 +      if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON)
 +      {
 +         if (Ansi)
 +         {
 +            if (GETPFNCLIENTW(Class->fnid) == pWnd->lpfnWndProc)
 +               Ret = GETPFNCLIENTA(Class->fnid);
 +         }
 +         else
 +         {
 +            if (GETPFNCLIENTA(Class->fnid) == pWnd->lpfnWndProc)
 +               Ret = GETPFNCLIENTW(Class->fnid);
 +         }
 +      }
 +      if ( Ret != pWnd->lpfnWndProc)
 +         return Ret;
 +   }
 +   if ( Ansi == !!(pWnd->state & WNDS_ANSIWINDOWPROC) )
 +      return Ret;
 +
 +   gcpd = (WNDPROC)UserGetCPD(
 +                       pWnd,
 +                      (Ansi ? UserGetCPDA2U : UserGetCPDU2A )|UserGetCPDWindow,
 +                      (ULONG_PTR)Ret);
 +
 +   return (gcpd ? gcpd : Ret);
 +}
 +
 +static WNDPROC
 +IntSetWindowProc(PWND pWnd,
 +                 WNDPROC NewWndProc,
 +                 BOOL Ansi)
 +{
 +   INT i;
 +   PCALLPROCDATA CallProc;
 +   PCLS Class;
 +   WNDPROC Ret, chWndProc = NULL;
 +
 +   // Retrieve previous window proc.
 +   Ret = IntGetWindowProc(pWnd, Ansi);
 +
 +   Class = pWnd->pcls;
 +
 +   if (IsCallProcHandle(NewWndProc))
 +   {
 +      CallProc = UserGetObject(gHandleTable, NewWndProc, TYPE_CALLPROC);
 +      if (CallProc)
 +      {  // Reset new WndProc.
 +         NewWndProc = CallProc->pfnClientPrevious;
 +         // Reset Ansi from CallProc handle. This is expected with wine "deftest".
 +         Ansi = !!(CallProc->wType & UserGetCPDU2A);
 +      }
 +   }
 +   // Switch from Client Side call to Server Side call if match. Ref: "deftest".
 +   for ( i = FNID_FIRST; i <= FNID_SWITCH; i++)
 +   {
 +       if (GETPFNCLIENTW(i) == NewWndProc)
 +       {
 +          chWndProc = GETPFNSERVER(i);
 +          break;
 +       }
 +       if (GETPFNCLIENTA(i) == NewWndProc)
 +       {
 +          chWndProc = GETPFNSERVER(i);
 +          break;
 +       }
 +   }
 +   // If match, set/reset to Server Side and clear ansi.
 +   if (chWndProc)
 +   {
 +      pWnd->lpfnWndProc = chWndProc;
 +      pWnd->Unicode = TRUE;
 +      pWnd->state &= ~WNDS_ANSIWINDOWPROC;
 +      pWnd->state |= WNDS_SERVERSIDEWINDOWPROC;
 +   }
 +   else
 +   {
 +      pWnd->Unicode = !Ansi;
 +      // Handle the state change in here.
 +      if (Ansi)
 +         pWnd->state |= WNDS_ANSIWINDOWPROC;
 +      else
 +         pWnd->state &= ~WNDS_ANSIWINDOWPROC;
 +
 +      if (pWnd->state & WNDS_SERVERSIDEWINDOWPROC)
 +         pWnd->state &= ~WNDS_SERVERSIDEWINDOWPROC;
 +
 +      if (!NewWndProc) NewWndProc = pWnd->lpfnWndProc;
 +
 +      if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON)
 +      {
 +         if (Ansi)
 +         {
 +            if (GETPFNCLIENTW(Class->fnid) == NewWndProc)
 +               chWndProc = GETPFNCLIENTA(Class->fnid);
 +         }
 +         else
 +         {
 +            if (GETPFNCLIENTA(Class->fnid) == NewWndProc)
 +               chWndProc = GETPFNCLIENTW(Class->fnid);
 +         }
 +      }
 +      // Now set the new window proc.
 +      pWnd->lpfnWndProc = (chWndProc ? chWndProc : NewWndProc);
 +   }
 +   return Ret;
 +}
 +
 +static BOOL FASTCALL
 +IntSetMenu(
 +   PWND Wnd,
 +   HMENU Menu,
 +   BOOL *Changed)
 +{
 +   PMENU OldMenu, NewMenu = NULL;
 +
 +   if ((Wnd->style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
 +   {
 +      ERR("SetMenu: Invalid handle 0x%p!\n",UserHMGetHandle(Wnd));
 +      EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
 +      return FALSE;
 +   }
 +
 +   *Changed = (Wnd->IDMenu != (UINT) Menu);
 +   if (! *Changed)
 +   {
 +      return TRUE;
 +   }
 +
 +   if (Wnd->IDMenu)
 +   {
 +      OldMenu = IntGetMenuObject((HMENU) Wnd->IDMenu);
 +      ASSERT(NULL == OldMenu || OldMenu->hWnd == Wnd->head.h);
 +   }
 +   else
 +   {
 +      OldMenu = NULL;
 +   }
 +
 +   if (NULL != Menu)
 +   {
 +      NewMenu = IntGetMenuObject(Menu);
 +      if (NULL == NewMenu)
 +      {
 +         if (NULL != OldMenu)
 +         {
 +            IntReleaseMenuObject(OldMenu);
 +         }
 +         EngSetLastError(ERROR_INVALID_MENU_HANDLE);
 +         return FALSE;
 +      }
 +      if (NULL != NewMenu->hWnd)
 +      {
 +         /* Can't use the same menu for two windows */
 +         if (NULL != OldMenu)
 +         {
 +            IntReleaseMenuObject(OldMenu);
 +         }
 +         EngSetLastError(ERROR_INVALID_MENU_HANDLE);
 +         return FALSE;
 +      }
 +
 +   }
 +
 +   Wnd->IDMenu = (UINT) Menu;
 +   if (NULL != NewMenu)
 +   {
 +      NewMenu->hWnd = Wnd->head.h;
 +      IntReleaseMenuObject(NewMenu);
 +   }
 +   if (NULL != OldMenu)
 +   {
 +      OldMenu->hWnd = NULL;
 +      IntReleaseMenuObject(OldMenu);
 +   }
 +
 +   return TRUE;
 +}
 +
 +
 +/* INTERNAL ******************************************************************/
 +
 +
 +VOID FASTCALL
 +co_DestroyThreadWindows(struct _ETHREAD *Thread)
 +{
 +   PTHREADINFO WThread;
 +   PLIST_ENTRY Current;
 +   PWND Wnd;
 +   USER_REFERENCE_ENTRY Ref;
 +   WThread = (PTHREADINFO)Thread->Tcb.Win32Thread;
 +
 +   while (!IsListEmpty(&WThread->WindowListHead))
 +   {
 +      Current = WThread->WindowListHead.Flink;
 +      Wnd = CONTAINING_RECORD(Current, WND, ThreadListEntry);
 +
 +      TRACE("thread cleanup: while destroy wnds, wnd=%p\n", Wnd);
 +
 +      /* Window removes itself from the list */
 +
 +      /*
 +       * FIXME: It is critical that the window removes itself! If now, we will loop
 +       * here forever...
 +       */
 +
 +      //ASSERT(co_UserDestroyWindow(Wnd));
 +
 +      UserRefObjectCo(Wnd, &Ref); // FIXME: Temp HACK??
 +      if (!co_UserDestroyWindow(Wnd))
 +      {
 +         ERR("Unable to destroy window %p at thread cleanup... This is _VERY_ bad!\n", Wnd);
 +      }
 +      UserDerefObjectCo(Wnd); // FIXME: Temp HACK??
 +   }
 +}
 +
- BOOL FASTCALL
- IntSetSystemMenu(PWND Window, PMENU Menu)
- {
-    PMENU OldMenu;
-    if(Window->SystemMenu)
-    {
-       OldMenu = IntGetMenuObject(Window->SystemMenu);
-       if(OldMenu)
-       {
-          OldMenu->fFlags &= ~ MNF_SYSDESKMN;
-          IntReleaseMenuObject(OldMenu);
-       }
-    }
-    if(Menu)
-    {
-       /* FIXME: Check window style, propably return FALSE? */
-       Window->SystemMenu = Menu->head.h;
-       Menu->fFlags |= MNF_SYSDESKMN;
-    }
-    else // Use spmenuSys too!
-       Window->SystemMenu = (HMENU)0;
-    return TRUE;
- }
 +BOOL FASTCALL
 +IntIsChildWindow(PWND Parent, PWND BaseWindow)
 +{
 +   PWND Window;
 +
 +   Window = BaseWindow;
 +   while (Window && ((Window->style & (WS_POPUP|WS_CHILD)) == WS_CHILD))
 +   {
 +      if (Window == Parent)
 +      {
 +         return(TRUE);
 +      }
 +
 +      Window = Window->spwndParent;
 +   }
 +
 +   return(FALSE);
 +}
 +
 +/*
 +   Link the window into siblings list
 +   children and parent are kept in place.
 +*/
 +VOID FASTCALL
 +IntLinkWindow(
 +   PWND Wnd,
 +   PWND WndInsertAfter /* set to NULL if top sibling */
 +)
 +{
 +  if ((Wnd->spwndPrev = WndInsertAfter))
 +   {
 +      /* link after WndInsertAfter */
 +      if ((Wnd->spwndNext = WndInsertAfter->spwndNext))
 +         Wnd->spwndNext->spwndPrev = Wnd;
 +
 +      Wnd->spwndPrev->spwndNext = Wnd;
 +   }
 +   else
 +   {
 +      /* link at top */
 +     if ((Wnd->spwndNext = Wnd->spwndParent->spwndChild))
 +         Wnd->spwndNext->spwndPrev = Wnd;
 +
 +     Wnd->spwndParent->spwndChild = Wnd;
 +   }
 +}
 +
 +/*
 + Note: Wnd->spwndParent can be null if it is the desktop.
 +*/
 +VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
 +{
 +    if (hWndPrev == HWND_NOTOPMOST)
 +    {
 +        if (!(Wnd->ExStyle & WS_EX_TOPMOST) &&
 +            (Wnd->ExStyle2 & WS_EX2_LINKED)) return;  /* nothing to do */
 +        Wnd->ExStyle &= ~WS_EX_TOPMOST;
 +        hWndPrev = HWND_TOP;  /* fallback to the HWND_TOP case */
 +    }
 +
 +    IntUnlinkWindow(Wnd);  /* unlink it from the previous location */
 +
 +    if (hWndPrev == HWND_BOTTOM)
 +    {
 +        /* Link in the bottom of the list */
 +        PWND WndInsertAfter;
 +
 +        WndInsertAfter = Wnd->spwndParent->spwndChild;
 +        while( WndInsertAfter && WndInsertAfter->spwndNext)
 +            WndInsertAfter = WndInsertAfter->spwndNext;
 +
 +        IntLinkWindow(Wnd, WndInsertAfter);
 +        Wnd->ExStyle &= ~WS_EX_TOPMOST;
 +    }
 +    else if (hWndPrev == HWND_TOPMOST)
 +    {
 +        /* Link in the top of the list */
 +        IntLinkWindow(Wnd, NULL);
 +
 +        Wnd->ExStyle |= WS_EX_TOPMOST;
 +    }
 +    else if (hWndPrev == HWND_TOP)
 +    {
 +        /* Link it after the last topmost window */
 +        PWND WndInsertBefore;
 +
 +        WndInsertBefore = Wnd->spwndParent->spwndChild;
 +
 +        if (!(Wnd->ExStyle & WS_EX_TOPMOST))  /* put it above the first non-topmost window */
 +        {
 +            while (WndInsertBefore != NULL && WndInsertBefore->spwndNext != NULL)
 +            {
 +                if (!(WndInsertBefore->ExStyle & WS_EX_TOPMOST)) break;
 +                if (WndInsertBefore == Wnd->spwndOwner)  /* keep it above owner */
 +                {
 +                    Wnd->ExStyle |= WS_EX_TOPMOST;
 +                    break;
 +                }
 +                WndInsertBefore = WndInsertBefore->spwndNext;
 +            }
 +        }
 +
 +        IntLinkWindow(Wnd, WndInsertBefore ? WndInsertBefore->spwndPrev : NULL);
 +    }
 +    else
 +    {
 +        /* Link it after hWndPrev */
 +        PWND WndInsertAfter;
 +
 +        WndInsertAfter = UserGetWindowObject(hWndPrev);
 +        /* Are we called with an erroneous handle */
 +        if(WndInsertAfter == NULL)
 +        {
 +            /* Link in a default position */
 +            IntLinkHwnd(Wnd, HWND_TOP);
 +            return;
 +        }
 +
 +        IntLinkWindow(Wnd, WndInsertAfter);
 +
 +        /* Fix the WS_EX_TOPMOST flag */
 +        if (!(WndInsertAfter->ExStyle & WS_EX_TOPMOST))
 +        {
 +            Wnd->ExStyle &= ~WS_EX_TOPMOST;
 +        }
 +        else
 +        {
 +            if(WndInsertAfter->spwndNext &&
 +               WndInsertAfter->spwndNext->ExStyle & WS_EX_TOPMOST)
 +            {
 +                Wnd->ExStyle |= WS_EX_TOPMOST;
 +            }
 +        }
 +    }
 +    Wnd->ExStyle2 |= WS_EX2_LINKED;
 +}
 +
 +VOID FASTCALL
 +IntProcessOwnerSwap(PWND Wnd, PWND WndNewOwner, PWND WndOldOwner)
 +{
 +   if (WndOldOwner)
 +   {
 +      if (Wnd->head.pti != WndOldOwner->head.pti)
 +      {
 +         if (!WndNewOwner ||
 +              Wnd->head.pti == WndNewOwner->head.pti ||
 +              WndOldOwner->head.pti != WndNewOwner->head.pti )
 +         {
 +            //ERR("ProcessOwnerSwap Old out.\n");
 +            UserAttachThreadInput(Wnd->head.pti, WndOldOwner->head.pti, FALSE);
 +         }
 +      }
 +   }
 +   if (WndNewOwner)
 +   {
 +      if (Wnd->head.pti != WndNewOwner->head.pti)
 +      {
 +         if (!WndOldOwner ||
 +              WndOldOwner->head.pti != WndNewOwner->head.pti )
 +         {
 +            //ERR("ProcessOwnerSwap New in.\n");
 +            UserAttachThreadInput(Wnd->head.pti, WndNewOwner->head.pti, TRUE);
 +         }
 +      }
 +   }
 +   // FIXME: System Tray checks.
 +}
 +
 +HWND FASTCALL
 +IntSetOwner(HWND hWnd, HWND hWndNewOwner)
 +{
 +   PWND Wnd, WndOldOwner, WndNewOwner;
 +   HWND ret;
 +
 +   Wnd = IntGetWindowObject(hWnd);
 +   if(!Wnd)
 +      return NULL;
 +
 +   WndOldOwner = Wnd->spwndOwner;
 +
 +   ret = WndOldOwner ? UserHMGetHandle(WndOldOwner) : 0;
 +   WndNewOwner = UserGetWindowObject(hWndNewOwner);
 +
 +   if (!WndNewOwner && hWndNewOwner)
 +   {
 +      EngSetLastError(ERROR_INVALID_PARAMETER);
 +      ret = NULL;
 +      goto Error;
 +   }
 +
 +   /* if parent belongs to a different thread and the window isn't */
 +   /* top-level, attach the two threads */
 +   IntProcessOwnerSwap(Wnd, WndNewOwner, WndOldOwner);
 +
 +   if (IntValidateOwnerDepth(Wnd, WndNewOwner))
 +   {
 +      if (WndNewOwner)
 +      {
 +         Wnd->spwndOwner= WndNewOwner;
 +      }
 +      else
 +      {
 +         Wnd->spwndOwner = NULL;
 +      }
 +   }
 +   else
 +   {
 +      IntProcessOwnerSwap(Wnd, WndOldOwner, WndNewOwner);
 +      EngSetLastError(ERROR_INVALID_PARAMETER);
 +      ret = NULL;
 +   }
 +Error:
 +   UserDereferenceObject(Wnd);
 +   return ret;
 +}
 +
 +PWND FASTCALL
 +co_IntSetParent(PWND Wnd, PWND WndNewParent)
 +{
 +   PWND WndOldParent, pWndExam;
 +   BOOL WasVisible;
 +   POINT pt;
 +   int swFlags = SWP_NOSIZE|SWP_NOZORDER;
 +
 +   ASSERT(Wnd);
 +   ASSERT(WndNewParent);
 +   ASSERT_REFS_CO(Wnd);
 +   ASSERT_REFS_CO(WndNewParent);
 +
 +   if (Wnd == Wnd->head.rpdesk->spwndMessage)
 +   {
 +      EngSetLastError(ERROR_ACCESS_DENIED);
 +      return( NULL);
 +   }
 +
 +   /* Some applications try to set a child as a parent */
 +   if (IntIsChildWindow(Wnd, WndNewParent))
 +   {
 +      TRACE("IntSetParent try to set a child as a parent.\n");
 +      EngSetLastError( ERROR_INVALID_PARAMETER );
 +      return NULL;
 +   }
 +
 +   pWndExam = WndNewParent; // Load parent Window to examine.
 +   // Now test for set parent to parent hit.
 +   while (pWndExam)
 +   {
 +      if (Wnd == pWndExam)
 +      {
 +         TRACE("IntSetParent Failed Test for set parent to parent!\n");
 +         EngSetLastError(ERROR_INVALID_PARAMETER);
 +         return NULL;
 +      }
 +      pWndExam = pWndExam->spwndParent;
 +   }
 +
 +   /*
 +    * Windows hides the window first, then shows it again
 +    * including the WM_SHOWWINDOW messages and all
 +    */
 +   WasVisible = co_WinPosShowWindow(Wnd, SW_HIDE);
 +
 +   /* Window must belong to current process */
 +   if (Wnd->head.pti->ppi != PsGetCurrentProcessWin32Process())
 +   {
 +      ERR("IntSetParent Window must belong to current process!\n");
 +      return NULL;
 +   }
 +
 +   WndOldParent = Wnd->spwndParent;
 +
 +   if ( WndOldParent &&
 +        WndOldParent->ExStyle & WS_EX_LAYOUTRTL)
 +      pt.x = Wnd->rcWindow.right;
 +   else
 +      pt.x = Wnd->rcWindow.left;
 +   pt.y = Wnd->rcWindow.top;
 +
 +   IntScreenToClient(WndOldParent, &pt);
 +
 +   if (WndOldParent) UserReferenceObject(WndOldParent); /* Caller must deref */
 +
 +   if (WndNewParent != WndOldParent)
 +   {
 +      /* Unlink the window from the siblings list */
 +      IntUnlinkWindow(Wnd);
 +      Wnd->ExStyle2 &= ~WS_EX2_LINKED;
 +
 +      /* Set the new parent */
 +      Wnd->spwndParent = WndNewParent;
 +
 +      if ( Wnd->style & WS_CHILD &&
 +           Wnd->spwndOwner &&
 +           Wnd->spwndOwner->ExStyle & WS_EX_TOPMOST )
 +      {
 +         ERR("SetParent Top Most from Pop up!\n");
 +         Wnd->ExStyle |= WS_EX_TOPMOST;
 +      }
 +
 +      /* Link the window with its new siblings */
 +      IntLinkHwnd( Wnd,
 +                  ((0 == (Wnd->ExStyle & WS_EX_TOPMOST) &&
 +                    WndNewParent == UserGetDesktopWindow() ) ? HWND_TOP : HWND_TOPMOST ) );
 +
 +   }
 +
 +   if ( WndNewParent == co_GetDesktopWindow(Wnd) &&
 +       !(Wnd->style & WS_CLIPSIBLINGS) )
 +   {
 +      Wnd->style |= WS_CLIPSIBLINGS;
 +      DceResetActiveDCEs(Wnd);
 +   }
 +
 +   /* if parent belongs to a different thread and the window isn't */
 +   /* top-level, attach the two threads */
 +   if ((Wnd->style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
 +   {
 +      if ( Wnd->spwndParent != co_GetDesktopWindow(Wnd))
 +      {
 +         if (Wnd->head.pti != WndOldParent->head.pti)
 +         {
 +            //ERR("SetParent Old out.\n");
 +            UserAttachThreadInput(Wnd->head.pti, WndOldParent->head.pti, FALSE);
 +         }
 +      }
 +      if ( WndNewParent != co_GetDesktopWindow(Wnd))
 +      {
 +         if (Wnd->head.pti != WndNewParent->head.pti)
 +         {
 +            //ERR("SetParent New in.\n");
 +            UserAttachThreadInput(Wnd->head.pti, WndNewParent->head.pti, TRUE);
 +         }
 +      }
 +   }
 +
 +   if (WndOldParent == UserGetMessageWindow() || WndNewParent == UserGetMessageWindow())
 +      swFlags |= SWP_NOACTIVATE;
 +
 +   IntNotifyWinEvent(EVENT_OBJECT_PARENTCHANGE, Wnd ,OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
 +   /*
 +    * SetParent additionally needs to make hwnd the top window
 +    * in the z-order and send the expected WM_WINDOWPOSCHANGING and
 +    * WM_WINDOWPOSCHANGED notification messages.
 +    */
 +   //ERR("IntSetParent SetWindowPos 1\n");
 +   co_WinPosSetWindowPos( Wnd,
 +                         (0 == (Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOP : HWND_TOPMOST),
 +                          pt.x, pt.y, 0, 0, swFlags);
 +   //ERR("IntSetParent SetWindowPos 2 X %d Y %d\n",pt.x, pt.y);
 +   if (WasVisible) co_WinPosShowWindow(Wnd, SW_SHOWNORMAL);
 +
 +   return WndOldParent;
 +}
 +
 +HWND FASTCALL
 +co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
 +{
 +   PWND Wnd = NULL, WndParent = NULL, WndOldParent;
 +   HWND hWndOldParent = NULL;
 +   USER_REFERENCE_ENTRY Ref, ParentRef;
 +
 +   if (IntIsBroadcastHwnd(hWndChild) || IntIsBroadcastHwnd(hWndNewParent))
 +   {
 +      EngSetLastError(ERROR_INVALID_PARAMETER);
 +      return( NULL);
 +   }
 +
 +   if (hWndChild == IntGetDesktopWindow())
 +   {
 +      ERR("UserSetParent Access Denied!\n");
 +      EngSetLastError(ERROR_ACCESS_DENIED);
 +      return( NULL);
 +   }
 +
 +   if (hWndNewParent)
 +   {
 +      if (!(WndParent = UserGetWindowObject(hWndNewParent)))
 +      {
 +         ERR("UserSetParent Bad New Parent!\n");
 +         return( NULL);
 +      }
 +   }
 +   else
 +   {
 +      if (!(WndParent = UserGetWindowObject(IntGetDesktopWindow())))
 +      {
 +         return( NULL);
 +      }
 +   }
 +
 +   if (!(Wnd = UserGetWindowObject(hWndChild)))
 +   {
 +      ERR("UserSetParent Bad Child!\n");
 +      return( NULL);
 +   }
 +
 +   UserRefObjectCo(Wnd, &Ref);
 +   UserRefObjectCo(WndParent, &ParentRef);
 +   //ERR("Enter co_IntSetParent\n");
 +   WndOldParent = co_IntSetParent(Wnd, WndParent);
 +   //ERR("Leave co_IntSetParent\n");
 +   UserDerefObjectCo(WndParent);
 +   UserDerefObjectCo(Wnd);
 +
 +   if (WndOldParent)
 +   {
 +      hWndOldParent = WndOldParent->head.h;
 +      UserDereferenceObject(WndOldParent);
 +   }
 +
 +   return( hWndOldParent);
 +}
 +
-    PMENU SystemMenu;
 +/* Unlink the window from siblings. children and parent are kept in place. */
 +VOID FASTCALL
 +IntUnlinkWindow(PWND Wnd)
 +{
 +   if (Wnd->spwndNext)
 +       Wnd->spwndNext->spwndPrev = Wnd->spwndPrev;
 +
 +   if (Wnd->spwndPrev)
 +       Wnd->spwndPrev->spwndNext = Wnd->spwndNext;
 +
 +   if (Wnd->spwndParent && Wnd->spwndParent->spwndChild == Wnd)
 +       Wnd->spwndParent->spwndChild = Wnd->spwndNext;
 +
 +   Wnd->spwndPrev = Wnd->spwndNext = NULL;
 +}
 +
 +/* FUNCTIONS *****************************************************************/
 +
 +/*
 + * As best as I can figure, this function is used by EnumWindows,
 + * EnumChildWindows, EnumDesktopWindows, & EnumThreadWindows.
 + *
 + * It's supposed to build a list of HWNDs to return to the caller.
 + * We can figure out what kind of list by what parameters are
 + * passed to us.
 + */
 +/*
 + * @implemented
 + */
 +NTSTATUS
 +APIENTRY
 +NtUserBuildHwndList(
 +   HDESK hDesktop,
 +   HWND hwndParent,
 +   BOOLEAN bChildren,
 +   ULONG dwThreadId,
 +   ULONG lParam,
 +   HWND* pWnd,
 +   ULONG* pBufSize)
 +{
 +   NTSTATUS Status;
 +   ULONG dwCount = 0;
 +
 +   if (pBufSize == 0)
 +       return ERROR_INVALID_PARAMETER;
 +
 +   if (hwndParent || !dwThreadId)
 +   {
 +      PDESKTOP Desktop;
 +      PWND Parent, Window;
 +
 +      if(!hwndParent)
 +      {
 +         if(hDesktop == NULL && !(Desktop = IntGetActiveDesktop()))
 +         {
 +            return ERROR_INVALID_HANDLE;
 +         }
 +
 +         if(hDesktop)
 +         {
 +            Status = IntValidateDesktopHandle(hDesktop,
 +                                              UserMode,
 +                                              0,
 +                                              &Desktop);
 +            if(!NT_SUCCESS(Status))
 +            {
 +               return ERROR_INVALID_HANDLE;
 +            }
 +         }
 +         hwndParent = Desktop->DesktopWindow;
 +      }
 +      else
 +      {
 +         hDesktop = 0;
 +      }
 +
 +      if((Parent = UserGetWindowObject(hwndParent)) &&
 +         (Window = Parent->spwndChild))
 +      {
 +         BOOL bGoDown = TRUE;
 +
 +         Status = STATUS_SUCCESS;
 +         while(TRUE)
 +         {
 +            if (bGoDown)
 +            {
 +               if(dwCount++ < *pBufSize && pWnd)
 +               {
 +                  _SEH2_TRY
 +                  {
 +                     ProbeForWrite(pWnd, sizeof(HWND), 1);
 +                     *pWnd = Window->head.h;
 +                     pWnd++;
 +                  }
 +                  _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
 +                  {
 +                     Status = _SEH2_GetExceptionCode();
 +                  }
 +                  _SEH2_END
 +                  if(!NT_SUCCESS(Status))
 +                  {
 +                     SetLastNtError(Status);
 +                     break;
 +                  }
 +               }
 +               if (Window->spwndChild && bChildren)
 +               {
 +                  Window = Window->spwndChild;
 +                  continue;
 +               }
 +               bGoDown = FALSE;
 +            }
 +            if (Window->spwndNext)
 +            {
 +               Window = Window->spwndNext;
 +               bGoDown = TRUE;
 +               continue;
 +            }
 +            Window = Window->spwndParent;
 +            if (Window == Parent)
 +            {
 +               break;
 +            }
 +         }
 +      }
 +
 +      if(hDesktop)
 +      {
 +         ObDereferenceObject(Desktop);
 +      }
 +   }
 +   else // Build EnumThreadWindows list!
 +   {
 +      PETHREAD Thread;
 +      PTHREADINFO W32Thread;
 +      PLIST_ENTRY Current;
 +      PWND Window;
 +
 +      Status = PsLookupThreadByThreadId((HANDLE)dwThreadId, &Thread);
 +      if (!NT_SUCCESS(Status))
 +      {
 +         ERR("Thread Id is not valid!\n");
 +         return ERROR_INVALID_PARAMETER;
 +      }
 +      if (!(W32Thread = (PTHREADINFO)Thread->Tcb.Win32Thread))
 +      {
 +         ObDereferenceObject(Thread);
 +         ERR("Thread is not initialized!\n");
 +         return ERROR_INVALID_PARAMETER;
 +      }
 +
 +      Current = W32Thread->WindowListHead.Flink;
 +      while (Current != &(W32Thread->WindowListHead))
 +      {
 +         Window = CONTAINING_RECORD(Current, WND, ThreadListEntry);
 +         ASSERT(Window);
 +
 +         if (dwCount < *pBufSize && pWnd)
 +         {
 +            _SEH2_TRY
 +            {
 +               ProbeForWrite(pWnd, sizeof(HWND), 1);
 +               *pWnd = Window->head.h;
 +               pWnd++;
 +            }
 +            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
 +            {
 +               Status = _SEH2_GetExceptionCode();
 +            }
 +            _SEH2_END
 +            if (!NT_SUCCESS(Status))
 +            {
 +               ERR("Failure to build window list!\n");
 +               SetLastNtError(Status);
 +               break;
 +            }
 +         }
 +         dwCount++;
 +         Current = Window->ThreadListEntry.Flink;
 +      }
 +
 +      ObDereferenceObject(Thread);
 +   }
 +
 +   *pBufSize = dwCount;
 +   return STATUS_SUCCESS;
 +}
 +
 +static void IntSendParentNotify( PWND pWindow, UINT msg )
 +{
 +    if ( (pWindow->style & (WS_CHILD | WS_POPUP)) == WS_CHILD &&
 +         !(pWindow->style & WS_EX_NOPARENTNOTIFY))
 +    {
 +        if (pWindow->spwndParent && pWindow->spwndParent != UserGetDesktopWindow())
 +        {
 +            USER_REFERENCE_ENTRY Ref;
 +            UserRefObjectCo(pWindow->spwndParent, &Ref);
 +            co_IntSendMessage( pWindow->spwndParent->head.h,
 +                               WM_PARENTNOTIFY,
 +                               MAKEWPARAM( msg, pWindow->IDMenu),
 +                               (LPARAM)pWindow->head.h );
 +            UserDerefObjectCo(pWindow->spwndParent);
 +        }
 +    }
 +}
 +
 +void FASTCALL
 +IntFixWindowCoordinates(CREATESTRUCTW* Cs, PWND ParentWindow, DWORD* dwShowMode)
 +{
 +#define IS_DEFAULT(x)  ((x) == CW_USEDEFAULT || (x) == (SHORT)0x8000)
 +
 +   /* default positioning for overlapped windows */
 +    if(!(Cs->style & (WS_POPUP | WS_CHILD)))
 +   {
 +      PMONITOR pMonitor;
 +      PRTL_USER_PROCESS_PARAMETERS ProcessParams;
 +
 +      pMonitor = UserGetPrimaryMonitor();
 +
 +      /* Check if we don't have a monitor attached yet */
 +      if(pMonitor == NULL)
 +      {
 +          Cs->x = Cs->y = 0;
 +          Cs->cx = 800;
 +          Cs->cy = 600;
 +          return;
 +      }
 +
 +      ProcessParams = PsGetCurrentProcess()->Peb->ProcessParameters;
 +
 +      if (IS_DEFAULT(Cs->x))
 +      {
 +          if (!IS_DEFAULT(Cs->y)) *dwShowMode = Cs->y;
 +
 +          if(ProcessParams->WindowFlags & STARTF_USEPOSITION)
 +          {
 +              Cs->x = ProcessParams->StartingX;
 +              Cs->y = ProcessParams->StartingY;
 +          }
 +          else
 +          {
 +               Cs->x = pMonitor->cWndStack * (UserGetSystemMetrics(SM_CXSIZE) + UserGetSystemMetrics(SM_CXFRAME));
 +               Cs->y = pMonitor->cWndStack * (UserGetSystemMetrics(SM_CYSIZE) + UserGetSystemMetrics(SM_CYFRAME));
 +               if (Cs->x > ((pMonitor->rcWork.right - pMonitor->rcWork.left) / 4) ||
 +                   Cs->y > ((pMonitor->rcWork.bottom - pMonitor->rcWork.top) / 4))
 +               {
 +                  /* reset counter and position */
 +                  Cs->x = 0;
 +                  Cs->y = 0;
 +                  pMonitor->cWndStack = 0;
 +               }
 +               pMonitor->cWndStack++;
 +          }
 +      }
 +
 +      if (IS_DEFAULT(Cs->cx))
 +      {
 +          if (ProcessParams->WindowFlags & STARTF_USEPOSITION)
 +          {
 +              Cs->cx = ProcessParams->CountX;
 +              Cs->cy = ProcessParams->CountY;
 +          }
 +          else
 +          {
 +              Cs->cx = (pMonitor->rcWork.right - pMonitor->rcWork.left) * 3 / 4;
 +              Cs->cy = (pMonitor->rcWork.bottom - pMonitor->rcWork.top) * 3 / 4;
 +          }
 +      }
 +      /* neither x nor cx are default. Check the y values .
 +       * In the trace we see Outlook and Outlook Express using
 +       * cy set to CW_USEDEFAULT when opening the address book.
 +       */
 +      else if (IS_DEFAULT(Cs->cy))
 +      {
 +          TRACE("Strange use of CW_USEDEFAULT in nHeight\n");
 +          Cs->cy = (pMonitor->rcWork.bottom - pMonitor->rcWork.top) * 3 / 4;
 +      }
 +   }
 +   else
 +   {
 +      /* if CW_USEDEFAULT is set for non-overlapped windows, both values are set to zero */
 +      if(IS_DEFAULT(Cs->x))
 +      {
 +         Cs->x = 0;
 +         Cs->y = 0;
 +      }
 +      if(IS_DEFAULT(Cs->cx))
 +      {
 +         Cs->cx = 0;
 +         Cs->cy = 0;
 +      }
 +   }
 +
 +#undef IS_DEFAULT
 +}
 +
 +/* Allocates and initializes a window */
 +PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
 +                              PLARGE_STRING WindowName,
 +                              PCLS Class,
 +                              PWND ParentWindow,
 +                              PWND OwnerWindow,
 +                              PVOID acbiBuffer,
 +                              PDESKTOP pdeskCreated)
 +{
 +   PWND pWnd = NULL;
 +   HWND hWnd;
 +   PTHREADINFO pti = NULL;
-    /* Create system menu */
-    if ((Cs->style & WS_SYSMENU)) // && (dwStyle & WS_CAPTION) == WS_CAPTION)
-    {
-       SystemMenu = IntGetSystemMenu(pWnd, TRUE, TRUE);
-       if(SystemMenu)
-       {  //    spmenuSys
-          pWnd->SystemMenu = SystemMenu->head.h;
-          IntReleaseMenuObject(SystemMenu);
-       }
-    }
 +   BOOL MenuChanged;
 +   BOOL bUnicodeWindow;
 +
 +   pti = pdeskCreated ? gptiDesktopThread : GetW32ThreadInfo();
 +
 +   if (!(Cs->dwExStyle & WS_EX_LAYOUTRTL))
 +   {      // Need both here for wine win.c test_CreateWindow.
 +      //if (Cs->hwndParent && ParentWindow)
 +      if (ParentWindow) // It breaks more tests..... WIP.
 +      {
 +         if ( (Cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD &&
 +              ParentWindow->ExStyle & WS_EX_LAYOUTRTL &&
 +             !(ParentWindow->ExStyle & WS_EX_NOINHERITLAYOUT) )
 +            Cs->dwExStyle |= WS_EX_LAYOUTRTL;
 +      }
 +      else
 +      { /*
 +         * Note from MSDN <http://msdn.microsoft.com/en-us/library/aa913269.aspx>:
 +         *
 +         * Dialog boxes and message boxes do not inherit layout, so you must
 +         * set the layout explicitly.
 +         */
 +         if ( Class->fnid != FNID_DIALOG )
 +         {
 +            if (pti->ppi->dwLayout & LAYOUT_RTL)
 +            {
 +               Cs->dwExStyle |= WS_EX_LAYOUTRTL;
 +            }
 +         }
 +      }
 +   }
 +
 +   /* Automatically add WS_EX_WINDOWEDGE */
 +   if ((Cs->dwExStyle & WS_EX_DLGMODALFRAME) ||
 +         ((!(Cs->dwExStyle & WS_EX_STATICEDGE)) &&
 +         (Cs->style & (WS_DLGFRAME | WS_THICKFRAME))))
 +      Cs->dwExStyle |= WS_EX_WINDOWEDGE;
 +   else
 +      Cs->dwExStyle &= ~WS_EX_WINDOWEDGE;
 +
 +   /* Is it a unicode window? */
 +   bUnicodeWindow =!(Cs->dwExStyle & WS_EX_SETANSICREATOR);
 +   Cs->dwExStyle &= ~WS_EX_SETANSICREATOR;
 +
 +   /* Allocate the new window */
 +   pWnd = (PWND) UserCreateObject( gHandleTable,
 +                                   pdeskCreated ? pdeskCreated : pti->rpdesk,
 +                                   pti,
 +                                  (PHANDLE)&hWnd,
 +                                   TYPE_WINDOW,
 +                                   sizeof(WND) + Class->cbwndExtra);
 +
 +   if (!pWnd)
 +   {
 +      goto AllocError;
 +   }
 +
 +   TRACE("Created window object with handle %p\n", hWnd);
 +
 +   if (pdeskCreated && pdeskCreated->DesktopWindow == NULL )
 +   {  /* HACK: Helper for win32csr/desktopbg.c */
 +      /* If there is no desktop window yet, we must be creating it */
 +      TRACE("CreateWindow setting desktop.\n");
 +      pdeskCreated->DesktopWindow = hWnd;
 +      pdeskCreated->pDeskInfo->spwnd = pWnd;
 +   }
 +
 +   /*
 +    * Fill out the structure describing it.
 +    */
 +   /* Remember, pWnd->head is setup in object.c ... */
 +   pWnd->spwndParent = ParentWindow;
 +   pWnd->spwndOwner = OwnerWindow;
 +   pWnd->fnid = 0;
 +   pWnd->spwndLastActive = pWnd;
 +   pWnd->state2 |= WNDS2_WIN40COMPAT; // FIXME!!!
 +   pWnd->pcls = Class;
 +   pWnd->hModule = Cs->hInstance;
 +   pWnd->style = Cs->style & ~WS_VISIBLE;
 +   pWnd->ExStyle = Cs->dwExStyle;
 +   pWnd->cbwndExtra = pWnd->pcls->cbwndExtra;
 +   pWnd->pActCtx = acbiBuffer;
 +   pWnd->InternalPos.MaxPos.x  = pWnd->InternalPos.MaxPos.y  = -1;
 +   pWnd->InternalPos.IconPos.x = pWnd->InternalPos.IconPos.y = -1;
 +
 +   if (pWnd->spwndParent != NULL && Cs->hwndParent != 0)
 +   {
 +       pWnd->HideFocus = pWnd->spwndParent->HideFocus;
 +       pWnd->HideAccel = pWnd->spwndParent->HideAccel;
 +   }
 +
 +   pWnd->head.pti->cWindows++;
 +
 +   if (Class->hIcon && !Class->hIconSm)
 +   {
 +      Class->hIconSmIntern = co_IntCopyImage( Class->hIcon, IMAGE_ICON,
 +                                              UserGetSystemMetrics( SM_CXSMICON ),
 +                                              UserGetSystemMetrics( SM_CYSMICON ), 0 );
 +      TRACE("IntCreateWindow hIconSmIntern %p\n",Class->hIconSmIntern);
 +      Class->CSF_flags |= CSF_CACHEDSMICON;
 +   }
 +
 +   if (pWnd->pcls->CSF_flags & CSF_SERVERSIDEPROC)
 +      pWnd->state |= WNDS_SERVERSIDEWINDOWPROC;
 +
 + /* BugBoy Comments: Comment below say that System classes are always created
 +    as UNICODE. In windows, creating a window with the ANSI version of CreateWindow
 +    sets the window to ansi as verified by testing with IsUnicodeWindow API.
 +
 +    No where can I see in code or through testing does the window change back
 +    to ANSI after being created as UNICODE in ROS. I didnt do more testing to
 +    see what problems this would cause. */
 +
 +   // Set WndProc from Class.
 +   pWnd->lpfnWndProc  = pWnd->pcls->lpfnWndProc;
 +
 +   // GetWindowProc, test for non server side default classes and set WndProc.
 +    if ( pWnd->pcls->fnid <= FNID_GHOST && pWnd->pcls->fnid >= FNID_BUTTON )
 +    {
 +      if (bUnicodeWindow)
 +      {
 +         if (GETPFNCLIENTA(pWnd->pcls->fnid) == pWnd->lpfnWndProc)
 +            pWnd->lpfnWndProc = GETPFNCLIENTW(pWnd->pcls->fnid);
 +      }
 +      else
 +      {
 +         if (GETPFNCLIENTW(pWnd->pcls->fnid) == pWnd->lpfnWndProc)
 +            pWnd->lpfnWndProc = GETPFNCLIENTA(pWnd->pcls->fnid);
 +      }
 +    }
 +
 +   // If not an Unicode caller, set Ansi creator bit.
 +   if (!bUnicodeWindow) pWnd->state |= WNDS_ANSICREATOR;
 +
 +   // Clone Class Ansi/Unicode proc type.
 +   if (pWnd->pcls->CSF_flags & CSF_ANSIPROC)
 +   {
 +      pWnd->state |= WNDS_ANSIWINDOWPROC;
 +      pWnd->Unicode = FALSE;
 +   }
 +   else
 +   { /*
 +      * It seems there can be both an Ansi creator and Unicode Class Window
 +      * WndProc, unless the following overriding conditions occur:
 +      */
 +      if ( !bUnicodeWindow &&
 +          ( Class->atomClassName == gpsi->atomSysClass[ICLS_BUTTON]    ||
 +            Class->atomClassName == gpsi->atomSysClass[ICLS_COMBOBOX]  ||
 +            Class->atomClassName == gpsi->atomSysClass[ICLS_COMBOLBOX] ||
 +            Class->atomClassName == gpsi->atomSysClass[ICLS_DIALOG]    ||
 +            Class->atomClassName == gpsi->atomSysClass[ICLS_EDIT]      ||
 +            Class->atomClassName == gpsi->atomSysClass[ICLS_IME]       ||
 +            Class->atomClassName == gpsi->atomSysClass[ICLS_LISTBOX]   ||
 +            Class->atomClassName == gpsi->atomSysClass[ICLS_MDICLIENT] ||
 +            Class->atomClassName == gpsi->atomSysClass[ICLS_STATIC] ) )
 +      { // Override Class and set the window Ansi WndProc.
 +         pWnd->state |= WNDS_ANSIWINDOWPROC;
 +         pWnd->Unicode = FALSE;
 +      }
 +      else
 +      { // Set the window Unicode WndProc.
 +         pWnd->state &= ~WNDS_ANSIWINDOWPROC;
 +         pWnd->Unicode = TRUE;
 +      }
 +   }
 +
 +   /* BugBoy Comments: if the window being created is a edit control, ATOM 0xCxxx,
 +      then my testing shows that windows (2k and XP) creates a CallProc for it immediately
 +      Dont understand why it does this. */
 +   if (Class->atomClassName == gpsi->atomSysClass[ICLS_EDIT])
 +   {
 +      PCALLPROCDATA CallProc;
 +      CallProc = CreateCallProc(NULL, pWnd->lpfnWndProc, pWnd->Unicode , pWnd->head.pti->ppi);
 +
 +      if (!CallProc)
 +      {
 +         EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
 +         ERR("Warning: Unable to create CallProc for edit control. Control may not operate correctly! hwnd %p\n", hWnd);
 +      }
 +      else
 +      {
 +         UserAddCallProcToClass(pWnd->pcls, CallProc);
 +      }
 +   }
 +
 +   InitializeListHead(&pWnd->PropListHead);
 +
 +   if ( WindowName->Buffer != NULL && WindowName->Length > 0 )
 +   {
 +      pWnd->strName.Buffer = DesktopHeapAlloc(pWnd->head.rpdesk,
 +                                             WindowName->Length + sizeof(UNICODE_NULL));
 +      if (pWnd->strName.Buffer == NULL)
 +      {
 +          goto AllocError;
 +      }
 +
 +      RtlCopyMemory(pWnd->strName.Buffer, WindowName->Buffer, WindowName->Length);
 +      pWnd->strName.Buffer[WindowName->Length / sizeof(WCHAR)] = L'\0';
 +      pWnd->strName.Length = WindowName->Length;
 +      pWnd->strName.MaximumLength = WindowName->Length + sizeof(UNICODE_NULL);
 +   }
 +
 +   /* Correct the window style. */
 +   if ((pWnd->style & (WS_CHILD | WS_POPUP)) != WS_CHILD)
 +   {
 +      pWnd->style |= WS_CLIPSIBLINGS;
 +      if (!(pWnd->style & WS_POPUP))
 +      {
 +         pWnd->style |= WS_CAPTION;
 +      }
 +   }
 +
 +   /* WS_EX_WINDOWEDGE depends on some other styles */
 +   if (pWnd->ExStyle & WS_EX_DLGMODALFRAME)
 +       pWnd->ExStyle |= WS_EX_WINDOWEDGE;
 +   else if (pWnd->style & (WS_DLGFRAME | WS_THICKFRAME))
 +   {
 +       if (!((pWnd->ExStyle & WS_EX_STATICEDGE) &&
 +            (pWnd->style & (WS_CHILD | WS_POPUP))))
 +           pWnd->ExStyle |= WS_EX_WINDOWEDGE;
 +   }
 +    else
 +        pWnd->ExStyle &= ~WS_EX_WINDOWEDGE;
 +
 +   if (!(pWnd->style & (WS_CHILD | WS_POPUP)))
 +      pWnd->state |= WNDS_SENDSIZEMOVEMSGS;
 +
-        if (Cs->hMenu)
 +   /* Set the window menu */
 +   if ((Cs->style & (WS_CHILD | WS_POPUP)) != WS_CHILD)
 +   {
- /*
++      if (Cs->hMenu)
++      {
 +         IntSetMenu(pWnd, Cs->hMenu, &MenuChanged);
++      }
 +      else if (pWnd->pcls->lpszMenuName) // Take it from the parent.
 +      {
 +          UNICODE_STRING MenuName;
 +          HMENU hMenu;
 +
 +          if (IS_INTRESOURCE(pWnd->pcls->lpszMenuName))
 +          {
 +             MenuName.Length = 0;
 +             MenuName.MaximumLength = 0;
 +             MenuName.Buffer = pWnd->pcls->lpszMenuName;
 +          }
 +          else
 +          {
 +             RtlInitUnicodeString( &MenuName, pWnd->pcls->lpszMenuName);
 +          }
 +          hMenu = co_IntCallLoadMenu( pWnd->pcls->hModule, &MenuName);
 +          if (hMenu) IntSetMenu(pWnd, hMenu, &MenuChanged);
 +      }
 +   }
 +   else // Not a child
 +      pWnd->IDMenu = (UINT) Cs->hMenu;
 +
 +
 +   if ( ParentWindow &&
 +        ParentWindow != ParentWindow->head.rpdesk->spwndMessage &&
 +        ParentWindow != ParentWindow->head.rpdesk->pDeskInfo->spwnd )
 +   {
 +       PWND Owner = IntGetNonChildAncestor(ParentWindow);
 +
 +       if (!IntValidateOwnerDepth(pWnd, Owner))
 +       {
 +          EngSetLastError(ERROR_INVALID_PARAMETER);
 +          goto Error;
 +       }
 +       if ( pWnd->spwndOwner &&
 +            pWnd->spwndOwner->ExStyle & WS_EX_TOPMOST )
 +       {
 +          pWnd->ExStyle |= WS_EX_TOPMOST;
 +       }
 +       if ( pWnd->spwndOwner &&
 +            Class->atomClassName != gpsi->atomSysClass[ICLS_IME] &&
 +            pti != pWnd->spwndOwner->head.pti)
 +       {
 +          //ERR("CreateWindow Owner in.\n");
 +          UserAttachThreadInput(pti, pWnd->spwndOwner->head.pti, TRUE);
 +       }
 +   }
 +
 +   /* Insert the window into the thread's window list. */
 +   InsertTailList (&pti->WindowListHead, &pWnd->ThreadListEntry);
 +
 +   /* Handle "CS_CLASSDC", it is tested first. */
 +   if ( (pWnd->pcls->style & CS_CLASSDC) && !(pWnd->pcls->pdce) )
 +   {  /* One DCE per class to have CLASS. */
 +      pWnd->pcls->pdce = DceAllocDCE( pWnd, DCE_CLASS_DC );
 +   }
 +   else if ( pWnd->pcls->style & CS_OWNDC)
 +   {  /* Allocate a DCE for this window. */
 +      DceAllocDCE(pWnd, DCE_WINDOW_DC);
 +   }
 +
 +   return pWnd;
 +
 +AllocError:
 +   ERR("IntCreateWindow Allocation Error.\n");
 +   SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
 +Error:
 +   if(pWnd)
 +      UserDereferenceObject(pWnd);
 +   return NULL;
 +}
 +
 +/*
 + * @implemented
 + */
 +PWND FASTCALL
 +co_UserCreateWindowEx(CREATESTRUCTW* Cs,
 +                     PUNICODE_STRING ClassName,
 +                     PLARGE_STRING WindowName,
 +                     PVOID acbiBuffer)
 +{
 +   ULONG style;
 +   PWND Window = NULL, ParentWindow = NULL, OwnerWindow;
 +   HWND hWnd, hWndParent, hWndOwner, hwndInsertAfter;
 +   PWINSTATION_OBJECT WinSta;
 +   PCLS Class = NULL;
 +   SIZE Size;
 +   POINT MaxSize, MaxPos, MinTrack, MaxTrack;
 +   CBT_CREATEWNDW * pCbtCreate;
 +   LRESULT Result;
 +   USER_REFERENCE_ENTRY ParentRef, Ref;
 +   PTHREADINFO pti;
 +   DWORD dwShowMode = SW_SHOW;
 +   CREATESTRUCTW *pCsw = NULL;
 +   PVOID pszClass = NULL, pszName = NULL;
 +   PWND ret = NULL;
 +
 +   /* Get the current window station and reference it */
 +   pti = GetW32ThreadInfo();
 +   if (pti == NULL || pti->rpdesk == NULL)
 +   {
 +      ERR("Thread is not attached to a desktop! Cannot create window!\n");
 +      return NULL; // There is nothing to cleanup.
 +   }
 +   WinSta = pti->rpdesk->rpwinstaParent;
 +   ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
 +
 +   pCsw = NULL;
 +   pCbtCreate = NULL;
 +
 +   /* Get the class and reference it */
 +   Class = IntGetAndReferenceClass(ClassName, Cs->hInstance, FALSE);
 +   if(!Class)
 +   {
 +       ERR("Failed to find class %wZ\n", ClassName);
 +       goto cleanup;
 +   }
 +
 +   /* Now find the parent and the owner window */
 +   hWndParent = pti->rpdesk->pDeskInfo->spwnd->head.h;
 +   hWndOwner = NULL;
 +
 +    if (Cs->hwndParent == HWND_MESSAGE)
 +    {
 +        Cs->hwndParent = hWndParent = pti->rpdesk->spwndMessage->head.h;
 +    }
 +    else if (Cs->hwndParent)
 +    {
 +        if ((Cs->style & (WS_CHILD|WS_POPUP)) != WS_CHILD)
 +            hWndOwner = Cs->hwndParent;
 +        else
 +            hWndParent = Cs->hwndParent;
 +    }
 +    else if ((Cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
 +    {
 +         ERR("Cannot create a child window without a parrent!\n");
 +         EngSetLastError(ERROR_TLW_WITH_WSCHILD);
 +         goto cleanup;  /* WS_CHILD needs a parent, but WS_POPUP doesn't */
 +    }
 +
 +    ParentWindow = hWndParent ? UserGetWindowObject(hWndParent): NULL;
 +    OwnerWindow = hWndOwner ? UserGetWindowObject(hWndOwner): NULL;
 +
 +    /* FIXME: Is this correct? */
 +    if(OwnerWindow)
 +        OwnerWindow = UserGetAncestor(OwnerWindow, GA_ROOT);
 +
 +   /* Fix the position and the size of the window */
 +   if (ParentWindow)
 +   {
 +