--- /dev/null
- #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, ¶ms);
+ 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, ¶ms);
+ 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;
+}
--- /dev/null
+/*
+ * 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, ¶ms, 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, ¶ms, 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);
+}
--- /dev/null
- 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)
+ {
+