Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2680 lines
83 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) 1993-1996 Microsoft Corporation. All Rights Reserved.
  3. //
  4. // MODULE: itbar.cpp
  5. //
  6. // PURPOSE: Implements the sizable coolbar window.
  7. //
  8. /********************************************************************************
  9. Please do not make any changes to this file because this file is going to be
  10. deleted from this project soon
  11. Instead add the changes to tbbands.cpp and tbbands.h
  12. *********************************************************************************/
  13. #include "pch.hxx"
  14. #include "ourguid.h"
  15. #include "browser.h"
  16. #include <resource.h>
  17. #include "itbar.h"
  18. #include "strconst.h"
  19. #include "thormsgs.h"
  20. #include <error.h>
  21. #include "xpcomm.h"
  22. #include "conman.h"
  23. #include "mailnews.h"
  24. #include "shared.h"
  25. #include <shlwapi.h>
  26. #include "statnery.h"
  27. #include "goptions.h"
  28. #include "menuutil.h"
  29. #include "menures.h"
  30. #include <shlobjp.h>
  31. #include <shlguidp.h>
  32. #include "demand.h"
  33. #include "baui.h"
  34. UINT GetCurColorRes(void);
  35. CCoolbar::CCoolbar() : m_cRef(1), m_yCapture(-1)
  36. {
  37. DOUTL(1, TEXT("ctor CCoolbar %x"), this);
  38. m_cRef = 1;
  39. m_ptbSite = NULL;
  40. m_cxMaxButtonWidth = 70;
  41. m_ftType = FOLDER_TYPESMAX;
  42. m_ptai = NULL;
  43. m_fSmallIcons = FALSE;
  44. m_hwndParent = NULL;
  45. m_hwndTools = NULL;
  46. m_hwndBrand = NULL;
  47. m_hwndSizer = NULL;
  48. m_hwndRebar = NULL;
  49. ZeroMemory(&m_cbsSavedInfo, sizeof(COOLBARSAVE));
  50. m_csSide = COOLBAR_TOP;
  51. m_dwState = 0;
  52. m_idbBack = 0;
  53. m_hbmBack = NULL;
  54. m_hbmBrand = NULL;
  55. Assert(2 == CIMLISTS);
  56. m_rghimlTools[IMLIST_DEFAULT] = NULL;
  57. m_rghimlTools[IMLIST_HOT] = NULL;
  58. m_hpal = NULL;
  59. m_hdc = NULL;
  60. m_xOrg = 0;
  61. m_yOrg = 0;
  62. m_cxBmp = 0;
  63. m_cyBmp = 0;
  64. m_cxBrand = 0;
  65. m_cyBrand = 0;
  66. m_cxBrandExtent = 0;
  67. m_cyBrandExtent = 0;
  68. m_cyBrandLeadIn = 0;
  69. m_rgbUpperLeft = 0;
  70. m_pMenuBand = NULL;
  71. m_pDeskBand = NULL;
  72. m_pShellMenu = NULL;
  73. m_pWinEvent = NULL;
  74. m_mbCallback = NULL;
  75. m_xCapture = -1;
  76. m_yCapture = -1;
  77. // Bug #12953 - Try to load the localized max button width from the resources
  78. TCHAR szBuffer[32];
  79. if (AthLoadString(idsMaxCoolbarBtnWidth, szBuffer, ARRAYSIZE(szBuffer)))
  80. {
  81. m_cxMaxButtonWidth = StrToInt(szBuffer);
  82. if (m_cxMaxButtonWidth == 0)
  83. m_cxMaxButtonWidth = 70;
  84. }
  85. }
  86. CCoolbar::~CCoolbar()
  87. {
  88. int i;
  89. DOUTL(1, TEXT("dtor CCoolbar %x"), this);
  90. if (m_ptbSite)
  91. {
  92. AssertSz(m_ptbSite == NULL, _T("CCoolbar::~CCoolbar() - For some reason ")
  93. _T("we still have a pointer to the site."));
  94. m_ptbSite->Release();
  95. m_ptbSite = NULL;
  96. }
  97. if (m_hpal)
  98. DeleteObject(m_hpal);
  99. if (m_hdc)
  100. DeleteDC(m_hdc);
  101. if (m_hbmBrand)
  102. DeleteObject(m_hbmBrand);
  103. if ( m_hbmBack )
  104. DeleteObject( m_hbmBack );
  105. for (i = 0; i < CIMLISTS; i++)
  106. {
  107. if (m_rghimlTools[i])
  108. ImageList_Destroy(m_rghimlTools[i]);
  109. }
  110. SafeRelease(m_pDeskBand);
  111. SafeRelease(m_pMenuBand);
  112. SafeRelease(m_pWinEvent);
  113. SafeRelease(m_pShellMenu);
  114. SafeRelease(m_mbCallback);
  115. }
  116. //
  117. // FUNCTION: CCoolbar::HrInit()
  118. //
  119. // PURPOSE: Initializes the coolbar with the information needed to load
  120. // any persisted reg settings and the correct arrays of buttons
  121. // to display.
  122. //
  123. // PARAMETERS:
  124. // <in> idBackground - Resource ID of the background bitmap to use.
  125. //
  126. // RETURN VALUE:
  127. // S_OK - Everything initialized correctly.
  128. //
  129. HRESULT CCoolbar::HrInit(DWORD idBackground, HMENU hmenu)
  130. {
  131. DWORD cbData;
  132. DWORD dwType;
  133. // Save the path and value so we can save ourselves on exit
  134. m_idbBack = idBackground;
  135. // See if we can get the previously saved information first
  136. ZeroMemory(&m_cbsSavedInfo, sizeof(COOLBARSAVE));
  137. cbData = sizeof(COOLBARSAVE);
  138. AthUserGetValue(NULL, c_szRegCoolbarLayout, &dwType, (LPBYTE)&m_cbsSavedInfo, &cbData);
  139. if (m_cbsSavedInfo.dwVersion != COOLBAR_VERSION)
  140. {
  141. // Either the version didn't match, or we didn't read anything. Use
  142. // default values
  143. m_cbsSavedInfo.dwVersion = COOLBAR_VERSION;
  144. m_cbsSavedInfo.csSide = COOLBAR_TOP;
  145. m_cbsSavedInfo.bs[0].wID = CBTYPE_MENUBAND;
  146. m_cbsSavedInfo.bs[0].dwStyle = RBBS_GRIPPERALWAYS;
  147. m_cbsSavedInfo.bs[1].wID = CBTYPE_BRAND;
  148. m_cbsSavedInfo.bs[2].wID = CBTYPE_TOOLS;
  149. m_cbsSavedInfo.bs[2].dwStyle = RBBS_BREAK;
  150. m_cbsSavedInfo.dwState |= CBSTATE_COMPRESSED;
  151. }
  152. m_csSide = m_cbsSavedInfo.csSide;
  153. m_dwState = m_cbsSavedInfo.dwState;
  154. m_hMenu = hmenu;
  155. return (S_OK);
  156. }
  157. HRESULT CCoolbar::QueryInterface(REFIID riid, LPVOID * ppvObj)
  158. {
  159. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IOleWindow)
  160. || IsEqualIID(riid, IID_IDockingWindow))
  161. {
  162. *ppvObj = (IDockingWindow*)this;
  163. m_cRef++;
  164. DOUTL(2, TEXT("CCoolbar::QI(IID_IDockingWindow) called. _cRef=%d"), m_cRef);
  165. return S_OK;
  166. }
  167. else if (IsEqualIID(riid, IID_IObjectWithSite))
  168. {
  169. *ppvObj = (IObjectWithSite*)this;
  170. m_cRef++;
  171. DOUTL(2, TEXT("CCoolbar::QI(IID_IObjectWithSite) called. _cRef=%d"), m_cRef);
  172. return S_OK;
  173. }
  174. else if (IsEqualIID(riid, IID_IShellMenuCallback))
  175. {
  176. *ppvObj = (IShellMenuCallback*)this;
  177. m_cRef++;
  178. DOUTL(2, TEXT("CCoolbar::QI(IID_IShellCallback) called. _cRef=%d"), m_cRef);
  179. return S_OK;
  180. }
  181. *ppvObj = NULL;
  182. return E_NOINTERFACE;
  183. }
  184. ULONG CCoolbar::AddRef()
  185. {
  186. m_cRef++;
  187. DOUTL(4, TEXT("CCoolbar::AddRef() - m_cRef = %d"), m_cRef);
  188. return m_cRef;
  189. }
  190. ULONG CCoolbar::Release()
  191. {
  192. m_cRef--;
  193. DOUTL(4, TEXT("CCoolbar::Release() - m_cRef = %d"), m_cRef);
  194. if (m_cRef > 0)
  195. return m_cRef;
  196. delete this;
  197. return 0;
  198. }
  199. //
  200. // FUNCTION: CCoolbar::GetWindow()
  201. //
  202. // PURPOSE: Returns the window handle of the top side rebar.
  203. //
  204. HRESULT CCoolbar::GetWindow(HWND * lphwnd)
  205. {
  206. if (m_hwndSizer)
  207. {
  208. *lphwnd = m_hwndSizer;
  209. return (S_OK);
  210. }
  211. else
  212. {
  213. *lphwnd = NULL;
  214. return (E_FAIL);
  215. }
  216. }
  217. HRESULT CCoolbar::ContextSensitiveHelp(BOOL fEnterMode)
  218. {
  219. return (E_NOTIMPL);
  220. }
  221. //
  222. // FUNCTION: CCoolbar::SetSite()
  223. //
  224. // PURPOSE: Allows the owner of the coolbar to tell it what the current
  225. // IDockingWindowSite interface to use is.
  226. //
  227. // PARAMETERS:
  228. // <in> punkSite - Pointer of the IUnknown to query for IDockingWindowSite.
  229. // If this is NULL, we just release our current pointer.
  230. //
  231. // RETURN VALUE:
  232. // S_OK - Everything worked
  233. // E_FAIL - Could not get IDockingWindowSite from the punkSite provided.
  234. //
  235. HRESULT CCoolbar::SetSite(IUnknown* punkSite)
  236. {
  237. // If we had a previous pointer, release it.
  238. if (m_ptbSite)
  239. {
  240. m_ptbSite->Release();
  241. m_ptbSite = NULL;
  242. }
  243. // If a new site was provided, get the IDockingWindowSite interface from it.
  244. if (punkSite)
  245. {
  246. if (FAILED(punkSite->QueryInterface(IID_IDockingWindowSite,
  247. (LPVOID*) &m_ptbSite)))
  248. {
  249. Assert(m_ptbSite);
  250. return E_FAIL;
  251. }
  252. }
  253. return (S_OK);
  254. }
  255. HRESULT CCoolbar::GetSite(REFIID riid, LPVOID *ppvSite)
  256. {
  257. return E_NOTIMPL;
  258. }
  259. //
  260. // FUNCTION: CCoolbar::ShowDW()
  261. //
  262. // PURPOSE: Causes the coolbar to be either shown or hidden.
  263. //
  264. // PARAMETERS:
  265. // <in> fShow - TRUE if the coolbar should be shown, FALSE to hide.
  266. //
  267. // RETURN VALUE:
  268. // HRESULT
  269. //
  270. #define SIZABLECLASS TEXT("SizableRebar")
  271. HRESULT CCoolbar::ShowDW(BOOL fShow)
  272. {
  273. HRESULT hres = S_OK;
  274. int i = 0, j = 0;
  275. // Check to see if our window has been created yet. If not, do that first.
  276. if (!m_hwndSizer && m_ptbSite)
  277. {
  278. m_hwndParent = NULL;
  279. hres = m_ptbSite->GetWindow(&m_hwndParent);
  280. if (SUCCEEDED(hres))
  281. {
  282. WNDCLASSEX wc;
  283. // Check to see if we need to register our window class
  284. wc.cbSize = sizeof(WNDCLASSEX);
  285. if (!GetClassInfoEx(g_hInst, SIZABLECLASS, &wc))
  286. {
  287. wc.style = 0;
  288. wc.lpfnWndProc = SizableWndProc;
  289. wc.cbClsExtra = 0;
  290. wc.cbWndExtra = 0;
  291. wc.hInstance = g_hInst;
  292. wc.hCursor = NULL;
  293. wc.hbrBackground = (HBRUSH) (COLOR_3DFACE + 1);
  294. wc.lpszMenuName = NULL;
  295. wc.lpszClassName = SIZABLECLASS;
  296. wc.hIcon = NULL;
  297. wc.hIconSm = NULL;
  298. RegisterClassEx(&wc);
  299. }
  300. // Load the background bitmap to use for the coolbar and also get
  301. // a handle to the HDC and Palette for the coolbar. This will be
  302. // used to draw the animated logo later.
  303. m_hdc = CreateCompatibleDC(NULL);
  304. if (GetDeviceCaps(m_hdc, RASTERCAPS) & RC_PALETTE)
  305. m_hpal = SHCreateShellPalette(m_hdc);
  306. // If we're trying to show the coolbar, then create the rebar and
  307. // add it's bands based on information saved in the registry.
  308. if (SUCCEEDED(CreateRebar(fShow)))
  309. {
  310. for (i = 0; i < (int) CBANDS; i++)
  311. {
  312. switch (m_cbsSavedInfo.bs[i].wID)
  313. {
  314. case CBTYPE_BRAND:
  315. hres = ShowBrand();
  316. break;
  317. case CBTYPE_MENUBAND:
  318. hres = CreateMenuBand(&m_cbsSavedInfo.bs[i]);
  319. break;
  320. case CBTYPE_TOOLS:
  321. hres = AddTools(&(m_cbsSavedInfo.bs[i]));
  322. break;
  323. }
  324. }
  325. }
  326. }
  327. }
  328. // Set our state flags. If we're going to hide, then also save our current
  329. // settings in the registry.
  330. /*
  331. if (fShow)
  332. ClearFlag(CBSTATE_HIDDEN);
  333. else
  334. {
  335. SetFlag(CBSTATE_HIDDEN);
  336. //SaveSettings();
  337. }
  338. */
  339. // Resize the rebar based on it's new hidden / visible state and also
  340. // show or hide the window.
  341. if (m_hwndSizer)
  342. {
  343. ResizeBorderDW(NULL, NULL, FALSE);
  344. //ShowWindow(m_hwndSizer, fShow ? SW_SHOW : SW_HIDE);
  345. }
  346. if (g_pConMan)
  347. g_pConMan->Advise(this);
  348. return hres;
  349. }
  350. void CCoolbar::HideToolbar(DWORD dwBandID)
  351. {
  352. REBARBANDINFO rbbi = {0};
  353. DWORD cBands;
  354. DWORD iBand;
  355. rbbi.cbSize = sizeof(REBARBANDINFO);
  356. rbbi.fMask = RBBIM_ID | RBBIM_STYLE;
  357. // Find the band
  358. cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  359. for (iBand = 0; iBand < cBands; iBand++)
  360. {
  361. SendMessage(m_hwndRebar, RB_GETBANDINFO, iBand, (LPARAM) &rbbi);
  362. if (rbbi.wID == dwBandID)
  363. {
  364. if (rbbi.fStyle & RBBS_HIDDEN)
  365. {
  366. rbbi.fStyle &= ~RBBS_HIDDEN;
  367. }
  368. else
  369. {
  370. rbbi.fStyle |= RBBS_HIDDEN;
  371. }
  372. rbbi.fMask = RBBIM_STYLE;
  373. SendMessage(m_hwndRebar, RB_SETBANDINFO, iBand, (LPARAM) &rbbi);
  374. return;
  375. }
  376. }
  377. }
  378. //
  379. // FUNCTION: CCoolbar::CloseDW()
  380. //
  381. // PURPOSE: Destroys the coolbar.
  382. //
  383. HRESULT CCoolbar::CloseDW(DWORD dwReserved)
  384. {
  385. if (m_hwndSizer)
  386. {
  387. SaveSettings();
  388. DestroyWindow(m_hwndSizer);
  389. m_hwndSizer = NULL;
  390. }
  391. if (m_pDeskBand)
  392. {
  393. IInputObject *pinpobj;
  394. if (SUCCEEDED(m_pDeskBand->QueryInterface(IID_IInputObject, (LPVOID*)&pinpobj)))
  395. {
  396. pinpobj->UIActivateIO(FALSE, NULL);
  397. pinpobj->Release();
  398. }
  399. IObjectWithSite *pobjsite;
  400. if (SUCCEEDED(m_pDeskBand->QueryInterface(IID_IObjectWithSite, (LPVOID*)&pobjsite)))
  401. {
  402. pobjsite->SetSite(NULL);
  403. pobjsite->Release();
  404. }
  405. m_pDeskBand->ShowDW(FALSE);
  406. }
  407. return S_OK;
  408. }
  409. //
  410. // FUNCTION: CCoolbar::ResizeBorderDW()
  411. //
  412. // PURPOSE: This is called when the coolbar needs to resize. The coolbar
  413. // in return figures out how much border space will be required
  414. // from the parent frame and tells the parent to reserve that
  415. // space. The coolbar then resizes itself to those dimensions.
  416. //
  417. // PARAMETERS:
  418. // <in> prcBorder - Rectangle containing the border space for the
  419. // parent.
  420. // <in> punkToolbarSite - Pointer to the IDockingWindowSite that we are
  421. // part of.
  422. // <in> fReserved - Ignored.
  423. //
  424. // RETURN VALUE:
  425. // HRESULT
  426. //
  427. HRESULT CCoolbar::ResizeBorderDW(LPCRECT prcBorder,
  428. IUnknown* punkToolbarSite,
  429. BOOL fReserved)
  430. {
  431. const DWORD c_cxResizeBorder = 3;
  432. const DWORD c_cyResizeBorder = 3;
  433. HRESULT hres = S_OK;
  434. RECT rcRequest = { 0, 0, 0, 0 };
  435. // If we don't have a stored site pointer, we can't resize.
  436. if (!m_ptbSite)
  437. {
  438. AssertSz(m_ptbSite, _T("CCoolbar::ResizeBorderDW() - Can't resize ")
  439. _T("without an IDockingWindowSite interface to call."));
  440. return (E_INVALIDARG);
  441. }
  442. // If we're visible, then calculate our border rectangle.
  443. /*
  444. if (IsFlagClear(CBSTATE_HIDDEN))
  445. {
  446. */
  447. RECT rcBorder, rcRebar, rcT;
  448. int cx, cy;
  449. // Get the size this rebar currently is
  450. GetWindowRect(m_hwndRebar, &rcRebar);
  451. cx = rcRebar.right - rcRebar.left;
  452. cy = rcRebar.bottom - rcRebar.top;
  453. // Find out how big our parent's border space is
  454. m_ptbSite->GetBorderDW((IDockingWindow*) this, &rcBorder);
  455. // If we're vertical, then we need to adjust our height to
  456. // match what the parent has. If we're horizontal, then
  457. // adjust our width.
  458. if (VERTICAL(m_csSide))
  459. cy = rcBorder.bottom - rcBorder.top;
  460. else
  461. cx = rcBorder.right - rcBorder.left;
  462. // Bug #31007 - There seems to be a problem in commctrl
  463. // IEBug #5574 either with the REBAR or with the Toolbar
  464. // when they are vertical. If the we try to
  465. // size them to 2 or less, we lock up. This
  466. // is a really poor fix, but there's no way
  467. // to get commctrl fixed this late in the game.
  468. if (cy < 5) cy = 10;
  469. if (cx < 5) cx = 10;
  470. // Move the rebar to the new position.
  471. if (m_csSide == COOLBAR_LEFT || m_csSide == COOLBAR_TOP)
  472. {
  473. SetWindowPos(m_hwndRebar, NULL, 0, 0, cx, cy,
  474. SWP_NOZORDER | SWP_NOACTIVATE);
  475. }
  476. else
  477. {
  478. if (m_csSide == COOLBAR_BOTTOM)
  479. SetWindowPos(m_hwndRebar, NULL, 0, c_cyResizeBorder,
  480. cx, cy, SWP_NOZORDER | SWP_NOACTIVATE);
  481. else
  482. SetWindowPos(m_hwndRebar, NULL, c_cxResizeBorder, 0,
  483. cx, cy, SWP_NOZORDER | SWP_NOACTIVATE);
  484. }
  485. // Figure out how much border space to ask the site for
  486. GetWindowRect(m_hwndRebar, &rcRebar);
  487. switch (m_csSide)
  488. {
  489. case COOLBAR_TOP:
  490. rcRequest.top = rcRebar.bottom - rcRebar.top + c_cxResizeBorder;
  491. break;
  492. case COOLBAR_LEFT:
  493. rcRequest.left = rcRebar.right - rcRebar.left + c_cyResizeBorder;
  494. break;
  495. case COOLBAR_BOTTOM:
  496. rcRequest.bottom = rcRebar.bottom - rcRebar.top + c_cxResizeBorder;
  497. break;
  498. case COOLBAR_RIGHT:
  499. rcRequest.right = rcRebar.right - rcRebar.left + c_cyResizeBorder;
  500. break;
  501. default:
  502. AssertSz(FALSE, _T("CCoolbar::ResizeBorderDW() - What other")
  503. _T(" sides are there???"));
  504. break;
  505. }
  506. // Ask the site for that border space
  507. if (SUCCEEDED(m_ptbSite->RequestBorderSpaceDW((IDockingWindow*) this, &rcRequest)))
  508. {
  509. // Position the window based on the area given to us
  510. switch (m_csSide)
  511. {
  512. case COOLBAR_TOP:
  513. SetWindowPos(m_hwndSizer, NULL,
  514. rcBorder.left,
  515. rcBorder.top,
  516. rcRebar.right - rcRebar.left,
  517. rcRequest.top + rcBorder.top,
  518. SWP_NOZORDER | SWP_NOACTIVATE);
  519. break;
  520. case COOLBAR_LEFT:
  521. SetWindowPos(m_hwndSizer, NULL,
  522. rcBorder.left,
  523. rcBorder.top,
  524. rcRequest.left,
  525. rcBorder.bottom - rcBorder.top,
  526. SWP_NOZORDER | SWP_NOACTIVATE);
  527. break;
  528. case COOLBAR_BOTTOM:
  529. SetWindowPos(m_hwndSizer, NULL,
  530. rcBorder.left,
  531. rcBorder.bottom - rcRequest.bottom,
  532. rcBorder.right - rcBorder.left,
  533. rcRequest.bottom,
  534. SWP_NOZORDER | SWP_NOACTIVATE);
  535. GetClientRect(m_hwndSizer, &rcT);
  536. break;
  537. case COOLBAR_RIGHT:
  538. SetWindowPos(m_hwndSizer, NULL,
  539. rcBorder.right - rcRequest.right,
  540. rcBorder.top,
  541. rcRequest.right,
  542. rcBorder.bottom - rcBorder.top,
  543. SWP_NOZORDER | SWP_NOACTIVATE);
  544. break;
  545. }
  546. }
  547. /*
  548. }
  549. */
  550. // Now tell the site how much border space we're using.
  551. m_ptbSite->SetBorderSpaceDW((IDockingWindow*) this, &rcRequest);
  552. return hres;
  553. }
  554. //
  555. // FUNCTION: CCoolbar::Invoke()
  556. //
  557. // PURPOSE: Allows the owner of the coolbar to force the coolbar to do
  558. // something.
  559. //
  560. // PARAMETERS:
  561. // <in> id - ID of the command the caller wants the coolbar to do.
  562. // <in> pv - Pointer to any parameters the coolbar might need to carry
  563. // out the command.
  564. //
  565. // RETURN VALUE:
  566. // S_OK - The command was carried out.
  567. //
  568. // COMMENTS:
  569. // <???>
  570. //
  571. HRESULT CCoolbar::Invoke(DWORD id, LPVOID pv)
  572. {
  573. switch (id)
  574. {
  575. // Starts animating the logo
  576. case idDownloadBegin:
  577. StartDownload();
  578. break;
  579. // Stops animating the logo
  580. case idDownloadEnd:
  581. StopDownload();
  582. break;
  583. // Update the enabled / disabled state of buttons on the toolbar
  584. case idStateChange:
  585. {
  586. // pv is a pointer to a COOLBARSTATECHANGE struct
  587. COOLBARSTATECHANGE* pcbsc = (COOLBARSTATECHANGE*) pv;
  588. SendMessage(m_hwndTools, TB_ENABLEBUTTON, pcbsc->id,
  589. MAKELONG(pcbsc->fEnable, 0));
  590. break;
  591. }
  592. case idToggleButton:
  593. {
  594. COOLBARSTATECHANGE* pcbsc = (COOLBARSTATECHANGE *) pv;
  595. SendMessage(m_hwndTools, TB_CHECKBUTTON, pcbsc->id,
  596. MAKELONG(pcbsc->fEnable, 0));
  597. break;
  598. }
  599. case idBitmapChange:
  600. {
  601. // pv is a pointer to a COOLBARBITMAPCHANGE struct
  602. COOLBARBITMAPCHANGE *pcbc = (COOLBARBITMAPCHANGE*) pv;
  603. SendMessage(m_hwndTools, TB_CHANGEBITMAP, pcbc->id, MAKELPARAM(pcbc->index, 0));
  604. break;
  605. }
  606. // Sends a message directly to the toolbar.
  607. case idSendToolMessage:
  608. #define ptm ((TOOLMESSAGE *)pv)
  609. ptm->lResult = SendMessage(m_hwndTools, ptm->uMsg, ptm->wParam, ptm->lParam);
  610. break;
  611. #undef ptm
  612. case idCustomize:
  613. SendMessage(m_hwndTools, TB_CUSTOMIZE, 0, 0);
  614. break;
  615. }
  616. return S_OK;
  617. }
  618. //
  619. // FUNCTION: CCoolbar::StartDownload()
  620. //
  621. // PURPOSE: Starts animating the logo.
  622. //
  623. void CCoolbar::StartDownload()
  624. {
  625. if (m_hwndBrand)
  626. {
  627. SetFlag(CBSTATE_ANIMATING);
  628. SetFlag(CBSTATE_FIRSTFRAME);
  629. m_yOrg = 0;
  630. SetTimer(m_hwndSizer, ANIMATION_TIMER, 100, NULL);
  631. }
  632. }
  633. //
  634. // FUNCTION: CCoolbar::StopDownload()
  635. //
  636. // PURPOSE: Stops animating the logo. Restores the logo to it's default
  637. // first frame.
  638. //
  639. void CCoolbar::StopDownload()
  640. {
  641. int i, cBands;
  642. REBARBANDINFO rbbi;
  643. // Set the background colors for this band back to the first frame
  644. cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  645. ZeroMemory(&rbbi, sizeof(rbbi));
  646. rbbi.cbSize = sizeof(REBARBANDINFO);
  647. rbbi.fMask = RBBIM_ID;
  648. for (i = 0; i < cBands; i++)
  649. {
  650. SendMessage(m_hwndRebar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
  651. if (CBTYPE_BRAND == rbbi.wID)
  652. {
  653. rbbi.fMask = RBBIM_COLORS;
  654. rbbi.clrFore = m_rgbUpperLeft;
  655. rbbi.clrBack = m_rgbUpperLeft;
  656. SendMessage(m_hwndRebar, RB_SETBANDINFO, i, (LPARAM) &rbbi);
  657. break;
  658. }
  659. }
  660. // Reset the state flags
  661. ClearFlag(CBSTATE_ANIMATING);
  662. ClearFlag(CBSTATE_FIRSTFRAME);
  663. KillTimer(m_hwndSizer, ANIMATION_TIMER);
  664. InvalidateRect(m_hwndBrand, NULL, FALSE);
  665. UpdateWindow(m_hwndBrand);
  666. }
  667. BOOL CCoolbar::CheckForwardWinEvent(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* plres)
  668. {
  669. HWND hwndForward = NULL;
  670. switch(uMsg)
  671. {
  672. case WM_NOTIFY:
  673. hwndForward = ((LPNMHDR)lParam)->hwndFrom;
  674. break;
  675. case WM_COMMAND:
  676. hwndForward = GET_WM_COMMAND_HWND(wParam, lParam);
  677. break;
  678. case WM_SYSCOLORCHANGE:
  679. case WM_WININICHANGE:
  680. case WM_PALETTECHANGED:
  681. hwndForward = m_hwndRebar;
  682. break;
  683. }
  684. if (hwndForward && m_pWinEvent && m_pWinEvent->IsWindowOwner(hwndForward) == S_OK)
  685. {
  686. LRESULT lres;
  687. m_pWinEvent->OnWinEvent(hwndForward, uMsg, wParam, lParam, &lres);
  688. if (plres)
  689. *plres = lres;
  690. return TRUE;
  691. }
  692. return FALSE;
  693. }
  694. //
  695. // FUNCTION: CCoolbar::SizableWndProc()
  696. //
  697. // PURPOSE: Handles messages sent to the coolbar root window.
  698. //
  699. LRESULT EXPORT_16 CALLBACK CCoolbar::SizableWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  700. {
  701. CCoolbar* pitbar = (CCoolbar*)GetProp(hwnd, TEXT("CCoolbar"));
  702. DWORD dw;
  703. if (!pitbar)
  704. goto CallDWP;
  705. switch(uMsg)
  706. {
  707. case WM_SYSCOLORCHANGE:
  708. // Reload the graphics
  709. LoadGlyphs(pitbar->m_hwndTools, CIMLISTS, pitbar->m_rghimlTools, (fIsWhistler() ? TB_BMP_CX : TB_BMP_CX_W2K),
  710. (fIsWhistler() ? ((GetCurColorRes() > 24) idb32256Browser : idbBrowser) :
  711. ((GetCurColorRes() > 8) ? idbNW256Browser : idbNWBrowser)));
  712. pitbar->UpdateToolbarColors();
  713. InvalidateRect(pitbar->m_hwndTools, NULL, TRUE);
  714. pitbar->CheckForwardWinEvent(hwnd, uMsg, wParam, lParam, NULL);
  715. break;
  716. case WM_WININICHANGE:
  717. case WM_FONTCHANGE:
  718. // Forward this to our child windows
  719. LoadGlyphs(pitbar->m_hwndTools, CIMLISTS, pitbar->m_rghimlTools, (fIsWhistler() ? TB_BMP_CX : TB_BMP_CX_W2K),
  720. (fIsWhistler() ? ((GetCurColorRes() > 24) idb32256Browser : idbBrowser) :
  721. ((GetCurColorRes() > 8) ? idbNW256Browser : idbNWBrowser)));
  722. SendMessage(pitbar->m_hwndTools, uMsg, wParam, lParam);
  723. InvalidateRect(pitbar->m_hwndTools, NULL, TRUE);
  724. pitbar->SetMinDimensions();
  725. pitbar->CheckForwardWinEvent(hwnd, uMsg, wParam, lParam, NULL);
  726. break;
  727. case WM_SETCURSOR:
  728. // We play with the cursor a bit to make the resizing cursor show
  729. // up when the user is over the edge of the coolbar that allows
  730. // them to drag to resize etc.
  731. if ((HWND) wParam == hwnd)
  732. {
  733. if (pitbar->m_dwState & CBSTATE_INMENULOOP)
  734. SetCursor(LoadCursor(NULL, IDC_ARROW));
  735. else
  736. SetCursor(LoadCursor(NULL,
  737. VERTICAL(pitbar->m_csSide) ? IDC_SIZEWE : IDC_SIZENS));
  738. return (TRUE);
  739. }
  740. return (FALSE);
  741. case WM_LBUTTONDOWN:
  742. // The user is about to resize the bar. Capture the cursor so we
  743. // can watch the changes.
  744. if (VERTICAL(pitbar->m_csSide))
  745. pitbar->m_xCapture = GET_X_LPARAM(lParam);
  746. else
  747. pitbar->m_yCapture = GET_Y_LPARAM(lParam);
  748. SetCapture(hwnd);
  749. break;
  750. case WM_MOUSEMOVE:
  751. // The user is resizing the bar. Handle updating the sizes as
  752. // they drag.
  753. if (VERTICAL(pitbar->m_csSide))
  754. {
  755. if (pitbar->m_xCapture != -1)
  756. {
  757. if (hwnd != GetCapture())
  758. pitbar->m_xCapture = -1;
  759. else
  760. pitbar->TrackSlidingX(GET_X_LPARAM(lParam));
  761. }
  762. }
  763. else
  764. {
  765. if (pitbar->m_yCapture != -1)
  766. {
  767. if (hwnd != GetCapture())
  768. pitbar->m_yCapture = -1;
  769. else
  770. pitbar->TrackSlidingY(GET_Y_LPARAM(lParam));
  771. }
  772. }
  773. break;
  774. case WM_LBUTTONUP:
  775. // The user is done resizing. release our capture and reset our
  776. // state.
  777. if (pitbar->m_yCapture != -1 || pitbar->m_xCapture != -1)
  778. {
  779. ReleaseCapture();
  780. pitbar->m_yCapture = -1;
  781. pitbar->m_xCapture = -1;
  782. }
  783. break;
  784. case WM_VKEYTOITEM:
  785. case WM_CHARTOITEM:
  786. // We must swallow these messages to avoid infinit SendMessage
  787. break;
  788. case WM_DRAWITEM:
  789. // Draws the animating brand
  790. if (wParam == idcBrand)
  791. pitbar->DrawBranding((LPDRAWITEMSTRUCT) lParam);
  792. break;
  793. case WM_MEASUREITEM:
  794. // Draws the animating brand
  795. if (wParam == idcBrand)
  796. {
  797. ((LPMEASUREITEMSTRUCT) lParam)->itemWidth = pitbar->m_cxBrand;
  798. ((LPMEASUREITEMSTRUCT) lParam)->itemHeight = pitbar->m_cyBrand;
  799. }
  800. break;
  801. case WM_TIMER:
  802. // This timer fires every time we need to draw the next frame in
  803. // animating brand.
  804. if (wParam == ANIMATION_TIMER)
  805. {
  806. if (pitbar->m_hwndBrand)
  807. {
  808. pitbar->m_yOrg += pitbar->m_cyBrand;
  809. if (pitbar->m_yOrg >= pitbar->m_cyBrandExtent)
  810. pitbar->m_yOrg = pitbar->m_cyBrandLeadIn;
  811. InvalidateRect(pitbar->m_hwndBrand, NULL, FALSE);
  812. UpdateWindow(pitbar->m_hwndBrand);
  813. }
  814. }
  815. break;
  816. case WM_NOTIFY:
  817. {
  818. LRESULT lres;
  819. if (pitbar->CheckForwardWinEvent(hwnd, uMsg, wParam, lParam, &lres))
  820. return lres;
  821. return pitbar->OnNotify(hwnd, lParam);
  822. }
  823. case WM_COMMAND:
  824. {
  825. LRESULT lres;
  826. if (pitbar->CheckForwardWinEvent(hwnd, uMsg, wParam, lParam, &lres))
  827. return lres;
  828. return SendMessage(pitbar->m_hwndParent, WM_COMMAND, wParam, lParam);
  829. }
  830. case WM_CONTEXTMENU:
  831. pitbar->OnContextMenu((HWND) wParam, LOWORD(lParam), HIWORD(lParam));
  832. break;
  833. case WM_PALETTECHANGED:
  834. // BUGBUG: we could optimize this by realizing and checking the
  835. // return value
  836. //
  837. // for now we will just invalidate ourselves and all children...
  838. RedrawWindow(pitbar->m_hwndSizer, NULL, NULL,
  839. RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
  840. break;
  841. case CM_CONNECT:
  842. // wParam is hMenuConnect, lParam is CmdID
  843. g_pConMan->Connect((HMENU) wParam, lParam, pitbar->m_hwndParent);
  844. g_pConMan->FreeConnectMenu((HMENU) wParam);
  845. break;
  846. case TT_ISTEXTVISIBLE:
  847. return (!(pitbar->m_dwState & CBSTATE_COMPRESSED));
  848. case WM_DESTROY:
  849. // Clean up our pointers
  850. RemoveProp(hwnd, TEXT("CCoolbar"));
  851. pitbar->Release(); // Corresponding to AddRef at SetProp
  852. DOUTL(1, _T("CCoolbar::WM_DESTROY - Called RemoveProp. Called")
  853. _T(" Release() new m_cRef=%d"), pitbar->m_cRef);
  854. //Unregister with the connection manager
  855. if (g_pConMan)
  856. g_pConMan->Unadvise(pitbar);
  857. // fall through
  858. default:
  859. CallDWP:
  860. return(DefWindowProc(hwnd, uMsg, wParam, lParam));
  861. }
  862. return 0L;
  863. }
  864. HRESULT CCoolbar::OnCommand(HWND hwnd, int idCmd, HWND hwndControl, UINT cmd)
  865. {
  866. LPTSTR pszTest;
  867. switch (idCmd)
  868. {
  869. case idcBrand: // click on the spinning globe
  870. OnHelpGoto(hwnd, ID_MSWEB_PRODUCT_NEWS);
  871. break;
  872. case ID_CUSTOMIZE:
  873. SendMessage(m_hwndTools, TB_CUSTOMIZE, 0, 0);
  874. break;
  875. case ID_TOOLBAR_TOP:
  876. //case ID_TOOLBAR_LEFT:
  877. case ID_TOOLBAR_BOTTOM:
  878. //case ID_TOOLBAR_RIGHT:
  879. {
  880. // There's a painting problem that occurs going from top to bottom
  881. // and vice versa. If that's what we're doing, we repaint when
  882. // we're done.
  883. BOOL fRepaint;
  884. fRepaint = (VERTICAL(m_csSide) == VERTICAL(idCmd - ID_TOOLBAR_TOP));
  885. m_csSide = (COOLBAR_SIDE) (idCmd - ID_TOOLBAR_TOP);
  886. ChangeOrientation();
  887. if (fRepaint)
  888. InvalidateRect(m_hwndTools, NULL, FALSE);
  889. }
  890. break;
  891. case ID_TEXT_LABELS:
  892. CompressBands(!IsFlagSet(CBSTATE_COMPRESSED));
  893. break;
  894. default:
  895. return S_FALSE;
  896. }
  897. return S_OK;
  898. }
  899. HRESULT CCoolbar::OnInitMenuPopup(HMENU hMenuContext)
  900. {
  901. CheckMenuRadioItem(hMenuContext, ID_TOOLBAR_TOP, ID_TOOLBAR_RIGHT,
  902. ID_TOOLBAR_TOP + m_csSide, MF_BYCOMMAND);
  903. CheckMenuItem(hMenuContext, ID_TEXT_LABELS,
  904. MF_BYCOMMAND | IsFlagSet(CBSTATE_COMPRESSED) ? MF_UNCHECKED : MF_CHECKED);
  905. return S_OK;
  906. }
  907. LRESULT CCoolbar::OnNotify(HWND hwnd, LPARAM lparam)
  908. {
  909. NMHDR *lpnmhdr = (NMHDR*)lparam;
  910. switch (lpnmhdr->idFrom)
  911. {
  912. case idcCoolbar:
  913. switch (lpnmhdr->code)
  914. {
  915. case RBN_HEIGHTCHANGE:
  916. ResizeBorderDW(NULL, NULL, FALSE);
  917. break;
  918. case RBN_CHILDSIZE:
  919. NMREBARCHILDSIZE *lpchildsize = (NMREBARCHILDSIZE*)lparam;
  920. if (lpchildsize->wID == CBTYPE_TOOLS)
  921. {
  922. SetWindowPos(m_hwndTools, NULL, lpchildsize->rcChild.left, lpchildsize->rcChild.right,
  923. lpchildsize->rcChild.right - lpchildsize->rcChild.left,
  924. lpchildsize->rcChild.bottom - lpchildsize->rcChild.top,
  925. SWP_NOZORDER | SWP_NOACTIVATE);
  926. }
  927. else
  928. if (lpchildsize->wID == CBTYPE_BRAND)
  929. {
  930. SetWindowPos(m_hwndBrand, NULL, lpchildsize->rcChild.left, lpchildsize->rcChild.right,
  931. lpchildsize->rcChild.right - lpchildsize->rcChild.left,
  932. lpchildsize->rcChild.bottom - lpchildsize->rcChild.top,
  933. SWP_NOZORDER | SWP_NOACTIVATE);
  934. }
  935. break;
  936. }
  937. case idcToolbar:
  938. if (lpnmhdr->code == TBN_GETBUTTONINFOA)
  939. return OnGetButtonInfo((TBNOTIFY*) lparam);
  940. if (lpnmhdr->code == TBN_QUERYDELETE)
  941. return (TRUE);
  942. if (lpnmhdr->code == TBN_QUERYINSERT)
  943. return (TRUE);
  944. if (lpnmhdr->code == TBN_ENDADJUST)
  945. {
  946. IAthenaBrowser *psbwr;
  947. // Update the size of the sizer
  948. SetMinDimensions();
  949. ResizeBorderDW(NULL, NULL, FALSE);
  950. // check IDockingWindowSite
  951. if (m_ptbSite)
  952. {
  953. // get IAthenaBrowser interface
  954. if (SUCCEEDED(m_ptbSite->QueryInterface(IID_IAthenaBrowser,(void**)&psbwr)))
  955. {
  956. psbwr->UpdateToolbar();
  957. psbwr->Release();
  958. }
  959. }
  960. }
  961. if (lpnmhdr->code == TBN_RESET)
  962. {
  963. // Remove all the buttons from the toolbar
  964. int cButtons = SendMessage(m_hwndTools, TB_BUTTONCOUNT, 0, 0);
  965. while (--cButtons >= 0)
  966. SendMessage(m_hwndTools, TB_DELETEBUTTON, cButtons, 0);
  967. // Set the buttons back to the default
  968. SendMessage(m_hwndTools, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
  969. SendMessage(m_hwndTools, TB_ADDBUTTONS, m_ptai->cDefButtons,
  970. (LPARAM) m_ptai->rgDefButtons);
  971. return (TRUE);
  972. }
  973. if (lpnmhdr->code == TBN_CUSTHELP)
  974. {
  975. // WinHelp(m_hwndTools, c_szMailHelpFile, HELP_CONTEXT, IDH_NEWS_COMM_GROUPBOX);
  976. OEHtmlHelp(m_hwndTools, c_szCtxHelpFileHTMLCtx, HH_DISPLAY_TOPIC, (DWORD) (LPCSTR) "idh_proced_cust_tool.htm");
  977. return (TRUE);
  978. }
  979. if (lpnmhdr->code == TBN_DROPDOWN)
  980. {
  981. return OnDropDown(hwnd, lpnmhdr);
  982. }
  983. break;
  984. }
  985. return (0L);
  986. }
  987. LRESULT CCoolbar::OnDropDown(HWND hwnd, LPNMHDR lpnmh)
  988. {
  989. HMENU hMenuPopup = NULL;
  990. TBNOTIFY *ptbn = (TBNOTIFY *)lpnmh ;
  991. UINT uiCmd = ptbn->iItem ;
  992. RECT rc;
  993. DWORD dwCmd = 0;
  994. IAthenaBrowser *pBrowser;
  995. BOOL fPostCmd = TRUE;
  996. IOleCommandTarget *pTarget;
  997. // Load and initialize the appropriate dropdown menu
  998. switch (uiCmd)
  999. {
  1000. case ID_POPUP_LANGUAGE:
  1001. {
  1002. // check IDockingWindowSite
  1003. if (m_ptbSite)
  1004. {
  1005. // get IAthenaBrowser interface
  1006. if (SUCCEEDED(m_ptbSite->QueryInterface(IID_IAthenaBrowser, (void**) &pBrowser)))
  1007. {
  1008. // get language menu from shell/browser
  1009. pBrowser->GetLanguageMenu(&hMenuPopup, 0);
  1010. pBrowser->Release();
  1011. }
  1012. }
  1013. }
  1014. break;
  1015. case ID_NEW_MSG_DEFAULT:
  1016. GetStationeryMenu(&hMenuPopup);
  1017. /* $INFOCOLUMN
  1018. // Disable Send Instant Msg item
  1019. if (SUCCEEDED(m_ptbSite->QueryInterface(IID_IAthenaBrowser, (void**) &pBrowser)))
  1020. {
  1021. CInfoColumn * pInfoColumn = NULL;
  1022. if(SUCCEEDED(pBrowser->GetInfoColumn(&pInfoColumn)))
  1023. {
  1024. IMsgrAb * pMsgrAb = pInfoColumn->GetBAComtrol();
  1025. if(pMsgrAb)
  1026. {
  1027. BOOL fRet;
  1028. pMsgrAb->get_InstMsg(&fRet);
  1029. if(fRet == FALSE)
  1030. EnableMenuItem(hMenuPopup, ID_SEND_INSTANT_MESSAGE, MF_BYCOMMAND | MF_GRAYED);
  1031. }
  1032. pInfoColumn->Release();
  1033. }
  1034. pBrowser->Release();
  1035. }
  1036. */
  1037. break;
  1038. case ID_PREVIEW_PANE:
  1039. {
  1040. // Load the menu
  1041. hMenuPopup = LoadPopupMenu(IDR_PREVIEW_POPUP);
  1042. if (!hMenuPopup)
  1043. break;
  1044. // check IDockingWindowSite
  1045. if (m_ptbSite)
  1046. {
  1047. // get IAthenaBrowser interface
  1048. if (SUCCEEDED(m_ptbSite->QueryInterface(IID_IOleCommandTarget, (void**) &pTarget)))
  1049. {
  1050. MenuUtil_EnablePopupMenu(hMenuPopup, pTarget);
  1051. pTarget->Release();
  1052. }
  1053. }
  1054. break;
  1055. }
  1056. default:
  1057. AssertSz(FALSE, "CCoolbar::OnDropDown() - Unhandled TBN_DROPDOWN notification");
  1058. return (TBDDRET_NODEFAULT);
  1059. }
  1060. // If we loaded a menu, then go ahead and display it
  1061. if (hMenuPopup)
  1062. {
  1063. SendMessage(m_hwndTools, TB_GETRECT, ptbn->iItem, (LPARAM)&rc);
  1064. MapWindowRect(m_hwndTools, HWND_DESKTOP, &rc);
  1065. SetFlag(CBSTATE_INMENULOOP);
  1066. dwCmd = TrackPopupMenuEx(hMenuPopup, TPM_RETURNCMD | TPM_LEFTALIGN,
  1067. rc.left, rc.bottom, m_hwndParent, NULL);
  1068. ClearFlag(CBSTATE_INMENULOOP);
  1069. }
  1070. // Clean up anything needing to be cleaned up
  1071. switch (uiCmd)
  1072. {
  1073. case ID_LANGUAGE:
  1074. break;
  1075. case ID_NEW_MSG_DEFAULT:
  1076. DestroyMenu(hMenuPopup);
  1077. break;
  1078. }
  1079. if (fPostCmd && dwCmd)
  1080. PostMessage(m_hwndSizer, WM_COMMAND, dwCmd, 0);
  1081. return (TBDDRET_DEFAULT);
  1082. }
  1083. void CCoolbar::OnContextMenu(HWND hwndFrom, int xPos, int yPos)
  1084. {
  1085. HMENU hMenu, hMenuContext;
  1086. TCHAR szBuf[256];
  1087. HWND hwnd;
  1088. HWND hwndSizer = GetParent(hwndFrom);
  1089. POINT pt = {xPos, yPos};
  1090. // Make sure the context menu only appears on the toolbar bars
  1091. hwnd = WindowFromPoint(pt);
  1092. /*
  1093. if (GetClassName(hwnd, szBuf, ARRAYSIZE(szBuf)))
  1094. if (0 != lstrcmpi(szBuf, TOOLBARCLASSNAME))
  1095. return;
  1096. */
  1097. if (hwnd == m_hwndTools)
  1098. {
  1099. if (NULL != (hMenu = LoadMenu(g_hLocRes, MAKEINTRESOURCE(IDR_TOOLBAR_POPUP))))
  1100. {
  1101. hMenuContext = GetSubMenu(hMenu, 0);
  1102. OnInitMenuPopup(hMenuContext);
  1103. SetFlag(CBSTATE_INMENULOOP);
  1104. TrackPopupMenu(hMenuContext, TPM_RIGHTBUTTON, xPos, yPos, 0,
  1105. hwndFrom, NULL);
  1106. ClearFlag(CBSTATE_INMENULOOP);
  1107. DestroyMenu(hMenu);
  1108. }
  1109. }
  1110. else
  1111. if (hwnd == m_hwndMenuBand)
  1112. {
  1113. HandleCoolbarPopup(xPos, yPos);
  1114. }
  1115. }
  1116. //
  1117. // FUNCTION: CCoolbar::OnGetButtonInfo()
  1118. //
  1119. // PURPOSE: Handles the TBN_GETBUTTONINFO notification by returning
  1120. // the buttons availble for the toolbar.
  1121. //
  1122. // PARAMETERS:
  1123. // ptbn - pointer to the TBNOTIFY struct we need to fill in.
  1124. //
  1125. // RETURN VALUE:
  1126. // Returns TRUE to tell the toolbar to use this button, or FALSE
  1127. // otherwise.
  1128. //
  1129. LRESULT CCoolbar::OnGetButtonInfo(TBNOTIFY* ptbn)
  1130. {
  1131. // Start by returning information for the first array of
  1132. // buttons
  1133. if ((ptbn->iItem < (int) m_ptai->cDefButtons && (ptbn->iItem >= 0)))
  1134. {
  1135. // Grab the button info out of the array
  1136. ptbn->tbButton = m_ptai->rgDefButtons[ptbn->iItem];
  1137. // Return the string info from the string resource. Note,
  1138. // pszText already points to a buffer allocated by the
  1139. // control and cchText has the length of that buffer.
  1140. LoadString(g_hLocRes, m_ptai->rgidsButtons[ptbn->tbButton.iString],
  1141. ptbn->pszText, ptbn->cchText);
  1142. return (TRUE);
  1143. }
  1144. else
  1145. {
  1146. // Now return information for the extra buttons not on the `
  1147. // toolbar by default.
  1148. if (ptbn->iItem < (int) (m_ptai->cDefButtons + m_ptai->cExtraButtons))
  1149. {
  1150. ptbn->tbButton = m_ptai->rgExtraButtons[ptbn->iItem - m_ptai->cDefButtons];
  1151. // The control has already created a buffer for us to copy
  1152. // the string into.
  1153. LoadString(g_hLocRes, m_ptai->rgidsButtons[ptbn->tbButton.iString],
  1154. ptbn->pszText, ptbn->cchText);
  1155. return (TRUE);
  1156. }
  1157. else
  1158. {
  1159. // No more buttons to add, so return FALSE.
  1160. return (FALSE);
  1161. }
  1162. }
  1163. }
  1164. HRESULT CCoolbar::ShowBrand(void)
  1165. {
  1166. REBARBANDINFO rbbi;
  1167. // create branding window
  1168. /*
  1169. m_hwndBrand = CreateWindow(TEXT("button"), NULL,WS_CHILD | BS_OWNERDRAW,
  1170. 0, 0, 400, 200, m_hwndRebar, (HMENU) idcBrand,
  1171. g_hInst, NULL);
  1172. */
  1173. m_hwndBrand = CreateWindow(TEXT("button"), NULL,WS_CHILD | BS_OWNERDRAW,
  1174. 0, 0, 0, 0, m_hwndRebar, (HMENU) idcBrand,
  1175. g_hInst, NULL);
  1176. if (!m_hwndBrand)
  1177. {
  1178. DOUTL(1, TEXT("!!!ERROR!!! CITB:Show CreateWindow(BRANDING) failed"));
  1179. return(E_OUTOFMEMORY);
  1180. }
  1181. LoadBrandingBitmap();
  1182. // add branding band
  1183. ZeroMemory(&rbbi, sizeof(rbbi));
  1184. rbbi.cbSize = sizeof(REBARBANDINFO);
  1185. rbbi.fMask = RBBIM_STYLE | RBBIM_COLORS | RBBIM_CHILD | RBBIM_ID;
  1186. rbbi.fStyle = RBBS_FIXEDSIZE;
  1187. rbbi.wID = CBTYPE_BRAND;
  1188. rbbi.clrFore = m_rgbUpperLeft;
  1189. rbbi.clrBack = m_rgbUpperLeft;
  1190. rbbi.hwndChild = m_hwndBrand;
  1191. SendMessage(m_hwndRebar, RB_INSERTBAND, (UINT) -1, (LPARAM) (LPREBARBANDINFO) &rbbi);
  1192. return (S_OK);
  1193. }
  1194. HRESULT CCoolbar::LoadBrandingBitmap()
  1195. {
  1196. HKEY hKey;
  1197. DIBSECTION dib;
  1198. DWORD dwcbData;
  1199. DWORD dwType = 0;
  1200. BOOL fReg = FALSE;
  1201. BOOL fRegLoaded = FALSE;
  1202. TCHAR szScratch[MAX_PATH];
  1203. TCHAR szExpanded[MAX_PATH];
  1204. LPTSTR psz;
  1205. if (m_hbmBrand)
  1206. {
  1207. DeleteObject(m_hbmBrand);
  1208. m_hbmBrand = NULL;
  1209. }
  1210. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, c_szRegKeyCoolbar, 0, KEY_QUERY_VALUE, &hKey))
  1211. {
  1212. fReg = TRUE;
  1213. dwcbData = MAX_PATH;
  1214. if (fReg && (ERROR_SUCCESS == RegQueryValueEx(hKey, IsFlagSet(CBSTATE_COMPRESSED) ? c_szValueSmBrandBitmap : c_szValueBrandBitmap, NULL, &dwType,
  1215. (LPBYTE)szScratch, &dwcbData)))
  1216. {
  1217. if (REG_EXPAND_SZ == dwType)
  1218. {
  1219. ExpandEnvironmentStrings(szScratch, szExpanded, ARRAYSIZE(szExpanded));
  1220. psz = szExpanded;
  1221. }
  1222. else
  1223. psz = szScratch;
  1224. m_hbmBrand = (HBITMAP) LoadImage(NULL, psz, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_CREATEDIBSECTION | LR_LOADFROMFILE);
  1225. if (m_hbmBrand)
  1226. fRegLoaded = TRUE;
  1227. }
  1228. }
  1229. if (!m_hbmBrand)
  1230. {
  1231. int id = IsFlagSet(CBSTATE_COMPRESSED) ? (fIsWhistler() ? idbHiBrand26 : idbBrand26) :
  1232. (fIsWhistler() ? idbHiBrand38 : idbBrand38);
  1233. m_hbmBrand = (HBITMAP)LoadImage(g_hLocRes, MAKEINTRESOURCE(id), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_CREATEDIBSECTION);
  1234. }
  1235. GetObject(m_hbmBrand, sizeof(DIBSECTION), &dib);
  1236. m_cxBrandExtent = dib.dsBm.bmWidth;
  1237. m_cyBrandExtent = dib.dsBm.bmHeight;
  1238. m_cxBrand = m_cxBrandExtent;
  1239. dwcbData = sizeof(DWORD);
  1240. if (!fRegLoaded || (ERROR_SUCCESS != RegQueryValueEx(hKey, IsFlagSet(CBSTATE_COMPRESSED) ? c_szValueSmBrandHeight : c_szValueBrandHeight, NULL, &dwType,
  1241. (LPBYTE)&m_cyBrand, &dwcbData)))
  1242. m_cyBrand = m_cxBrandExtent;
  1243. if (!fRegLoaded || (ERROR_SUCCESS != RegQueryValueEx(hKey, IsFlagSet(CBSTATE_COMPRESSED) ? c_szValueSmBrandLeadIn : c_szValueBrandLeadIn, NULL, &dwType,
  1244. (LPBYTE)&m_cyBrandLeadIn, &dwcbData)))
  1245. m_cyBrandLeadIn = 4;
  1246. m_cyBrandLeadIn *= m_cyBrand;
  1247. SelectObject(m_hdc, m_hbmBrand);
  1248. m_rgbUpperLeft = GetPixel(m_hdc, 1, 1);
  1249. if (fReg)
  1250. RegCloseKey(hKey);
  1251. // now look for old branding entries for IE2.0 and, if found, stick them
  1252. // in the first frame of the animation sequence
  1253. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyIEMain, 0, KEY_QUERY_VALUE, &hKey))
  1254. {
  1255. dwcbData = MAX_PATH;
  1256. if (ERROR_SUCCESS == RegQueryValueEx(hKey, IsFlagSet(CBSTATE_COMPRESSED) ? c_szValueSmallBitmap : c_szValueLargeBitmap, NULL, &dwType,
  1257. (LPBYTE)szScratch, &dwcbData))
  1258. {
  1259. if (REG_EXPAND_SZ == dwType)
  1260. {
  1261. ExpandEnvironmentStrings(szScratch, szExpanded, ARRAYSIZE(szExpanded));
  1262. psz = szExpanded;
  1263. }
  1264. else
  1265. psz = szScratch;
  1266. HBITMAP hbmOld = (HBITMAP) LoadImage(NULL, psz, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_CREATEDIBSECTION | LR_LOADFROMFILE);
  1267. if (hbmOld)
  1268. {
  1269. HDC hdcOld = CreateCompatibleDC(m_hdc);
  1270. if (hdcOld)
  1271. {
  1272. GetObject(hbmOld, sizeof(DIBSECTION), &dib);
  1273. SelectObject(hdcOld, hbmOld);
  1274. m_rgbUpperLeft = GetPixel(hdcOld, 1, 1);
  1275. StretchBlt(m_hdc, 0, 0, m_cxBrandExtent, m_cyBrand, hdcOld, 0, 0,
  1276. dib.dsBm.bmWidth, dib.dsBm.bmHeight, SRCCOPY);
  1277. DeleteDC(hdcOld);
  1278. }
  1279. DeleteObject(hbmOld);
  1280. }
  1281. }
  1282. RegCloseKey(hKey);
  1283. }
  1284. return(S_OK);
  1285. }
  1286. void CCoolbar::DrawBranding(LPDRAWITEMSTRUCT lpdis)
  1287. {
  1288. HPALETTE hpalPrev;
  1289. int x, y, cx, cy;
  1290. int yOrg = 0;
  1291. if (IsFlagSet(CBSTATE_ANIMATING))
  1292. yOrg = m_yOrg;
  1293. if (IsFlagSet(CBSTATE_FIRSTFRAME))
  1294. {
  1295. REBARBANDINFO rbbi;
  1296. int cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  1297. ZeroMemory(&rbbi, sizeof(rbbi));
  1298. rbbi.cbSize = sizeof(REBARBANDINFO);
  1299. rbbi.fMask = RBBIM_ID;
  1300. for (int i = 0; i < cBands; i++)
  1301. {
  1302. SendMessage(m_hwndRebar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
  1303. if (CBTYPE_BRAND == rbbi.wID)
  1304. {
  1305. rbbi.fMask = RBBIM_COLORS;
  1306. rbbi.clrFore = m_rgbUpperLeft;
  1307. rbbi.clrBack = m_rgbUpperLeft;
  1308. SendMessage(m_hwndRebar, RB_SETBANDINFO, i, (LPARAM) &rbbi);
  1309. break;
  1310. }
  1311. }
  1312. ClearFlag(CBSTATE_FIRSTFRAME);
  1313. }
  1314. if (m_hpal)
  1315. {
  1316. hpalPrev = SelectPalette(lpdis->hDC, m_hpal, TRUE);
  1317. RealizePalette(lpdis->hDC);
  1318. }
  1319. x = lpdis->rcItem.left;
  1320. cx = lpdis->rcItem.right - x;
  1321. y = lpdis->rcItem.top;
  1322. cy = lpdis->rcItem.bottom - y;
  1323. if (m_cxBrand > m_cxBrandExtent)
  1324. {
  1325. HBRUSH hbrBack = CreateSolidBrush(m_rgbUpperLeft);
  1326. int xRight = lpdis->rcItem.right;
  1327. x += (m_cxBrand - m_cxBrandExtent) / 2;
  1328. cx = m_cxBrandExtent;
  1329. lpdis->rcItem.right = x;
  1330. FillRect(lpdis->hDC, &lpdis->rcItem, hbrBack);
  1331. lpdis->rcItem.right = xRight;
  1332. lpdis->rcItem.left = x + cx;
  1333. FillRect(lpdis->hDC, &lpdis->rcItem, hbrBack);
  1334. DeleteObject(hbrBack);
  1335. }
  1336. BitBlt(lpdis->hDC, x, y, cx, cy, m_hdc, 0, yOrg, SRCCOPY);
  1337. if (m_hpal)
  1338. {
  1339. SelectPalette(lpdis->hDC, hpalPrev, TRUE);
  1340. RealizePalette(lpdis->hDC);
  1341. }
  1342. }
  1343. BOOL CCoolbar::SetMinDimensions(void)
  1344. {
  1345. REBARBANDINFO rbbi;
  1346. LRESULT lButtonSize;
  1347. int i, cBands;
  1348. ZeroMemory(&rbbi, sizeof(rbbi));
  1349. rbbi.cbSize = sizeof(REBARBANDINFO);
  1350. cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  1351. for (i = 0; i < cBands; i++)
  1352. {
  1353. rbbi.fMask = RBBIM_ID;
  1354. SendMessage(m_hwndRebar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
  1355. switch (rbbi.wID)
  1356. {
  1357. case CBTYPE_BRAND:
  1358. rbbi.cxMinChild = m_cxBrand;
  1359. rbbi.cyMinChild = m_cyBrand;
  1360. break;
  1361. case CBTYPE_TOOLS:
  1362. case CBTYPE_MENUBAND:
  1363. lButtonSize = SendMessage(m_hwndTools, TB_GETBUTTONSIZE, 0, 0L);
  1364. rbbi.cxMinChild = VERTICAL(m_csSide) ? HIWORD(lButtonSize) : LOWORD(lButtonSize);
  1365. rbbi.cyMinChild = VERTICAL(m_csSide) ? LOWORD(lButtonSize) : HIWORD(lButtonSize);
  1366. break;
  1367. }
  1368. rbbi.fMask = RBBIM_CHILDSIZE;
  1369. SendMessage(m_hwndRebar, RB_SETBANDINFO, i, (LPARAM)&rbbi);
  1370. }
  1371. return TRUE;
  1372. }
  1373. BOOL CCoolbar::CompressBands(BOOL fCompress)
  1374. {
  1375. LRESULT lTBStyle = 0;
  1376. int i, cBands;
  1377. REBARBANDINFO rbbi;
  1378. if (!!fCompress == IsFlagSet(CBSTATE_COMPRESSED))
  1379. // no change -- return immediately
  1380. return(FALSE);
  1381. if (fCompress)
  1382. SetFlag(CBSTATE_COMPRESSED);
  1383. else
  1384. ClearFlag(CBSTATE_COMPRESSED);
  1385. m_yOrg = 0;
  1386. LoadBrandingBitmap();
  1387. cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  1388. ZeroMemory(&rbbi, sizeof(rbbi));
  1389. rbbi.cbSize = sizeof(REBARBANDINFO);
  1390. for (i = 0; i < cBands; i++)
  1391. {
  1392. rbbi.fMask = RBBIM_ID;
  1393. SendMessage(m_hwndRebar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
  1394. if (fCompress)
  1395. {
  1396. switch (rbbi.wID)
  1397. {
  1398. case CBTYPE_TOOLS:
  1399. SendMessage(m_hwndTools, TB_SETMAXTEXTROWS, 0, 0L);
  1400. SendMessage(m_hwndTools, TB_SETBUTTONWIDTH, 0, (LPARAM) MAKELONG(0,MAX_TB_COMPRESSED_WIDTH));
  1401. break;
  1402. }
  1403. }
  1404. else
  1405. {
  1406. switch (rbbi.wID)
  1407. {
  1408. case CBTYPE_TOOLS:
  1409. SendMessage(m_hwndTools, TB_SETMAXTEXTROWS,
  1410. VERTICAL(m_csSide) ? MAX_TB_TEXT_ROWS_VERT : MAX_TB_TEXT_ROWS_HORZ, 0L);
  1411. SendMessage(m_hwndTools, TB_SETBUTTONWIDTH, 0, (LPARAM) MAKELONG(0, m_cxMaxButtonWidth));
  1412. break;
  1413. }
  1414. }
  1415. }
  1416. SetMinDimensions();
  1417. return(TRUE);
  1418. }
  1419. void CCoolbar::TrackSlidingX(int x)
  1420. {
  1421. int cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0L);
  1422. int cRows = SendMessage(m_hwndRebar, RB_GETROWCOUNT, 0, 0L);
  1423. int cxRow = SendMessage(m_hwndRebar, RB_GETROWHEIGHT, cBands - 1, 0L); // This should work correctly if vertical
  1424. REBARBANDINFO rbbi;
  1425. RECT rc;
  1426. int cxBefore;
  1427. BOOL fChanged = FALSE;
  1428. ZeroMemory(&rbbi, sizeof(rbbi));
  1429. rbbi.cbSize = sizeof(REBARBANDINFO);
  1430. rbbi.fMask = RBBIM_STYLE;
  1431. GetWindowRect(m_hwndRebar, &rc);
  1432. cxBefore = rc.right - rc.left;
  1433. if (((m_csSide == COOLBAR_LEFT) && (x < (m_xCapture - (cxRow / 2)))) ||
  1434. ((m_csSide == COOLBAR_RIGHT) && (x > (m_xCapture + (cxRow / 2)))))
  1435. {
  1436. if (cRows == 1)
  1437. fChanged = CompressBands(TRUE);
  1438. /*
  1439. else
  1440. {
  1441. while (0 > --cBands)
  1442. {
  1443. SendMessage(m_hwndRebar, RB_GETBANDINFO, cBands, (LPARAM) &rbbi);
  1444. if (fChanged = (rbbi.fStyle & RBBS_BREAK))
  1445. {
  1446. rbbi.fStyle &= ~RBBS_BREAK;
  1447. SendMessage(m_hwndRebar, RB_SETBANDINFO, cBands, (LPARAM) &rbbi);
  1448. break;
  1449. }
  1450. }
  1451. }
  1452. */
  1453. }
  1454. else if (((m_csSide == COOLBAR_LEFT) && (x > (m_xCapture + (cxRow / 2)))) ||
  1455. ((m_csSide == COOLBAR_RIGHT) && (x < (m_xCapture - (cxRow / 2)))))
  1456. {
  1457. /*
  1458. if (!(fChanged = CompressBands(FALSE)) && (cRows < (cBands - 1)))
  1459. {
  1460. while (0 > --cBands)
  1461. {
  1462. SendMessage(m_hwndRebar, RB_GETBANDINFO, cBands, (LPARAM) &rbbi);
  1463. if (fChanged = !(rbbi.fStyle & (RBBS_BREAK | RBBS_FIXEDSIZE)))
  1464. {
  1465. rbbi.fStyle |= RBBS_BREAK;
  1466. SendMessage(m_hwndRebar, RB_SETBANDINFO, cBands, (LPARAM) &rbbi);
  1467. break;
  1468. }
  1469. }
  1470. }
  1471. */
  1472. }
  1473. // TODO: There is a drawing glitch when you resize from 3 bars (No Text) to 3 bars
  1474. // with text. The _yCapture gets set to a value greater than y. So on the
  1475. // next MOUSEMOVE it figures that the user moved up and switches from 3 bars with text
  1476. // to 2 bars with text.
  1477. if (fChanged)
  1478. {
  1479. GetWindowRect(m_hwndRebar, &rc);
  1480. m_xCapture += (rc.right - rc.left) - cxBefore;
  1481. }
  1482. }
  1483. void CCoolbar::TrackSlidingY(int y)
  1484. {
  1485. int cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0L);
  1486. int cRows = SendMessage(m_hwndRebar, RB_GETROWCOUNT, 0, 0L);
  1487. int cyRow = SendMessage(m_hwndRebar, RB_GETROWHEIGHT, cBands - 1, 0L);
  1488. REBARBANDINFO rbbi;
  1489. RECT rc;
  1490. int cyBefore;
  1491. BOOL fChanged = FALSE;
  1492. ZeroMemory(&rbbi, sizeof(rbbi));
  1493. rbbi.cbSize = sizeof(REBARBANDINFO);
  1494. rbbi.fMask = RBBIM_STYLE;
  1495. GetWindowRect(m_hwndRebar, &rc);
  1496. cyBefore = rc.bottom - rc.top;
  1497. if (((m_csSide == COOLBAR_TOP) && (y < (m_yCapture - (cyRow / 2)))) ||
  1498. ((m_csSide == COOLBAR_BOTTOM) && (y > (m_yCapture + (cyRow / 2)))))
  1499. {
  1500. if (cRows == 1)
  1501. fChanged = CompressBands(TRUE);
  1502. /*
  1503. else
  1504. {
  1505. while (0 > --cBands)
  1506. {
  1507. SendMessage(m_hwndRebar, RB_GETBANDINFO, cBands, (LPARAM) &rbbi);
  1508. if (fChanged = (rbbi.fStyle & RBBS_BREAK))
  1509. {
  1510. rbbi.fStyle &= ~RBBS_BREAK;
  1511. SendMessage(m_hwndRebar, RB_SETBANDINFO, cBands, (LPARAM) &rbbi);
  1512. break;
  1513. }
  1514. }
  1515. }
  1516. */
  1517. }
  1518. else if (((m_csSide == COOLBAR_TOP) && (y > (m_yCapture + (cyRow / 2)))) ||
  1519. ((m_csSide == COOLBAR_BOTTOM) && (y < (m_yCapture - (cyRow / 2)))))
  1520. {
  1521. /*
  1522. if (!(fChanged = CompressBands(FALSE)) && (cRows < (cBands - 1)))
  1523. {
  1524. while (0 > --cBands)
  1525. {
  1526. SendMessage(m_hwndRebar, RB_GETBANDINFO, cBands, (LPARAM) &rbbi);
  1527. if (fChanged = !(rbbi.fStyle & (RBBS_BREAK | RBBS_FIXEDSIZE)))
  1528. {
  1529. rbbi.fStyle |= RBBS_BREAK;
  1530. SendMessage(m_hwndRebar, RB_SETBANDINFO, cBands, (LPARAM) &rbbi);
  1531. break;
  1532. }
  1533. }
  1534. }
  1535. */
  1536. }
  1537. // TODO: There is a drawing glitch when you resize from 3 bars (No Text) to 3 bars
  1538. // with text. The _yCapture gets set to a value greater than y. So on the
  1539. // next MOUSEMOVE it figures that the user moved up and switches from 3 bars with text
  1540. // to 2 bars with text.
  1541. if (fChanged)
  1542. {
  1543. GetWindowRect(m_hwndRebar, &rc);
  1544. m_yCapture += (rc.bottom - rc.top) - cyBefore;
  1545. }
  1546. }
  1547. // Flips the rebar from being horizontal to to vertical or the other way.
  1548. BOOL CCoolbar::ChangeOrientation()
  1549. {
  1550. LONG lStyle, lTBStyle;
  1551. lTBStyle = SendMessage(m_hwndTools, TB_GETSTYLE, 0, 0L);
  1552. lStyle = GetWindowLong(m_hwndRebar, GWL_STYLE);
  1553. SendMessage(m_hwndTools, WM_SETREDRAW, 0, 0L);
  1554. if (VERTICAL(m_csSide))
  1555. {
  1556. // Moving to Vertical
  1557. lStyle |= CCS_VERT;
  1558. lTBStyle |= TBSTYLE_WRAPABLE;
  1559. }
  1560. else
  1561. {
  1562. // Moving to Horizontal
  1563. lStyle &= ~CCS_VERT;
  1564. lTBStyle &= ~TBSTYLE_WRAPABLE;
  1565. }
  1566. SendMessage(m_hwndTools, TB_SETSTYLE, 0, lTBStyle);
  1567. SendMessage(m_hwndTools, WM_SETREDRAW, 1, 0L);
  1568. SetWindowLong(m_hwndRebar, GWL_STYLE, lStyle);
  1569. SetMinDimensions();
  1570. ResizeBorderDW(NULL, NULL, FALSE);
  1571. return TRUE;
  1572. }
  1573. //
  1574. // FUNCTION: CCoolbar::CreateRebar(BOOL fVisible)
  1575. //
  1576. // PURPOSE: Creates a new rebar and sizer window.
  1577. //
  1578. // RETURN VALUE:
  1579. // Returns S_OK if the bar was created and inserted correctly,
  1580. // hrAlreadyExists if a band already is in that position,
  1581. // E_OUTOFMEMORY if a window couldn't be created.
  1582. //
  1583. HRESULT CCoolbar::CreateRebar(BOOL fVisible)
  1584. {
  1585. if (m_hwndSizer)
  1586. return (hrAlreadyExists);
  1587. // $TODO: Only give the bar with the address bar the WS_TABSTOP style.
  1588. m_hwndSizer = CreateWindowEx(0, SIZABLECLASS, NULL, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | (fVisible ? WS_VISIBLE : 0),
  1589. 0, 0, 100, 36, m_hwndParent, (HMENU) 0, g_hInst, NULL);
  1590. if (m_hwndSizer)
  1591. {
  1592. DOUTL(4, TEXT("Calling SetProp. AddRefing new m_cRef=%d"), m_cRef + 1);
  1593. AddRef(); // Note we Release in WM_DESTROY
  1594. SetProp(m_hwndSizer, TEXT("CCoolbar"), this);
  1595. /*
  1596. m_hwndRebar = CreateWindowEx(WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL,
  1597. RBS_FIXEDORDER | RBS_VARHEIGHT | RBS_BANDBORDERS | WS_VISIBLE |
  1598. WS_BORDER | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
  1599. CCS_NODIVIDER | CCS_NOPARENTALIGN | (VERTICAL(m_csSide) ? CCS_VERT : 0),
  1600. 0, 0, 100, 136, m_hwndSizer, (HMENU) idcCoolbar, g_hInst, NULL);
  1601. */
  1602. m_hwndRebar = CreateWindowEx(WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL,
  1603. RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_REGISTERDROP | RBS_DBLCLKTOGGLE |
  1604. WS_VISIBLE | WS_BORDER | WS_CHILD | WS_CLIPCHILDREN |
  1605. WS_CLIPSIBLINGS | CCS_NODIVIDER | CCS_NOPARENTALIGN |
  1606. (VERTICAL(m_csSide) ? CCS_VERT : 0),
  1607. 0, 0, 100, 136, m_hwndSizer, (HMENU) idcCoolbar, g_hInst, NULL);
  1608. if (m_hwndRebar)
  1609. {
  1610. SendMessage(m_hwndRebar, RB_SETTEXTCOLOR, 0, (LPARAM)GetSysColor(COLOR_BTNTEXT));
  1611. SendMessage(m_hwndRebar, RB_SETBKCOLOR, 0, (LPARAM)GetSysColor(COLOR_BTNFACE));
  1612. //SendMessage(m_hwndRebar, RB_SETEXTENDEDSTYLE, RBS_EX_OFFICE9, RBS_EX_OFFICE9);
  1613. return (S_OK);
  1614. }
  1615. }
  1616. DestroyWindow(m_hwndSizer);
  1617. return (E_OUTOFMEMORY);
  1618. }
  1619. void SendSaveRestoreMessage(HWND hwnd, const TOOLBARARRAYINFO *ptai, BOOL fSave)
  1620. {
  1621. TBSAVEPARAMS tbsp;
  1622. char szSubKey[MAX_PATH], sz[MAX_PATH];
  1623. DWORD dwType;
  1624. DWORD dwVersion;
  1625. DWORD cbData = sizeof(DWORD);
  1626. DWORD dwError;
  1627. tbsp.hkr = AthUserGetKeyRoot();
  1628. AthUserGetKeyPath(sz, ARRAYSIZE(sz));
  1629. if (ptai->pszRegKey != NULL)
  1630. {
  1631. wnsprintf(szSubKey, ARRAYSIZE(szSubKey),c_szPathFileFmt, sz, ptai->pszRegKey);
  1632. tbsp.pszSubKey = szSubKey;
  1633. }
  1634. else
  1635. {
  1636. tbsp.pszSubKey = sz;
  1637. }
  1638. tbsp.pszValueName = ptai->pszRegValue;
  1639. // First check to see if the version has changed
  1640. if (!fSave)
  1641. {
  1642. if (ERROR_SUCCESS == AthUserGetValue(ptai->pszRegKey, c_szRegToolbarVersion, &dwType, (LPBYTE) &dwVersion, &cbData))
  1643. {
  1644. if (dwVersion == COOLBAR_VERSION)
  1645. SendMessage(hwnd, TB_SAVERESTORE, (WPARAM)fSave, (LPARAM)&tbsp);
  1646. }
  1647. }
  1648. else
  1649. {
  1650. dwVersion = COOLBAR_VERSION;
  1651. SendMessage(hwnd, TB_SAVERESTORE, (WPARAM)fSave, (LPARAM)&tbsp);
  1652. dwError = AthUserSetValue(ptai->pszRegKey, c_szRegToolbarVersion, REG_DWORD, (LPBYTE) &dwVersion, cbData);
  1653. }
  1654. }
  1655. //
  1656. // FUNCTION: CCoolbar::SaveSettings()
  1657. //
  1658. // PURPOSE: Called when we should save our state out to the specified reg
  1659. // key.
  1660. //
  1661. void CCoolbar::SaveSettings(void)
  1662. {
  1663. char szSubKey[MAX_PATH], sz[MAX_PATH];
  1664. DWORD iBand;
  1665. REBARBANDINFO rbbi;
  1666. HKEY hKey;
  1667. DWORD cBands;
  1668. // If we don't have the window, there is nothing to save.
  1669. if (!m_hwndRebar || !m_ptai)
  1670. return;
  1671. ZeroMemory(&rbbi, sizeof(REBARBANDINFO));
  1672. cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  1673. // Collect the bar-specific information
  1674. m_cbsSavedInfo.dwVersion = COOLBAR_VERSION;
  1675. m_cbsSavedInfo.dwState = m_dwState;
  1676. m_cbsSavedInfo.csSide = m_csSide;
  1677. // Loop through the bands and save their information as well
  1678. rbbi.cbSize = sizeof(REBARBANDINFO);
  1679. rbbi.fMask = RBBIM_STYLE | RBBIM_CHILD | RBBIM_SIZE | RBBIM_ID;
  1680. for (iBand = 0; iBand < cBands; iBand++)
  1681. {
  1682. Assert(IsWindow(m_hwndRebar));
  1683. if (SendMessage(m_hwndRebar, RB_GETBANDINFO, iBand, (LPARAM) &rbbi))
  1684. {
  1685. // Save the information that we care about with this band
  1686. m_cbsSavedInfo.bs[iBand].cx = rbbi.cx;
  1687. m_cbsSavedInfo.bs[iBand].dwStyle = rbbi.fStyle;
  1688. m_cbsSavedInfo.bs[iBand].wID = rbbi.wID;
  1689. // If this band has a toolbar, then we should instruct the toolbar
  1690. // to save it's information now
  1691. if (m_cbsSavedInfo.bs[iBand].wID == CBTYPE_TOOLS)
  1692. {
  1693. SendSaveRestoreMessage(rbbi.hwndChild, m_ptai, TRUE);
  1694. }
  1695. }
  1696. else
  1697. {
  1698. // Default Values
  1699. m_cbsSavedInfo.bs[iBand].wID = CBTYPE_NONE;
  1700. m_cbsSavedInfo.bs[iBand].dwStyle = 0;
  1701. m_cbsSavedInfo.bs[iBand].cx = 0;
  1702. }
  1703. }
  1704. // We have all the information collected, now save that to the specified
  1705. // registry location
  1706. AthUserSetValue(NULL, c_szRegCoolbarLayout, REG_BINARY, (const LPBYTE)&m_cbsSavedInfo, sizeof(COOLBARSAVE));
  1707. }
  1708. //
  1709. // FUNCTION: CCoolbar::AddTools()
  1710. //
  1711. // PURPOSE: Inserts the primary toolbar into the coolbar.
  1712. //
  1713. // PARAMETERS:
  1714. // pbs - Pointer to a PBANDSAVE struct with the styles and size of the
  1715. // band to insert.
  1716. //
  1717. // RETURN VALUE:
  1718. // Returns an HRESULT signifying success or failure.
  1719. //
  1720. HRESULT CCoolbar::AddTools(PBANDSAVE pbs)
  1721. {
  1722. REBARBANDINFO rbbi;
  1723. // add tools band
  1724. ZeroMemory(&rbbi, sizeof(rbbi));
  1725. rbbi.cbSize = sizeof(REBARBANDINFO);
  1726. rbbi.fMask = RBBIM_SIZE | RBBIM_ID | RBBIM_STYLE;
  1727. rbbi.fStyle = pbs->dwStyle;
  1728. rbbi.cx = pbs->cx;
  1729. // rbbi.wID = CBTYPE_TOOLS;
  1730. rbbi.wID = pbs->wID;
  1731. if (IsFlagClear(CBSTATE_NOBACKGROUND) && !m_hbmBack && m_idbBack)
  1732. m_hbmBack = (HBITMAP) LoadImage(g_hLocRes, MAKEINTRESOURCE(m_idbBack),
  1733. IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_CREATEDIBSECTION);
  1734. if (m_hbmBack)
  1735. {
  1736. rbbi.fMask |= RBBIM_BACKGROUND;
  1737. rbbi.fStyle |= RBBS_FIXEDBMP;
  1738. rbbi.hbmBack = m_hbmBack;
  1739. }
  1740. else
  1741. {
  1742. rbbi.fMask |= RBBIM_COLORS;
  1743. rbbi.clrFore = GetSysColor(COLOR_BTNTEXT);
  1744. rbbi.clrBack = GetSysColor(COLOR_BTNFACE);
  1745. }
  1746. SendMessage(m_hwndRebar, RB_INSERTBAND, (UINT) -1, (LPARAM) (LPREBARBANDINFO) &rbbi);
  1747. return(S_OK);
  1748. }
  1749. HRESULT CCoolbar::SetFolderType(FOLDERTYPE ftType)
  1750. {
  1751. TCHAR szToolsText[(MAX_TB_TEXT_LENGTH+2) * MAX_TB_BUTTONS];
  1752. int i, cBands;
  1753. REBARBANDINFO rbbi;
  1754. HWND hwndDestroy = NULL;
  1755. // If we haven't created the rebar yet, this will fail. Call ShowDW() first.
  1756. if (!IsWindow(m_hwndRebar))
  1757. return (E_FAIL);
  1758. // Check to see if this would actually be a change
  1759. if (ftType == m_ftType)
  1760. return (S_OK);
  1761. // First find the band with the toolbar
  1762. cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  1763. ZeroMemory(&rbbi, sizeof(rbbi));
  1764. rbbi.cbSize = sizeof(REBARBANDINFO);
  1765. rbbi.fMask = RBBIM_ID;
  1766. for (i = 0; i < cBands; i++)
  1767. {
  1768. SendMessage(m_hwndRebar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
  1769. if (CBTYPE_TOOLS == rbbi.wID)
  1770. break;
  1771. }
  1772. // We didn't find it.
  1773. if (i >= cBands)
  1774. return (E_FAIL);
  1775. // Destroy the old toolbar if it exists
  1776. if (IsWindow(m_hwndTools))
  1777. {
  1778. // Save it's button configuration
  1779. SendSaveRestoreMessage(m_hwndTools, m_ptai, TRUE);
  1780. SendMessage(m_hwndTools, TB_SETIMAGELIST, 0, NULL);
  1781. SendMessage(m_hwndTools, TB_SETHOTIMAGELIST, 0, NULL);
  1782. hwndDestroy = m_hwndTools;
  1783. }
  1784. // Update our internal state information with the new folder type
  1785. Assert(ftType < FOLDER_TYPESMAX);
  1786. m_ftType = ftType;
  1787. m_ptai = &(g_rgToolbarArrayInfo[m_ftType]);
  1788. // Create a new toolbar
  1789. m_hwndTools = CreateWindowEx(WS_EX_TOOLWINDOW, TOOLBARCLASSNAME, NULL,
  1790. WS_CHILD | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS
  1791. | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
  1792. | CCS_NODIVIDER | CCS_NOPARENTALIGN
  1793. | CCS_ADJUSTABLE | CCS_NORESIZE |
  1794. (VERTICAL(m_csSide) ? TBSTYLE_WRAPABLE : 0),
  1795. 0, 0, 0, 0, m_hwndRebar, (HMENU) idcToolbar,
  1796. g_hInst, NULL);
  1797. Assert(m_hwndTools);
  1798. if (!m_hwndTools)
  1799. {
  1800. DOUTL(1, TEXT("CCoolbar::SetFolderType() CreateWindow(TOOLBAR) failed"));
  1801. return(E_OUTOFMEMORY);
  1802. }
  1803. InitToolbar();
  1804. // If we have previously save configuration info for this toolbar, load it
  1805. SendSaveRestoreMessage(m_hwndTools, m_ptai, FALSE);
  1806. // First find the band with the toolbar
  1807. cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  1808. ZeroMemory(&rbbi, sizeof(rbbi));
  1809. rbbi.cbSize = sizeof(REBARBANDINFO);
  1810. rbbi.fMask = RBBIM_ID;
  1811. for (i = 0; i < cBands; i++)
  1812. {
  1813. SendMessage(m_hwndRebar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
  1814. if (CBTYPE_TOOLS == rbbi.wID)
  1815. break;
  1816. }
  1817. // Add the toolbar to the rebar
  1818. ZeroMemory(&rbbi, sizeof(rbbi));
  1819. rbbi.cbSize = sizeof(REBARBANDINFO);
  1820. rbbi.fMask = RBBIM_CHILD;
  1821. rbbi.hwndChild = m_hwndTools;
  1822. SendMessage(m_hwndRebar, RB_SETBANDINFO, (UINT) i, (LPARAM) (LPREBARBANDINFO) &rbbi);
  1823. if (hwndDestroy)
  1824. DestroyWindow(hwndDestroy);
  1825. SetMinDimensions();
  1826. ResizeBorderDW(NULL, NULL, FALSE);
  1827. return (S_OK);
  1828. }
  1829. void CCoolbar::SetSide(COOLBAR_SIDE csSide)
  1830. {
  1831. m_csSide = csSide;
  1832. ChangeOrientation();
  1833. }
  1834. void CCoolbar::SetText(BOOL fText)
  1835. {
  1836. CompressBands(!fText);
  1837. }
  1838. UINT GetCurColorRes(void)
  1839. {
  1840. HDC hdc;
  1841. UINT uColorRes;
  1842. hdc = GetDC(NULL);
  1843. uColorRes = GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL);
  1844. ReleaseDC(NULL, hdc);
  1845. return uColorRes;
  1846. }
  1847. /* InitToolbar:
  1848. **
  1849. ** Purpose:
  1850. ** makes decisions about small/large bitmaps and which
  1851. ** imagelist given the colordepth, then calls the
  1852. ** barutil InitToolbar
  1853. */
  1854. void CCoolbar::InitToolbar()
  1855. {
  1856. TCHAR szToolsText[(MAX_TB_TEXT_LENGTH+2) * MAX_TB_BUTTONS];
  1857. HKEY hKey;
  1858. TCHAR szValue[32];
  1859. DWORD cbValue = sizeof(szValue);
  1860. int idBmp;
  1861. // Check to see if the user has decided to use that crazy 16x16 images
  1862. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, c_szRegSmallIconsPath,
  1863. 0, KEY_READ, &hKey))
  1864. {
  1865. if (ERROR_SUCCESS == RegQueryValueEx(hKey, c_szRegSmallIconsValue, 0,
  1866. 0, (LPBYTE) szValue, &cbValue))
  1867. {
  1868. // people in IE decided it would be cool to store a boolean
  1869. // value as REG_SZ "Yes" and "No". Lovely.
  1870. m_fSmallIcons = !lstrcmpi(szValue, c_szYes);
  1871. }
  1872. RegCloseKey(hKey);
  1873. }
  1874. if (m_fSmallIcons)
  1875. {
  1876. idBmp = (fIsWhistler() ? ((GetCurColorRes() > 24) ? idb32SmBrowser : idbSmBrowser): idbNWSmBrowser);
  1877. }
  1878. // Check to see what our color depth is
  1879. else if (GetCurColorRes() > 24)
  1880. {
  1881. idBmp = (fIsWhistler() ? idb32256Browser : idbNW256Browser);
  1882. }
  1883. else if (GetCurColorRes() > 8)
  1884. {
  1885. idBmp = (fIsWhistler() ? idb256Browser : idbNW256Browser);
  1886. }
  1887. else
  1888. {
  1889. idBmp = (fIsWhistler() ? idbBrowser : idbNWBrowser);
  1890. }
  1891. LoadToolNames((UINT*) m_ptai->rgidsButtons, m_ptai->cidsButtons, szToolsText);
  1892. SendMessage(m_hwndTools, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DRAWDDARROWS);
  1893. ::InitToolbar(m_hwndTools, CIMLISTS, m_rghimlTools, m_ptai->cDefButtons,
  1894. m_ptai->rgDefButtons, szToolsText,
  1895. m_fSmallIcons ? TB_SMBMP_CX : (fIsWhistler() ? TB_BMP_CX : TB_BMP_CX_W2K),
  1896. m_fSmallIcons ? TB_SMBMP_CY : TB_BMP_CY,
  1897. IsFlagSet(CBSTATE_COMPRESSED) ? MAX_TB_COMPRESSED_WIDTH : m_cxMaxButtonWidth,
  1898. idBmp,
  1899. IsFlagSet(CBSTATE_COMPRESSED), VERTICAL(m_csSide));
  1900. //Register with the connection manager
  1901. if (g_pConMan)
  1902. {
  1903. //If Work offline is set then we should check the work offline button
  1904. SendMessage(m_hwndTools, TB_CHECKBUTTON, ID_WORK_OFFLINE, (LPARAM)(MAKELONG(g_pConMan->IsGlobalOffline(), 0)));
  1905. }
  1906. }
  1907. void CCoolbar::UpdateToolbarColors(void)
  1908. {
  1909. REBARBANDINFO rbbi;
  1910. UINT i;
  1911. UINT cBands;
  1912. // First find the band with the toolbar
  1913. cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  1914. ZeroMemory(&rbbi, sizeof(rbbi));
  1915. rbbi.cbSize = sizeof(REBARBANDINFO);
  1916. rbbi.fMask = RBBIM_ID;
  1917. for (i = 0; i < cBands; i++)
  1918. {
  1919. SendMessage(m_hwndRebar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
  1920. if (CBTYPE_TOOLS == rbbi.wID)
  1921. break;
  1922. }
  1923. // add tools band
  1924. ZeroMemory(&rbbi, sizeof(rbbi));
  1925. rbbi.cbSize = sizeof(REBARBANDINFO);
  1926. rbbi.fMask = RBBIM_COLORS;
  1927. rbbi.clrFore = GetSysColor(COLOR_BTNTEXT);
  1928. rbbi.clrBack = GetSysColor(COLOR_BTNFACE);
  1929. SendMessage(m_hwndRebar, RB_SETBANDINFO, i, (LPARAM) (LPREBARBANDINFO) &rbbi);
  1930. }
  1931. HRESULT CCoolbar::OnConnectionNotify(CONNNOTIFY nCode,
  1932. LPVOID pvData,
  1933. CConnectionManager *pConMan)
  1934. {
  1935. if ((m_hwndTools) && (nCode == CONNNOTIFY_WORKOFFLINE))
  1936. {
  1937. SendMessage(m_hwndTools, TB_CHECKBUTTON, ID_WORK_OFFLINE, (LPARAM)MAKELONG((BOOL)pvData, 0));
  1938. }
  1939. return S_OK;
  1940. }
  1941. //
  1942. // FUNCTION: InitToolbar()
  1943. //
  1944. // PURPOSE: Given all the parameters needed to configure a toolbar,
  1945. // this function loads the image lists and configures the
  1946. // toolbar.
  1947. //
  1948. // PARAMETERS:
  1949. // hwnd - Handle of the toolbar window to init.
  1950. // phiml - Array of imagelists where the hot, disabled, and normal
  1951. // buttons are returned.
  1952. // nBtns - The number of buttons in the ptbb array.
  1953. // ptbb - Array of buttons to add to the toolbar.
  1954. // pStrings - List of toolbar button / tooltip strings to add.
  1955. // cx, cy - Size of the bitmaps being added to the toolbar.
  1956. // cxMax - Maximum button width.
  1957. // idBmp - Resource id of the first image list to load.
  1958. //
  1959. void InitToolbar(const HWND hwnd, const int cHiml, HIMAGELIST *phiml,
  1960. UINT nBtns, const TBBUTTON *ptbb,
  1961. const TCHAR *pStrings,
  1962. const int cxImg, const int cyImg, const int cxMax,
  1963. const int idBmp, const BOOL fCompressed,
  1964. const BOOL fVertical)
  1965. {
  1966. int nRows;
  1967. if (fCompressed)
  1968. nRows = 0;
  1969. else
  1970. nRows = fVertical ? MAX_TB_TEXT_ROWS_VERT : MAX_TB_TEXT_ROWS_HORZ;
  1971. LoadGlyphs(hwnd, cHiml, phiml, cxImg, idBmp);
  1972. // this tells the toolbar what version we are
  1973. SendMessage(hwnd, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
  1974. SendMessage(hwnd, TB_SETMAXTEXTROWS, nRows, 0L);
  1975. SendMessage(hwnd, TB_SETBITMAPSIZE, 0, MAKELONG(cxImg, cyImg));
  1976. SendMessage(hwnd, TB_SETBUTTONWIDTH, 0, MAKELONG(0, cxMax));
  1977. if (pStrings) SendMessage(hwnd, TB_ADDSTRING, 0, (LPARAM) pStrings);
  1978. if (nBtns) SendMessage(hwnd, TB_ADDBUTTONS, nBtns, (LPARAM) ptbb);
  1979. }
  1980. void LoadGlyphs(const HWND hwnd, const int cHiml, HIMAGELIST *phiml, const int cx,
  1981. const int idBmp)
  1982. {
  1983. const UINT uFlags = LR_LOADMAP3DCOLORS | LR_CREATEDIBSECTION;
  1984. HIMAGELIST LocHiml[CIMLISTS];
  1985. if (phiml == NULL)
  1986. {
  1987. phiml = LocHiml;
  1988. }
  1989. for (int i = 0; i < cHiml; i++)
  1990. {
  1991. if (phiml[i])
  1992. ImageList_Destroy(phiml[i]);
  1993. phiml[i] = ImageList_LoadImage(g_hLocRes,
  1994. MAKEINTRESOURCE(idBmp + i), cx, 0, RGB(255, 0, 255),
  1995. IMAGE_BITMAP, uFlags);
  1996. }
  1997. SendMessage(hwnd, TB_SETIMAGELIST, 0, (LPARAM) phiml[IMLIST_DEFAULT]);
  1998. // if we weren't given a full set of lists to do, then don't set this
  1999. if (CIMLISTS == cHiml)
  2000. {
  2001. SendMessage(hwnd, TB_SETHOTIMAGELIST, 0, (LPARAM) phiml[IMLIST_HOT]);
  2002. }
  2003. }
  2004. BOOL LoadToolNames(const UINT *rgIds, const UINT cIds, TCHAR *szTools)
  2005. {
  2006. for (UINT i = 0; i < cIds; i++)
  2007. {
  2008. LoadString(g_hLocRes, rgIds[i], szTools, MAX_TB_TEXT_LENGTH);
  2009. szTools += lstrlen(szTools) + 1;
  2010. }
  2011. *szTools = TEXT('\0');
  2012. return(TRUE);
  2013. }
  2014. HRESULT CCoolbar::Update(void)
  2015. {
  2016. DWORD cButtons = 0;
  2017. OLECMD *rgCmds;
  2018. TBBUTTON tb;
  2019. DWORD cCmds = 0;
  2020. IOleCommandTarget *pTarget = NULL;
  2021. DWORD i;
  2022. DWORD dwState;
  2023. // Get the number of buttons on the toolbar
  2024. cButtons = SendMessage(m_hwndTools, TB_BUTTONCOUNT, 0, 0);
  2025. if (0 == cButtons)
  2026. return (S_OK);
  2027. // Allocate an array of OLECMD structures for the buttons
  2028. if (!MemAlloc((LPVOID *) &rgCmds, sizeof(OLECMD) * cButtons))
  2029. return (E_OUTOFMEMORY);
  2030. // Loop through the buttons and get the ID for each
  2031. for (i = 0; i < cButtons; i++)
  2032. {
  2033. if (SendMessage(m_hwndTools, TB_GETBUTTON, i, (LPARAM) &tb))
  2034. {
  2035. // Toolbar returns zero for seperators
  2036. if (tb.idCommand)
  2037. {
  2038. rgCmds[cCmds].cmdID = tb.idCommand;
  2039. rgCmds[cCmds].cmdf = 0;
  2040. cCmds++;
  2041. }
  2042. }
  2043. }
  2044. // I don't see how this can be false
  2045. Assert(m_ptbSite);
  2046. // Do the QueryStatus thing
  2047. if (SUCCEEDED(m_ptbSite->QueryInterface(IID_IOleCommandTarget, (void**) &pTarget)))
  2048. {
  2049. if (SUCCEEDED(pTarget->QueryStatus(NULL, cCmds, rgCmds, NULL)))
  2050. {
  2051. // Go through the array now and do the enable / disable thing
  2052. for (i = 0; i < cCmds; i++)
  2053. {
  2054. // Get the current state of the button
  2055. dwState = SendMessage(m_hwndTools, TB_GETSTATE, rgCmds[i].cmdID, 0);
  2056. // Update the state with the feedback we've been provided
  2057. if (rgCmds[i].cmdf & OLECMDF_ENABLED)
  2058. dwState |= TBSTATE_ENABLED;
  2059. else
  2060. dwState &= ~TBSTATE_ENABLED;
  2061. if (rgCmds[i].cmdf & OLECMDF_LATCHED)
  2062. dwState |= TBSTATE_CHECKED;
  2063. else
  2064. dwState &= ~TBSTATE_CHECKED;
  2065. // Radio check has no meaning here.
  2066. Assert(0 == (rgCmds[i].cmdf & OLECMDF_NINCHED));
  2067. SendMessage(m_hwndTools, TB_SETSTATE, rgCmds[i].cmdID, dwState);
  2068. // If this is the work offline button, we need to do a bit more work
  2069. if (rgCmds[i].cmdID == ID_WORK_OFFLINE)
  2070. {
  2071. _UpdateWorkOffline(rgCmds[i].cmdf);
  2072. }
  2073. }
  2074. }
  2075. pTarget->Release();
  2076. }
  2077. MemFree(rgCmds);
  2078. return (S_OK);
  2079. }
  2080. void CCoolbar::_UpdateWorkOffline(DWORD cmdf)
  2081. {
  2082. TBBUTTONINFO tbbi = { 0 };
  2083. TCHAR szRes[CCHMAX_STRINGRES];
  2084. int idString;
  2085. // Because we change the text and image for the "Work Offline" button,
  2086. // we need to do some work here based on whether or not the button is
  2087. // checked or not.
  2088. if (cmdf & OLECMDF_LATCHED)
  2089. {
  2090. idString = idsWorkOnline;
  2091. tbbi.iImage = iCBWorkOnline;
  2092. }
  2093. else
  2094. {
  2095. idString = idsWorkOffline;
  2096. tbbi.iImage = iCBWorkOffline;
  2097. }
  2098. // Load the new string
  2099. AthLoadString(idString, szRes, ARRAYSIZE(szRes));
  2100. // Fill in the struct
  2101. tbbi.cbSize = sizeof(TBBUTTONINFO);
  2102. tbbi.dwMask = TBIF_IMAGE | TBIF_TEXT;
  2103. tbbi.pszText = szRes;
  2104. // Update the button
  2105. SendMessage(m_hwndTools, TB_SETBUTTONINFO, ID_WORK_OFFLINE, (LPARAM) &tbbi);
  2106. }
  2107. HRESULT CCoolbar::CreateMenuBand(PBANDSAVE pbs)
  2108. {
  2109. HRESULT hres;
  2110. HWND hwndBrowser;
  2111. HMENU hMenu;
  2112. IShellMenu *pShellMenu;
  2113. //Get the hwnd for the browser
  2114. if (g_pBrowser)
  2115. {
  2116. hres = g_pBrowser->GetWindow(&hwndBrowser);
  2117. if (hres != S_OK)
  2118. return hres;
  2119. }
  2120. //hMenu = ::GetMenu(hwndBrowser);
  2121. //Cocreate menuband
  2122. hres = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER, IID_IShellMenu, (LPVOID*)&m_pShellMenu);
  2123. if (hres != S_OK)
  2124. {
  2125. return hres;
  2126. }
  2127. /*
  2128. m_mbCallback = new CMenuCallback;
  2129. if (m_mbCallback == NULL)
  2130. {
  2131. hres = S_FALSE;
  2132. return hres;
  2133. }
  2134. */
  2135. m_pShellMenu->Initialize(m_mbCallback, -1, ANCESTORDEFAULT, SMINIT_DEFAULTTOTRACKPOPUP | SMINIT_HORIZONTAL |
  2136. /*SMINIT_USEMESSAGEFILTER|*/ SMINIT_TOPLEVEL);
  2137. m_pShellMenu->SetMenu(m_hMenu, hwndBrowser, SMSET_DONTOWN);
  2138. hres = AddMenuBand(pbs);
  2139. return hres;
  2140. }
  2141. HRESULT CCoolbar::AddMenuBand(PBANDSAVE pbs)
  2142. {
  2143. REBARBANDINFO rbbi;
  2144. HRESULT hres;
  2145. HWND hwndMenuBand = NULL;
  2146. IObjectWithSite *pObj;
  2147. hres = m_pShellMenu->QueryInterface(IID_IDeskBand, (LPVOID*)&m_pDeskBand);
  2148. if (FAILED(hres))
  2149. return hres;
  2150. hres = m_pShellMenu->QueryInterface(IID_IMenuBand, (LPVOID*)&m_pMenuBand);
  2151. if (FAILED(hres))
  2152. return hres;
  2153. hres = m_pDeskBand->QueryInterface(IID_IWinEventHandler, (LPVOID*)&m_pWinEvent);
  2154. if (FAILED(hres))
  2155. return hres;
  2156. hres = m_pDeskBand->QueryInterface(IID_IObjectWithSite, (LPVOID*)&pObj);
  2157. if (FAILED(hres))
  2158. return hres;
  2159. pObj->SetSite((IDockingWindow*)this);
  2160. pObj->Release();
  2161. m_pDeskBand->GetWindow(&m_hwndMenuBand);
  2162. ZeroMemory(&rbbi, sizeof(rbbi));
  2163. rbbi.cbSize = sizeof(REBARBANDINFO);
  2164. rbbi.fMask = RBBIM_SIZE | RBBIM_ID | RBBIM_STYLE | RBBIM_CHILD;
  2165. rbbi.fStyle = pbs->dwStyle;
  2166. rbbi.cx = pbs->cx;
  2167. rbbi.wID = pbs->wID;
  2168. rbbi.hwndChild = m_hwndMenuBand;
  2169. SendMessage(m_hwndRebar, RB_INSERTBAND, (UINT)-1, (LPARAM)(LPREBARBANDINFO)&rbbi);
  2170. HWND hwndBrowser;
  2171. if (g_pBrowser)
  2172. {
  2173. hres = g_pBrowser->GetWindow(&hwndBrowser);
  2174. if (hres != S_OK)
  2175. return hres;
  2176. }
  2177. SetForegroundWindow(hwndBrowser);
  2178. /*
  2179. IInputObject* pio;
  2180. if (SUCCEEDED(m_pDeskBand->QueryInterface(IID_IInputObject, (void**)&pio)))
  2181. {
  2182. pio->UIActivateIO(TRUE, NULL);
  2183. pio->Release();
  2184. }
  2185. */
  2186. m_pDeskBand->ShowDW(TRUE);
  2187. SetNotRealSite();
  2188. //Get Bandinfo and set
  2189. return S_OK;
  2190. }
  2191. HRESULT CCoolbar::TranslateMenuMessage(MSG *pmsg, LRESULT *lpresult)
  2192. {
  2193. if (m_pMenuBand)
  2194. return m_pMenuBand->TranslateMenuMessage(pmsg, lpresult);
  2195. else
  2196. return S_FALSE;
  2197. }
  2198. HRESULT CCoolbar::IsMenuMessage(MSG *lpmsg)
  2199. {
  2200. if (m_pMenuBand)
  2201. return m_pMenuBand->IsMenuMessage(lpmsg);
  2202. else
  2203. return S_FALSE;
  2204. }
  2205. void CCoolbar::SetNotRealSite()
  2206. {
  2207. IOleCommandTarget *pOleCmd;
  2208. if (m_pDeskBand->QueryInterface(IID_IOleCommandTarget, (LPVOID*)&pOleCmd) == S_OK)
  2209. {
  2210. //pOleCmd->Exec(&CGID_MenuBand, MBANDCID_NOTAREALSITE, TRUE, NULL, NULL);
  2211. pOleCmd->Exec(&CLSID_MenuBand, 3, TRUE, NULL, NULL);
  2212. pOleCmd->Release();
  2213. }
  2214. }
  2215. void CCoolbar::HandleCoolbarPopup(UINT xPos, UINT yPos)
  2216. {
  2217. // Load the context menu
  2218. HMENU hMenu = LoadPopupMenu(IDR_COOLBAR_POPUP);
  2219. if (!hMenu)
  2220. return;
  2221. // Loop through the bands and see which ones are visible
  2222. DWORD cBands, iBand;
  2223. REBARBANDINFO rbbi = {0};
  2224. rbbi.cbSize = sizeof(REBARBANDINFO);
  2225. rbbi.fMask = RBBIM_STYLE | RBBIM_ID;
  2226. cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  2227. for (iBand = 0; iBand < cBands; iBand++)
  2228. {
  2229. if (SendMessage(m_hwndRebar, RB_GETBANDINFO, iBand, (LPARAM) &rbbi))
  2230. {
  2231. if (!(rbbi.fStyle & RBBS_HIDDEN))
  2232. {
  2233. switch (rbbi.wID)
  2234. {
  2235. case CBTYPE_TOOLS:
  2236. CheckMenuItem(hMenu, ID_COOLTOOLBAR, MF_BYCOMMAND | MF_CHECKED);
  2237. break;
  2238. }
  2239. }
  2240. }
  2241. }
  2242. SetFlag(CBSTATE_INMENULOOP);
  2243. DWORD cmd;
  2244. cmd = TrackPopupMenuEx(hMenu, TPM_RETURNCMD | TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
  2245. xPos, yPos, m_hwndSizer, NULL);
  2246. if (cmd != 0)
  2247. {
  2248. switch (cmd)
  2249. {
  2250. case ID_COOLTOOLBAR:
  2251. HideToolbar(CBTYPE_TOOLS);
  2252. break;
  2253. }
  2254. }
  2255. ClearFlag(CBSTATE_INMENULOOP);
  2256. if (hMenu)
  2257. DestroyMenu(hMenu);
  2258. }