itbar.cpp
上传用户:xhy777
上传日期:2007-02-14
资源大小:24088k
文件大小:318k
源码类别:

系统编程

开发平台:

Visual C++

  1. #include "priv.h"
  2. #include "sccls.h"
  3. #include "itbdrop.h"
  4. #include <urlhist.h>
  5. #include "autocomp.h"
  6. #include "itbar.h"
  7. #include "address.h"
  8. #include "isfband.h"
  9. #include <winbase.h>
  10. #include "qlink.h"
  11. #include "inpobj.h"
  12. #include "basebar.h"
  13. #include "shbrowse.h"
  14. #include "menuisf.h"
  15. #include "menuband.h"
  16. #include "brand.h"
  17. #include "resource.h"
  18. #include "theater.h"
  19. #include "browmenu.h"
  20. #include "util.h"
  21. #include "tbmenu.h"
  22. #include "apithk.h"
  23. #include "shbrows2.h"
  24. #include "stdenum.h"
  25. #include "iehelpid.h"
  26. #define WANT_CBANDSITE_CLASS
  27. #include "bandsite.h"
  28. #include "schedule.h"
  29. #include "uemapp.h"
  30. #include "mluisupp.h"
  31. #ifdef UNIX
  32. extern "C"  const GUID  CLSID_MsgBand;
  33. #endif
  34. // The edit button hackery needs to be moved to shdocvw.  This define identifies this code.
  35. #define EDIT_HACK
  36. // Offset of the comctl32 default bitmaps
  37. #define OFFSET_HIST             (MAX_TB_BUTTONS - 1 + 0)   // 15
  38. #define OFFSET_STD              (MAX_TB_BUTTONS - 1 + 6)   // 21
  39. #define OFFSET_VIEW             (MAX_TB_BUTTONS - 1 + 21)  // 36
  40. // This is the offset in the toolbar for the Shell glyphs and the Shell toolbar labels
  41. #define SHELLTOOLBAR_OFFSET     (MAX_TB_BUTTONS - 1 + 1)  // 16
  42. #define FONTGLYPH_OFFSET        (MAX_TB_BUTTONS - 1 + 38) // 53
  43. #define BRIEFCASEGLYPH_OFFSET   (MAX_TB_BUTTONS - 1 + 34) // 49
  44. #define RNAUIGLYPH_OFFSET       (MAX_TB_BUTTONS - 1 + 36) // 51
  45. #define WEBCHECKGLYPH_OFFSET    (MAX_TB_BUTTONS - 1 + 42) // 57
  46. #ifdef EDIT_HACK
  47. #define EDITGLYPH_OFFSET        (9)
  48. #endif
  49. #define IDT_UPDATETOOLBAR       0x1
  50. #define TIMEOUT_UPDATETOOLBAR   400
  51. const GUID CLSID_Separator = { 0x67077B90L, 0x4F9D, 0x11D0, 0xB8, 0x84, 0x00, 0xAA, 0x00, 0xB6, 0x01, 0x04 };
  52. extern HRESULT VariantClearLazy(VARIANTARG *pvarg);
  53. // How many CT_TABLE structures to allocated at a time.
  54. #define TBBMPLIST_CHUNK     5
  55. #define MAX_EXTERNAL_BAND_NAME_LEN 64
  56. #define MAX_TB_COMPRESSED_WIDTH 42
  57. // 16 is added to the the MAX_TB defines. This is added through the strings
  58. // in the RC file. This is done so that the localization folks can increase
  59. // or decrease the width of the toolbar buttons
  60. #define MAX_TB_WIDTH_LORES      38
  61. #define MAX_TB_WIDTH_HIRES      60
  62. // Dimensions of Coolbar Glyphs ..
  63. #define TB_SMBMP_CX               16
  64. #define TB_SMBMP_CY               16
  65. #define TB_BMP_CX               20
  66. #define TB_BMP_CY               20
  67. #define CX_SEPARATOR    6     // we override toolbar control's default separator width of 8
  68. #define DM_TBSITE   0
  69. #define DM_TBCMD    0
  70. #define DM_TBREF    TF_SHDREF
  71. #define DM_LAYOUT   0
  72. #define DM_ITBAR    0
  73. #define TF_TBCUST   0x01000000
  74. #if CBIDX_LAST != 5
  75. #error Expected CBIDX_LAST to have value of 5
  76. #endif
  77. #if (FCIDM_EXTERNALBANDS_LAST - FCIDM_EXTERNALBANDS_FIRST + 1) < MAXEXTERNALBANDS
  78. #error Insufficient range for FCIDM_EXTERNALBANDS_FIRST to FCIDM_EXTERNALBANDS_LAST
  79. #endif
  80. __inline UINT EXTERNALBAND_VBF_BIT(UINT uiBandExt)
  81. {
  82.     ASSERT(uiBandExt < MAXEXTERNALBANDS);
  83.     // Formula: take 1, shift left by uiBandExt + 16
  84.     //      => a bit in range (0x80000000, 0x00010000)
  85.     UINT uBit = 1 << (uiBandExt + 16);
  86.     ASSERT(uBit & VBF_EXTERNALBANDS);
  87.     return uBit;
  88. }
  89. __inline BOOL IS_EXTERNALBAND(int idBand)
  90. {
  91.     return (InRange(idBand, CBIDX_EXTERNALFIRST, CBIDX_EXTERNALLAST));
  92. }
  93. __inline int MAP_TO_EXTERNAL(int idBand)
  94. {
  95.     ASSERT(IS_EXTERNALBAND(idBand));
  96.     // CBIDX_LAST is one-based, mapping is zero-based
  97.     return (idBand - (1 + CBIDX_LAST));
  98. }
  99. // maximum number of menu items in the context menus for back and forward.
  100. #define MAX_NAV_MENUITEMS               9
  101. #define DEFAULT_SEARCH_GUID    SRCID_SFileSearch //SRCID_SWebSearch
  102. #define SZ_PROP_CUSTDLG     TEXT("Itbar custom dialog hwnd")
  103. #define REG_KEY_BANDSTATE  TEXT("Software\Microsoft\Internet Explorer\Toolbar")
  104. DWORD DoNetConnect(HWND hwnd);
  105. DWORD DoNetDisconnect(HWND hwnd);
  106. void _LoadToolbarGlyphs(HWND hwnd, IMLCACHE *pimlCache, int cx, int idBmp);
  107. BOOL _UseSmallIcons();
  108. typedef struct tagTBBMP_LIST
  109. {
  110.     HINSTANCE hInst;
  111.     UINT_PTR  uiResID;
  112.     UINT  uiOffset;
  113.     BITBOOL  fNormal:1;
  114.     BITBOOL  fHot:1;
  115.     BITBOOL  fDisabled:1;
  116. } TBBMP_LIST;
  117. typedef struct tagCMDMAP
  118. {
  119.     GUID    guidButtonGroup;
  120.     UINT    nCmdID;
  121.     LPARAM lParam;  // app's data
  122. } CMDMAP;
  123. typedef struct tagCMDMAPCUSTOMIZE
  124. {
  125.     TBBUTTON btn;
  126.     CMDMAP cm;
  127. } CMDMAPCUSTOMIZE;
  128. typedef struct {
  129.     // the IOleCommandTarget info:
  130.     GUID guid;
  131.     UINT nCmdID;
  132.     UINT fButtonState;
  133. } BUTTONSAVEINFO;
  134. #define TBSI_VERSION            7
  135. typedef struct {
  136.     int cVersion;
  137. } TOOLBARSAVEINFO;
  138. typedef struct {
  139.     HDSA hdsa;
  140.     BITBOOL fAdjust:1;
  141.     BITBOOL fDirty:1;
  142. } CUSTOMIZEINFO, *LPCUSTOMIZEINFO;
  143. //Current latest version.
  144. #define CBS_VERSION             17
  145. // NOTE: Be very careful changing COOLBARSAVE because _LoadUpgradeSettings makes
  146. // assumptions about the layout of the structure.  To avoid breaking that
  147. // upgrade code, be sure you:
  148. //
  149. //  - don't change the order of existing members
  150. //  - always add new members to the end of the structure.
  151. //  - update _LoadUpgradeSettings if appropriate
  152. //
  153. typedef struct tagCOOLBARSAVE
  154. {
  155.     UINT        cbVer;
  156.     UINT        uiMaxTBWidth;
  157.     UINT        uiMaxQLWidth;
  158. #ifdef UNIX
  159.     BITBOOL     fUnUsed : 28;       // unused
  160. #endif
  161.     BITBOOL     fVertical : 1;      // The bar is oriented vertically
  162.     BITBOOL     fNoText :1;         // "NoText"
  163.     BITBOOL     fList : 1;          // toolbar is TBSTYLE_LIST (text on right) + TBSTYLE_EX_MIXEDBUTTONS
  164.     BITBOOL     fAutoHide : 1;      // Auto hide toolbar in theater mode
  165.     BITBOOL     fStatusBar : 1;     // Status bar in theater mode
  166.     BITBOOL     fSaveInShellIntegrationMode : 1;     // Did we save in shell integration mode?
  167.     UINT        uiVisible;          // "Visible bands"
  168.     UINT        cyRebar;
  169.     BANDSAVE    bs[CBANDSMAX];
  170.     CLSID       aclsidExternalBands[ MAXEXTERNALBANDS ];  // Check classid
  171.     CLSID       clsidVerticalBar;       //clsid of bar persisted within vertical band
  172.     CLSID       clsidHorizontalBar;
  173. } COOLBARSAVE, *LPCOOLBARSAVE;
  174. //Flags for dwFlags passed to UpdateToolbarDisplay()
  175. #define UTD_TEXTLABEL  0x00000001
  176. #define UTD_VISIBLE    0x00000002
  177. static const TCHAR c_szRegKeyCoolbar[] = TSZIEPATH TEXT("\Toolbar");
  178. static const TCHAR c_szValueTheater[]  = TEXT("Theater");
  179. typedef struct tagFOLDERSEARCHITEM
  180. {
  181.     UINT    idCmd;
  182.     GUID    guidSearch;
  183.     int     iIcon;
  184.     WCHAR   wszUrl[MAX_URL_STRING];
  185.     WCHAR   wszName[80];           // friendly name
  186. }FOLDERSEARCHITEM, *LPFOLDERSEARCHITEM;
  187. BOOL NavigateSearchBar(IWebBrowser2 *pwb2, LPCWSTR pwszUrl);
  188. BOOL _GetSearchHKEY(LPGUID lpguidSearch, HKEY *phkey);
  189. #define REG_SZ_STATIC       TEXT("Software\Microsoft\Windows\CurrentVersion\Explorer\FindExtensions\Static")
  190. #define REG_SZ_SEARCH_GUID  TEXT("SearchGUID")
  191. #define REG_SZ_SEARCH_URL   TEXT("SearchGUID\Url")
  192. #define VIEW_OFFSET (SHELLGLYPHS_OFFSET + HIST_MAX + STD_MAX)
  193. #define VIEW_ALLFOLDERS  (VIEW_NETCONNECT + 14)
  194. static const TBBUTTON    c_tbExplorer[] =
  195. {
  196.     // override default toolbar width for separators; iBitmap member of
  197.     // TBBUTTON struct is a union of bitmap index & separator width
  198.     { 0, TBIDM_BACK  ,      0,               BTNS_DROPDOWN | BTNS_SHOWTEXT, {0,0}, 0, 0 },
  199.     { 1, TBIDM_FORWARD,     0,               BTNS_DROPDOWN, {0,0}, 0, 1 },
  200.     { 2, TBIDM_STOPDOWNLOAD, TBSTATE_ENABLED, BTNS_BUTTON, {0,0}, 0, 2 },
  201.     { 3, TBIDM_REFRESH,      TBSTATE_ENABLED, BTNS_BUTTON, {0,0}, 0, 3 },
  202.     { 4, TBIDM_HOME,         TBSTATE_ENABLED, BTNS_BUTTON, {0,0}, 0, 4 },
  203.     { VIEW_PARENTFOLDER + VIEW_OFFSET,    TBIDM_PREVIOUSFOLDER,   TBSTATE_ENABLED, BTNS_BUTTON, {0,0}, 0, VIEW_PARENTFOLDER + VIEW_OFFSET },
  204.     { VIEW_NETCONNECT + VIEW_OFFSET,      TBIDM_CONNECT,          TBSTATE_ENABLED, BTNS_BUTTON, {0,0}, 0, VIEW_NETCONNECT + VIEW_OFFSET },
  205.     { VIEW_NETDISCONNECT + VIEW_OFFSET,   TBIDM_DISCONNECT,       TBSTATE_ENABLED, BTNS_BUTTON, {0,0}, 0, VIEW_NETDISCONNECT + VIEW_OFFSET },
  206.     { CX_SEPARATOR, 0,          TBSTATE_ENABLED, BTNS_SEP, {0,0}, 0, -1 },
  207.     { 5, TBIDM_SEARCH,       TBSTATE_ENABLED, BTNS_SHOWTEXT, {0,0}, 0, 5 },
  208.     { VIEW_ALLFOLDERS + VIEW_OFFSET,    TBIDM_ALLFOLDERS,         TBSTATE_ENABLED, BTNS_SHOWTEXT, {0,0}, 0, VIEW_ALLFOLDERS + VIEW_OFFSET },
  209.     { 6, TBIDM_FAVORITES,       TBSTATE_ENABLED,  BTNS_SHOWTEXT, {0,0}, 0, 6 },
  210.     { 12, TBIDM_HISTORY,        TBSTATE_ENABLED, BTNS_SHOWTEXT, {0,0}, 0, 12},
  211.     { CX_SEPARATOR,    0,       TBSTATE_ENABLED, BTNS_SEP, {0,0}, 0, -1 },
  212. #ifndef DISABLE_FULLSCREEN
  213.     // IE UNIX : No theater mode for beta1
  214.     { 14, TBIDM_THEATER,         TBSTATE_ENABLED, BTNS_BUTTON, {0,0}, 0, 14 },
  215. #endif
  216. };
  217. static const BROWSER_RESTRICTIONS c_rest[] = {
  218.     REST_BTN_BACK,
  219.     REST_BTN_FORWARD,
  220.     REST_BTN_STOPDOWNLOAD,
  221.     REST_BTN_REFRESH,
  222.     REST_BTN_HOME,
  223.     REST_BROWSER_NONE,      // no policy for up
  224.     REST_BROWSER_NONE,      // no policy for map drive
  225.     REST_BROWSER_NONE,      // no policy for disconnect drive
  226.     REST_BROWSER_NONE,      // separator
  227.     REST_BTN_SEARCH,
  228.     REST_BTN_ALLFOLDERS,
  229.     REST_BTN_FAVORITES,
  230.     REST_BTN_HISTORY,
  231.     REST_BROWSER_NONE,      // separator
  232. #ifndef DISABLE_FULLSCREEN
  233.     REST_BTN_THEATER,
  234. #endif
  235. };
  236. #define SUPERCLASS CBaseBar
  237. class CInternetToolbar :
  238.    public CBaseBar,
  239.    public IDockingWindow,
  240.    public IObjectWithSite,  // *not* CObjectWithSite (want _ptbSite)
  241.    public IExplorerToolbar,
  242.    public DWebBrowserEvents,
  243.    public IPersistStreamInit,
  244.    public IShellChangeNotify,
  245.    public ISearchItems
  246. {
  247. public:
  248.     // *** IUnknown ***
  249.     virtual STDMETHODIMP QueryInterface(REFIID riid, void ** ppvObj);
  250.     virtual STDMETHODIMP_(ULONG) AddRef(void) { return SUPERCLASS::AddRef(); };
  251.     virtual STDMETHODIMP_(ULONG) Release(void){ return SUPERCLASS::Release(); };
  252.     // *** IOleWindow methods ***
  253.     virtual STDMETHODIMP GetWindow(HWND * lphwnd) { return SUPERCLASS::GetWindow(lphwnd);};
  254.     virtual STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode) {return SUPERCLASS::ContextSensitiveHelp(fEnterMode);};
  255.     // *** IDockingWindow methods ***
  256.     virtual STDMETHODIMP ShowDW(BOOL fShow);
  257.     virtual STDMETHODIMP CloseDW(DWORD dwReserved);
  258.     virtual STDMETHODIMP ResizeBorderDW(LPCRECT prcBorder, IUnknown* punkToolbarSite, BOOL fReserved);
  259.     // *** IObjectWithSite methods ***
  260.     virtual STDMETHODIMP SetSite(IUnknown* punkSite);
  261.     // BUGBUG is E_NOTIMPL ok?
  262.     virtual STDMETHODIMP GetSite(REFIID riid, void** ppvSite) { ASSERT(0); return E_NOTIMPL; };
  263.     // *** IInputObjectSite methods ***
  264.     virtual STDMETHODIMP OnFocusChangeIS(IUnknown *punk, BOOL fSetFocus);
  265.     // *** IInputObject methods ***
  266.     virtual STDMETHODIMP TranslateAcceleratorIO(LPMSG lpMsg);
  267.     // *** IServiceProvider methods ***
  268.     virtual STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, LPVOID* ppvObj);
  269.     // *** IExplorerToolbar method ***
  270.     virtual STDMETHODIMP SetCommandTarget(IUnknown* punkCmdTarget, const GUID* pguidButtonGroup, DWORD dwFlags);
  271.     virtual STDMETHODIMP AddStdBrowserButtons(void);
  272.     virtual STDMETHODIMP AddButtons(const GUID* pguidButtonGroup, UINT nButtons, const TBBUTTON * lpButtons);
  273.     virtual STDMETHODIMP AddString(const GUID * pguidButtonGroup, HINSTANCE hInst, UINT_PTR uiResID, LONG_PTR *pOffset);
  274.     virtual STDMETHODIMP GetButton(const GUID* pguidButtonGroup, UINT uiCommand, LPTBBUTTON lpButton);
  275.     virtual STDMETHODIMP GetState(const GUID* pguidButtonGroup, UINT uiCommand, UINT * pfState);
  276.     virtual STDMETHODIMP SetState(const GUID* pguidButtonGroup, UINT uiCommand, UINT fState);
  277.     virtual STDMETHODIMP AddBitmap(const GUID * pguidButtonGroup, UINT uiBMPType, UINT uiCount, TBADDBITMAP * ptb,
  278.                                    LRESULT * pOffset, COLORREF rgbMask);
  279.     virtual STDMETHODIMP GetBitmapSize(UINT * uiID);
  280.     virtual STDMETHODIMP SendToolbarMsg(const GUID * pguidButtonGroup, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT * plRes);
  281.     virtual STDMETHODIMP SetImageList( const GUID* pguidCmdGroup, HIMAGELIST himlNormal, HIMAGELIST himlHot, HIMAGELIST himlDisabled);
  282.     virtual STDMETHODIMP ModifyButton( const GUID * pguidButtonGroup, UINT uiCommand, LPTBBUTTON lpButton);
  283.     // IOleCommandTarget
  284.     virtual STDMETHODIMP QueryStatus(const GUID *pguidCmdGroup,
  285.                                      ULONG cCmds, OLECMD rgCmds[], OLECMDTEXT *pcmdtext);
  286.     virtual STDMETHODIMP Exec(const GUID *pguidCmdGroup,
  287.                               DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn,
  288.                               VARIANTARG *pvarargOut);
  289.     // IPersistStreamInit
  290.     STDMETHOD(GetClassID)(GUID *pguid);
  291.     STDMETHOD(Load)(IStream *pStm);
  292.     STDMETHOD(Save)(IStream *pStm, BOOL fClearDirty);
  293.     STDMETHOD(InitNew)(void);
  294.     STDMETHOD(IsDirty)(void);
  295.     STDMETHOD(GetSizeMax)(ULARGE_INTEGER  *pcbSize);
  296.     /* IDispatch methods */
  297.     virtual STDMETHODIMP GetTypeInfoCount(UINT *pctinfo);
  298.     virtual STDMETHODIMP GetTypeInfo(UINT itinfo,LCID lcid,ITypeInfo **pptinfo);
  299.     virtual STDMETHODIMP GetIDsOfNames(REFIID riid,OLECHAR **rgszNames,UINT cNames,
  300.                                        LCID lcid, DISPID * rgdispid);
  301.     virtual STDMETHODIMP Invoke(DISPID dispidMember,REFIID riid,LCID lcid,WORD wFlags,
  302.                                 DISPPARAMS * pdispparams, VARIANT * pvarResult,
  303.                                 EXCEPINFO * pexcepinfo,UINT * puArgErr);
  304.     // IShellChangeNotify
  305.     virtual STDMETHODIMP OnChange(LONG lEvent, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
  306.     // CBaseBar overrides
  307.     virtual LRESULT v_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  308.     // *** ISearchItems methods ***
  309.     virtual STDMETHODIMP GetDefaultSearchUrl(LPWSTR pwzUrl, UINT cch);
  310.     CInternetToolbar();
  311. protected:
  312.     virtual ~CInternetToolbar();
  313.     static LRESULT CALLBACK SizableWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  314.     void _OnCommand(WPARAM wParam, LPARAM lParam);
  315.     BOOL _SendToToolband(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* plres);
  316.     LRESULT _OnNotify(LPNMHDR pnmh);
  317.     void _OnTooltipNeeded(LPTOOLTIPTEXT pnmTT);
  318.     void _QueryStatusTip(IOleCommandTarget *pct, LPTOOLTIPTEXT pnmTT, UINT uiCmd, const GUID* pguid);
  319.     BOOL _UpEnabled();
  320.     void _UpdateCommonButton(int iCmd, UINT nCmdID);
  321.     void _UpdateToolbar(BOOL fForce);
  322.     void _UpdateToolbarNow();
  323.     void _UpdateGroup(const GUID *pguidCmdGroup, int cnt, OLECMD rgcmds[], const GUID* pguidButton, const int buttonsInternal[]);
  324.     void _CSHSetStatusBar(BOOL fOn);
  325.     void _StartDownload();
  326.     void _StopDownload(BOOL fClosing);
  327.     void _SendDocCommand(UINT idCmd);
  328.     BOOL _CompressBands(BOOL fCompress, UINT uRowsNew, BOOL fForceUpdate);
  329.     void _TrackSliding(int x, int y);
  330.     HRESULT _DoNavigateA(LPSTR pszURL,int iNewSelection);
  331.     HRESULT _DoNavigateW(LPWSTR pwzURL,int iNewSelection);
  332.     HRESULT _DoNavigate(BSTR bstrURL,int iNewSelection);
  333.     void _Unadvise(void);
  334.     LRESULT _OnBeginDrag(NMREBAR* pnm);
  335.     void _InsertURL(LPTSTR pszURL);
  336.     void _ShowContextMenu(HWND hwnd, LPARAM lParam, LPRECT prcExclude);
  337.     BOOL _ShowBackForwardMenu(BOOL fForward, POINT pt, LPRECT prcExclude);
  338.     // search helper methods
  339.     BOOL _GetFolderSearchData();
  340.     void _SetSearchStuff();
  341.     BOOL _GetSearchUrl(LPWSTR pwszUrl, DWORD cch);
  342.     HRESULT _GetFolderSearches(IFolderSearches **ppfs);
  343.     void _ReloadButtons();
  344.     void _UpdateToolsStyle(BOOL fList);
  345.     void _InitBitmapDSA();
  346.     void _InitForScreenSize();
  347.     void _InitToolbar();
  348.     BOOL _FoldersButtonAvailable();
  349.     void _AdminMarkDefaultButtons(PTBBUTTON ptbb, UINT cButtons);
  350.     void _MarkDefaultButtons(PTBBUTTON ptbb, UINT cButtons);
  351.     void _AddCommonButtons();
  352.     HRESULT _CreateBands();
  353.     BOOL    _ShowBands(UINT fVisible);
  354.     HRESULT _ShowTools(PBANDSAVE pbs);
  355.     HRESULT _ShowAddressBand(PBANDSAVE pbs);
  356.     HRESULT _ShowExternalBand(PBANDSAVE pbs, int idBand );
  357.     HRESULT _ShowLinks(PBANDSAVE pbs);
  358.     HRESULT _ShowBrand(PBANDSAVE pbs);
  359.     HRESULT _ShowMenu(PBANDSAVE pbs);
  360.     void _ShowBandCommon(PBANDSAVE pbs, LPBANDITEMDATA pbid, BOOL fShow);
  361.     void _EnsureAllBandsShown();
  362.     HRESULT _GetMinRowHeight();
  363.     HBITMAP _LoadBackBmp(LPTSTR * ppszBitmap, BMPCACHE * pbmpCache, BOOL fInternet);
  364.     HBITMAP _LoadBackBitmap();
  365.     void    _SetBackground();
  366.     void    _CommonHandleFileSysChange(LONG lEvent, LPITEMIDLIST* ppidl);
  367.     LPITEMIDLIST _GetCurrentPidl(void);
  368.     int     _ConvertHwndToID(HWND hwnd);
  369.     HRESULT _GetPersistedBand(const CLSID clsid, REFIID riid, void ** ppiface);
  370.     // Multiple command target
  371.     LRESULT _AddBitmapFromForeignModule(UINT uiGetMSG, UINT uiSetMSG, UINT uiCount, HINSTANCE hinst,
  372.                                         UINT_PTR nID, COLORREF rgbMask);
  373.     HRESULT _LoadDefaultSettings(void);
  374.     HRESULT _LoadUpgradeSettings(ULONG cbRead);
  375.     HRESULT _LoadDefaultWidths(void);
  376.     void _TryLoadIE3Settings();
  377.     HRESULT _UpdateToolbarDisplay(DWORD dwFlags, UINT uVisibleBands, BOOL fNoText, BOOL fPersist);
  378.     void _UpdateBrandSize();
  379.     void _ShowVisible(DWORD dwVisible, BOOL fPersist);
  380.     void _BuildSaveStruct(COOLBARSAVE* pcs);
  381.     void _RestoreSaveStruct(COOLBARSAVE* pcs);
  382.     void _GetVisibleBrowserBar(UINT idBar, CLSID *pclsidOut);
  383.     LPBANDITEMDATA _AddNewBand(IDeskBand* pdb, DWORD dwID);
  384.     void _TheaterModeLayout(BOOL fEnter);
  385.     HBITMAP          _bmpBack; // this is the state we think the itbar is in
  386.     static BMPCACHE  s_bmpBackShell; // this is the state of the shell bmp cache
  387.     static BMPCACHE  s_bmpBackInternet; // this is the state of the internet bmp cache
  388.     static IMLCACHE  s_imlTBGlyphs;
  389.     HWND            _hwndMenu;
  390.     HWND            _hwndAddressBand;
  391.     IDockingWindowSite* _ptbsite;
  392.     IOleCommandTarget*  _ptbsitect;
  393.     IBrowserService2*   _pbs2;
  394.     IServiceProvider*   _psp;
  395.     IBandProxy *        _pbp;
  396.     BITBOOL            _fCreatedBandProxy:1;
  397.     BITBOOL            _fBackEnabled:1;
  398.     BITBOOL            _fForwardEnabled:1;
  399.     BITBOOL            _fEditEnabled:1;
  400.     BITBOOL            _fShow:1;
  401.     BITBOOL            _fAnimating:1;
  402.     BITBOOL            _fCompressed:1;
  403.     BITBOOL            _fUserNavigated :1;
  404.     BITBOOL            _fAutoCompInitialized :1;
  405.     BITBOOL            _fDirty:1;
  406.     BITBOOL            _fUsingDefaultBands:1;
  407.     BITBOOL            _fTransitionToHTML:1;
  408.     BITBOOL            _fInitialPidlIsWeb:1;
  409.     BITBOOL            _fTheater: 1; // are we in theater mode?  claim no border space
  410.     BITBOOL            _fAutoHide :1;
  411.     BITBOOL            _fRebarDragging :1;
  412.     BITBOOL            _fShellView:1;   // are we in shell view or web view?
  413.     BITBOOL            _fNoShowMenu:1;    // can show menu band?
  414.     BITBOOL            _fUpdateToolbarTimer:1;
  415.     BITBOOL            _fNeedUpdateToolbar:1;
  416.     BITBOOL            _fNavigateComplete:1;
  417.     BITBOOL            _fLoading:1;     // are we still loading the bar?
  418.     BITBOOL            _fDestroyed:1;   // Did we destroy our member varibles and are shutting down? If so, don't use the varibles. (Stress bug w/messages coming in)
  419.     UINT            _nVisibleBands;     // bitmask of which bands are visible: VBF_*
  420.     IWebBrowser2*   _pdie;
  421.     DWORD           _dwcpCookie;        // DIID_DWebBrowserEvents2
  422.     int             _xCapture;
  423.     int             _yCapture;
  424.     // for multiple command target support
  425.     HDSA            _hdsaTBBMPs;
  426.     UINT            _uiMaxTBWidth;
  427.     UINT            _uiTBTextRows;
  428.     UINT            _uiTBDefaultTextRows;
  429.     // search stuff
  430.     HDPA            _hdpaFSI; // folder search items
  431.     GUID            _guidCurrentSearch;
  432.     GUID            _guidDefaultSearch;
  433.     COOLBARSAVE     _cs;             //Coolbar layout info from registry!
  434.     struct EXTERNALBANDINFO {
  435.         CLSID       clsid;          // CLSID of the band
  436.         LPWSTR      pwszName;       // Band name
  437.         LPWSTR      pwszHelp;       // Band help text
  438.     };
  439.     EXTERNALBANDINFO _rgebi[ MAXEXTERNALBANDS ];
  440.     void _LoadExternalBandInfo();
  441.     TBBUTTON _tbExplorer[ARRAYSIZE(c_tbExplorer)];
  442.     int      _iButtons;
  443. #ifdef EDIT_HACK
  444.     // Variables for customizing the edit button glyph
  445.     HIMAGELIST      _himlEdit;          // Monochrome Image list for the edit button
  446.     HIMAGELIST      _himlEditHot;       // Hot image list for edit button
  447.     int             _iEditIcon;         // index of current edit icon
  448.     // Functions for managing a custom edit glyph
  449.     void _InitEditButtonStyle();
  450.     void _SetEditGlyph(int iIcon);
  451.     void _RefreshEditGlyph();
  452.     void _UpdateEditButton();
  453.     static HIMAGELIST _CreateGrayScaleImagelist(HBITMAP hbmpImage, HBITMAP hbmpMask);
  454.     static BSTR _GetEditProgID(IHTMLDocument2* pHTMLDocument);
  455.     //
  456.     // We can have multiple edit verbs associated with a document.  The following class
  457.     // maintains a list of verbs.
  458.     //
  459.     #define FCIDM_EDITFIRST  2000
  460.     #define FCIDM_EDITLAST   2100
  461.     #define SZ_EDITVERB_PROP  TEXT("CEditVerb_This")
  462.     #define IL_EDITBUTTON 2     // Index of image list used for the edit button
  463.     #define IL_SEARCHBUTTON 3   //                   ||             search button
  464.     // MSAA Menu Info declarations.
  465.     // These will eventually be incorporated into oleacc.h - but for the
  466.     // moment, we declare them privately...
  467.     #define MSAA_MENU_SIG  0xAA0DF00DL
  468.     class CEditVerb
  469.     {
  470.     public:
  471.         CEditVerb();
  472.         ~CEditVerb();
  473.         // Functions for managing the verbs
  474.         BOOL Add(LPTSTR pszProgID);
  475.         UINT GetSize() { return _nElements; }
  476.         void RemoveAll();
  477.         // Functions to access the default edit verb
  478.         int   GetIcon() { return (_nElements && _pVerb[_nDefault].fShowIcon) ? _GetVerb(_nDefault).iIcon : -1; }
  479.         BOOL  GetToolTip(LPTSTR pszToolTip, UINT cchMax, BOOL fStripAmpersands = TRUE);
  480.         BOOL  GetMenuText(LPTSTR pszText, UINT cchMax) { return GetToolTip(pszText, cchMax, FALSE); }
  481.         void  Edit(LPCTSTR pszUrl) { _Edit(pszUrl, _nDefault); }
  482.         // Pop-up menu
  483.         BOOL ShowEditMenu(POINT pt, HWND hwnd, LPTSTR pszUrl);
  484.         // Get default editor from the registry
  485.         void InitDefaultEditor(HKEY hkey = NULL);
  486.     protected:
  487.         struct MSAAMenuInfo
  488.         {
  489.             DWORD m_MSAASig;  // Must be MSAA_MENU_SIG
  490.             DWORD m_CharLen;  // Length in characters of text, excluding terminating NUL
  491.             LPWSTR m_pWStr;   // Menu text, in UNICODE, with terminating UNICODE-NUL.
  492.         };
  493.         struct EDITVERB
  494.         {
  495.             MSAAMenuInfo m_MSAA;     // MSAA info - must be first element.
  496.             HKEY    hkeyProgID;      // Key the we shellexec
  497.             BITBOOL fUseOpenVerb:1;  // use open verb instead of edit
  498.             BITBOOL fInit:1;         // true if the data below has beed initialized
  499.             BITBOOL fShowIcon:1;     // true if icon should show up on button
  500.             int     iIcon;           // cached icon index
  501.             UINT    idCmd;           // menu id
  502.             LPTSTR  pszDesc;         // executable name or document name
  503.             LPTSTR  pszMenuText;     // Menu text
  504.             LPTSTR  pszExe;          // Path of the exe used to edit
  505.         };
  506.         EDITVERB* _Add(HKEY hkeyProgID, BOOL fPermitOpenVerb, BOOL fCheckForOfficeApp, BOOL fShowIcon);
  507.         EDITVERB& _GetVerb(UINT nIndex);
  508.         void      _FetchInfo(UINT nIndex);
  509.         void      _Edit(LPCTSTR pszUrl, UINT nIndex);
  510.         LPCTSTR   _GetDescription(EDITVERB& rVerb);
  511.         void      _SetMSAAMenuInfo(EDITVERB& rVerb);
  512.         void      _ClearMSAAMenuInfo(EDITVERB& rVerb);
  513.         void      _FormatMenuText(UINT nIndex);
  514.         BOOL      _IsUnique(EDITVERB& rNewVerb);
  515.         BOOL      _IsHtmlStub(LPCWSTR pszPath);
  516.         LPCTSTR   _GetExePath(EDITVERB& rVerb);
  517.         LPCTSTR   _GetDefaultEditor();
  518.         static LRESULT CALLBACK _WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  519.         // Member data
  520.         UINT        _nElements;         // number of edit verbs
  521.         UINT        _nDefault;          // Default edit verb
  522.         EDITVERB*   _pVerb;             // array of edit verbs
  523.         WNDPROC     _lpfnOldWndProc;    // former wndProc
  524.         LPWSTR      _pszDefaultEditor;  // Friendly name of default HTML editor
  525.         BOOL        _fInitEditor;       // if we checked for a default editor
  526.     };
  527.     CEditVerb  _aEditVerb;
  528. #endif
  529.     // internal bandsite class
  530.     class CBrowserToolsBand;
  531.     class CITBandSite : public CBandSite
  532.     {
  533.         CITBandSite();
  534.         virtual STDMETHODIMP Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut);
  535.         virtual STDMETHODIMP AddBand(IUnknown *punk);
  536.         virtual STDMETHODIMP HasFocusIO();
  537.     protected:
  538.         virtual void v_SetTabstop(LPREBARBANDINFO prbbi);
  539.         BOOL _SetMinDimensions();
  540.         friend class CInternetToolbar;
  541.         friend class CBrowserToolsBand;
  542.         virtual HRESULT _OnContextMenu(WPARAM wParm, LPARAM lParam);
  543.         virtual HRESULT _Initialize(HWND hwndParent);
  544.     };
  545.     CITBandSite _bs;
  546. #define TOOLSBANDCLASS CInternetToolbar::CBrowserToolsBand
  547.     class CBrowserToolsBand : public CToolbarBand
  548.     {
  549.         CMDMAP* _GetCmdMapByIndex(int nIndex) { return _GetCmdMap(nIndex, TRUE);};
  550.         CMDMAP* _GetCmdMapByID(int id)  { return _GetCmdMap(id, FALSE);};
  551.         LRESULT _ToolsCustNotify (LPNMHDR pnmh);  // Handle TBCustomization Notify
  552.         BOOL _SaveRestoreToolbar(BOOL fSave);
  553.         void _FreeCustomizeInfo();
  554.         void _FreeCmdMap(CMDMAP*);
  555.         BOOL _RemoveAllButtons();
  556.         int _CommandFromIndex(UINT uIndex);
  557.         HRESULT _ConvertCmd(const GUID* pguidButtonGroup, UINT id, GUID* pguidOut, UINT * pid);
  558.         void _OnDeletingButton(TBNOTIFY* ptbn);
  559.         LONG_PTR _AddString(LPWSTR pwstr);
  560.         void _PreProcessButtonString(TBBUTTON *ptbn, DWORD dwFlags);
  561.         void _PreProcessExternalTBButton(TBBUTTON *ptbn);
  562.         UINT _ProcessExternalButtons(PTBBUTTON ptbb, UINT cButtons);
  563.         void _GetButtons(IOleCommandTarget* pct, const GUID* pguid, HDSA hdsa);
  564.         void _RecalcButtonWidths();
  565.         void            _UpdateTextSettings(INT_PTR ids);
  566.         static BOOL_PTR CALLBACK _BtnAttrDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  567.         static void     _PopulateComboBox(HWND hwnd, const int iResource[], UINT cResources);
  568.         static void     _SetComboSelection(HWND hwnd, int iCurOption);
  569.         void            _SetDialogSelections(HWND hDlg, BOOL fSmallIcons);
  570.         static void     _PopulateDialog(HWND hDlg);
  571.         void            _OnBeginCustomize(LPNMTBCUSTOMIZEDLG pnm);
  572.         BOOL _BuildButtonDSA();
  573.         CMDMAPCUSTOMIZE* _GetCmdMapCustomize(GUID* guid, UINT nCmdID);
  574.         virtual STDMETHODIMP Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut);
  575.         virtual STDMETHODIMP GetClassID(CLSID *pClassID) {return E_NOTIMPL;};
  576.         virtual STDMETHODIMP Load(IStream *pStm) {return E_NOTIMPL;};
  577.         virtual STDMETHODIMP Save(IStream *pStm, BOOL fClearDirty) {return E_NOTIMPL;};
  578.         // *** IUnknown ***
  579.         virtual STDMETHODIMP_(ULONG) AddRef(void) { return CToolBand::AddRef(); };
  580.         virtual STDMETHODIMP_(ULONG) Release(void){ return CToolBand::Release(); };
  581.         virtual STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj);
  582.         // *** IDeskBand methods ***
  583.         virtual STDMETHODIMP GetBandInfo(DWORD dwBandID, DWORD fViewMode, DESKBANDINFO* pdbi);
  584.         // *** IWinEventHandler methods ***
  585.         virtual STDMETHODIMP OnWinEvent(HWND hwnd, UINT dwMsg, WPARAM wParam, LPARAM lParam, LRESULT* plres);
  586.         // *** IDockingWindow methods ***
  587.         virtual STDMETHODIMP CloseDW(DWORD dwReserved) { return S_OK;};
  588.         // *** IInputObject methods ***
  589.         virtual STDMETHODIMP TranslateAcceleratorIO(LPMSG lpMsg);
  590.     protected:
  591.         IOleCommandTarget* _CommandTargetFromCmdMap(CMDMAP* pcm);
  592.         LRESULT _OnToolbarDropDown(TBNOTIFY *ptbn);
  593.         virtual LRESULT _OnNotify(LPNMHDR pnmh);
  594.         LRESULT _OnContextMenu(LPARAM lParam, WPARAM wParam);
  595.         CMDMAP* _GetCmdMap(int i, BOOL fByIndex);
  596.         void _OnEndCustomize();
  597.         LRESULT _TryShowBackForwardMenu(DWORD dwItemSpec, LPPOINT ppt, LPRECT prcExclude);
  598.         CBrowserToolsBand();
  599.         void _FreeBtnsAdded();
  600.         friend class CInternetToolbar;
  601.         friend class CITBandSite;
  602.         GUID            _guidCurrentButtonGroup;
  603.         IOleCommandTarget* _pctCurrentButtonGroup;
  604.         LPTBBUTTON      _pbtnsAdded;
  605.         int             _cBtnsAdded;
  606.         DWORD            _nNextCommandID;
  607.         CUSTOMIZEINFO *_pcinfo;
  608.         BITBOOL    _fCustomize :1;
  609.         BITBOOL    _fNeedFreeCmdMapsAdded :1;
  610.     };
  611.     CBrowserToolsBand _btb;
  612.     friend class CBrowserToolsBand;
  613.     friend class CITBandSite;
  614.     friend void CInternetToolbar_CleanUp();
  615.     friend void CInternetToolbar_Preload();
  616.     friend void ITBar_LoadToolbarGlyphs(HWND hwnd);
  617. };
  618. //
  619. // Gets the stream corresponding to the type of the given pidl
  620. //     If the stream already doesn't exist, then it returns NULL.
  621. HRESULT _GetStreamName(DWORD dwITBS, LPTSTR pszName, DWORD cchSize)
  622. {
  623.     HRESULT hr = S_OK;
  624.     ASSERT(pszName);
  625.     switch (dwITBS)
  626.     {
  627.     case ITBS_WEB:
  628.         StrCpyN(pszName, TEXT("WebBrowser"), cchSize);
  629.         break;
  630.     case ITBS_SHELL:
  631.         StrCpyN(pszName, TEXT("ShellBrowser"), cchSize);
  632.         break;
  633.     case ITBS_EXPLORER:
  634.         StrCpyN(pszName, TEXT("Explorer"), cchSize);
  635.         break;
  636.     default:
  637.         hr = E_FAIL;
  638.         break;
  639.     }
  640.     if (FAILED(hr))
  641.         pszName[0] = '';
  642.     return hr;
  643. }
  644. //
  645. // Gets the stream corresponding to the type of the given pidl
  646. //     If the stream already doesn't exist, then it returns NULL.
  647. IStream *GetRegStream(BOOL fInternet, LPCTSTR pszValue, DWORD grfMode)
  648. {
  649.     IStream *pstm = NULL;
  650.     HKEY    hkToolbar;
  651.     if (RegCreateKey(HKEY_CURRENT_USER, c_szRegKeyCoolbar, &hkToolbar) == ERROR_SUCCESS)
  652.     {
  653.         TCHAR   szStreamName[MAX_PATH];
  654.         if (SUCCEEDED(_GetStreamName(fInternet, szStreamName, ARRAYSIZE(szStreamName))))
  655.             pstm = OpenRegStream(hkToolbar, szStreamName, pszValue, grfMode);
  656.         RegCloseKey(hkToolbar);
  657.     }
  658.     return(pstm);
  659. }
  660. //
  661. // Gets the stream corresponding to the type of the given pidl
  662. //     If the stream already doesn't exist, then it returns NULL.
  663. IStream *GetITBarStream(BOOL fInternet, DWORD grfMode)
  664. {
  665.     return GetRegStream(fInternet, TEXT("ITBarLayout"), grfMode);
  666. }
  667. IMLCACHE CInternetToolbar::s_imlTBGlyphs = {NULL};
  668. BMPCACHE CInternetToolbar::s_bmpBackShell = {NULL};
  669. BMPCACHE CInternetToolbar::s_bmpBackInternet = {NULL};
  670. BOOL g_fSmallIcons = FALSE;
  671. void IMLCACHE_CleanUp(IMLCACHE * pimlCache, DWORD dwFlags)
  672. {
  673.     for (int i = 0; i < CIMLISTS; i++)
  674.     {
  675.         if (pimlCache->arhimlPendingDelete[i])
  676.             ImageList_Destroy(pimlCache->arhimlPendingDelete[i]);
  677.         if ((dwFlags & IML_DESTROY) && pimlCache->arhiml[i])
  678.             ImageList_Destroy(pimlCache->arhiml[i]);
  679.     }
  680. }
  681. void ITBar_LoadToolbarGlyphs(HWND hwnd)
  682. {
  683.     int cx, idBmp;
  684.     g_fSmallIcons = _UseSmallIcons();
  685.     if (g_fSmallIcons) {
  686.         cx = TB_SMBMP_CX;
  687.         idBmp = IDB_IETOOLBAR16;
  688.     } else {
  689.         cx = TB_BMP_CX;
  690.         idBmp = IDB_IETOOLBAR;
  691.     }
  692.     if (SHGetCurColorRes() > 8)
  693.         idBmp += DELTA_HICOLOR;
  694.     _LoadToolbarGlyphs(hwnd, &CInternetToolbar::s_imlTBGlyphs, cx, idBmp);
  695. }
  696. void CInternetToolbar_Preload()
  697. {
  698.    ENTERCRITICAL;
  699.    ITBar_LoadToolbarGlyphs(NULL);
  700.    Brand_InitBrandContexts();
  701.    LEAVECRITICAL;
  702. }
  703. void CInternetToolbar_CleanUp()
  704. {
  705.     TraceMsg(DM_ITBAR, "CInternetToolbar: Destroying shared GDI objects");
  706.     if (CInternetToolbar::s_bmpBackInternet.hbmp)
  707.         DeleteObject(CInternetToolbar::s_bmpBackInternet.hbmp);
  708.     if (CInternetToolbar::s_bmpBackShell.hbmp)
  709.         DeleteObject(CInternetToolbar::s_bmpBackShell.hbmp);
  710.     IMLCACHE_CleanUp(&CInternetToolbar::s_imlTBGlyphs, IML_DESTROY);
  711. }
  712. STDAPI CInternetToolbar_CreateInstance(IUnknown* pUnkOuter, IUnknown** ppunk, LPCOBJECTINFO poi)
  713. {
  714.     // aggregation checking is handled in class factory
  715.     CInternetToolbar *pitbar = new CInternetToolbar();
  716.     if (pitbar)
  717.     {
  718.         *ppunk = SAFECAST(pitbar, IDockingWindow *);
  719.         return S_OK;
  720.     }
  721.     return E_OUTOFMEMORY;
  722. }
  723. LRESULT CInternetToolbar::v_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  724. {
  725.     if ( uMsg == WM_SYSCOLORCHANGE )
  726.     {
  727.         // refresh the back drop incase the colours have changed
  728.         _SetBackground();
  729.     }
  730.     return SUPERCLASS::v_WndProc( hwnd, uMsg, wParam, lParam );
  731. }
  732. void CInternetToolbar::_LoadExternalBandInfo()
  733. {
  734. #ifdef DEBUG
  735.     int i;
  736.     // Should have been zero-initialized
  737.     for (i = 0; i < ARRAYSIZE(_rgebi); i++)
  738.     {
  739.         ASSERT(IsEqualGUID(_rgebi[i].clsid, GUID_NULL));
  740.         ASSERT(_rgebi[i].pwszName == NULL);
  741.         ASSERT(_rgebi[i].pwszHelp == NULL);
  742.     }
  743. #endif
  744.     HKEY hkey;
  745.     DWORD dwClsidIndex = 0;
  746.     if (RegOpenKeyEx( HKEY_LOCAL_MACHINE, REG_KEY_BANDSTATE, 0, KEY_READ, &hkey) == ERROR_SUCCESS)
  747.     {
  748.         TCHAR tszReg[MAX_PATH];
  749.         StrCpy(tszReg, TEXT("CLSID\"));
  750.         const int cchClsidPrefix = 6;      // 6 = strlen("CLSID\")
  751.         LPTSTR ptszClsid = tszReg + cchClsidPrefix;
  752.         DWORD cchClsid;
  753.         for (DWORD dwIndex = 0;
  754.              cchClsid = ARRAYSIZE(tszReg) - cchClsidPrefix,
  755.              dwClsidIndex < ARRAYSIZE(_rgebi) &&
  756.              RegEnumValue( hkey, dwIndex, ptszClsid, &cchClsid, NULL, NULL, NULL, NULL ) == ERROR_SUCCESS;
  757.              dwIndex++)
  758.         {
  759.             CLSID clsid;
  760.             if (GUIDFromString( ptszClsid, &clsid ))
  761.             {
  762.                 // Don't save the CLSID until we're sure it worked
  763.                 _rgebi[dwClsidIndex].clsid = clsid;
  764.                 HKEY hkeyClsid;
  765.                 if (RegOpenKeyEx(HKEY_CLASSES_ROOT, tszReg, 0, KEY_READ, &hkeyClsid) == ERROR_SUCCESS)
  766.                 {
  767.                     WCHAR wszBuf[MAX_PATH];
  768.                     // Get the name; use SHLoadRegUIString so the app can localize
  769.                     SHLoadRegUIStringW( hkeyClsid, L"", wszBuf, ARRAYSIZE(wszBuf) );
  770.                     Str_SetPtrW( &_rgebi[dwClsidIndex].pwszName, wszBuf);
  771.                     // Get the help; use SHLoadRegUIString so the app can localize
  772.                     SHLoadRegUIStringW( hkeyClsid, L"HelpText", wszBuf, ARRAYSIZE(wszBuf) );
  773.                     Str_SetPtrW( &_rgebi[dwClsidIndex].pwszHelp, wszBuf);
  774.                     RegCloseKey(hkeyClsid);
  775.                 }
  776.                 dwClsidIndex++;
  777.             }
  778.         }
  779.         RegCloseKey( hkey );
  780.     }
  781. }
  782. CInternetToolbar::CInternetToolbar() : CBaseBar(), _yCapture(-1), _iButtons(-1)
  783. #ifdef EDIT_HACK
  784. , _iEditIcon(-1)
  785. #endif
  786. {
  787.     DllAddRef();
  788.     if (GetSystemMetrics(SM_CXSCREEN) < 650)
  789.         _uiMaxTBWidth = MAX_TB_WIDTH_LORES;
  790.     else
  791.         _uiMaxTBWidth = MAX_TB_WIDTH_HIRES;
  792.     ASSERT(_fLoading == FALSE);
  793.     ASSERT(_btb._guidCurrentButtonGroup == CLSID_NULL);
  794.     _btb._nNextCommandID = 1000;
  795.     _LoadExternalBandInfo();
  796. }
  797. void CInternetToolbar::_Unadvise(void)
  798. {
  799.     if(_dwcpCookie)
  800.     {
  801.         ConnectToConnectionPoint(NULL, DIID_DWebBrowserEvents2, FALSE, _pdie, &_dwcpCookie, NULL);
  802.     }
  803. }
  804. int CALLBACK DeleteDPAPtrCB(void *pItem, void *pData)
  805. {
  806.     LocalFree(pItem);
  807.     return TRUE;
  808. }
  809. CInternetToolbar::~CInternetToolbar()
  810. {
  811.     ATOMICRELEASE(_pdie);
  812.     if(_pbp && _fCreatedBandProxy)
  813.         _pbp->SetSite(NULL);
  814.     ATOMICRELEASE(_pbp);
  815.     ASSERT(!_ptbsite && !_ptbsitect && !_psp && !_pbs2);
  816.     SetSite(NULL);
  817.     DPA_DestroyCallback(_hdpaFSI, DeleteDPAPtrCB, NULL);
  818.     for (int i = 0; i < ARRAYSIZE(_rgebi); i++)
  819.     {
  820.         Str_SetPtrW( &_rgebi[i].pwszName, NULL);
  821.         Str_SetPtrW( &_rgebi[i].pwszHelp, NULL);
  822.     }
  823.     TraceMsg(TF_SHDLIFE, "dtor CInternetToolbar %x", this);
  824.     DllRelease();
  825. }
  826. #define IID_DWebBrowserEvents DIID_DWebBrowserEvents
  827. HRESULT CInternetToolbar::QueryInterface(REFIID riid, void ** ppvObj)
  828. {
  829.     static const QITAB qit[] = {
  830.         // perf: last tuned 980728
  831.         QITABENTMULTI(CInternetToolbar, IDispatch, DWebBrowserEvents),  // IID_IDispatch
  832.         QITABENT(CInternetToolbar, IExplorerToolbar),       // IID_IDispatch
  833.         QITABENT(CInternetToolbar, IObjectWithSite),        // IID_IObjectWithSite
  834.         QITABENT(CInternetToolbar, IPersistStreamInit),     // IID_IPersistStreamInit
  835.         QITABENT(CInternetToolbar, IDockingWindow),         // IID_IDockingWindow
  836.         QITABENT(CInternetToolbar, DWebBrowserEvents),      // IID_DWebBrowserEvents
  837.         QITABENT(CInternetToolbar, IShellChangeNotify),     // rare IID_IShellChangeNotify
  838.         QITABENT(CInternetToolbar, ISearchItems),           // rare IID_ISearchItems
  839.         { 0 },
  840.     };
  841.     HRESULT hres = QISearch(this, qit, riid, ppvObj);
  842.     if (FAILED(hres))
  843.         hres = SUPERCLASS::QueryInterface(riid, ppvObj);
  844.     return hres;
  845. }
  846. /* IDispatch methods */
  847. HRESULT CInternetToolbar::GetTypeInfoCount(UINT *pctinfo)
  848. {
  849.     return(E_NOTIMPL);
  850. }
  851. HRESULT CInternetToolbar::GetTypeInfo(UINT itinfo,LCID lcid,ITypeInfo **pptinfo)
  852. {
  853.     return(E_NOTIMPL);
  854. }
  855. HRESULT CInternetToolbar::GetIDsOfNames(REFIID riid,OLECHAR **rgszNames,UINT cNames,
  856.                                         LCID lcid, DISPID * rgdispid)
  857. {
  858.     return(E_NOTIMPL);
  859. }
  860. #if 0
  861. //  BUGBUG - StevePro changed it so this code isnt called
  862. //  this is a goodness, because it calls SHVerbExists() which
  863. //  is a TCHAR API, that is actually compiled as an ANSI API
  864. //  and since we are UNICODE it just always fails.
  865. //  leaving this in so that we know about the issue of
  866. //  frontpad.exe possibly needing to be disabled.
  867. BOOL _ShowEditForExtension(LPCTSTR pszExtension)
  868. {
  869.     TCHAR szBuf[MAX_PATH];
  870.     if (SHVerbExists(pszExtension, TEXT("edit"), szBuf)) {
  871.         // don't show it if it's just our own
  872.         if (StrStrI(szBuf, TEXT("frontpad.exe"))) {
  873.             return FALSE;
  874.         }
  875.         return TRUE;
  876.     }
  877.     return FALSE;
  878. }
  879. #endif
  880. #ifdef EDIT_HACK
  881. //+-------------------------------------------------------------------------
  882. // This function scans the html document for META tags that indicate the
  883. // program that was used to create the HTML page.  Examples are:
  884. //
  885. //  <meta name="ProgID" content="word.document" >
  886. //  <meta name="ProgID" content="excel.sheet" >
  887. //
  888. // If a match is found, the content of the first match is returned.  This
  889. // progid is used to edit the document.
  890. //--------------------------------------------------------------------------
  891. BSTR CInternetToolbar::_GetEditProgID
  892. (
  893.     IHTMLDocument2* pHTMLDocument
  894. )
  895. {
  896.     BSTR bstrProgID = NULL;
  897.     //
  898.     // First get all document elements.  Note that this is very fast in
  899.     // ie5 because the collection directly accesses the internal tree.
  900.     //
  901.     IHTMLElementCollection * pAllCollection;
  902.     if (SUCCEEDED(pHTMLDocument->get_all(&pAllCollection)))
  903.     {
  904.         IHTMLMetaElement* pMetaElement;
  905.         IHTMLBodyElement* pBodyElement;
  906.         IHTMLFrameSetElement* pFrameSetElement;
  907.         IDispatch* pDispItem;
  908.         //
  909.         // Now we scan the document for meta tags.  Since these must reside in
  910.         // in the head, and since Trident always creates a body tag, we can
  911.         // stop looking when we hit the body.
  912.         //
  913.         // Note, the alternative of using pAllCollection->tags to return the
  914.         // collection of meta tags is likely more expensive because it will
  915.         // walk the whole tree (unless Trident optimizes this).
  916.         //
  917.         long lItemCnt;
  918.         VARIANT vEmpty;
  919.         V_VT(&vEmpty) = VT_EMPTY;
  920.         VARIANT vIndex;
  921.         V_VT(&vIndex) = VT_I4;
  922.         EVAL(SUCCEEDED(pAllCollection->get_length(&lItemCnt)));
  923.         for (long lItem = 0; lItem < lItemCnt; lItem++)
  924.         {
  925.             V_I4(&vIndex) = lItem;
  926.             if (S_OK == pAllCollection->item(vIndex, vEmpty, &pDispItem))
  927.             {
  928.                 //
  929.                 // First see if it's a meta tag
  930.                 //
  931.                 if (SUCCEEDED(pDispItem->QueryInterface(IID_IHTMLMetaElement,
  932.                                                     (void **)&pMetaElement)))
  933.                 {
  934.                     BSTR bstrName = NULL;
  935.                     //
  936.                     // We have a META element, check its NAME and CONTENT
  937.                     //
  938.                     if ( SUCCEEDED(pMetaElement->get_name(&bstrName)) && (bstrName != NULL) &&
  939.                          (StrCmpIW(bstrName, OLESTR("ProgId")) == 0) &&
  940.                          SUCCEEDED(pMetaElement->get_content(&bstrProgID)) && (bstrProgID != NULL)
  941.                        )
  942.                     {
  943.                         // We got the ProgID, so terminate the search;
  944.                         lItem = lItemCnt;
  945.                     }
  946.                     if (bstrName != NULL)
  947.                         SysFreeString(bstrName);
  948.                     pMetaElement->Release();
  949.                 }
  950.                 //
  951.                 // Next check for the body tag
  952.                 //
  953.                 else if (SUCCEEDED(pDispItem->QueryInterface(IID_IHTMLBodyElement,
  954.                                                     (void **)&pBodyElement)) )
  955.                 {
  956.                     // Found the body tag, so terminate the search
  957.                     lItem = lItemCnt;
  958.                     pBodyElement->Release();
  959.                 }
  960.                 //
  961.                 // Finally, check for a frameset tag
  962.                 //
  963.                 else if (SUCCEEDED(pDispItem->QueryInterface(IID_IHTMLFrameSetElement,
  964.                                                     (void **)&pFrameSetElement)) )
  965.                 {
  966.                     // Found a frameset tag, so terminate the search
  967.                     lItem = lItemCnt;
  968.                     pFrameSetElement->Release();
  969.                 }
  970.                 pDispItem->Release();
  971.             }
  972.         }
  973.         // Make sure that these don't have to be cleared (should not have been modified)
  974.         ASSERT(vEmpty.vt == VT_EMPTY);
  975.         ASSERT(vIndex.vt == VT_I4);
  976.         pAllCollection->Release();
  977.     }
  978.     return bstrProgID;
  979. }
  980. //+-------------------------------------------------------------------------
  981. // Returns grey-scale image from the icon passed in.
  982. //--------------------------------------------------------------------------
  983. HIMAGELIST CInternetToolbar::_CreateGrayScaleImagelist(HBITMAP hbmpImage, HBITMAP hbmpMask)
  984. {
  985.     // Determine the button dimensions
  986.     int cx = g_fSmallIcons ? TB_SMBMP_CX : TB_BMP_CX;
  987.     int cy = g_fSmallIcons ? TB_SMBMP_CY : TB_BMP_CY;
  988.     // Start with a 24 bit color image list
  989.     HIMAGELIST himlEdit = ImageList_Create(cx, cy, ILC_COLOR24 | ILC_MASK, 1, 1);
  990.     if (NULL == himlEdit)
  991.     {
  992.         return NULL;
  993.     }
  994.     ImageList_Add(himlEdit, hbmpImage, hbmpMask);
  995.     // Get the dib section from the image list
  996.     IMAGEINFO ii;
  997.     if (ImageList_GetImageInfo(himlEdit, 0, &ii))
  998.     {
  999.         DIBSECTION ds = {0};
  1000.         if (GetObject(ii.hbmImage, sizeof(ds), &ds))
  1001.         {
  1002.             //
  1003.             // Map each pixel to a monochrome equivalent.
  1004.             //
  1005.             BYTE* pBits = (BYTE*)ds.dsBm.bmBits;
  1006.             BYTE* pScan = pBits;
  1007.             int xWid = ds.dsBm.bmWidth;
  1008.             int yHei = ds.dsBm.bmHeight;
  1009.             long cbScan = ((xWid * 24 + 31) & ~31) / 8;
  1010.             for (int y=0; y < yHei; ++y)
  1011.             {
  1012.                 for (int x=0; x < xWid; ++x)
  1013.                 {
  1014.                     //
  1015.                     // Map to equivalent gray color by setting r,g,b to the same value.
  1016.                     // Using the average of r,g,b can be too dark, and using the max
  1017.                     // of r,g,b can be too bright.  So, as a simple algorithm we use
  1018.                     // the average of the two schemes.  This is cheaper than using true
  1019.                     // intensity matching.
  1020.                     //
  1021.                     BYTE nMax = max(max(pScan[0], pScan[1]), pScan[2]);
  1022.                     BYTE nAve = ((UINT)pScan[0] + pScan[1] + pScan[2])/3;
  1023.                     pScan[0] = pScan[1] = pScan[2] = ((UINT)nMax + nAve)/2;
  1024.                     // Increment to next pixel
  1025.                     pScan += 3;
  1026.                 }
  1027.                 // Increment to the next scan line
  1028.                 pBits += cbScan;
  1029.                 pScan = pBits;
  1030.             }
  1031.         }
  1032.     }
  1033.     return himlEdit;
  1034. }
  1035. //+-------------------------------------------------------------------------
  1036. // Returns image and mask bitmaps for the desired image list item
  1037. //--------------------------------------------------------------------------
  1038. BOOL MyImageList_GetBitmaps
  1039. (
  1040.     HIMAGELIST himl,        // image list to use
  1041.     int iImage,             // image to copy
  1042.     int x,                  // x-offset to draw in bitmap
  1043.     int y,                  // x-offset to draw in bitmap
  1044.     int cx,                 // width of bitmap
  1045.     int cy,                 // height of bitmap
  1046.     HBITMAP* phbmpImage,    // returned color bitmap
  1047.     HBITMAP* phbmpMask      // returned mask bitmap
  1048. )
  1049. {
  1050.     ASSERT(phbmpImage);
  1051.     ASSERT(phbmpMask);
  1052.     BOOL fRet = FALSE;
  1053.     HDC hdc = GetDC(NULL);
  1054.     HDC hdcDst = CreateCompatibleDC(hdc);
  1055.     if (hdcDst)
  1056.     {
  1057.         HBITMAP hbmpImage = CreateCompatibleBitmap(hdc, cx, cy);
  1058.         if (hbmpImage)
  1059.         {
  1060.             HBITMAP hbmpMask = CreateBitmap(cx, cy, 1, 1, NULL);
  1061.             if (hbmpMask)
  1062.             {
  1063.                 // Draw  mask bitmap
  1064.                 HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcDst, hbmpMask);
  1065.                 PatBlt(hdcDst, 0, 0, cx, cy, WHITENESS);
  1066.                 ImageList_Draw(himl, iImage, hdcDst, x, y, ILD_MASK);
  1067.                 // Draw image bitmap
  1068.                 SelectObject(hdcDst, hbmpImage);
  1069.                 ImageList_Draw(himl, iImage, hdcDst, x, y, ILD_NORMAL);
  1070.                 SelectObject(hdcDst, hbmpOld);
  1071.                 *phbmpImage = hbmpImage;
  1072.                 *phbmpMask  = hbmpMask;
  1073.                 fRet = TRUE;
  1074.             }
  1075.             else
  1076.             {
  1077.                 DeleteObject(hbmpImage);
  1078.             }
  1079.         }
  1080.         DeleteDC(hdcDst);
  1081.     }
  1082.     ReleaseDC(NULL, hdc);
  1083.     return fRet;
  1084. }
  1085. extern HBITMAP CreateMirroredBitmap( HBITMAP hbmOrig);
  1086. //+-------------------------------------------------------------------------
  1087. // Creates a special image list for the edit button and configures the edit
  1088. // button to use it.  If the hIcon is -1, the edit button is reset to use
  1089. // it's default glyph.
  1090. //--------------------------------------------------------------------------
  1091. void CInternetToolbar::_SetEditGlyph
  1092. (
  1093.     int iIcon   // new edit button glyph, index into shell image cache
  1094. )
  1095. {
  1096.     // If no toolbar, we just need to see if we need to free the old image lists.
  1097.     if (_btb._hwnd == NULL)
  1098.     {
  1099.         if (iIcon == -1)
  1100.         {
  1101.             if (_himlEdit)
  1102.             {
  1103.                 ImageList_Destroy(_himlEdit);
  1104.                 _himlEdit = NULL;
  1105.             }
  1106.             if (_himlEditHot)
  1107.             {
  1108.                 ImageList_Destroy(_himlEditHot);
  1109.                 _himlEditHot = NULL;
  1110.             }
  1111.         }
  1112.         else
  1113.         {
  1114.             // Can't set the glyph if no toolbar!
  1115.             ASSERT(FALSE);
  1116.         }
  1117.         return;
  1118.     }
  1119.     UINT uiCmd = -1;
  1120.     // Dochost merges under one of two clsids, so have to check both
  1121.     if (FAILED(_btb._ConvertCmd(&CLSID_InternetButtons, DVIDM_EDITPAGE, NULL, &uiCmd)) &&
  1122.         FAILED(_btb._ConvertCmd(&CLSID_MSOButtons, DVIDM_EDITPAGE, NULL, &uiCmd)))
  1123.     {
  1124.         // The edit button is not on toolbar, so free the edit glyphs
  1125.         iIcon = -1;
  1126.     }
  1127.     // If the current icon is already set, we are done
  1128.     if (_iEditIcon == iIcon)
  1129.     {
  1130.         if (_himlEdit)
  1131.         {
  1132.             // Set up the new image lists
  1133.             SendMessage(_btb._hwnd, TB_SETIMAGELIST, IL_EDITBUTTON, (LPARAM)_himlEdit);
  1134.             if (_himlEditHot)
  1135.             {
  1136.                 SendMessage(_btb._hwnd, TB_SETHOTIMAGELIST, IL_EDITBUTTON, (LPARAM)_himlEditHot);
  1137.             }
  1138.             // Redirect the edit button to the new image list
  1139.             TBBUTTONINFO tbi = {0};
  1140.             tbi.cbSize = sizeof(tbi);
  1141.             tbi.dwMask = TBIF_IMAGE;
  1142.             tbi.iImage = MAKELONG(0, IL_EDITBUTTON);
  1143.             SendMessage(_btb._hwnd, TB_SETBUTTONINFO, uiCmd, (LPARAM)&tbi);
  1144.         }
  1145.         return;
  1146.     }
  1147.     _iEditIcon = iIcon;
  1148.     if (-1 == iIcon)
  1149.     {
  1150.         if (_himlEdit)
  1151.         {
  1152.             if (uiCmd != -1)
  1153.             {
  1154.                 // Reset to the original edit glyph
  1155.                 TBBUTTONINFO tbi = {0};
  1156.                 tbi.cbSize = sizeof(tbi);
  1157.                 tbi.dwMask = TBIF_IMAGE;
  1158.                 tbi.iImage = EDITGLYPH_OFFSET;
  1159.                 SendMessage(_btb._hwnd, TB_SETBUTTONINFO, uiCmd, (LPARAM)&tbi);
  1160.             }
  1161.             // Destroy the custom edit glyphs.  Note that we have to reset the primary image list
  1162.             // or the image sizes are screwed up.
  1163.             SendMessage(_btb._hwnd, TB_SETIMAGELIST, IL_EDITBUTTON, (LPARAM)NULL);
  1164.             ImageList_Destroy(_himlEdit);
  1165.             _himlEdit = NULL;
  1166.         }
  1167.         if (_himlEditHot)
  1168.         {
  1169.             SendMessage(_btb._hwnd, TB_SETHOTIMAGELIST, IL_EDITBUTTON, (LPARAM)NULL);
  1170.             ImageList_Destroy(_himlEditHot);
  1171.             _himlEditHot = NULL;
  1172.         }
  1173.     }
  1174.     else
  1175.     {
  1176.         // Determine the button dimensions
  1177.         int cx = g_fSmallIcons ? TB_SMBMP_CX : TB_BMP_CX;
  1178.         int cy = g_fSmallIcons ? TB_SMBMP_CY : TB_BMP_CY;
  1179.         // Get the image bitmaps
  1180.         HBITMAP hbmpImage = NULL;
  1181.         HBITMAP hbmpMask = NULL;
  1182.         BOOL bMirrored = IS_WINDOW_RTL_MIRRORED(_btb._hwnd);
  1183.         HIMAGELIST himlSmall;
  1184.         int cxSmall;
  1185.         int cySmall;
  1186.         if (Shell_GetImageLists(NULL, &himlSmall) &&
  1187.             ImageList_GetIconSize(himlSmall, &cxSmall, &cySmall) &&
  1188.             MyImageList_GetBitmaps(himlSmall, iIcon, (cx - cxSmall)/2, (cy - cySmall)/2,
  1189.                                    cx, cy, &hbmpImage, &hbmpMask))
  1190.         {
  1191.             if (bMirrored) 
  1192.             {
  1193.                 HBITMAP hbmpTemp;
  1194.                 hbmpTemp = CreateMirroredBitmap(hbmpImage);
  1195.                 if (hbmpTemp)
  1196.                 {
  1197.                     DeleteObject(hbmpImage);
  1198.                     hbmpImage = hbmpTemp;
  1199.                 }
  1200.                 hbmpTemp = CreateMirroredBitmap(hbmpMask);
  1201.                 if (hbmpTemp)
  1202.                 {
  1203.                     DeleteObject(hbmpMask);
  1204.                     hbmpMask = hbmpTemp;
  1205.                 }
  1206.             }
  1207.             // Create a monochrome glyph for the edit button
  1208.             HIMAGELIST himlEdit = _CreateGrayScaleImagelist(hbmpImage, hbmpMask);
  1209.             SendMessage(_btb._hwnd, TB_SETIMAGELIST, IL_EDITBUTTON, (LPARAM)himlEdit);
  1210.             if (_himlEdit)
  1211.             {
  1212.                 ImageList_Destroy(_himlEdit);
  1213.             }
  1214.             _himlEdit = himlEdit;
  1215.             // Create a hot glyph for the edit button
  1216.             HIMAGELIST himlEditHot = ImageList_Create(cx, cy, ILC_COLORDDB | ILC_MASK, 1, 1);
  1217.             int nIndex = ImageList_Add(himlEditHot, hbmpImage, hbmpMask);
  1218.             SendMessage(_btb._hwnd, TB_SETHOTIMAGELIST, IL_EDITBUTTON, (LPARAM)himlEditHot);
  1219.             if (_himlEditHot)
  1220.             {
  1221.                 ImageList_Destroy(_himlEditHot);
  1222.             }
  1223.             _himlEditHot = himlEditHot;
  1224.             // Redirect the edit button to the new image list
  1225.             if (_himlEdit)
  1226.             {
  1227.                 TBBUTTONINFO tbi = {0};
  1228.                 tbi.cbSize = sizeof(tbi);
  1229.                 tbi.dwMask = TBIF_IMAGE;
  1230.                 tbi.iImage = MAKELONG(nIndex, IL_EDITBUTTON);
  1231.                 SendMessage(_btb._hwnd, TB_SETBUTTONINFO, uiCmd, (LPARAM)&tbi);
  1232.             }
  1233.             DeleteObject(hbmpImage);
  1234.             DeleteObject(hbmpMask);
  1235.         }
  1236.         else
  1237.         {
  1238.             // Couldn't create images so use the default edit glyph
  1239.             _SetEditGlyph(-1);
  1240.         }
  1241.     }
  1242. }
  1243. //+-------------------------------------------------------------------------
  1244. // Initializes the edit button to display a drop-down menu if there are
  1245. // multiple verbs.  Also optionally displays a custion glyph.
  1246. //--------------------------------------------------------------------------
  1247. void CInternetToolbar::_InitEditButtonStyle()
  1248. {
  1249.     // If we have or want a custon edit glyph, load it
  1250.     _SetEditGlyph(_aEditVerb.GetIcon());
  1251.     UINT uiCmd;
  1252.     // Dochost merges under one of two clsids, so have to check both
  1253.     if (SUCCEEDED(_btb._ConvertCmd(&CLSID_InternetButtons, DVIDM_EDITPAGE, NULL, &uiCmd)) ||
  1254.         SUCCEEDED(_btb._ConvertCmd(&CLSID_MSOButtons, DVIDM_EDITPAGE, NULL, &uiCmd)))
  1255.     {
  1256.         ASSERT(uiCmd != -1);
  1257.         // If multiple verbs, make the button a split button
  1258.         TBBUTTONINFO tbi = {0};
  1259.         tbi.cbSize = sizeof(tbi);
  1260.         tbi.dwMask = TBIF_STYLE | TBIF_STATE;
  1261.         tbi.fsState = 0;
  1262.         if (_aEditVerb.GetSize() > 1)
  1263.         {
  1264.             tbi.fsStyle |= BTNS_DROPDOWN;
  1265.         }
  1266.         if (_aEditVerb.GetSize() > 0)
  1267.         {
  1268.             tbi.fsState = TBSTATE_ENABLED;
  1269.         }
  1270.         SendMessage(_btb._hwnd, TB_SETBUTTONINFO, uiCmd, (LPARAM)&tbi);
  1271.     }
  1272. }
  1273. //+-------------------------------------------------------------------------
  1274. // If the edit button is displaying a custon glyph, this function reloads
  1275. // the glyph.
  1276. //--------------------------------------------------------------------------
  1277. void CInternetToolbar::_RefreshEditGlyph()
  1278. {
  1279.     // If we have a custon edit glyph, reload it
  1280.     if (_himlEdit)
  1281.     {
  1282.         // Refresh the edit glyph
  1283.         _iEditIcon = -1;
  1284.         _InitEditButtonStyle();
  1285.     }
  1286. }
  1287. //+-------------------------------------------------------------------------
  1288. // Updates the edit button based on the document type currently loaded
  1289. //--------------------------------------------------------------------------
  1290. void CInternetToolbar::_UpdateEditButton()
  1291. {
  1292.     _aEditVerb.RemoveAll();
  1293.     _fEditEnabled = FALSE;
  1294.     //
  1295.     // First add editors associated with the url
  1296.     //
  1297.     BSTR bstrUrl = NULL;
  1298.     _pdie->get_LocationURL(&bstrUrl);
  1299.     if (bstrUrl)
  1300.     {
  1301.         LPTSTR pszExt;
  1302.         //
  1303.         // Find the cache file associated with the url.  The file extension for this entry
  1304.         // is based off of the mime type. (Note that get_mimeType on the document
  1305.         // returns a frindly name that is hard to translate back to an actual mimetype.
  1306.         // So we use the file extension instead.)
  1307.         //
  1308.         WCHAR szCacheFileName[MAX_PATH];
  1309.         *szCacheFileName = 0;
  1310.         if (FAILED(URLToCacheFile(bstrUrl, szCacheFileName, ARRAYSIZE(szCacheFileName))))
  1311.         {
  1312.             // If we can't get a file associated with the url, probably want to disable the edit button
  1313.             // because most apps need a file to edit.
  1314.             SysFreeString(bstrUrl);
  1315.             return;
  1316.         }
  1317.         pszExt = PathFindExtension(szCacheFileName);
  1318.         // bug 79055 - The cache has a bug where some html entries are not
  1319.         // given a file extension.  Too risky to fix for 5.x, so we'll just
  1320.         // assume .htm for http if no extension is present.
  1321.         if (L'' == *pszExt && GetUrlScheme(bstrUrl) == URL_SCHEME_HTTP)
  1322.         {
  1323.             StrCpyN(szCacheFileName, L".htm", ARRAYSIZE(szCacheFileName));
  1324.             pszExt = szCacheFileName;
  1325.         }
  1326.         if (*pszExt)
  1327.         {
  1328.             _aEditVerb.Add(pszExt);
  1329.             // If ".html", use the ".htm" editors too
  1330.             if (StrCmpI(pszExt, L".html") == 0 )
  1331.             {
  1332.                 //  This is an html document, so add the .htm editors
  1333.                 if (!_aEditVerb.Add(TEXT(".htm")) && StrCmpI(pszExt, L".html") != 0)
  1334.                 {
  1335.                     _aEditVerb.Add(TEXT(".html"));
  1336.                 }
  1337.             }
  1338.         }
  1339.         SysFreeString(bstrUrl);
  1340.     }
  1341.     //
  1342.     // See if the feature to search the doc for the progid is enabled
  1343.     //
  1344.     static int fCheckDocForProgID = -1;
  1345.     if (fCheckDocForProgID == -1)
  1346.     {
  1347.         fCheckDocForProgID = SHRegGetBoolUSValue(REGSTR_PATH_MAIN,
  1348.                  TEXT("CheckDocumentForProgID"), FALSE, TRUE) ? 1 : 0;
  1349.     }
  1350.     // Check for a meta tag that specifies a progid for editing this document
  1351.     if (fCheckDocForProgID)
  1352.     {
  1353.         //
  1354.         // Next see if this is an html document with a progid
  1355.         //
  1356.         IWebBrowser2*       pWB2 = NULL;
  1357.         IDispatch *         pDispatch = NULL;
  1358.         IHTMLDocument2 *    pHTMLDocument = NULL;
  1359.         // Get the html document currently loaded
  1360.         if (_psp &&
  1361.             SUCCEEDED(_psp->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, (void **)&pWB2)) &&
  1362.             SUCCEEDED(pWB2->get_Document(&pDispatch)) &&
  1363.             SUCCEEDED(pDispatch->QueryInterface(IID_IHTMLDocument2, (void **)&pHTMLDocument)))
  1364.         {
  1365.             //
  1366.             // Check the current document for a META tag specifying the program to use to
  1367.             // edit this file.
  1368.             //
  1369.             BSTR bstrProgID = _GetEditProgID(pHTMLDocument);
  1370.             if (bstrProgID)
  1371.             {
  1372.                 USES_CONVERSION;
  1373.                 _aEditVerb.Add(W2T(bstrProgID));
  1374.                 SysFreeString(bstrProgID);
  1375.             }
  1376.         }
  1377.         SAFERELEASE(pWB2);
  1378.         SAFERELEASE(pDispatch);
  1379.         SAFERELEASE(pHTMLDocument);
  1380.     }
  1381.     _fEditEnabled = (_aEditVerb.GetSize() > 0);
  1382.     // Update edit glyph, drop-down style, & enabled state
  1383.     _InitEditButtonStyle();
  1384. }
  1385. #endif //EDIT_HACK
  1386. HRESULT CInternetToolbar::Invoke(DISPID dispidMember,REFIID riid,LCID lcid,WORD wFlags,
  1387.                                  DISPPARAMS * pdispparams, VARIANT * pvarResult,
  1388.                                  EXCEPINFO * pexcepinfo,UINT * puArgErr)
  1389. {
  1390.     ASSERT(pdispparams);
  1391.     if(!pdispparams)
  1392.         return E_INVALIDARG;
  1393.     switch(dispidMember)
  1394.     {
  1395.     case DISPID_NAVIGATECOMPLETE2:
  1396.     {
  1397.         //
  1398.         // Notify the brand and theater mode objects about whether we're in shell or
  1399.         // web mode. Wait til now to do it (rather than doing it in SetCommandTarget)
  1400.         // because they might want to ask the browser about the new pidl, which isn't
  1401.         // yet filled in at SetCommandTarget time.
  1402.         //
  1403.         DWORD nCmdexecopt = _fShellView ? CITE_SHELL : CITE_INTERNET;
  1404.         LPBANDITEMDATA pbid = _bs._GetBandItemDataStructByID(CBIDX_BRAND);
  1405.         if (pbid)
  1406.         {
  1407.             IUnknown_Exec(pbid->pdb, &CGID_PrivCITCommands, CITIDM_ONINTERNET, nCmdexecopt, NULL, NULL);
  1408.         }
  1409.         if (_fTheater)
  1410.         {
  1411.             IUnknown_Exec(_ptbsite, &CGID_Theater, THID_ONINTERNET, nCmdexecopt, NULL, NULL);
  1412.         }
  1413.         _fNavigateComplete = TRUE;
  1414.     }
  1415.     break;
  1416.     case DISPID_BEFORENAVIGATE:
  1417.     {
  1418.         BOOL fWeb = FALSE;
  1419.         ASSERT((pdispparams->rgvarg[5].vt == VT_BSTR) &&
  1420.                (pdispparams->rgvarg[5].bstrVal != NULL));
  1421.         PARSEDURL pu = { 0 };
  1422.         USES_CONVERSION;
  1423.         pu.cbSize = SIZEOF(pu);
  1424.         ParseURL(W2T(pdispparams->rgvarg[5].bstrVal), &pu);
  1425.         if ((URL_SCHEME_UNKNOWN != pu.nScheme) && (URL_SCHEME_FILE != pu.nScheme))
  1426.             fWeb = TRUE;
  1427.         UINT uiState = 0;
  1428.         GetState(&CLSID_CommonButtons, TBIDM_STOPDOWNLOAD, &uiState);
  1429.         if ((uiState & TBSTATE_HIDDEN) && fWeb)
  1430.         {
  1431.             _fTransitionToHTML = TRUE;
  1432.             uiState &= ~TBSTATE_HIDDEN;
  1433.             SetState(&CLSID_CommonButtons, TBIDM_STOPDOWNLOAD, uiState);
  1434.         }
  1435.         // Default to the edit button hidden
  1436.         _fEditEnabled = FALSE;
  1437.     }
  1438.     break;
  1439.     case DISPID_DOWNLOADBEGIN:// This is when we just started to navigate?  No bits?
  1440.         _StartDownload();
  1441.         break;
  1442.     case DISPID_DOWNLOADCOMPLETE:    // we be done
  1443.         _fTransitionToHTML = FALSE;
  1444.         _StopDownload(FALSE);
  1445.         break;
  1446.     case DISPID_DOCUMENTCOMPLETE:   // This is where we have all the bits
  1447.     {
  1448.         //
  1449.         // Sometimes we get a premature document complete.  We can catch this
  1450.         // by checking to see if we have received a DISPID_NAVIGATECOMPLETE2 event.
  1451.         //
  1452.         if (_fNavigateComplete)
  1453.         {
  1454.             _fNavigateComplete = FALSE;
  1455.             _UpdateEditButton();
  1456.         }
  1457.         break;
  1458.     }
  1459.     case DISPID_COMMANDSTATECHANGE:
  1460.         BOOL fEnable;
  1461.         if(!pdispparams || (pdispparams->cArgs != 2) ||
  1462.            (pdispparams->rgvarg[0].vt != VT_BOOL) ||
  1463.            (pdispparams->rgvarg[1].vt != VT_I4))
  1464.             return E_INVALIDARG;
  1465.         fEnable = (BOOL) pdispparams->rgvarg[0].boolVal;
  1466.         UINT uiCmd;
  1467.         switch (pdispparams->rgvarg[1].lVal)
  1468.         {
  1469.         case CSC_UPDATECOMMANDS:
  1470.             // corresponds to OLECMDID_UPDATECOMMANDS from Exec()
  1471.             _UpdateToolbar(FALSE);
  1472.             break;
  1473.         case CSC_NAVIGATEBACK:
  1474.             _fBackEnabled = fEnable;
  1475.             _btb._ConvertCmd(&CLSID_CommonButtons, TBIDM_BACK, NULL, &uiCmd);
  1476.             SendMessage(_btb._hwnd, TB_ENABLEBUTTON, uiCmd,    MAKELONG(fEnable, 0));
  1477.             break;
  1478.         case CSC_NAVIGATEFORWARD:
  1479.             _fForwardEnabled = fEnable;
  1480.             _btb._ConvertCmd(&CLSID_CommonButtons, TBIDM_FORWARD, NULL, &uiCmd);
  1481.             SendMessage(_btb._hwnd, TB_ENABLEBUTTON, uiCmd, MAKELONG(fEnable, 0));
  1482.             break;
  1483.         default:
  1484.             return(E_INVALIDARG);
  1485.         }
  1486.         // BUGBUG need to handle the case of navigation failure and
  1487.         // do some cleanup
  1488.     }
  1489.     return S_OK;
  1490. }
  1491. //***   CInternetToolbar::IInputObjectSite::* {
  1492. HRESULT CInternetToolbar::OnFocusChangeIS(IUnknown *punk, BOOL fSetFocus)
  1493. {
  1494.     return UnkOnFocusChangeIS(_ptbsite, SAFECAST(this, IInputObject*), fSetFocus);
  1495. }
  1496. // }
  1497. //***   CInternetToolbar::IInputObject::* {
  1498. HRESULT CInternetToolbar::TranslateAcceleratorIO(LPMSG lpMsg)
  1499. {
  1500.     LPBANDITEMDATA pbid;
  1501.     if (_fShow)
  1502.     {
  1503.         if (lpMsg->message == WM_KEYDOWN)
  1504.         {
  1505.             switch (lpMsg->wParam)
  1506.             {
  1507.             case VK_F4:
  1508.         Laddrband:
  1509.                 if (_nVisibleBands & VBF_ADDRESS)
  1510.                 {
  1511.                     pbid = _bs._GetBandItemDataStructByID(CBIDX_ADDRESS);
  1512.                     if (EVAL(pbid))
  1513.                     {
  1514.                         HRESULT hrT;
  1515.                         hrT = UnkTranslateAcceleratorIO(pbid->pdb, lpMsg);
  1516.                         ASSERT(hrT == S_OK);
  1517.                     }
  1518.                 }
  1519.                 return S_OK;    // (even if we just eat it)
  1520.             }
  1521.         }
  1522.         else if(lpMsg->message == WM_SYSCHAR)
  1523.         {
  1524.             static CHAR szAccel[2] = "";
  1525.             CHAR   szChar [2] = "";
  1526.             if ('' == szAccel[0])
  1527.                 MLLoadStringA(IDS_ADDRBAND_ACCELLERATOR, szAccel, ARRAYSIZE(szAccel));
  1528.             szChar[0] = (CHAR)lpMsg->wParam;
  1529.             
  1530.             if (lstrcmpiA(szChar,szAccel) == 0)
  1531.             {
  1532.                 goto Laddrband;
  1533.             }
  1534.         }
  1535.         return _bs.TranslateAcceleratorIO(lpMsg);
  1536.     }
  1537.     return S_FALSE;
  1538. }
  1539. // }
  1540. HRESULT CInternetToolbar::SetSite(IUnknown* punkSite)
  1541. {
  1542.     ATOMICRELEASE(_ptbsite);
  1543.     ATOMICRELEASE(_ptbsitect);
  1544.     ATOMICRELEASE(_pbs2);
  1545.     ATOMICRELEASE(_psp);
  1546.     _Unadvise();
  1547.     ATOMICRELEASE(_pdie);
  1548.     ASSERT(_ptbsite==NULL);
  1549.     ASSERT(_ptbsitect==NULL);
  1550.     ASSERT(_pbs2==NULL);
  1551.     ASSERT(_pdie==NULL);
  1552.     if (_pbp && _fCreatedBandProxy)
  1553.         _pbp->SetSite(punkSite);
  1554.     if (punkSite)
  1555.     {
  1556.         punkSite->QueryInterface(IID_IDockingWindowSite, (void **)&_ptbsite);
  1557.         punkSite->QueryInterface(IID_IOleCommandTarget, (void **)&_ptbsitect);
  1558.         punkSite->QueryInterface(IID_IBrowserService2, (void **)&_pbs2);
  1559.         punkSite->QueryInterface(IID_IServiceProvider, (void **)&_psp);
  1560.         if (_psp)
  1561.         {
  1562.             _psp->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, (void **)&_pdie);
  1563.             ASSERT(_pdie);
  1564.         }
  1565.         else
  1566.         {
  1567.             ASSERT(0);
  1568.         }
  1569.     }
  1570.     else
  1571.     {
  1572.         SetClient(NULL);
  1573.     }
  1574.     return S_OK;
  1575. }
  1576. //***
  1577. //
  1578. void CInternetToolbar::_UpdateGroup(const GUID *pguidCmdGroup, int cnt,
  1579.     OLECMD rgcmds[], const GUID* pguidButton, const int buttonsInternal[])
  1580. {
  1581.     if (!IsEqualGUID(*pguidButton, CLSID_CommonButtons) &&
  1582.         !IsEqualGUID(*pguidButton, _btb._guidCurrentButtonGroup))
  1583.         return; // we don't have any buttons at this time, so no use checking
  1584.     if (_ptbsitect) {
  1585.         _ptbsitect->QueryStatus(pguidCmdGroup, cnt, rgcmds, NULL);
  1586.         // make sure stop is enabled while we are animating
  1587.         if (_fAnimating && pguidCmdGroup == NULL && rgcmds[0].cmdID == OLECMDID_STOP) {
  1588.             rgcmds[0].cmdf = OLECMDF_ENABLED;
  1589.         }
  1590.     }
  1591.     for (int i = 0; i < cnt; i++)
  1592.     {
  1593.         // do nothing if command is not available or not in our table
  1594.         if (rgcmds[i].cmdf & OLECMDF_SUPPORTED)
  1595.         {
  1596.             UINT idBut;
  1597.             if (SUCCEEDED(_btb._ConvertCmd(pguidButton, buttonsInternal[i], NULL, (UINT*)&idBut)))
  1598.             {
  1599.                 SendMessage(_btb._hwnd, TB_ENABLEBUTTON, idBut,
  1600.                     (rgcmds[i].cmdf & OLECMDF_ENABLED) ? TRUE : FALSE);
  1601.                 SendMessage(_btb._hwnd, TB_CHECKBUTTON, idBut,
  1602.                     (rgcmds[i].cmdf & OLECMDF_LATCHED) ? TRUE : FALSE);
  1603.             }
  1604.         }
  1605.     }
  1606.     return;
  1607. }
  1608. void CInternetToolbar::_UpdateToolbar(BOOL fForce)
  1609. {
  1610.     if (fForce || SHIsChildOrSelf(GetForegroundWindow(), _hwnd) == S_OK)
  1611.     {
  1612.         if (!_fUpdateToolbarTimer)
  1613.         {
  1614.             SetTimer(_hwnd, IDT_UPDATETOOLBAR, TIMEOUT_UPDATETOOLBAR, NULL);
  1615.             _fUpdateToolbarTimer = TRUE;
  1616.             _UpdateToolbarNow();
  1617.         }
  1618.         else
  1619.         {
  1620.             _fNeedUpdateToolbar = TRUE;
  1621.         }
  1622.     }
  1623. }
  1624. BOOL CInternetToolbar::_UpEnabled()
  1625. {
  1626.     OLECMD rgcmd = { FCIDM_PREVIOUSFOLDER, 0 };
  1627.     _ptbsitect->QueryStatus(&CGID_ShellBrowser, 1, &rgcmd, NULL);
  1628.     return (rgcmd.cmdf & OLECMDF_ENABLED);
  1629. }
  1630. void CInternetToolbar::_UpdateCommonButton(int iCmd, UINT nCmdID)
  1631. {
  1632.     switch (nCmdID) {
  1633.     case TBIDM_THEATER:
  1634.         SendMessage(_btb._hwnd, TB_CHECKBUTTON, iCmd, _fTheater);
  1635.         break;
  1636.     case TBIDM_PREVIOUSFOLDER:
  1637.     case TBIDM_BACK:
  1638.     case TBIDM_FORWARD:
  1639.         {
  1640.             BOOL fEnabled;
  1641.             switch (nCmdID) {
  1642.             case TBIDM_PREVIOUSFOLDER:  fEnabled = _UpEnabled();       break;
  1643.             case TBIDM_BACK:            fEnabled = _fBackEnabled;      break;
  1644.             case TBIDM_FORWARD:         fEnabled = _fForwardEnabled;   break;
  1645.             }
  1646.             SendMessage(_btb._hwnd, TB_ENABLEBUTTON, iCmd, MAKELONG(fEnabled, 0));
  1647.         }
  1648.         break;
  1649.     }
  1650. }
  1651. void CInternetToolbar::_UpdateToolbarNow()
  1652. {
  1653.     _fNeedUpdateToolbar = FALSE;
  1654.     {
  1655.         // MUST not be static (due to ConvertCmd overwrite)
  1656.         OLECMD rgcmds[] = {
  1657.             { OLECMDID_STOP, 0 }, // NOTE: must be first
  1658.             { OLECMDID_REFRESH, 0 },
  1659.         };
  1660.         static const int buttonsInternal[] = { // MUST be in same order as above array
  1661.             TBIDM_STOPDOWNLOAD,
  1662.             TBIDM_REFRESH,
  1663.         };
  1664.         _UpdateGroup(NULL, ARRAYSIZE(buttonsInternal), rgcmds, &CLSID_CommonButtons, buttonsInternal);
  1665.     }
  1666.     {
  1667.         OLECMD rgcmds[] = {
  1668.             { SBCMDID_SEARCHBAR, 0 },
  1669.             { SBCMDID_FAVORITESBAR, 0 },
  1670.             { SBCMDID_HISTORYBAR, 0 },
  1671. #ifdef ENABLE_CHANNELPANE
  1672.             { SBCMDID_CHANNELSBAR, 0 },
  1673. #endif
  1674.             { SBCMDID_EXPLORERBAR, 0 },
  1675.         };
  1676.         static const int buttonsInternal[] = { // MUST be in same order as above array
  1677.             TBIDM_SEARCH,
  1678.             TBIDM_FAVORITES,
  1679.             TBIDM_HISTORY,
  1680. #ifdef ENABLE_CHANNELPANE
  1681.             TBIDM_CHANNELS,
  1682. #endif
  1683.             TBIDM_ALLFOLDERS,
  1684.         };
  1685.         _UpdateGroup(&CGID_Explorer, ARRAYSIZE(buttonsInternal), rgcmds, &CLSID_CommonButtons, buttonsInternal);
  1686.     }
  1687.     int nButtons = (int) SendMessage(_btb._hwnd, TB_BUTTONCOUNT, 0, 0L);
  1688.     for (int nIndex = 0; nIndex < nButtons; nIndex++)
  1689.     {
  1690.         CMDMAP* pcm = _btb._GetCmdMapByIndex(nIndex);
  1691.         if (pcm)
  1692.         {
  1693.             int iCmd = _btb._CommandFromIndex(nIndex);
  1694.             if (IsEqualGUID(pcm->guidButtonGroup, CLSID_CommonButtons))
  1695.             {
  1696.                 _UpdateCommonButton(iCmd, pcm->nCmdID);
  1697.             }
  1698.             else
  1699.             {
  1700.                 // If either of these rip, the button is stale
  1701.                 ASSERT(IsEqualGUID(pcm->guidButtonGroup, _btb._guidCurrentButtonGroup));
  1702.                 ASSERT(_btb._pctCurrentButtonGroup);
  1703.                 OLECMD ocButton;
  1704.                 ocButton.cmdID = pcm->nCmdID;
  1705.                 ocButton.cmdf = 0;
  1706.                 if (SUCCEEDED(_btb._pctCurrentButtonGroup->QueryStatus(&pcm->guidButtonGroup, 1, &ocButton, NULL)))
  1707.                 {
  1708.                     SendMessage(_btb._hwnd, TB_ENABLEBUTTON, iCmd,
  1709.                                 (ocButton.cmdf & OLECMDF_ENABLED) ? TRUE : FALSE);
  1710.                     SendMessage(_btb._hwnd, TB_CHECKBUTTON, iCmd,
  1711.                                 (ocButton.cmdf & OLECMDF_LATCHED) ? TRUE : FALSE);
  1712.                 }
  1713.             }
  1714.         }
  1715.     }
  1716.     _btb._BandInfoChanged();
  1717. }
  1718. void CInternetToolbar::_StartDownload()
  1719. {
  1720.     UINT uiCmd;
  1721.     if (SUCCEEDED(_btb._ConvertCmd(&CLSID_CommonButtons, TBIDM_STOPDOWNLOAD, NULL, &uiCmd)))
  1722.     {
  1723.         SendMessage(_btb._hwnd, TB_ENABLEBUTTON, uiCmd, MAKELONG(TRUE, 0));
  1724.         _fAnimating = TRUE;
  1725.     }
  1726. }
  1727. //
  1728. // Parameters:
  1729. //  fClosing -- TRUE only if we are calling this from CloseDW member.
  1730. //              In that case, we can skip all UI-update code.
  1731. //
  1732. void CInternetToolbar::_StopDownload(BOOL fClosing)
  1733. {
  1734.     _fAnimating = FALSE;
  1735. }
  1736. HRESULT CInternetToolbar::CloseDW(DWORD dwReserved)
  1737. {
  1738.     _fDestroyed = TRUE; // Stop using the member variables, they are invalid.
  1739.     _StopDownload(TRUE);
  1740.     ASSERT(!_btb._pcinfo);
  1741.     ATOMICRELEASE(_btb._pctCurrentButtonGroup);
  1742.     _btb._FreeBtnsAdded();
  1743.     if (_btb._hwnd)
  1744.     {
  1745.         _btb._RemoveAllButtons();
  1746.         SendMessage(_btb._hwnd, TB_SETIMAGELIST, 0, NULL);
  1747.         SendMessage(_btb._hwnd, TB_SETHOTIMAGELIST, 0, NULL);
  1748.         DSA_Destroy(_hdsaTBBMPs);
  1749.         _hdsaTBBMPs = NULL;  // So we don't try to re-destroy in _InitBitmapDSA()
  1750.         _hdsaTBBMPs = NULL;
  1751.     }
  1752. #ifdef EDIT_HACK
  1753.     _SetEditGlyph(-1);
  1754. #endif
  1755.     _bs._Close();
  1756.     SUPERCLASS::CloseDW(dwReserved);
  1757.     _btb._hwnd = NULL;
  1758.     // We advise during ShowDW, so unadvise here. Also, we hit a stress
  1759.     // case where it seems that an event came in after closedw but before
  1760.     // one of the other _Unadvise calls. This event percolated down to
  1761.     // a reference to _hdsaCT which we freed above, causing a GPF.
  1762.     //
  1763.     _Unadvise();
  1764.     return S_OK;
  1765. }
  1766. void CInternetToolbar::CITBandSite::v_SetTabstop(LPREBARBANDINFO prbbi)
  1767. {
  1768.     // Don't set tabstops for all bands in the browser case.  A band
  1769.     // can still make itself a tabstop by setting WS_TABSTOP.
  1770.     return;
  1771. }
  1772. BOOL CInternetToolbar::CITBandSite::_SetMinDimensions()
  1773. {
  1774.     INT_PTR fRedraw = SendMessage(_hwnd, WM_SETREDRAW, FALSE, 0);
  1775.     int icBands = (int) SendMessage( _hwnd, RB_GETBANDCOUNT, 0, 0 );
  1776.     for (int i = 0; i < icBands; i++)
  1777.     {
  1778.         REBARBANDINFO rbbi;
  1779.         rbbi.cbSize = sizeof(REBARBANDINFO);
  1780.         rbbi.fMask = RBBIM_ID | RBBIM_CHILDSIZE;
  1781.         if (SendMessage(_hwnd, RB_GETBANDINFO, i, (LPARAM) &rbbi))
  1782.         {
  1783.             LPBANDITEMDATA pbid = (LPBANDITEMDATA)_GetBandItemDataStructByID(rbbi.wID);
  1784.             if (EVAL(pbid) && IS_VALID_HANDLE(pbid->hwnd, WND))
  1785.             {
  1786.                 rbbi.cxMinChild = pbid->ptMinSize.x;
  1787.                 rbbi.cyMinChild = pbid->ptMinSize.y;
  1788.             }
  1789.             else
  1790.             {
  1791.                 rbbi.cxMinChild = 0;
  1792.                 rbbi.cyMinChild = 0;
  1793.             }
  1794.             SendMessage(_hwnd, RB_SETBANDINFO, i, (LPARAM) &rbbi);
  1795.         }
  1796.     }
  1797.     SendMessage(_hwnd, WM_SETREDRAW, fRedraw, 0);
  1798.     return TRUE;
  1799. }
  1800. BOOL HimlCacheDirty(IMLCACHE* pimlCache, BOOL fSmallIcons)
  1801. {
  1802.     if (fSmallIcons != pimlCache->fSmallIcons)
  1803.         return TRUE;
  1804.     COLORREF cr3D = GetSysColor(COLOR_3DFACE);
  1805.     if (cr3D != pimlCache->cr3D)
  1806.         return TRUE;
  1807.     for (int i = 0; i < CIMLISTS; i++)
  1808.         if (!pimlCache->arhiml[i])
  1809.             return TRUE;
  1810.     return FALSE;
  1811. }
  1812. #define SZ_REGKEY_SMALLICONS       REGSTR_PATH_EXPLORER TEXT("\SmallIcons")
  1813. #define SZ_REGVALUE_SMALLICONS     TEXT("SmallIcons")
  1814. BOOL _DefaultToSmallIcons()
  1815. {
  1816.     // On NT5, we want to default to small icons.
  1817.     return (GetUIVersion() >= 5) || SHRestricted2(REST_SMALLICONS, NULL, 0);
  1818. }
  1819. BOOL _UseSmallIcons()
  1820. {
  1821.     BOOL fDefaultToSmall = _DefaultToSmallIcons();
  1822.     return SHRegGetBoolUSValue(SZ_REGKEY_SMALLICONS, SZ_REGVALUE_SMALLICONS,
  1823.                                         FALSE, fDefaultToSmall);
  1824. }
  1825. BOOL _UseMapNetDrvBtns()
  1826. {
  1827. #define SZ_REGKEY_ADVFOLDER        TEXT("Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced")
  1828. #define SZ_REGVALUE_MAPNETDRV      TEXT("MapNetDrvBtn")
  1829.     DWORD dwData = 0;
  1830.     if (GetUIVersion() >= 4)
  1831.     {
  1832.         DWORD cbData = SIZEOF(dwData);
  1833.         DWORD dwDefault = 0;
  1834.         DWORD cbDefault = SIZEOF(dwDefault);
  1835.         SHRegGetUSValue(SZ_REGKEY_ADVFOLDER, SZ_REGVALUE_MAPNETDRV, NULL,
  1836.                             &dwData, &cbData, FALSE, &dwDefault, cbDefault);
  1837.     }
  1838.     return dwData;
  1839. }
  1840. void _LoadToolbarGlyphs(HWND hwnd, IMLCACHE *pimlCache, int cx, int idBmp)
  1841. {
  1842.     // set uMsg and uFlags for first iteration of loop (default state)
  1843.     UINT uMsg = TB_SETIMAGELIST;
  1844.     UINT uFlags = LR_CREATEDIBSECTION;
  1845.     int i;
  1846.     HBITMAP hBMP;
  1847.     BOOL fSmallIcons = g_fSmallIcons;
  1848.     if (HimlCacheDirty(pimlCache, fSmallIcons))
  1849.     {
  1850.         COLORREF cr3D   = GetSysColor(COLOR_3DFACE);
  1851.         COLORREF crMask = RGB( 255, 0, 255 );
  1852. #ifdef UNIX
  1853.         if (SHGetCurColorRes() < 2 )
  1854.         {
  1855.             crMask = CLR_NONE;
  1856.         }
  1857. #endif
  1858.         ENTERCRITICAL;
  1859.         if (!HimlCacheDirty(pimlCache, fSmallIcons) )
  1860.             goto DontReload;
  1861.         for (i = 0; i < CIMLISTS; i++)
  1862.         {
  1863.             if ((!pimlCache->arhiml[i]) || (cr3D != pimlCache->cr3D) || fSmallIcons != pimlCache->fSmallIcons)
  1864.             {
  1865.                 TraceMsg(DM_ITBAR, "CInternetToolbar: Loading New Images");
  1866.                 if (pimlCache->arhimlPendingDelete[i])
  1867.                     ImageList_Destroy(pimlCache->arhimlPendingDelete[i]);
  1868.                 pimlCache->arhimlPendingDelete[i] = pimlCache->arhiml[i];
  1869.                 pimlCache->arhiml[i] = ImageList_LoadImage(HINST_THISDLL,
  1870.                                                MAKEINTRESOURCE(idBmp + i), cx, 0, crMask,
  1871.                                                IMAGE_BITMAP, uFlags);
  1872.                 if (pimlCache->arhiml[i])
  1873.                 {
  1874.                     // add shell glyphs
  1875.                     int idShellBmp = IDB_SHSTD;
  1876.                     int iDelta = idBmp - IDB_IETOOLBAR;
  1877.                     idShellBmp += iDelta;
  1878.                     hBMP = LoadBitmap(HINST_THISDLL, MAKEINTRESOURCE(idShellBmp + i));
  1879.                     ImageList_AddMasked(pimlCache->arhiml[i], (HBITMAP)hBMP, crMask);
  1880.                     DeleteObject(hBMP);
  1881.                 }
  1882.             }
  1883.         }
  1884.         pimlCache->cr3D = cr3D;
  1885.         pimlCache->fSmallIcons = fSmallIcons;
  1886. DontReload:
  1887.         LEAVECRITICAL;
  1888.     }
  1889.     if (hwnd) {
  1890.         ASSERT(IS_VALID_HANDLE(hwnd, WND));
  1891.         for (i = 0; i < CIMLISTS; i++)
  1892.         {
  1893.             SendMessage(hwnd, uMsg, 0, (LPARAM) pimlCache->arhiml[i]);
  1894.             // set uMsg and uFlags for last iteration of loop (hot state)
  1895.             uMsg = TB_SETHOTIMAGELIST;
  1896.             uFlags = 0;
  1897.         }
  1898.     }
  1899. }
  1900. void CInternetToolbar::_InitBitmapDSA()
  1901. {
  1902.     DSA_Destroy(_hdsaTBBMPs);
  1903.     _hdsaTBBMPs = DSA_Create(SIZEOF(TBBMP_LIST), TBBMPLIST_CHUNK);
  1904.     if (_hdsaTBBMPs) {
  1905.         TBBMP_LIST tbl = { HINST_COMMCTRL, 0, 0, TRUE, TRUE, FALSE };
  1906.         tbl.uiResID = IDB_STD_SMALL_COLOR;
  1907.         tbl.uiOffset = OFFSET_STD;
  1908.         DSA_AppendItem(_hdsaTBBMPs, &tbl);
  1909.         tbl.uiResID = IDB_STD_LARGE_COLOR;
  1910.         DSA_AppendItem(_hdsaTBBMPs, &tbl);
  1911.         tbl.uiResID = IDB_VIEW_SMALL_COLOR;
  1912.         tbl.uiOffset = OFFSET_VIEW;
  1913.         DSA_AppendItem(_hdsaTBBMPs, &tbl);
  1914.         tbl.uiResID = IDB_VIEW_LARGE_COLOR;
  1915.         DSA_AppendItem(_hdsaTBBMPs, &tbl);
  1916.         tbl.uiResID = IDB_HIST_SMALL_COLOR;
  1917.         tbl.uiOffset = OFFSET_HIST;
  1918.         DSA_AppendItem(_hdsaTBBMPs, &tbl);
  1919.         tbl.uiResID = IDB_HIST_LARGE_COLOR;
  1920.         DSA_AppendItem(_hdsaTBBMPs, &tbl);
  1921.     }
  1922. }
  1923. void CInternetToolbar::_InitForScreenSize()
  1924. {
  1925.     TCHAR szScratch[16];
  1926.     if (GetSystemMetrics(SM_CXSCREEN) < 650) 
  1927.     {
  1928.         MLLoadString(IDS_TB_WIDTH_EXTRA_LORES, szScratch, ARRAYSIZE(szScratch));
  1929.         _uiMaxTBWidth = MAX_TB_WIDTH_LORES;
  1930.     } 
  1931.     else 
  1932.     {
  1933.         MLLoadString(IDS_TB_WIDTH_EXTRA_HIRES, szScratch, ARRAYSIZE(szScratch));
  1934.         _uiMaxTBWidth = MAX_TB_WIDTH_HIRES;
  1935.     }
  1936.     _uiMaxTBWidth += StrToInt(szScratch) * WIDTH_FACTOR;
  1937. }
  1938. // removes all buttons marked hidden.  returns the number
  1939. // of buttons left
  1940. int RemoveHiddenButtons(TBBUTTON* ptbn, int iCount)
  1941. {
  1942.     int i;
  1943.     int iTotal = 0;
  1944.     TBBUTTON* ptbn1 = ptbn;
  1945.     for (i = 0; i < iCount; i++, ptbn1++) 
  1946.     {
  1947.         if (!(ptbn1->fsState & TBSTATE_HIDDEN)) 
  1948.         {
  1949.             if (ptbn1 != ptbn) 
  1950.             {
  1951.                 *ptbn = *ptbn1;
  1952.             }
  1953.             ptbn++;
  1954.             iTotal++;
  1955.         }
  1956.     }
  1957.     return iTotal;
  1958. }
  1959. #ifdef DEBUG
  1960. void _AssertRestrictionOrderIsCorrect()
  1961. {
  1962.     COMPILETIME_ASSERT(ARRAYSIZE(c_tbExplorer) == ARRAYSIZE(c_rest));
  1963.     for (UINT i = 0; i < ARRAYSIZE(c_tbExplorer); i++)
  1964.     {
  1965.         // If any of these rip, it means that c_rest and c_tbExplorer have
  1966.         // gotten out of sync.  Need to fix up c_rest to match c_tbExplorer.
  1967.         switch (c_tbExplorer[i].idCommand)
  1968.         {
  1969.             case TBIDM_BACK:            ASSERT(c_rest[i] == REST_BTN_BACK);         break;
  1970.             case TBIDM_FORWARD:         ASSERT(c_rest[i] == REST_BTN_FORWARD);      break;
  1971.             case TBIDM_STOPDOWNLOAD:    ASSERT(c_rest[i] == REST_BTN_STOPDOWNLOAD); break;
  1972.             case TBIDM_REFRESH:         ASSERT(c_rest[i] == REST_BTN_REFRESH);      break;
  1973.             case TBIDM_HOME:            ASSERT(c_rest[i] == REST_BTN_HOME);         break;
  1974.             case TBIDM_SEARCH:          ASSERT(c_rest[i] == REST_BTN_SEARCH);       break;
  1975.             case TBIDM_HISTORY:         ASSERT(c_rest[i] == REST_BTN_HISTORY);      break;
  1976.             case TBIDM_FAVORITES:       ASSERT(c_rest[i] == REST_BTN_FAVORITES);    break;
  1977.             case TBIDM_ALLFOLDERS:      ASSERT(c_rest[i] == REST_BTN_ALLFOLDERS);   break;
  1978.             case TBIDM_THEATER:         ASSERT(c_rest[i] == REST_BTN_THEATER);      break;
  1979.             default:                    ASSERT(c_rest[i] == REST_BROWSER_NONE);     break;
  1980.         }
  1981.     }
  1982. }
  1983. #endif
  1984. __inline BOOL CInternetToolbar::_FoldersButtonAvailable()
  1985. {
  1986.     return (GetUIVersion() >= 4);
  1987. }
  1988. void CInternetToolbar::_AdminMarkDefaultButtons(PTBBUTTON ptbb, UINT cButtons)
  1989. {
  1990.     // We only have policies for web buttons.
  1991.     ASSERT(!_fShellView);
  1992.     // Caller should have checked this.
  1993.     ASSERT(SHRestricted2(REST_SPECIFYDEFAULTBUTTONS, NULL, 0));
  1994.     // SHRestricted2 returns 0 if it can't find the policy.  Assert that
  1995.     // this lines up with RESTOPT_BTN_STATE_DEFAULT.
  1996.     COMPILETIME_ASSERT(RESTOPT_BTN_STATE_DEFAULT == 0);
  1997.     for (UINT i = 0; i < cButtons; i++) 
  1998.     {
  1999.         if (c_rest[i] != 0) {
  2000.             DWORD dwRest = SHRestricted2(c_rest[i], NULL, 0);
  2001.             ptbb[i].fsState = SHBtnStateFromRestriction(dwRest, ptbb[i].fsState);
  2002.         }
  2003.     }
  2004.     // Folders button is not available on non-integrated platforms, so
  2005.     // set state to hidden even if policy specifies that it should be shown.
  2006.     ASSERT(c_tbExplorer[10].idCommand == TBIDM_ALLFOLDERS);
  2007.     if (!_FoldersButtonAvailable())
  2008.         ptbb[10].fsState |= TBSTATE_HIDDEN;
  2009. }
  2010. void CInternetToolbar::_MarkDefaultButtons(PTBBUTTON ptbb, UINT cButtons)
  2011. {
  2012.     if (_fShellView) 
  2013.     {
  2014.         ASSERT(c_tbExplorer[2].idCommand == TBIDM_STOPDOWNLOAD);
  2015.         ptbb[2].fsState |= TBSTATE_HIDDEN;
  2016.         ASSERT(c_tbExplorer[3].idCommand == TBIDM_REFRESH);
  2017.         ptbb[3].fsState |= TBSTATE_HIDDEN;
  2018.         ASSERT(c_tbExplorer[4].idCommand == TBIDM_HOME);
  2019.         ptbb[4].fsState |= TBSTATE_HIDDEN;
  2020.         ASSERT(c_tbExplorer[9].idCommand == TBIDM_SEARCH);
  2021.         ASSERT(c_tbExplorer[12].idCommand == TBIDM_HISTORY);
  2022.         ASSERT(c_tbExplorer[13].idCommand == 0);    // (a separator)
  2023.         if (GetUIVersion() < 5) 
  2024.         {
  2025.             ptbb[9].fsState |= TBSTATE_HIDDEN;
  2026.             ptbb[12].fsState |= TBSTATE_HIDDEN;
  2027.             ptbb[13].fsState |= TBSTATE_HIDDEN;
  2028.         }
  2029.         else
  2030.         {
  2031.             if (SHRestricted(REST_NOSHELLSEARCHBUTTON))
  2032.             {
  2033.                 ptbb[9].fsState |= TBSTATE_HIDDEN;
  2034.             }
  2035.             ASSERT(c_tbExplorer[6].idCommand == TBIDM_CONNECT);
  2036.             ASSERT(c_tbExplorer[7].idCommand == TBIDM_DISCONNECT);
  2037.             if (SHRestricted(REST_NONETCONNECTDISCONNECT))
  2038.             {
  2039.                 ptbb[6].fsState |= TBSTATE_HIDDEN;
  2040.                 ptbb[7].fsState |= TBSTATE_HIDDEN;
  2041.             }
  2042.         }
  2043.         ASSERT(c_tbExplorer[11].idCommand == TBIDM_FAVORITES);
  2044.         ptbb[11].fsState |= TBSTATE_HIDDEN;
  2045.     }
  2046.     ASSERT(c_tbExplorer[5].idCommand == TBIDM_PREVIOUSFOLDER);
  2047.     if (!_fShellView)
  2048.         ptbb[5].fsState |= TBSTATE_HIDDEN;
  2049.     ASSERT(c_tbExplorer[6].idCommand == TBIDM_CONNECT);
  2050.     ASSERT(c_tbExplorer[7].idCommand == TBIDM_DISCONNECT);
  2051.     if (!_fShellView || !_UseMapNetDrvBtns()) 
  2052.     {
  2053.         ptbb[6].fsState |= TBSTATE_HIDDEN;
  2054.         ptbb[7].fsState |= TBSTATE_HIDDEN;
  2055.     }
  2056.     // If this TBIDM_ALLFOLDERS assertion rips, remember to fix up _AdminMarkDefaultButtons too.
  2057.     ASSERT(c_tbExplorer[10].idCommand == TBIDM_ALLFOLDERS);
  2058.     if (!_fShellView || GetUIVersion() < 5)
  2059.         ptbb[10].fsState |= TBSTATE_HIDDEN;
  2060.     ASSERT(c_tbExplorer[14].idCommand == TBIDM_THEATER);
  2061.     ptbb[14].fsState |= TBSTATE_HIDDEN;
  2062. }
  2063. void CInternetToolbar::_AddCommonButtons()
  2064. {
  2065.     TBBUTTON    tbExplorer[ARRAYSIZE(c_tbExplorer)];
  2066.     memcpy(tbExplorer, c_tbExplorer, SIZEOF(TBBUTTON) * ARRAYSIZE(c_tbExplorer));
  2067.     _MarkDefaultButtons(tbExplorer, ARRAYSIZE(c_tbExplorer));
  2068. #ifdef DEBUG
  2069.     _AssertRestrictionOrderIsCorrect();
  2070. #endif
  2071.     if (!_fShellView && SHRestricted2(REST_SPECIFYDEFAULTBUTTONS, NULL, 0))
  2072.         _AdminMarkDefaultButtons(tbExplorer, ARRAYSIZE(c_tbExplorer));
  2073.     int iButtons = RemoveHiddenButtons(tbExplorer, ARRAYSIZE(tbExplorer));
  2074.     for (int i = 0; i < iButtons; i++) 
  2075.     {
  2076.         if (!(tbExplorer[i].fsStyle & BTNS_SEP)) 
  2077.         {
  2078.             CMDMAP* pcm = (CMDMAP*)LocalAlloc(LPTR, SIZEOF(CMDMAP));
  2079.             if (pcm) 
  2080.             {
  2081.                 pcm->guidButtonGroup = CLSID_CommonButtons;
  2082.                 pcm->nCmdID = tbExplorer[i].idCommand;
  2083.                 tbExplorer[i].idCommand = _btb._nNextCommandID++;
  2084.                 tbExplorer[i].dwData = (LPARAM)pcm;
  2085.             }
  2086.         }
  2087.     }
  2088.     SendMessage(_btb._hwnd, TB_ADDBUTTONS, iButtons, (LPARAM) tbExplorer);
  2089.     _btb._RecalcButtonWidths();
  2090. }
  2091. #define IS_LIST_STYLE(hwnd) (BOOLIFY(GetWindowLong(hwnd, GWL_STYLE) & TBSTYLE_LIST))
  2092. void CInternetToolbar::_UpdateToolsStyle(BOOL fList)
  2093. {
  2094.     if (BOOLIFY(fList) != IS_LIST_STYLE(_btb._hwnd))
  2095.     {
  2096.         _fDirty = TRUE;
  2097.         // toggle TBSTYLE_LIST
  2098.         SHSetWindowBits(_btb._hwnd, GWL_STYLE, TBSTYLE_LIST, fList ? TBSTYLE_LIST : 0);
  2099.         // toggle TBSTYLE_EX_MIXEDBUTTONS
  2100.         SendMessage(_btb._hwnd, TB_SETEXTENDEDSTYLE, TBSTYLE_EX_MIXEDBUTTONS, fList ? TBSTYLE_EX_MIXEDBUTTONS : 0);
  2101.     }
  2102. }
  2103. void CInternetToolbar::_InitToolbar()
  2104. {
  2105.     TCHAR szShellTBText[1024];  // This should be enough
  2106.     ZeroMemory(szShellTBText, sizeof(szShellTBText));
  2107.     int nRows = _fCompressed ? 0 : _uiTBTextRows;
  2108.     // this tells the toolbar what version we are
  2109.     SendMessage(_btb._hwnd, TB_BUTTONSTRUCTSIZE,    SIZEOF(TBBUTTON), 0);
  2110.     SendMessage(_btb._hwnd, TB_SETEXTENDEDSTYLE,    0,
  2111.                     TBSTYLE_EX_DRAWDDARROWS | TBSTYLE_EX_HIDECLIPPEDBUTTONS);
  2112.     SendMessage(_btb._hwnd, TB_SETMAXTEXTROWS,      nRows, 0L);
  2113.     SendMessage(_btb._hwnd, TB_SETDROPDOWNGAP,  GetSystemMetrics(SM_CXEDGE) / 2, 0);
  2114.     SendMessage(_btb._hwnd, CCM_SETVERSION, COMCTL32_VERSION, 0);
  2115.     _UpdateToolsStyle(_cs.fList);
  2116.     ITBar_LoadToolbarGlyphs(_btb._hwnd);
  2117.     _InitBitmapDSA();
  2118.     _InitForScreenSize();
  2119.     SendMessage(_btb._hwnd, TB_ADDSTRING, (WPARAM)MLGetHinst(), IDS_IE_TB_LABELS);
  2120.     _AddCommonButtons();
  2121.     INT_PTR nRet = SendMessage(_btb._hwnd, TB_ADDSTRING, (WPARAM)MLGetHinst(), IDS_SHELL_TB_LABELS);
  2122.     ASSERT(nRet == SHELLTOOLBAR_OFFSET);
  2123. }
  2124. HRESULT CInternetToolbar::_ShowTools(PBANDSAVE pbs)
  2125. {
  2126.     HRESULT         hr  = S_OK;
  2127.     LPBANDITEMDATA  pbid = _bs._GetBandItemDataStructByID(CBIDX_TOOLS);
  2128.     if (!pbid) {
  2129.         ASSERT(!_btb._hwnd);
  2130.         _btb._hwnd = CreateWindowEx(WS_EX_TOOLWINDOW, TOOLBARCLASSNAME, NULL,
  2131.                                 WS_CHILD | TBSTYLE_FLAT |
  2132.                                 TBSTYLE_TOOLTIPS |
  2133.                                 WS_CLIPCHILDREN |
  2134.                                 WS_CLIPSIBLINGS | CCS_NODIVIDER | CCS_NOPARENTALIGN |
  2135.                                 CCS_NORESIZE,
  2136.                                 0, 0, 0, 0, _bs._hwnd, (HMENU) FCIDM_TOOLBAR, HINST_THISDLL, NULL);
  2137.         if (_btb._hwnd) {
  2138.             _btb._hwnd = _btb._hwnd;
  2139.             _InitToolbar();
  2140.             pbid = _AddNewBand((IDeskBand*)&_btb, CBIDX_TOOLS);
  2141.         }
  2142.         if (!pbid)
  2143.             return E_OUTOFMEMORY;
  2144.     } else {
  2145.         pbs = NULL;
  2146.     }
  2147.     _ShowBandCommon(pbs, pbid, _nVisibleBands & VBF_TOOLS);
  2148.     return hr;
  2149. }
  2150. void CInternetToolbar::_ShowBandCommon(PBANDSAVE pbs, LPBANDITEMDATA pbid, BOOL fShow)
  2151. {
  2152.     REBARBANDINFO   rbbi;
  2153.     pbid->fShow = BOOLIFY(fShow);
  2154.     pbid->pdb->ShowDW(pbid->fShow);
  2155.     INT_PTR i = BandIDtoIndex(_bs._hwnd, pbid->dwBandID);
  2156.     if (pbs)
  2157.     {
  2158.         rbbi.cbSize = sizeof(REBARBANDINFO);
  2159.         rbbi.fMask = RBBIM_SIZE | RBBIM_STYLE;
  2160.         // we just want to change the RBBS_BREAK bit
  2161.         // assert that our caller doesn't expect to set any other bits
  2162.         // ASSERT(!(pbs->fStyle & ~RBBS_BREAK)); <--- I hit this assert all the time
  2163.         // get old style
  2164.         SendMessage(_bs._hwnd, RB_GETBANDINFO, i, (LPARAM)&rbbi);
  2165.         rbbi.fStyle = (rbbi.fStyle & ~RBBS_BREAK) | (pbs->fStyle & RBBS_BREAK);
  2166.         rbbi.cx = pbs->cx;
  2167.         SendMessage(_bs._hwnd, RB_SETBANDINFO, i, (LPARAM)&rbbi);
  2168.     }
  2169.     if ( pbid->dwModeFlags & DBIMF_BREAK )
  2170.     {
  2171.         rbbi.cbSize = sizeof(REBARBANDINFO);
  2172.         rbbi.fMask = RBBIM_STYLE;
  2173.         if (SendMessage(_bs._hwnd, RB_GETBANDINFO, i, (LPARAM) &rbbi))
  2174.         {
  2175.             // in theater mode we don't allow bands to have breaks
  2176.             if ((rbbi.fStyle & RBBS_BREAK ) && _fTheater)
  2177.             {
  2178.                 rbbi.fStyle &= ~RBBS_BREAK;
  2179.                 SendMessage(_bs._hwnd, RB_SETBANDINFO, i, (LPARAM) &rbbi);
  2180.             }
  2181.         }
  2182.     }
  2183.     SendMessage(_bs._hwnd, RB_SHOWBAND, i, pbid->fShow);
  2184. }
  2185. HRESULT CInternetToolbar::_GetPersistedBand(const CLSID clsid, REFIID riid, void ** ppiface)
  2186. {
  2187.     HRESULT hr  = E_FAIL;
  2188.     TCHAR szStreamName[MAX_PATH];
  2189.     if (SUCCEEDED(_GetStreamName(_fInitialPidlIsWeb, szStreamName, ARRAYSIZE(szStreamName))))
  2190.     {
  2191.         static BOOL fBrowserOnly = (WhichPlatform() != PLATFORM_INTEGRATED);
  2192.         TCHAR szKey[MAX_PATH];
  2193.         TCHAR szGUID[MAX_PATH];
  2194.         wnsprintf(szKey, ARRAYSIZE(szKey), TEXT("Software\Microsoft\Internet Explorer\Toolbar\%s"), szStreamName);
  2195.         SHStringFromGUID(clsid, szGUID, ARRAYSIZE(szGUID));
  2196.         if (ERROR_SUCCESS == SHGetValue(HKEY_CURRENT_USER, szKey, szGUID, NULL, NULL, NULL))
  2197.         {
  2198.             // Was the stream saved by an Integrated shell and we are in browser only mode?
  2199.             if ((_cs.fSaveInShellIntegrationMode) && fBrowserOnly)
  2200.             {
  2201.                 // Yes, so we need to ignore the stream.
  2202.             }
  2203.             else
  2204.             {
  2205.                 IStream * pstm = GetRegStream(_fInitialPidlIsWeb, szGUID, STGM_READ);
  2206.                 if (pstm)
  2207.                 {
  2208.                     hr = _bs.LoadFromStreamBS(pstm, riid, ppiface);
  2209.                     pstm->Release();
  2210.                 }
  2211.             }
  2212.         }
  2213.     }
  2214.     if (FAILED(hr))
  2215.     {
  2216.         hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, riid, ppiface);
  2217.         if (SUCCEEDED(hr))
  2218.         {
  2219.             IPersistStreamInit * ppsi;
  2220.             ((IUnknown *) *ppiface)->QueryInterface(IID_IPersistStreamInit, (void **) &ppsi);
  2221.             if (ppsi)
  2222.             {
  2223.                 ppsi->InitNew();
  2224.                 ppsi->Release();
  2225.             }
  2226.         }
  2227.     }
  2228.     return hr;
  2229. }
  2230. HRESULT CInternetToolbar::_ShowExternalBand( PBANDSAVE pbs, int idBand )
  2231. {
  2232.     HRESULT hr;
  2233.     if (IS_EXTERNALBAND(idBand))
  2234.     {
  2235.         int idBandExt = MAP_TO_EXTERNAL(idBand);
  2236.         if (!IsEqualCLSID(_rgebi[idBandExt].clsid, GUID_NULL))
  2237.         {
  2238.             LPBANDITEMDATA pbid = _bs._GetBandItemDataStructByID( idBand );
  2239.             BOOL fIsVisible = _nVisibleBands & EXTERNALBAND_VBF_BIT(idBandExt);
  2240.             if (!pbid && fIsVisible)
  2241.             {
  2242.                 IDeskBand *pitbBand;
  2243.                 hr = _GetPersistedBand(_rgebi[idBandExt].clsid, IID_IDeskBand, (void **) &pitbBand);
  2244.                 if (SUCCEEDED(hr))
  2245.                 {
  2246.                     pbid = _AddNewBand( pitbBand, idBand );
  2247.                     pitbBand->Release();
  2248.                 }
  2249.                 if (!pbid)
  2250.                     return E_OUTOFMEMORY;
  2251.             } else {
  2252.                 pbs = NULL;
  2253.                 if (!pbid)
  2254.                     return S_OK;
  2255.             }
  2256.             _ShowBandCommon(pbs, pbid, fIsVisible );
  2257.         }
  2258.     }
  2259.     return S_OK;
  2260. }
  2261. HRESULT CInternetToolbar::_ShowAddressBand(PBANDSAVE pbs)
  2262. {
  2263.     HRESULT         hr  = S_OK;
  2264.     LPBANDITEMDATA  pbid = _bs._GetBandItemDataStructByID(CBIDX_ADDRESS);
  2265.     if (!pbid)
  2266.     {
  2267.         IDeskBand *pitbAddressBand;
  2268.         hr = _GetPersistedBand(CLSID_AddressBand, IID_IDeskBand, (void **)&pitbAddressBand);
  2269.         if (SUCCEEDED(hr))
  2270.         {
  2271.             pbid = _AddNewBand(pitbAddressBand, CBIDX_ADDRESS);
  2272.             if (pbid)
  2273.                 _hwndAddressBand = pbid->hwnd;
  2274.             pitbAddressBand->Release();
  2275.         }
  2276.         ASSERT(IS_VALID_HANDLE(_hwndAddressBand, WND));
  2277.         if (!pbid)
  2278.             return E_OUTOFMEMORY;
  2279.     } else
  2280.         pbs = NULL;
  2281.     _ShowBandCommon(pbs, pbid, _nVisibleBands & VBF_ADDRESS);
  2282.     return S_OK;
  2283. }
  2284. LPBANDITEMDATA CInternetToolbar::_AddNewBand(IDeskBand* pdb, DWORD dwID)
  2285. {
  2286.     if (SUCCEEDED(_bs._AddBandByID(pdb, dwID)))
  2287.     {
  2288.         return _bs._GetBandItemDataStructByID(dwID);
  2289.     }
  2290.     return NULL;
  2291. }
  2292. HRESULT CInternetToolbar::_ShowLinks(PBANDSAVE pbs)
  2293. {
  2294.     HRESULT hr = S_OK;
  2295.     LPBANDITEMDATA pbid = _bs._GetBandItemDataStructByID(CBIDX_LINKS);
  2296.     if (!pbid)
  2297.     {
  2298.         IDeskBand* pdbLinks = NULL;
  2299.         // Check if custom link band GUID is present in the registry,
  2300.         // and if so, do a full CoCreateInstance using this GUID.
  2301.         // Otherwise, just do the normal internal call to the link's band factory.
  2302.         if (!_fInitialPidlIsWeb ||
  2303.             FAILED(CreateFromRegKey(c_szRegKeyCoolbar, TEXT("QuickLinksCLSID"), IID_IDeskBand, (void **)&pdbLinks)))
  2304.         {
  2305.             hr = _GetPersistedBand(CLSID_QuickLinks, IID_IDeskBand, (void **)&pdbLinks);
  2306.             IUnknown_Exec(pdbLinks, &CLSID_QuickLinks, QLCMD_SINGLELINE, 1, NULL, NULL);
  2307.         }
  2308.         if (pdbLinks)
  2309.         {
  2310.             // mark it so ISFBand knows it's qlinks (for UAssist)
  2311.             VARIANTARG v;
  2312. #ifdef DEBUG
  2313.             {
  2314.                 // n.b. we overwrite old persisted guys (which should be -1)
  2315.                 IUnknown_Exec(pdbLinks, &CGID_ISFBand, ISFBID_PRIVATEID, 0, NULL, &v);
  2316.                 ASSERT(v.lVal == -1 || v.lVal == CSIDL_FAVORITES);
  2317.             }
  2318. #endif
  2319.             v.vt = VT_I4;
  2320.             v.lVal = CSIDL_FAVORITES;   // close enough for our purposes...
  2321.             IUnknown_Exec(pdbLinks, &CGID_ISFBand, ISFBID_PRIVATEID, 0, &v, NULL);
  2322.             pbid = _AddNewBand(pdbLinks, CBIDX_LINKS);
  2323.             pdbLinks->Release();
  2324.         }
  2325.         if (!pbid)
  2326.             return E_OUTOFMEMORY;
  2327.     } else
  2328.         pbs = NULL;
  2329.     _ShowBandCommon(pbs, pbid, _nVisibleBands & VBF_LINKS);
  2330.     return hr;
  2331. }
  2332. HRESULT CInternetToolbar::_ShowMenu(PBANDSAVE pbs)
  2333. {
  2334.     LPBANDITEMDATA pbid = _bs._GetBandItemDataStructByID(CBIDX_MENU);
  2335.     if (!pbid)
  2336.     {
  2337.         CFavoritesCallback* pfcb = new CFavoritesCallback();
  2338.         if (pfcb)
  2339.         {
  2340.             IShellMenu* psm = (IShellMenu*)new CMenuBand();
  2341.             if (psm)
  2342.             {
  2343.                 VARIANTARG var;
  2344.                 if (SUCCEEDED(IUnknown_Exec(_pbs2, &CGID_Explorer, SBCMDID_GETCURRENTMENU, 0, NULL, &var)) &&
  2345.                         var.vt == VT_INT_PTR && var.byref)
  2346.                 {
  2347.                     IDeskBand* pdbMenu;
  2348.                     psm->Initialize(pfcb, -1, ANCESTORDEFAULT, SMINIT_HORIZONTAL | SMINIT_TOPLEVEL);
  2349.                     if (SUCCEEDED(psm->SetMenu((HMENU)var.byref, GetParent(_hwnd), SMSET_DONTOWN)))
  2350.                     {
  2351.                         if (SUCCEEDED(psm->QueryInterface(IID_IDeskBand, (void**)&pdbMenu)))
  2352.                         {
  2353.                             pbid = _AddNewBand(pdbMenu, CBIDX_MENU);
  2354.                             if (pbid)
  2355.                             {
  2356.                                 // Tell the menuband we're not a real bar/bandsite/band
  2357.                                 IUnknown_Exec(pbid->pdb, &CGID_MenuBand, MBANDCID_NOTAREALSITE, TRUE, NULL, NULL);
  2358.                                 _bs.SetBandState(CBIDX_MENU, BSSF_NOTITLE, BSSF_NOTITLE);
  2359.                                 _hwndMenu = pbid->hwnd;
  2360.                             }
  2361.                             ASSERT(IS_VALID_HANDLE(_hwndMenu, WND));
  2362.                             pdbMenu->Release();
  2363.                         }
  2364.                     }
  2365.                 }
  2366.                 psm->Release();
  2367.             }
  2368.             pfcb->Release();
  2369.         }
  2370.         if (!pbid)
  2371.             return E_OUTOFMEMORY;
  2372.     } else
  2373.         pbs = NULL;
  2374.     _ShowBandCommon(pbs, pbid, _nVisibleBands & VBF_MENU);
  2375.     return S_OK;
  2376. }
  2377. HRESULT _GetBackBitmapLocation(LPTSTR psz, BOOL fInternet)
  2378. {
  2379.     HRESULT hres = E_FAIL;
  2380.     DWORD dwType;
  2381.     DWORD dwcbData;
  2382.     // IE4 shipped back bitmap customization affecting both browser and shell.
  2383.     // IE5 wants these to be separate customizations.  But in the roaming
  2384.     // case a customized IE4 customer shouldn't lose customization when going
  2385.     // to the IE5 machine.  So we might need to check twice:
  2386.     //
  2387.     if (fInternet)
  2388.     {
  2389.         // Try the IE5 internet location.
  2390.         dwcbData = MAX_PATH * SIZEOF(TCHAR);
  2391.         hres = SHGetValue(HKEY_CURRENT_USER, c_szRegKeyCoolbar, TEXT("BackBitmapIE5"), &dwType, psz, &dwcbData);
  2392.     }
  2393.     else
  2394.     {
  2395.         // Try the NT5 shell location.
  2396.         dwcbData = MAX_PATH * SIZEOF(TCHAR);
  2397.         hres = SHGetValue(HKEY_CURRENT_USER, c_szRegKeyCoolbar, TEXT("BackBitmapShell"), &dwType, psz, &dwcbData);
  2398.     }
  2399.     if (ERROR_SUCCESS != hres)
  2400.     {
  2401.         // Try the old combined internet/shell location
  2402.         dwcbData = MAX_PATH * SIZEOF(TCHAR);
  2403.         hres = SHGetValue(HKEY_CURRENT_USER, c_szRegKeyCoolbar, TEXT("BackBitmap"), &dwType, psz, &dwcbData);
  2404.     }
  2405.     if (ERROR_SUCCESS != hres)
  2406.     {
  2407.         *psz = '';
  2408.     }
  2409.     return hres;
  2410. }
  2411. HBITMAP CInternetToolbar::_LoadBackBmp(LPTSTR * ppszBitmap, BMPCACHE * pbmpCache, BOOL fInternet)
  2412. {
  2413.     HIGHCONTRAST    hc;
  2414.     HBITMAP     hbmp = pbmpCache->hbmp;
  2415.     COLORREF    cr3D = GetSysColor(COLOR_3DFACE);
  2416.     TCHAR       szScratch[MAX_PATH];
  2417.     LPTSTR      pszBitmap = NULL;
  2418.     BOOL        fBitmapInvalid = FALSE;
  2419.     ENTERCRITICAL;
  2420.     // If the stashed hbmp's cr3D color changed, we need to mark invalid
  2421.     if (pbmpCache->hbmp && pbmpCache->cr3D != cr3D)
  2422.         fBitmapInvalid = TRUE;
  2423.     // get the location spec for the bitmap
  2424.     hc.cbSize = sizeof(HIGHCONTRAST);
  2425.     if ((SystemParametersInfoA(SPI_GETHIGHCONTRAST, hc.cbSize, (LPVOID) &hc, FALSE)) &&
  2426.         (hc.dwFlags & HCF_HIGHCONTRASTON))
  2427.     {
  2428.         // we have no bitmap in high contrast
  2429.     }
  2430.     else if (SUCCEEDED(_GetBackBitmapLocation(szScratch, fInternet)))
  2431.     {
  2432.         pszBitmap = szScratch;
  2433.     }
  2434.     // if they are removing the bitmap, we need to mark invalid
  2435.     if (!pszBitmap && *ppszBitmap)
  2436.         fBitmapInvalid = TRUE;
  2437.     // or it's location has been changed, we need to mark invalid
  2438.     if (pszBitmap && (!*ppszBitmap || lstrcmpi(pszBitmap, *ppszBitmap)))
  2439.         fBitmapInvalid = TRUE;
  2440.     if (fBitmapInvalid)
  2441.     {
  2442.         TraceMsg(DM_ITBAR, "CInternetToolbar: Loading Background Bitmap");
  2443.         Str_SetPtr(ppszBitmap, pszBitmap);
  2444.         hbmp=NULL;
  2445.         if (*ppszBitmap)
  2446.         {
  2447.             if ((*ppszBitmap)[0])
  2448.                 hbmp = (HBITMAP) LoadImage(NULL, szScratch, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_CREATEDIBSECTION | LR_LOADFROMFILE | LR_LOADMAP3DCOLORS );
  2449.             if (!hbmp)
  2450.             {
  2451. #ifdef OLD_SWIRLY_BACKDROP
  2452.                 if (SHGetCurColorRes() <= 8)
  2453.                     hbmp = (HBITMAP) LoadImage(HINST_THISDLL, MAKEINTRESOURCE(IDB_BACK), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_CREATEDIBSECTION | LR_LOADMAP3DCOLORS );
  2454. #endif
  2455.             }
  2456.         }
  2457. #ifdef OLD_LEGACY_BAD_COLOUR_CODE
  2458.         if (hbmp)
  2459.         {
  2460.             // mapping needed ?
  2461.             // BUGBUG: this will be removed as soon as I get the new backdrop....
  2462.             if ( /* cr3D != RGB(192,192,192) */ FALSE)
  2463.             {
  2464.                 RGBQUAD     rgbTable[256];
  2465.                 RGBQUAD     rgbFace;
  2466.                 HDC         dc;
  2467.                 HBITMAP     hbmSave;
  2468.                 UINT        i;
  2469.                 UINT        n;
  2470.                 dc = CreateCompatibleDC(NULL);
  2471.                 hbmSave = (HBITMAP)SelectObject(dc, hbmp);
  2472.                 n = GetDIBColorTable(dc, 0, 256, rgbTable);
  2473.                 rgbFace.rgbRed   = GetRValue(cr3D);
  2474.                 rgbFace.rgbGreen = GetGValue(cr3D);
  2475.                 rgbFace.rgbBlue  = GetBValue(cr3D);
  2476.                 for (i = 0; i < n; i++)
  2477.                 {
  2478.                     if ( rgbTable[i].rgbRed == 192 && rgbTable[i].rgbGreen == 192 && rgbTable[i].rgbBlue == 192 )
  2479.                     {
  2480.                         rgbTable[i] = rgbFace;
  2481.                     }
  2482.                     else
  2483.                     {
  2484.                         rgbTable[i].rgbRed   = (rgbTable[i].rgbRed   * rgbFace.rgbRed  ) / 192;
  2485.                         rgbTable[i].rgbGreen = (rgbTable[i].rgbGreen * rgbFace.rgbGreen) / 192;
  2486.                         rgbTable[i].rgbBlue  = (rgbTable[i].rgbBlue  * rgbFace.rgbBlue ) / 192;
  2487.                     }
  2488.                 }
  2489.                 SetDIBColorTable(dc, 0, n, rgbTable);
  2490.                 SelectObject(dc, hbmSave);
  2491.                 DeleteDC(dc);
  2492.             }
  2493.         }
  2494. #endif
  2495.         if (pbmpCache->hbmp)
  2496.             DeleteObject(pbmpCache->hbmp);
  2497.         pbmpCache->hbmp = hbmp;
  2498.         pbmpCache->cr3D = cr3D;
  2499.     }
  2500.     LEAVECRITICAL;
  2501.     return hbmp;
  2502. }
  2503. HBITMAP CInternetToolbar::_LoadBackBitmap()
  2504. {
  2505.     if (SHIsLowMemoryMachine(ILMM_IE4))
  2506.         return NULL;
  2507.     if (_fInitialPidlIsWeb)
  2508.     {
  2509.         static LPTSTR s_pszBitmapInternet = NULL;
  2510.         return _LoadBackBmp(&s_pszBitmapInternet, &s_bmpBackInternet, _fInitialPidlIsWeb);
  2511.     }
  2512.     else
  2513.     {
  2514.         static LPTSTR s_pszBitmapShell = NULL;
  2515.         return _LoadBackBmp(&s_pszBitmapShell, &s_bmpBackShell, _fInitialPidlIsWeb);
  2516.     }
  2517. }
  2518. void CInternetToolbar::_SetBackground()
  2519. {
  2520.     REBARBANDINFO   rbbi;
  2521.     HBITMAP         hbmp;
  2522.     // Theater mode doesn't allow bitmap customization, so don't bother loading one from the cache
  2523.     if (_fTheater)
  2524.         hbmp = NULL;
  2525.     else
  2526.         hbmp = _LoadBackBitmap();
  2527.     // don't bother updating the bkcolor if we know we'll just set it to CLR_NONE below (otherwise rebar invalidates)
  2528.     if (!hbmp)
  2529.         SendMessage(_bs._hwnd, RB_SETBKCOLOR, 0, (LPARAM)GetSysColor(COLOR_BTNFACE));
  2530.     // If we think we have a bitmap, or the cache thinks we have a bitmap, we have some work to do
  2531.     if (_bmpBack || hbmp)
  2532.     {
  2533.         BOOL fRemove = (NULL!=_bmpBack && NULL==hbmp);
  2534.         if (hbmp)
  2535.             SendMessage(_bs._hwnd, RB_SETBKCOLOR, 0, (LPARAM)CLR_NONE);
  2536.         _bmpBack = hbmp;
  2537.         rbbi.cbSize = sizeof(REBARBANDINFO);
  2538.         INT_PTR fRedraw = SendMessage(_bs._hwnd, WM_SETREDRAW, FALSE, 0);
  2539.         INT icBands = (INT) SendMessage( _bs._hwnd, RB_GETBANDCOUNT, 0, 0 );
  2540.         for (int i = 0; i < icBands; i++)
  2541.         {
  2542.             rbbi.fMask = RBBIM_ID | RBBIM_CHILD | RBBIM_BACKGROUND;
  2543.             if (SendMessage(_bs._hwnd, RB_GETBANDINFO, i, (LPARAM) &rbbi))
  2544.             {
  2545.                 if (rbbi.wID != CBIDX_BRAND && rbbi.hbmBack != hbmp)
  2546.                 {
  2547.                     rbbi.fMask = RBBIM_BACKGROUND;
  2548.                     rbbi.hbmBack = hbmp;
  2549.                     SendMessage(_bs._hwnd, RB_SETBANDINFO, i, (LPARAM) &rbbi);
  2550.                     InvalidateRect(rbbi.hwndChild, NULL, TRUE);
  2551.                 }
  2552.             }
  2553.         }
  2554.         SendMessage(_bs._hwnd, WM_SETREDRAW, fRedraw, 0);
  2555.         // When removing the background bitmap, we need to invalidate *outside*
  2556.         // of the WM_SETREDRAW so we actually erase the background properly
  2557.         //
  2558.         if (fRemove)
  2559.             InvalidateRect(_bs._hwnd, NULL, TRUE);
  2560.     }
  2561. }
  2562. HRESULT CInternetToolbar::_ShowBrand(PBANDSAVE pbs)
  2563. {
  2564.     REBARBANDINFO       rbbi;
  2565.     LPBANDITEMDATA      pbid;
  2566.     INT_PTR             i;
  2567.     HRESULT             hr = S_OK;
  2568.     BOOL                fCreated = FALSE;
  2569.     pbid = _bs._GetBandItemDataStructByID(CBIDX_BRAND);
  2570.     if (!pbid)
  2571.     {
  2572.         IDeskBand *pdbBrandBand;
  2573.         hr = CBrandBand_CreateInstance(NULL, (IUnknown **)&pdbBrandBand, NULL);
  2574.         if (SUCCEEDED(hr))
  2575.         {
  2576.             pbid = _AddNewBand(pdbBrandBand, CBIDX_BRAND);
  2577.             fCreated = TRUE;
  2578.             pdbBrandBand->Release();
  2579.         }
  2580.         else
  2581.             return hr;
  2582.     }
  2583.     if (!pbid)
  2584.         return E_OUTOFMEMORY;
  2585.     pbid->pdb->ShowDW(TRUE);
  2586.     i = BandIDtoIndex(_bs._hwnd, CBIDX_BRAND);
  2587.     if (fCreated)
  2588.     {
  2589.         // add these to ::IDeskBand::GetBandInfo()
  2590.         rbbi.cbSize = sizeof(REBARBANDINFO);
  2591.         rbbi.fMask = RBBIM_STYLE;
  2592.         rbbi.fStyle = RBBS_FIXEDSIZE | RBBS_VARIABLEHEIGHT;
  2593.         if (pbs)
  2594.         {
  2595.             rbbi.fMask |= RBBIM_SIZE;
  2596.             rbbi.fStyle |= pbs->fStyle;
  2597.             rbbi.cx = pbs->cx;
  2598.         }
  2599.         SendMessage(_bs._hwnd, RB_SETBANDINFO, i, (LPARAM)&rbbi);
  2600.         // this can cause the band to move because a fixed size band
  2601.         // is forced in a particular location.
  2602.         // so we need to re-fetch the index
  2603.         i = BandIDtoIndex(_bs._hwnd, CBIDX_BRAND);
  2604.     }
  2605.     SendMessage(_bs._hwnd, RB_SHOWBAND, i, _nVisibleBands & VBF_BRAND);
  2606.     return S_OK;
  2607. }
  2608. void CInternetToolbar::_EnsureAllBandsShown()
  2609. {
  2610.     if (_hwnd) {
  2611.         INT_PTR fRedraw = SendMessage(_bs._hwnd, WM_SETREDRAW, FALSE, 0);
  2612.         _ShowMenu(NULL);
  2613.         _ShowTools(NULL);
  2614.         _ShowAddressBand(NULL);
  2615.         _ShowLinks(NULL);
  2616.         _ShowBrand(NULL);
  2617.         for (int i = CBIDX_EXTERNALFIRST; i <= CBIDX_EXTERNALLAST; i++) {
  2618.             _ShowExternalBand( NULL, i );
  2619.         }
  2620.         _SetBackground();
  2621.         _bs._SetMinDimensions();
  2622.         SendMessage(_bs._hwnd, WM_SETREDRAW, fRedraw, 0);
  2623.     }
  2624. }
  2625. BOOL CInternetToolbar::_ShowBands(UINT fVisible)
  2626. {
  2627.     fVisible &= VBF_VALID;
  2628.     if (fVisible == _nVisibleBands)
  2629.         return(TRUE);
  2630.     _nVisibleBands = fVisible;
  2631.     _EnsureAllBandsShown();
  2632.     ShowDW(_fShow);
  2633.     return(TRUE);
  2634. }
  2635. HRESULT CInternetToolbar::_CreateBands()
  2636. {
  2637.     HRESULT hres = S_OK;
  2638.     if (!_hwnd && _ptbsite)
  2639.     {
  2640.         HWND hwndParent;
  2641.         hres= _ptbsite->GetWindow(&hwndParent);
  2642.         if (SUCCEEDED(hres))
  2643.         {
  2644.             TCHAR szScratch[16];
  2645.             int i;
  2646.             // Check if coolbar layout had already been loaded from the registry
  2647.             if(_cs.cbVer != CBS_VERSION)
  2648.             {
  2649.                 TraceMsg(DM_ITBAR, "CInternetToolbar:ShowDW failed. Bad Version");
  2650.                 ASSERT(0);
  2651.                 return(S_FALSE);
  2652.             }
  2653.             _nVisibleBands = _cs.uiVisible;
  2654.             _InitComCtl32();    // don't check result, if this fails our CreateWindows will fail
  2655.             MLLoadString(IDS_WEB_TB_TEXTROWS, szScratch, ARRAYSIZE(szScratch));
  2656.             _uiTBTextRows = _uiTBDefaultTextRows = StrToInt(szScratch);
  2657.             _fCompressed = (_cs.fNoText != FALSE);
  2658.             _hwnd = SHCreateWorkerWindow(SizableWndProc, hwndParent, 0, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  2659.                                        (HMENU)FCIDM_REBAR, this);
  2660.             if (!IS_VALID_HANDLE(_hwnd, WND))
  2661.             {
  2662.                 TraceMsg(TF_ERROR, "_hwnd failed");
  2663.                 return E_OUTOFMEMORY;
  2664.             }
  2665.             // delay until now
  2666.             // this sets up the parent child chain so that these children can
  2667.             // queryservice through us
  2668.             SetClient(SAFECAST(&_bs, IInputObjectSite*));