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.

3815 lines
114 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) 1993-1996 Microsoft Corporation. All Rights Reserved.
  3. //
  4. // MODULE: bands.cpp
  5. //
  6. // PURPOSE: Implements the sizable coolbar window.
  7. //
  8. #include "pch.hxx"
  9. #include "ourguid.h"
  10. #include "browser.h"
  11. #include <resource.h>
  12. #include "tbbands.h"
  13. #include "strconst.h"
  14. #include "thormsgs.h"
  15. #include <error.h>
  16. #include "xpcomm.h"
  17. #include "conman.h"
  18. #include "mailnews.h"
  19. #include "htmlhelp.h"
  20. #include "statnery.h"
  21. #include "goptions.h"
  22. #include "menuutil.h"
  23. #include "menures.h"
  24. #include <shlobjp.h>
  25. #include <ieguidp.h>
  26. #include "mbcallbk.h"
  27. #include "baui.h"
  28. #include "imsgsite.h"
  29. #include "acctutil.h"
  30. #include "tbinfo.h"
  31. #include "tbcustom.h"
  32. #include "oerules.h"
  33. #include <notify.h>
  34. #include "demand.h"
  35. #include "mirror.h"
  36. UINT GetCurColorRes(void);
  37. #define RECTWIDTH(rc) (rc.right - rc.left)
  38. #define RECTHEIGHT(rc) (rc.bottom - rc.top)
  39. #define SZ_PROP_CUSTDLG TEXT("Itbar custom dialog hwnd")
  40. const INITBANDINFO c_DefaultTable[MAX_PARENT_TYPES] =
  41. {
  42. //Version, #bands,
  43. {BROWSER_BAND_VERSION, 4, {
  44. {CBTYPE_MENUBAND, RBBS_GRIPPERALWAYS | RBBS_USECHEVRON, 100},
  45. {CBTYPE_BRAND, RBBS_FIXEDSIZE, 100},
  46. {CBTYPE_TOOLS, RBBS_BREAK | RBBS_USECHEVRON, 100},
  47. {CBTYPE_RULESTOOLBAR, RBBS_BREAK | RBBS_HIDDEN, 100}
  48. }
  49. },
  50. {NOTE_BAND_VERSION, 3, {
  51. {CBTYPE_MENUBAND, RBBS_GRIPPERALWAYS | RBBS_USECHEVRON, 100},
  52. {CBTYPE_BRAND, RBBS_FIXEDSIZE, 100},
  53. {CBTYPE_TOOLS, RBBS_BREAK | RBBS_USECHEVRON, 100}
  54. }
  55. }
  56. };
  57. //Table for RegKeys
  58. const LPCTSTR c_BandRegKeyInfo[] = {
  59. c_szRegBrowserBands,
  60. c_szRegNoteBands
  61. };
  62. const TOOLBAR_INFO* c_DefButtonInfo[MAX_PARENT_TYPES] = {
  63. c_rgBrowserToolbarInfo,
  64. c_rgNoteToolbarInfo
  65. };
  66. //Hot bitmap ids are def + 1
  67. //Small, HI, Lo
  68. const ImageListStruct c_ImageListStruct[MAX_PARENT_TYPES] = {
  69. {2, {idbSmBrowser, idb256Browser, idbBrowser}},
  70. {2, {idbSmBrowser, idb256Browser, idbBrowser}}
  71. };
  72. const ImageListStruct c_NWImageListStruct[MAX_PARENT_TYPES] = {
  73. {2, {idbNWSmBrowser, idbNW256Browser, idbNWBrowser}},
  74. {2, {idbNWSmBrowser, idbNW256Browser, idbNWBrowser}}
  75. };
  76. const ImageListStruct c_32ImageListStruct[MAX_PARENT_TYPES] = {
  77. {2, {idb32SmBrowser, idb32256Browser, idbBrowser}},
  78. {2, {idb32SmBrowser, idb32256Browser, idbBrowser}}
  79. };
  80. const int c_RulesImageList[3] =
  81. {
  82. idbSmRulesTB, idbHiRulesTB, idbLoRulesTB
  83. };
  84. const int c_NWRulesImageList[3] =
  85. {
  86. idbNWSmRulesTB, idbNWHiRulesTB, idbNWLoRulesTB
  87. };
  88. const int c_32RulesImageList[3] =
  89. {
  90. idb32SmRulesTB, idb32HiRulesTB, idb32LoRulesTB
  91. };
  92. CBands::CBands() : m_cRef(1), m_yCapture(-1)
  93. {
  94. DOUTL(1, TEXT("ctor CBands %x"), this);
  95. m_cRef = 1;
  96. m_ptbSite = NULL;
  97. m_ptbSiteCT = NULL;
  98. m_cxMaxButtonWidth = 70;
  99. m_ftType = FOLDER_TYPESMAX;
  100. m_hwndParent = NULL;
  101. m_hwndTools = NULL;
  102. m_hwndBrand = NULL;
  103. m_hwndSizer = NULL;
  104. m_hwndRebar = NULL;
  105. m_dwState = 0;
  106. m_idbBack = 0;
  107. m_hbmBack = NULL;
  108. m_hbmBrand = NULL;
  109. Assert(2 == CIMLISTS);
  110. m_hpal = NULL;
  111. m_hdc = NULL;
  112. m_xOrg = 0;
  113. m_yOrg = 0;
  114. m_cxBmp = 0;
  115. m_cyBmp = 0;
  116. m_cxBrand = 0;
  117. m_cyBrand = 0;
  118. m_cxBrandExtent = 0;
  119. m_cyBrandExtent = 0;
  120. m_cyBrandLeadIn = 0;
  121. m_rgbUpperLeft = 0;
  122. m_pSavedBandInfo = NULL;
  123. m_pMenuBand = NULL;
  124. m_pDeskBand = NULL;
  125. m_pShellMenu = NULL;
  126. m_pWinEvent = NULL;
  127. m_xCapture = -1;
  128. m_yCapture = -1;
  129. // Bug #12953 - Try to load the localized max button width from the resources
  130. TCHAR szBuffer[32];
  131. if (AthLoadString(idsMaxCoolbarBtnWidth, szBuffer, ARRAYSIZE(szBuffer)))
  132. {
  133. m_cxMaxButtonWidth = StrToInt(szBuffer);
  134. if (m_cxMaxButtonWidth == 0)
  135. m_cxMaxButtonWidth = 70;
  136. }
  137. m_fBrandLoaded = FALSE;
  138. m_dwBrandSize = BRAND_SIZE_SMALL;
  139. m_hwndRulesToolbar = NULL;
  140. m_hwndFilterCombo = NULL;
  141. m_dwToolbarTextState = TBSTATE_FULLTEXT;
  142. m_dwIconSize = LARGE_ICONS;
  143. m_fDirty = FALSE;
  144. m_dwPrevTextStyle = TBSTATE_FULLTEXT;
  145. m_pTextStyleNotify = NULL;
  146. m_hComboBoxFont = 0;
  147. }
  148. CBands::~CBands()
  149. {
  150. int i;
  151. DOUTL(1, TEXT("dtor CBands %x"), this);
  152. if (m_ptbSite)
  153. {
  154. AssertSz(m_ptbSite == NULL, _T("CBands::~CBands() - For some reason ")
  155. _T("we still have a pointer to the site."));
  156. m_ptbSite->Release();
  157. m_ptbSite = NULL;
  158. }
  159. if (m_hpal)
  160. DeleteObject(m_hpal);
  161. if (m_hdc)
  162. DeleteDC(m_hdc);
  163. if (m_hbmBrand)
  164. DeleteObject(m_hbmBrand);
  165. if ( m_hbmBack )
  166. DeleteObject(m_hbmBack);
  167. SafeRelease(m_pDeskBand);
  168. SafeRelease(m_pMenuBand);
  169. SafeRelease(m_pWinEvent);
  170. SafeRelease(m_pShellMenu);
  171. SafeRelease(m_pTextStyleNotify);
  172. if (m_pSavedBandInfo)
  173. MemFree(m_pSavedBandInfo);
  174. if (m_hComboBoxFont != 0)
  175. DeleteObject(m_hComboBoxFont);
  176. }
  177. //
  178. // FUNCTION: CBands::HrInit()
  179. //
  180. // PURPOSE: Initializes the coolbar with the information needed to load
  181. // any persisted reg settings and the correct arrays of buttons
  182. // to display.
  183. //
  184. // PARAMETERS:
  185. // <in> idBackground - Resource ID of the background bitmap to use.
  186. //
  187. // RETURN VALUE:
  188. // S_OK - Everything initialized correctly.
  189. //
  190. HRESULT CBands::HrInit(DWORD idBackground, HMENU hmenu, DWORD dwParentType)
  191. {
  192. DWORD cbData;
  193. DWORD dwType;
  194. LRESULT lResult;
  195. HRESULT hr;
  196. if ((int)idBackground == -1)
  197. SetFlag(TBSTATE_NOBACKGROUND);
  198. m_idbBack = idBackground;
  199. m_hMenu = hmenu;
  200. m_dwParentType = dwParentType;
  201. m_cSavedBandInfo = ((c_DefaultTable[m_dwParentType].cBands * sizeof(BANDSAVE)) + sizeof(DWORD) * 2);
  202. if (MemAlloc((LPVOID*)&m_pSavedBandInfo, m_cSavedBandInfo))
  203. {
  204. ZeroMemory(m_pSavedBandInfo, m_cSavedBandInfo);
  205. cbData = m_cSavedBandInfo;
  206. lResult = AthUserGetValue(NULL, c_BandRegKeyInfo[m_dwParentType], &dwType, (LPBYTE)m_pSavedBandInfo, &cbData);
  207. if ((lResult != ERROR_SUCCESS) || (m_pSavedBandInfo->dwVersion != c_DefaultTable[m_dwParentType].dwVersion))
  208. {
  209. //Set up default bands
  210. CopyMemory(m_pSavedBandInfo, &c_DefaultTable[m_dwParentType],
  211. m_cSavedBandInfo);
  212. //Set Icon size to Large
  213. m_dwIconSize = LARGE_ICONS;
  214. }
  215. else
  216. {
  217. //Validate the data we retrieved from the registry
  218. ValidateRetrievedData(m_pSavedBandInfo);
  219. cbData = sizeof(DWORD);
  220. if (ERROR_SUCCESS != AthUserGetValue(NULL, c_szRegToolbarIconSize, &dwType, (LPBYTE)&m_dwIconSize, &cbData))
  221. m_dwIconSize = LARGE_ICONS;
  222. }
  223. //If there is one, load it.
  224. LoadBackgroundImage();
  225. cbData = sizeof(DWORD);
  226. if (ERROR_SUCCESS != AthUserGetValue(NULL, c_szRegPrevToolbarText, &dwType, (LPBYTE)&m_dwPrevTextStyle,
  227. &cbData))
  228. {
  229. m_dwPrevTextStyle = TBSTATE_FULLTEXT;
  230. }
  231. DWORD dwState;
  232. if (ERROR_SUCCESS != AthUserGetValue(NULL, c_szRegToolbarText, &dwType, (LPBYTE)&dwState, &cbData))
  233. {
  234. SetTextState(TBSTATE_FULLTEXT);
  235. }
  236. else
  237. {
  238. SetTextState(dwState);
  239. }
  240. //Create notification object
  241. hr = CreateNotify(&m_pTextStyleNotify);
  242. if (SUCCEEDED(hr))
  243. {
  244. hr = m_pTextStyleNotify->Initialize((TCHAR*)c_szToolbarNotifications);
  245. }
  246. return hr;
  247. }
  248. else
  249. hr = E_OUTOFMEMORY;
  250. return hr;
  251. }
  252. HRESULT CBands::ValidateRetrievedData(INITBANDINFO *pSavedBandData)
  253. {
  254. DWORD i = 0;
  255. DWORD j = 0;
  256. //We reach here if the version number is the same. So we just need to verify the rest of the data
  257. //We should definitely find MenuBandID. If we do find it, it should never be hidden
  258. DOUTL(16, "Validating Retrieved Data\n");
  259. // Make sure that the number of bands is greater than zero.
  260. if (pSavedBandData->cBands == 0)
  261. {
  262. // Structure has no bands, so this must be invalid and we fall back on the defaults.
  263. CopyMemory(pSavedBandData, &c_DefaultTable[m_dwParentType], m_cSavedBandInfo);
  264. return (S_OK);
  265. }
  266. if (pSavedBandData)
  267. {
  268. for (i = 0; i < c_DefaultTable[m_dwParentType].cBands; i++)
  269. {
  270. for (j = 0; j < c_DefaultTable[m_dwParentType].cBands; j++)
  271. {
  272. if (c_DefaultTable[m_dwParentType].BandData[i].wID == pSavedBandData->BandData[j].wID)
  273. {
  274. if ((pSavedBandData->BandData[j].wID == CBTYPE_MENUBAND) &&
  275. (!!(pSavedBandData->BandData[j].dwStyle & RBBS_HIDDEN)))
  276. {
  277. DOUTL(16, "Menuband was found hidden\n");
  278. //If the Menuband style is hidden, mask it
  279. pSavedBandData->BandData[j].dwStyle &= ~RBBS_HIDDEN;
  280. }
  281. break;
  282. }
  283. }
  284. if (j >= c_DefaultTable[m_dwParentType].cBands)
  285. {
  286. //We did not find the id we were looking for. We treat this case the same as the case
  287. //where version number didn't match
  288. DOUTL(16, "ID: %d not found: Resetting\n", c_DefaultTable[m_dwParentType].BandData[i].wID);
  289. CopyMemory(pSavedBandData, &c_DefaultTable[m_dwParentType], m_cSavedBandInfo);
  290. break;
  291. }
  292. }
  293. return S_OK;
  294. }
  295. else
  296. return E_FAIL;
  297. }
  298. HRESULT CBands::QueryInterface(REFIID riid, LPVOID * ppvObj)
  299. {
  300. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IOleWindow)
  301. || IsEqualIID(riid, IID_IDockingWindow))
  302. {
  303. *ppvObj = (IDockingWindow*)this;
  304. m_cRef++;
  305. DOUTL(2, TEXT("CBands::QI(IID_IDockingWindow) called. _cRef=%d"), m_cRef);
  306. return S_OK;
  307. }
  308. else if (IsEqualIID(riid, IID_IObjectWithSite))
  309. {
  310. *ppvObj = (IObjectWithSite*)this;
  311. m_cRef++;
  312. DOUTL(2, TEXT("CBands::QI(IID_IObjectWithSite) called. _cRef=%d"), m_cRef);
  313. return S_OK;
  314. }
  315. else if (IsEqualIID(riid, IID_IShellMenuCallback))
  316. {
  317. *ppvObj = (IShellMenuCallback*)this;
  318. m_cRef++;
  319. DOUTL(2, TEXT("CBands::QI(IID_IShellCallback) called. _cRef=%d"), m_cRef);
  320. return S_OK;
  321. }
  322. *ppvObj = NULL;
  323. return E_NOINTERFACE;
  324. }
  325. ULONG CBands::AddRef()
  326. {
  327. m_cRef++;
  328. DOUTL(4, TEXT("CBands::AddRef() - m_cRef = %d"), m_cRef);
  329. return m_cRef;
  330. }
  331. ULONG CBands::Release()
  332. {
  333. m_cRef--;
  334. DOUTL(4, TEXT("CBands::Release() - m_cRef = %d"), m_cRef);
  335. if (m_cRef > 0)
  336. return m_cRef;
  337. delete this;
  338. return 0;
  339. }
  340. //
  341. // FUNCTION: CBands::GetWindow()
  342. //
  343. // PURPOSE: Returns the window handle of the top side rebar.
  344. //
  345. HRESULT CBands::GetWindow(HWND * lphwnd)
  346. {
  347. if (m_hwndSizer)
  348. {
  349. *lphwnd = m_hwndSizer;
  350. return (S_OK);
  351. }
  352. else
  353. {
  354. *lphwnd = NULL;
  355. return (E_FAIL);
  356. }
  357. }
  358. HRESULT CBands::ContextSensitiveHelp(BOOL fEnterMode)
  359. {
  360. return (E_NOTIMPL);
  361. }
  362. //
  363. // FUNCTION: CBands::SetSite()
  364. //
  365. // PURPOSE: Allows the owner of the coolbar to tell it what the current
  366. // IDockingWindowSite interface to use is.
  367. //
  368. // PARAMETERS:
  369. // <in> punkSite - Pointer of the IUnknown to query for IDockingWindowSite.
  370. // If this is NULL, we just release our current pointer.
  371. //
  372. // RETURN VALUE:
  373. // S_OK - Everything worked
  374. // E_FAIL - Could not get IDockingWindowSite from the punkSite provided.
  375. //
  376. HRESULT CBands::SetSite(IUnknown* punkSite)
  377. {
  378. // If we had a previous pointer, release it.
  379. if (m_ptbSite)
  380. {
  381. m_ptbSite->Release();
  382. m_ptbSite = NULL;
  383. }
  384. // If a new site was provided, get the IDockingWindowSite interface from it.
  385. if (punkSite)
  386. {
  387. if (FAILED(punkSite->QueryInterface(IID_IDockingWindowSite,
  388. (LPVOID*) &m_ptbSite)))
  389. {
  390. Assert(m_ptbSite);
  391. return E_FAIL;
  392. }
  393. }
  394. return (S_OK);
  395. }
  396. HRESULT CBands::GetSite(REFIID riid, LPVOID *ppvSite)
  397. {
  398. return E_NOTIMPL;
  399. }
  400. //
  401. // FUNCTION: CBands::ShowDW()
  402. //
  403. // PURPOSE: Causes the coolbar to be either shown or hidden.
  404. //
  405. // PARAMETERS:
  406. // <in> fShow - TRUE if the coolbar should be shown, FALSE to hide.
  407. //
  408. // RETURN VALUE:
  409. // HRESULT
  410. //
  411. #define SIZABLECLASS TEXT("SizableRebar")
  412. HRESULT CBands::ShowDW(BOOL fShow)
  413. {
  414. HRESULT hres = S_OK;
  415. int i = 0, j = 0;
  416. IConnectionPoint *pCP = NULL;
  417. // Check to see if our window has been created yet. If not, do that first.
  418. if (!m_hwndSizer && m_ptbSite)
  419. {
  420. //Get the command target interface
  421. if (FAILED(hres = m_ptbSite->QueryInterface(IID_IOleCommandTarget, (LPVOID*)&m_ptbSiteCT)))
  422. {
  423. return hres;
  424. }
  425. m_hwndParent = NULL;
  426. hres = m_ptbSite->GetWindow(&m_hwndParent);
  427. if (SUCCEEDED(hres))
  428. {
  429. WNDCLASSEX wc;
  430. // Check to see if we need to register our window class
  431. wc.cbSize = sizeof(WNDCLASSEX);
  432. if (!GetClassInfoEx(g_hInst, SIZABLECLASS, &wc))
  433. {
  434. wc.style = 0;
  435. wc.lpfnWndProc = SizableWndProc;
  436. wc.cbClsExtra = 0;
  437. wc.cbWndExtra = 0;
  438. wc.hInstance = g_hInst;
  439. wc.hCursor = NULL;
  440. wc.hbrBackground = (HBRUSH) (COLOR_3DFACE + 1);
  441. wc.lpszMenuName = NULL;
  442. wc.lpszClassName = SIZABLECLASS;
  443. wc.hIcon = NULL;
  444. wc.hIconSm = NULL;
  445. RegisterClassEx(&wc);
  446. }
  447. // Load the background bitmap to use for the coolbar and also get
  448. // a handle to the HDC and Palette for the coolbar. This will be
  449. // used to draw the animated logo later.
  450. m_hdc = CreateCompatibleDC(NULL);
  451. if (GetDeviceCaps(m_hdc, RASTERCAPS) & RC_PALETTE)
  452. m_hpal = SHCreateShellPalette(m_hdc);
  453. // If we're trying to show the coolbar, then create the rebar and
  454. // add it's bands based on information saved in the registry.
  455. if (SUCCEEDED(CreateRebar(fShow)))
  456. {
  457. for (i = 0; i < (int) m_pSavedBandInfo->cBands; i++)
  458. {
  459. switch (m_pSavedBandInfo->BandData[i].wID)
  460. {
  461. case CBTYPE_BRAND:
  462. hres = ShowBrand();
  463. break;
  464. case CBTYPE_MENUBAND:
  465. hres = CreateMenuBand(&m_pSavedBandInfo->BandData[i]);
  466. break;
  467. case CBTYPE_TOOLS:
  468. hres = AddTools(&(m_pSavedBandInfo->BandData[i]));
  469. break;
  470. case CBTYPE_RULESTOOLBAR:
  471. hres = AddRulesToolbar(&(m_pSavedBandInfo->BandData[i]));
  472. }
  473. }
  474. m_pTextStyleNotify->Register(m_hwndSizer, g_hwndInit, FALSE);
  475. }
  476. }
  477. }
  478. //The first time OE is started, we should look at the key c_szShowToolbarIEAK or
  479. //if OE is started after IEAK is ran. Bug# 67503
  480. LRESULT lResult;
  481. DWORD dwType;
  482. DWORD cbData = sizeof(DWORD);
  483. DWORD dwShowToolbar = 1;
  484. lResult = AthUserGetValue(NULL, c_szShowToolbarIEAK, &dwType, (LPBYTE)&dwShowToolbar, &cbData);
  485. if (lResult == ERROR_SUCCESS)
  486. {
  487. HideToolbar(!dwShowToolbar, CBTYPE_TOOLS);
  488. }
  489. // Resize the rebar based on it's new hidden / visible state and also
  490. // show or hide the window.
  491. if (m_hwndSizer)
  492. {
  493. ResizeBorderDW(NULL, NULL, FALSE);
  494. ShowWindow(m_hwndSizer, fShow ? SW_SHOW : SW_HIDE);
  495. }
  496. if (g_pConMan)
  497. g_pConMan->Advise(this);
  498. return hres;
  499. }
  500. void CBands::HideToolbar(BOOL fHide, DWORD dwBandID)
  501. {
  502. REBARBANDINFO rbbi = {0};
  503. DWORD iBand;
  504. iBand = (DWORD) SendMessage(m_hwndRebar, RB_IDTOINDEX, dwBandID, 0);
  505. if (iBand != -1)
  506. {
  507. SendMessage(m_hwndRebar, RB_SHOWBAND, iBand, !fHide);
  508. }
  509. LoadBrandingBitmap();
  510. SetMinDimensions();
  511. if (dwBandID == CBTYPE_RULESTOOLBAR)
  512. {
  513. if (!fHide)
  514. UpdateFilters(m_DefaultFilterId);
  515. }
  516. }
  517. BOOL CBands::IsToolbarVisible()
  518. {
  519. return IsBandVisible(CBTYPE_TOOLS);
  520. }
  521. BOOL CBands::IsBandVisible(DWORD dwBandId)
  522. {
  523. int iBand;
  524. iBand = (int) SendMessage(m_hwndRebar, RB_IDTOINDEX, dwBandId, 0);
  525. if (iBand != -1)
  526. {
  527. REBARBANDINFO rbbi = {0};
  528. rbbi.cbSize = sizeof(REBARBANDINFO);
  529. rbbi.fMask = RBBIM_STYLE;
  530. SendMessage(m_hwndRebar, RB_GETBANDINFO, iBand, (LPARAM)&rbbi);
  531. return (!(rbbi.fStyle & RBBS_HIDDEN));
  532. }
  533. return FALSE;
  534. }
  535. //
  536. // FUNCTION: CBands::CloseDW()
  537. //
  538. // PURPOSE: Destroys the coolbar.
  539. //
  540. HRESULT CBands::CloseDW(DWORD dwReserved)
  541. {
  542. SafeRelease(m_pWinEvent);
  543. SafeRelease(m_pMenuBand);
  544. //Bug# 68607
  545. if (m_pDeskBand)
  546. {
  547. m_pDeskBand->CloseDW(dwReserved);
  548. IInputObject *pinpobj;
  549. IObjectWithSite *pobjsite;
  550. if (SUCCEEDED(m_pDeskBand->QueryInterface(IID_IObjectWithSite, (LPVOID*)&pobjsite)))
  551. {
  552. pobjsite->SetSite(NULL);
  553. pobjsite->Release();
  554. }
  555. //m_pDeskBand->ShowDW(FALSE);
  556. }
  557. SafeRelease(m_pShellMenu);
  558. if (m_hwndSizer)
  559. {
  560. m_pTextStyleNotify->Unregister(m_hwndSizer);
  561. SaveSettings();
  562. DestroyWindow(m_hwndSizer);
  563. m_hwndSizer = NULL;
  564. }
  565. SafeRelease(m_pDeskBand);
  566. SafeRelease(m_ptbSiteCT);
  567. return S_OK;
  568. }
  569. //
  570. // FUNCTION: CBands::ResizeBorderDW()
  571. //
  572. // PURPOSE: This is called when the coolbar needs to resize. The coolbar
  573. // in return figures out how much border space will be required
  574. // from the parent frame and tells the parent to reserve that
  575. // space. The coolbar then resizes itself to those dimensions.
  576. //
  577. // PARAMETERS:
  578. // <in> prcBorder - Rectangle containing the border space for the
  579. // parent.
  580. // <in> punkToolbarSite - Pointer to the IDockingWindowSite that we are
  581. // part of.
  582. // <in> fReserved - Ignored.
  583. //
  584. // RETURN VALUE:
  585. // HRESULT
  586. //
  587. HRESULT CBands::ResizeBorderDW(LPCRECT prcBorder,
  588. IUnknown* punkToolbarSite,
  589. BOOL fReserved)
  590. {
  591. const DWORD c_cxResizeBorder = 3;
  592. const DWORD c_cyResizeBorder = 3;
  593. HRESULT hres = S_OK;
  594. RECT rcRequest = { 0, 0, 0, 0 };
  595. // If we don't have a stored site pointer, we can't resize.
  596. if (!m_ptbSite)
  597. {
  598. AssertSz(m_ptbSite, _T("CBands::ResizeBorderDW() - Can't resize ")
  599. _T("without an IDockingWindowSite interface to call."));
  600. return (E_INVALIDARG);
  601. }
  602. // If we're visible, then calculate our border rectangle.
  603. RECT rcBorder, rcRebar, rcT;
  604. int cx, cy;
  605. // Get the size this rebar currently is
  606. GetWindowRect(m_hwndRebar, &rcRebar);
  607. cx = rcRebar.right - rcRebar.left;
  608. cy = rcRebar.bottom - rcRebar.top;
  609. // Find out how big our parent's border space is
  610. m_ptbSite->GetBorderDW((IDockingWindow*) this, &rcBorder);
  611. cx = rcBorder.right - rcBorder.left;
  612. // Bug #31007 - There seems to be a problem in commctrl
  613. // IEBug #5574 either with the REBAR or with the Toolbar
  614. // when they are vertical. If the we try to
  615. // size them to 2 or less, we lock up. This
  616. // is a really poor fix, but there's no way
  617. // to get commctrl fixed this late in the game.
  618. if (cy < 5) cy = 10;
  619. if (cx < 5) cx = 10;
  620. SetWindowPos(m_hwndRebar, NULL, 0, 0, cx, cy, SWP_NOZORDER | SWP_NOACTIVATE);
  621. // Figure out how much border space to ask the site for
  622. GetWindowRect(m_hwndRebar, &rcRebar);
  623. rcRequest.top = rcRebar.bottom - rcRebar.top + c_cxResizeBorder;
  624. // Ask the site for that border space
  625. if (SUCCEEDED(m_ptbSite->RequestBorderSpaceDW((IDockingWindow*) this, &rcRequest)))
  626. {
  627. // Position the window based on the area given to us
  628. SetWindowPos(m_hwndSizer, NULL,
  629. rcBorder.left,
  630. rcBorder.top,
  631. rcRebar.right - rcRebar.left,
  632. rcRequest.top + rcBorder.top,
  633. SWP_NOZORDER | SWP_NOACTIVATE);
  634. }
  635. // Now tell the site how much border space we're using.
  636. m_ptbSite->SetBorderSpaceDW((IDockingWindow*) this, &rcRequest);
  637. return hres;
  638. }
  639. //
  640. // FUNCTION: CBands::Invoke()
  641. //
  642. // PURPOSE: Allows the owner of the coolbar to force the coolbar to do
  643. // something.
  644. //
  645. // PARAMETERS:
  646. // <in> id - ID of the command the caller wants the coolbar to do.
  647. // <in> pv - Pointer to any parameters the coolbar might need to carry
  648. // out the command.
  649. //
  650. // RETURN VALUE:
  651. // S_OK - The command was carried out.
  652. //
  653. // COMMENTS:
  654. // <???>
  655. //
  656. HRESULT CBands::Invoke(DWORD id, LPVOID pv)
  657. {
  658. switch (id)
  659. {
  660. // Starts animating the logo
  661. case idDownloadBegin:
  662. StartDownload();
  663. break;
  664. // Stops animating the logo
  665. case idDownloadEnd:
  666. StopDownload();
  667. break;
  668. // Update the enabled / disabled state of buttons on the toolbar
  669. case idStateChange:
  670. {
  671. // pv is a pointer to a COOLBARSTATECHANGE struct
  672. COOLBARSTATECHANGE* pcbsc = (COOLBARSTATECHANGE*) pv;
  673. SendMessage(m_hwndTools, TB_ENABLEBUTTON, pcbsc->id,
  674. MAKELONG(pcbsc->fEnable, 0));
  675. break;
  676. }
  677. case idToggleButton:
  678. {
  679. COOLBARSTATECHANGE* pcbsc = (COOLBARSTATECHANGE *) pv;
  680. SendMessage(m_hwndTools, TB_CHECKBUTTON, pcbsc->id,
  681. MAKELONG(pcbsc->fEnable, 0));
  682. break;
  683. }
  684. case idBitmapChange:
  685. {
  686. // pv is a pointer to a COOLBARBITMAPCHANGE struct
  687. COOLBARBITMAPCHANGE *pcbc = (COOLBARBITMAPCHANGE*) pv;
  688. SendMessage(m_hwndTools, TB_CHANGEBITMAP, pcbc->id, MAKELPARAM(pcbc->index, 0));
  689. break;
  690. }
  691. // Sends a message directly to the toolbar.
  692. case idSendToolMessage:
  693. #define ptm ((TOOLMESSAGE *)pv)
  694. ptm->lResult = SendMessage(m_hwndTools, ptm->uMsg, ptm->wParam, ptm->lParam);
  695. break;
  696. #undef ptm
  697. case idCustomize:
  698. SendMessage(m_hwndTools, TB_CUSTOMIZE, 0, 0);
  699. break;
  700. case idNotifyFilterChange:
  701. m_DefaultFilterId = (*(RULEID*)pv);
  702. if (IsBandVisible(CBTYPE_RULESTOOLBAR))
  703. UpdateFilters(m_DefaultFilterId);
  704. break;
  705. case idIsFilterBarVisible:
  706. *((BOOL*)pv) = IsBandVisible(CBTYPE_RULESTOOLBAR);
  707. break;
  708. }
  709. return S_OK;
  710. }
  711. //
  712. // FUNCTION: CBands::StartDownload()
  713. //
  714. // PURPOSE: Starts animating the logo.
  715. //
  716. void CBands::StartDownload()
  717. {
  718. if (m_hwndBrand)
  719. {
  720. SetFlag(TBSTATE_ANIMATING);
  721. SetFlag(TBSTATE_FIRSTFRAME);
  722. m_yOrg = 0;
  723. SetTimer(m_hwndSizer, ANIMATION_TIMER, 100, NULL);
  724. }
  725. }
  726. //
  727. // FUNCTION: CBands::StopDownload()
  728. //
  729. // PURPOSE: Stops animating the logo. Restores the logo to it's default
  730. // first frame.
  731. //
  732. void CBands::StopDownload()
  733. {
  734. int i, cBands;
  735. REBARBANDINFO rbbi;
  736. // Set the background colors for this band back to the first frame
  737. cBands = (int) SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  738. ZeroMemory(&rbbi, sizeof(rbbi));
  739. rbbi.cbSize = sizeof(REBARBANDINFO);
  740. rbbi.fMask = RBBIM_ID;
  741. for (i = 0; i < cBands; i++)
  742. {
  743. SendMessage(m_hwndRebar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
  744. if (CBTYPE_BRAND == rbbi.wID)
  745. {
  746. rbbi.fMask = RBBIM_COLORS;
  747. rbbi.clrFore = m_rgbUpperLeft;
  748. rbbi.clrBack = m_rgbUpperLeft;
  749. SendMessage(m_hwndRebar, RB_SETBANDINFO, i, (LPARAM) &rbbi);
  750. break;
  751. }
  752. }
  753. // Reset the state flags
  754. ClearFlag(TBSTATE_ANIMATING);
  755. ClearFlag(TBSTATE_FIRSTFRAME);
  756. KillTimer(m_hwndSizer, ANIMATION_TIMER);
  757. InvalidateRect(m_hwndBrand, NULL, FALSE);
  758. UpdateWindow(m_hwndBrand);
  759. }
  760. BOOL CBands::CheckForwardWinEvent(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* plres)
  761. {
  762. HWND hwndForward = NULL;
  763. switch(uMsg)
  764. {
  765. case WM_NOTIFY:
  766. hwndForward = ((LPNMHDR)lParam)->hwndFrom;
  767. break;
  768. case WM_COMMAND:
  769. hwndForward = GET_WM_COMMAND_HWND(wParam, lParam);
  770. break;
  771. case WM_SYSCOLORCHANGE:
  772. case WM_WININICHANGE:
  773. case WM_PALETTECHANGED:
  774. hwndForward = HWND_BROADCAST;
  775. break;
  776. }
  777. if (hwndForward && m_pWinEvent && m_pWinEvent->IsWindowOwner(hwndForward) == S_OK)
  778. {
  779. LRESULT lres;
  780. m_pWinEvent->OnWinEvent(hwndForward, uMsg, wParam, lParam, &lres);
  781. if (plres)
  782. *plres = lres;
  783. return TRUE;
  784. }
  785. return FALSE;
  786. }
  787. void CBands::ChangeImages()
  788. {
  789. _SetImages(m_hwndTools, (fIsWhistler() ?
  790. ((GetCurColorRes() > 24) ? c_32ImageListStruct[m_dwParentType].ImageListTable : c_ImageListStruct[m_dwParentType].ImageListTable)
  791. : c_NWImageListStruct[m_dwParentType].ImageListTable ));
  792. if (IsBandVisible(CBTYPE_RULESTOOLBAR))
  793. _SetImages(m_hwndRulesToolbar, (fIsWhistler() ?
  794. ((GetCurColorRes() > 24) ? c_32RulesImageList : c_RulesImageList)
  795. : c_NWRulesImageList ));
  796. }
  797. //
  798. // FUNCTION: CBands::SizableWndProc()
  799. //
  800. // PURPOSE: Handles messages sent to the coolbar root window.
  801. //
  802. LRESULT EXPORT_16 CALLBACK CBands::SizableWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  803. {
  804. CBands* pitbar = (CBands*)GetProp(hwnd, TEXT("CBands"));
  805. DWORD dw;
  806. if (!pitbar)
  807. goto CallDWP;
  808. switch(uMsg)
  809. {
  810. case WM_SYSCOLORCHANGE:
  811. {
  812. // Reload the graphics
  813. pitbar->ChangeImages();
  814. pitbar->UpdateToolbarColors();
  815. InvalidateRect(pitbar->m_hwndTools, NULL, TRUE);
  816. pitbar->CheckForwardWinEvent(hwnd, uMsg, wParam, lParam, NULL);
  817. break;
  818. }
  819. case WM_WININICHANGE:
  820. case WM_FONTCHANGE:
  821. // Forward this to our child windows
  822. pitbar->ChangeImages();
  823. SendMessage(pitbar->m_hwndTools, uMsg, wParam, lParam);
  824. SendMessage(pitbar->m_hwndRulesToolbar, uMsg, wParam, lParam);
  825. SendMessage(pitbar->m_hwndRebar, uMsg, wParam, lParam);
  826. InvalidateRect(pitbar->m_hwndTools, NULL, TRUE);
  827. pitbar->SetMinDimensions();
  828. pitbar->CheckForwardWinEvent(hwnd, uMsg, wParam, lParam, NULL);
  829. //Update the combo box with the new font
  830. pitbar->FilterBoxFontChange();
  831. break;
  832. case WM_SETCURSOR:
  833. // We play with the cursor a bit to make the resizing cursor show
  834. // up when the user is over the edge of the coolbar that allows
  835. // them to drag to resize etc.
  836. if ((HWND) wParam == hwnd)
  837. {
  838. if (pitbar->m_dwState & TBSTATE_INMENULOOP)
  839. SetCursor(LoadCursor(NULL, IDC_ARROW));
  840. else
  841. SetCursor(LoadCursor(NULL, IDC_SIZENS));
  842. return (TRUE);
  843. }
  844. return (FALSE);
  845. case WM_LBUTTONDOWN:
  846. // The user is about to resize the bar. Capture the cursor so we
  847. // can watch the changes.
  848. pitbar->m_yCapture = GET_Y_LPARAM(lParam);
  849. SetCapture(hwnd);
  850. break;
  851. case WM_MOUSEMOVE:
  852. // The user is resizing the bar. Handle updating the sizes as
  853. // they drag.
  854. if (pitbar->m_yCapture != -1)
  855. {
  856. if (hwnd != GetCapture())
  857. pitbar->m_yCapture = -1;
  858. else
  859. pitbar->TrackSliding(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
  860. }
  861. break;
  862. case WM_LBUTTONUP:
  863. // The user is done resizing. release our capture and reset our
  864. // state.
  865. if (pitbar->m_yCapture != -1 || pitbar->m_xCapture != -1)
  866. {
  867. ReleaseCapture();
  868. pitbar->m_yCapture = -1;
  869. pitbar->m_xCapture = -1;
  870. }
  871. break;
  872. case WM_VKEYTOITEM:
  873. case WM_CHARTOITEM:
  874. // We must swallow these messages to avoid infinit SendMessage
  875. break;
  876. case WM_DRAWITEM:
  877. // Draws the animating brand
  878. if (wParam == idcBrand)
  879. pitbar->DrawBranding((LPDRAWITEMSTRUCT) lParam);
  880. break;
  881. case WM_MEASUREITEM:
  882. // Draws the animating brand
  883. if (wParam == idcBrand)
  884. {
  885. ((LPMEASUREITEMSTRUCT) lParam)->itemWidth = pitbar->m_cxBrand;
  886. ((LPMEASUREITEMSTRUCT) lParam)->itemHeight = pitbar->m_cyBrand;
  887. }
  888. break;
  889. case WM_TIMER:
  890. // This timer fires every time we need to draw the next frame in
  891. // animating brand.
  892. if (wParam == ANIMATION_TIMER)
  893. {
  894. if (pitbar->m_hwndBrand)
  895. {
  896. pitbar->m_yOrg += pitbar->m_cyBrand;
  897. if (pitbar->m_yOrg >= pitbar->m_cyBrandExtent)
  898. pitbar->m_yOrg = pitbar->m_cyBrandLeadIn;
  899. InvalidateRect(pitbar->m_hwndBrand, NULL, FALSE);
  900. UpdateWindow(pitbar->m_hwndBrand);
  901. }
  902. }
  903. break;
  904. case WM_NOTIFY:
  905. {
  906. LRESULT lres;
  907. if (pitbar->CheckForwardWinEvent(hwnd, uMsg, wParam, lParam, &lres))
  908. return lres;
  909. return pitbar->OnNotify(hwnd, lParam);
  910. }
  911. case WM_COMMAND:
  912. {
  913. LRESULT lres;
  914. if (pitbar->CheckForwardWinEvent(hwnd, uMsg, wParam, lParam, &lres))
  915. return lres;
  916. if (pitbar->HandleComboBoxNotifications(wParam, lParam))
  917. return 0L;
  918. if (wParam == ID_CUSTOMIZE)
  919. {
  920. //SendMessage(m_hwndTools, TB_CUSTOMIZE, 0, 0);
  921. pitbar->OnCommand(hwnd, (int) wParam, NULL, 0);
  922. return 0L;
  923. }
  924. //Bug# 58029. lParam is the destination folder. So it needs to be set to zero if
  925. //we want the treeview dialog to show up.
  926. if (wParam == ID_MOVE_TO_FOLDER || wParam == ID_COPY_TO_FOLDER)
  927. return SendMessage(pitbar->m_hwndParent, WM_COMMAND, wParam, (LPARAM)0);
  928. else
  929. return SendMessage(pitbar->m_hwndParent, WM_COMMAND, wParam, lParam);
  930. }
  931. case WM_CONTEXTMENU:
  932. pitbar->OnContextMenu((HWND) wParam, LOWORD(lParam), HIWORD(lParam));
  933. break;
  934. case WM_PALETTECHANGED:
  935. // BUGBUG: we could optimize this by realizing and checking the
  936. // return value
  937. //
  938. // for now we will just invalidate ourselves and all children...
  939. RedrawWindow(pitbar->m_hwndSizer, NULL, NULL,
  940. RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
  941. break;
  942. case CM_CONNECT:
  943. // wParam is hMenuConnect, lParam is CmdID
  944. g_pConMan->Connect((HMENU) wParam, (DWORD) lParam, pitbar->m_hwndParent);
  945. g_pConMan->FreeConnectMenu((HMENU) wParam);
  946. break;
  947. case TT_ISTEXTVISIBLE:
  948. return (pitbar->m_dwToolbarTextState != TBSTATE_NOTEXT);
  949. case WM_OE_TOOLBAR_STYLE:
  950. pitbar->UpdateTextSettings((DWORD) wParam);
  951. break;
  952. case WM_DESTROY:
  953. {
  954. IConnectionPoint *pCP = NULL;
  955. // Clean up our pointers
  956. RemoveProp(hwnd, TEXT("CBands"));
  957. pitbar->Release(); // Corresponding to AddRef at SetProp
  958. DOUTL(1, _T("CBands::WM_DESTROY - Called RemoveProp. Called")
  959. _T(" Release() new m_cRef=%d"), pitbar->m_cRef);
  960. pitbar->CleanupImages();
  961. //Unregister with the connection manager
  962. if (g_pConMan)
  963. g_pConMan->Unadvise(pitbar);
  964. RemoveProp(pitbar->m_hwndTools, SZ_PROP_CUSTDLG);
  965. // fall through
  966. }
  967. default:
  968. CallDWP:
  969. return(DefWindowProc(hwnd, uMsg, wParam, lParam));
  970. }
  971. return 0L;
  972. }
  973. void CBands::CleanupImages()
  974. {
  975. CleanupRulesToolbar();
  976. CleanupImages(m_hwndTools);
  977. }
  978. void CBands::CleanupRulesToolbar()
  979. {
  980. HIMAGELIST himl;
  981. if (IsWindow(m_hwndRulesToolbar))
  982. {
  983. CleanupImages(m_hwndRulesToolbar);
  984. }
  985. }
  986. void CBands::CleanupImages(HWND hwnd)
  987. {
  988. HIMAGELIST himl;
  989. himl = (HIMAGELIST)SendMessage(hwnd, TB_SETIMAGELIST, 0, 0);
  990. if (himl)
  991. {
  992. //This is the old image list
  993. ImageList_Destroy(himl);
  994. }
  995. himl = (HIMAGELIST)SendMessage(hwnd, TB_SETHOTIMAGELIST, 0, 0);
  996. if (himl)
  997. {
  998. //This is the old image list
  999. ImageList_Destroy(himl);
  1000. }
  1001. }
  1002. //idComboBox is the Identifier of the combo box
  1003. //idCmd is the command id or the notification id
  1004. //hwnd is the window handle of the combo box
  1005. LRESULT CBands::HandleComboBoxNotifications(WPARAM wParam, LPARAM lParam)
  1006. {
  1007. LRESULT retval = 0;
  1008. int ItemIndex;
  1009. int idCmd, id;
  1010. HWND hwnd;
  1011. idCmd = GET_WM_COMMAND_CMD(wParam, lParam);
  1012. id = GET_WM_COMMAND_ID(wParam, lParam);
  1013. hwnd = GET_WM_COMMAND_HWND(wParam, lParam);
  1014. if (hwnd != m_hwndFilterCombo)
  1015. return 0;
  1016. switch (idCmd)
  1017. {
  1018. case CBN_SELENDOK:
  1019. ItemIndex = ComboBox_GetCurSel(m_hwndFilterCombo);
  1020. if(ItemIndex < 0)
  1021. break;
  1022. RULEID FilterID;
  1023. FilterID = (RULEID)ComboBox_GetItemData(hwnd, ItemIndex);
  1024. SendMessage(m_hwndParent, WM_COMMAND, MAKEWPARAM(ID_VIEW_APPLY, 0), (LPARAM)FilterID);
  1025. retval = 1;
  1026. break;
  1027. }
  1028. return retval;
  1029. }
  1030. HRESULT CBands::OnCommand(HWND hwnd, int idCmd, HWND hwndControl, UINT cmd)
  1031. {
  1032. LPTSTR pszTest;
  1033. switch (idCmd)
  1034. {
  1035. case idcBrand: // click on the spinning globe
  1036. // We don't want to do anything at all here.
  1037. break;
  1038. case ID_CUSTOMIZE:
  1039. SendMessage(m_hwndTools, TB_CUSTOMIZE, 0, 0);
  1040. break;
  1041. default:
  1042. return S_FALSE;
  1043. }
  1044. return S_OK;
  1045. }
  1046. //Move this function to utils.
  1047. HMENU LoadMenuPopup(HINSTANCE hinst, UINT id)
  1048. {
  1049. HMENU hMenuSub = NULL;
  1050. HMENU hMenu = LoadMenu(hinst, MAKEINTRESOURCE(id));
  1051. if (hMenu) {
  1052. hMenuSub = GetSubMenu(hMenu, 0);
  1053. if (hMenuSub) {
  1054. RemoveMenu(hMenu, 0, MF_BYPOSITION);
  1055. }
  1056. DestroyMenu(hMenu);
  1057. }
  1058. return hMenuSub;
  1059. }
  1060. LRESULT CBands::OnNotify(HWND hwnd, LPARAM lparam)
  1061. {
  1062. NMHDR *lpnmhdr = (NMHDR*)lparam;
  1063. if ((lpnmhdr->idFrom == idcCoolbar) || (lpnmhdr->hwndFrom == m_hwndRebar))
  1064. {
  1065. switch (lpnmhdr->code)
  1066. {
  1067. case RBN_HEIGHTCHANGE:
  1068. ResizeBorderDW(NULL, NULL, FALSE);
  1069. break;
  1070. case RBN_CHEVRONPUSHED:
  1071. {
  1072. ITrackShellMenu* ptsm;
  1073. CoCreateInstance(CLSID_TrackShellMenu, NULL, CLSCTX_INPROC_SERVER, IID_ITrackShellMenu,
  1074. (LPVOID*)&ptsm);
  1075. if (!ptsm)
  1076. break;
  1077. ptsm->Initialize(0, 0, 0, SMINIT_TOPLEVEL|SMINIT_VERTICAL);
  1078. LPNMREBARCHEVRON pnmch = (LPNMREBARCHEVRON) lpnmhdr;
  1079. switch (pnmch->wID)
  1080. {
  1081. case CBTYPE_TOOLS:
  1082. {
  1083. ptsm->SetObscured(m_hwndTools, NULL, SMSET_TOP);
  1084. HMENU hmenu;
  1085. hmenu = LoadMenuPopup(g_hLocRes, IDR_TBCHEV_MENU);
  1086. if (hmenu)
  1087. {
  1088. ptsm->SetMenu(hmenu, m_hwndRebar, SMSET_BOTTOM);
  1089. }
  1090. break;
  1091. }
  1092. case CBTYPE_MENUBAND:
  1093. {
  1094. ptsm->SetObscured(m_hwndMenuBand, m_pShellMenu, SMSET_TOP);
  1095. break;
  1096. }
  1097. }
  1098. MapWindowPoints(m_hwndRebar, HWND_DESKTOP, (LPPOINT)&pnmch->rc, 2);
  1099. POINTL pt = {pnmch->rc.left, pnmch->rc.right};
  1100. ptsm->Popup(m_hwndRebar, &pt, (RECTL*)&pnmch->rc, MPPF_BOTTOM);
  1101. ptsm->Release();
  1102. break;
  1103. }
  1104. case RBN_LAYOUTCHANGED:
  1105. {
  1106. LoadBrandingBitmap();
  1107. SetMinDimensions();
  1108. break;
  1109. }
  1110. }
  1111. }
  1112. else if ((lpnmhdr->idFrom == idcToolbar) || (lpnmhdr->hwndFrom == m_hwndTools))
  1113. {
  1114. if (lpnmhdr->code == TBN_GETBUTTONINFOA)
  1115. return OnGetButtonInfo((TBNOTIFY*) lparam);
  1116. if (lpnmhdr->code == TBN_QUERYDELETE)
  1117. return (TRUE);
  1118. if (lpnmhdr->code == TBN_QUERYINSERT)
  1119. return (TRUE);
  1120. if (lpnmhdr->code == TBN_GETINFOTIP)
  1121. return OnGetInfoTip((LPNMTBGETINFOTIP) lparam);
  1122. if (lpnmhdr->code == TBN_ENDADJUST)
  1123. {
  1124. DWORD dwSize;
  1125. DWORD dwType;
  1126. DWORD dwIconSize;
  1127. DWORD dwText;
  1128. CBands *pBrowserCoolbar = NULL;
  1129. if (m_dwParentType == PARENT_TYPE_NOTE)
  1130. {
  1131. if ((g_pBrowser) && (FAILED(g_pBrowser->GetCoolbar(&pBrowserCoolbar))))
  1132. pBrowserCoolbar = NULL;
  1133. }
  1134. if ((AthUserGetValue(NULL, c_szRegToolbarText, &dwType, (LPBYTE)&dwText, &dwSize) != ERROR_SUCCESS) ||
  1135. (dwText != m_dwToolbarTextState))
  1136. {
  1137. //Save the Text Labels into the registry
  1138. AthUserSetValue(NULL, c_szRegToolbarText, REG_DWORD, (LPBYTE)&m_dwToolbarTextState, sizeof(DWORD));
  1139. /*
  1140. if (pBrowserCoolbar)
  1141. {
  1142. pBrowserCoolbar->UpdateTextSettings(m_dwToolbarTextState);
  1143. }
  1144. */
  1145. }
  1146. if ((AthUserGetValue(NULL, c_szRegToolbarIconSize, &dwType, (LPBYTE)&dwIconSize, &dwSize) != ERROR_SUCCESS) ||
  1147. (dwIconSize != m_dwIconSize))
  1148. {
  1149. SetIconSize(m_dwIconSize);
  1150. AthUserSetValue(NULL, c_szRegToolbarIconSize, REG_DWORD, (LPBYTE)&m_dwIconSize, sizeof(DWORD));
  1151. if (pBrowserCoolbar)
  1152. {
  1153. pBrowserCoolbar->SetIconSize(m_dwIconSize);
  1154. }
  1155. }
  1156. if (m_fDirty)
  1157. {
  1158. //Recalculate button widths and set ideal sizes
  1159. CalcIdealSize();
  1160. if (pBrowserCoolbar)
  1161. {
  1162. pBrowserCoolbar->CalcIdealSize();
  1163. }
  1164. }
  1165. if (pBrowserCoolbar)
  1166. {
  1167. pBrowserCoolbar->Release();
  1168. pBrowserCoolbar = NULL;
  1169. }
  1170. // check IDockingWindowSite
  1171. if (m_ptbSite)
  1172. {
  1173. IAthenaBrowser *psbwr;
  1174. // get IAthenaBrowser interface
  1175. if (SUCCEEDED(m_ptbSite->QueryInterface(IID_IAthenaBrowser,(void**)&psbwr)))
  1176. {
  1177. psbwr->UpdateToolbar();
  1178. psbwr->Release();
  1179. }
  1180. }
  1181. m_fDirty = FALSE;
  1182. }
  1183. if (lpnmhdr->code == TBN_TOOLBARCHANGE)
  1184. {
  1185. m_fDirty = TRUE;
  1186. }
  1187. if (lpnmhdr->code == TBN_RESET)
  1188. {
  1189. // Remove all the buttons from the toolbar
  1190. int cButtons = (int) SendMessage(m_hwndTools, TB_BUTTONCOUNT, 0, 0);
  1191. while (--cButtons >= 0)
  1192. SendMessage(m_hwndTools, TB_DELETEBUTTON, cButtons, 0);
  1193. // Set the buttons back to the default
  1194. SendMessage(m_hwndTools, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
  1195. _LoadDefaultButtons(m_hwndTools, (TOOLBAR_INFO *) m_pTBInfo);
  1196. _UpdateTextSettings(idsShowTextLabels);
  1197. m_dwIconSize = LARGE_ICONS;
  1198. return (TRUE);
  1199. }
  1200. if (lpnmhdr->code == TBN_DROPDOWN)
  1201. {
  1202. if (m_dwParentType == PARENT_TYPE_NOTE)
  1203. {
  1204. SendMessage(m_hwndParent, WM_NOTIFY, NULL, lparam);
  1205. return (0L);
  1206. }
  1207. return OnDropDown(hwnd, lpnmhdr);
  1208. }
  1209. if (lpnmhdr->code == TBN_INITCUSTOMIZE)
  1210. {
  1211. _OnBeginCustomize((NMTBCUSTOMIZEDLG*)lpnmhdr);
  1212. return TBNRF_HIDEHELP;
  1213. }
  1214. }
  1215. return (0L);
  1216. }
  1217. void CBands::_OnBeginCustomize(LPNMTBCUSTOMIZEDLG pnm)
  1218. {
  1219. HWND hwnd = (HWND) GetProp(pnm->hDlg, SZ_PROP_CUSTDLG);
  1220. if (!hwnd)
  1221. {
  1222. //
  1223. // hasn't been initialized.
  1224. //
  1225. // we need to check this because this init will be called
  1226. // when the user hits reset as well
  1227. hwnd = CreateDialogParam(g_hLocRes, MAKEINTRESOURCE(iddToolbarTextIcons), pnm->hDlg,
  1228. _BtnAttrDlgProc, (LPARAM)this);
  1229. if (hwnd)
  1230. {
  1231. // store hwnd of our dialog as property on tb cust dialog
  1232. SetProp(pnm->hDlg, SZ_PROP_CUSTDLG, hwnd);
  1233. // populate dialog controls
  1234. _PopulateDialog(hwnd);
  1235. // initialize dialog control selection states
  1236. _SetDialogSelections(hwnd);
  1237. RECT rc, rcWnd, rcClient;
  1238. GetWindowRect(pnm->hDlg, &rcWnd);
  1239. GetClientRect(pnm->hDlg, &rcClient);
  1240. GetWindowRect(hwnd, &rc);
  1241. // enlarge tb dialog to make room for our dialog
  1242. SetWindowPos(pnm->hDlg, NULL, 0, 0, RECTWIDTH(rcWnd), RECTHEIGHT(rcWnd) + RECTHEIGHT(rc), SWP_NOMOVE | SWP_NOZORDER);
  1243. // position our dialog at the bottom of the tb dialog
  1244. SetWindowPos(hwnd, HWND_TOP, rcClient.left, rcClient.bottom, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
  1245. }
  1246. }
  1247. }
  1248. INT_PTR CALLBACK CBands::_BtnAttrDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1249. {
  1250. CBands* pitbar = (CBands*)GetWindowLongPtr(hDlg, DWLP_USER);
  1251. switch (uMsg)
  1252. {
  1253. case WM_INITDIALOG:
  1254. SetWindowLongPtr(hDlg, DWLP_USER, lParam);
  1255. return TRUE;
  1256. case WM_COMMAND:
  1257. {
  1258. BOOL retval = FALSE;
  1259. if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELENDOK)
  1260. {
  1261. HWND hwnd = GET_WM_COMMAND_HWND(wParam, lParam);
  1262. int iSel = (int) SendMessage(hwnd, CB_GETCURSEL, 0, 0);
  1263. int idsSel = (int) SendMessage(hwnd, CB_GETITEMDATA, iSel, 0);
  1264. if (GET_WM_COMMAND_ID(wParam, lParam) == IDC_SHOWTEXT)
  1265. {
  1266. pitbar->_UpdateTextSettings(idsSel);
  1267. retval = TRUE;
  1268. }
  1269. else
  1270. if (GET_WM_COMMAND_ID(wParam, lParam) == IDC_SMALLICONS)
  1271. {
  1272. pitbar->m_dwIconSize = ((idsSel == idsLargeIcons) ? LARGE_ICONS : SMALL_ICONS);
  1273. retval = TRUE;
  1274. }
  1275. }
  1276. return retval;
  1277. }
  1278. case WM_DESTROY:
  1279. return TRUE;
  1280. }
  1281. return FALSE;
  1282. }
  1283. void CBands::_PopulateComboBox(HWND hwnd, const int iResource[], UINT cResources)
  1284. {
  1285. TCHAR sz[256];
  1286. // loop through iResource[], load each string resource and insert into combobox
  1287. for (UINT i = 0; i < cResources; i++) {
  1288. if (LoadString(g_hLocRes, iResource[i], sz, ARRAYSIZE(sz))) {
  1289. int iIndex = (int) SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)sz);
  1290. SendMessage(hwnd, CB_SETITEMDATA, iIndex, iResource[i]);
  1291. }
  1292. }
  1293. }
  1294. void CBands::_SetComboSelection(HWND hwnd, int iCurOption)
  1295. {
  1296. int cItems = (int) SendMessage(hwnd, CB_GETCOUNT, 0, 0);
  1297. while (cItems--) {
  1298. int iItemData = (int) SendMessage(hwnd, CB_GETITEMDATA, cItems, 0);
  1299. if (iItemData == iCurOption) {
  1300. SendMessage(hwnd, CB_SETCURSEL, cItems, 0);
  1301. break;
  1302. }
  1303. else {
  1304. // iCurOption should be in list somewhere;
  1305. // assert that we're not done looking
  1306. Assert(cItems);
  1307. }
  1308. }
  1309. }
  1310. #define IS_LIST_STYLE(hwnd) (!!(GetWindowLong(hwnd, GWL_STYLE) & TBSTYLE_LIST))
  1311. void CBands::_SetDialogSelections(HWND hDlg)
  1312. {
  1313. CBands* pitbar = (CBands*)this;
  1314. DWORD dw;
  1315. int iCurOption;
  1316. HWND hwnd;
  1317. hwnd = GetDlgItem(hDlg, IDC_SHOWTEXT);
  1318. dw = _GetTextState();
  1319. switch (dw)
  1320. {
  1321. case TBSTATE_NOTEXT:
  1322. iCurOption = idsNoTextLabels;
  1323. break;
  1324. case TBSTATE_PARTIALTEXT:
  1325. iCurOption = idsPartialTextLabels;
  1326. break;
  1327. case TBSTATE_FULLTEXT:
  1328. default:
  1329. iCurOption = idsShowTextLabels;
  1330. }
  1331. _SetComboSelection(hwnd, iCurOption);
  1332. dw = _GetIconSize();
  1333. switch (dw)
  1334. {
  1335. case SMALL_ICONS:
  1336. iCurOption = idsSmallIcons;
  1337. break;
  1338. default:
  1339. case LARGE_ICONS:
  1340. iCurOption = idsLargeIcons;
  1341. break;
  1342. }
  1343. hwnd = GetDlgItem(hDlg, IDC_SMALLICONS);
  1344. _SetComboSelection(hwnd, iCurOption);
  1345. }
  1346. static const int c_iTextOptions[] = {
  1347. idsShowTextLabels,
  1348. idsPartialTextLabels,
  1349. idsNoTextLabels,
  1350. };
  1351. static const int c_iIconOptions[] = {
  1352. idsSmallIcons,
  1353. idsLargeIcons,
  1354. };
  1355. void CBands::_PopulateDialog(HWND hDlg)
  1356. {
  1357. HWND hwnd;
  1358. hwnd = GetDlgItem(hDlg, IDC_SHOWTEXT);
  1359. _PopulateComboBox(hwnd, c_iTextOptions, ARRAYSIZE(c_iTextOptions));
  1360. hwnd = GetDlgItem(hDlg, IDC_SMALLICONS);
  1361. _PopulateComboBox(hwnd, c_iIconOptions, ARRAYSIZE(c_iIconOptions));
  1362. }
  1363. void CBands::_UpdateTextSettings(int ids)
  1364. {
  1365. BOOL fText, fList;
  1366. DWORD dwState;
  1367. switch (ids) {
  1368. case idsShowTextLabels:
  1369. fList = FALSE;
  1370. fText = TRUE;
  1371. dwState = TBSTATE_FULLTEXT;
  1372. break;
  1373. case idsPartialTextLabels:
  1374. fList = TRUE;
  1375. fText = TRUE;
  1376. dwState = TBSTATE_PARTIALTEXT;
  1377. break;
  1378. case idsNoTextLabels:
  1379. fList = FALSE; // (but we really don't care)
  1380. fText = FALSE;
  1381. dwState = TBSTATE_NOTEXT;
  1382. break;
  1383. }
  1384. DWORD dwStyle = GetWindowLong(m_hwndTools, GWL_STYLE);
  1385. SetWindowLong(m_hwndTools, GWL_STYLE, fList ? dwStyle | TBSTYLE_LIST : dwStyle & (~TBSTYLE_LIST));
  1386. SendMessage(m_hwndTools, TB_SETEXTENDEDSTYLE, TBSTYLE_EX_MIXEDBUTTONS, fList ? TBSTYLE_EX_MIXEDBUTTONS : 0);
  1387. CompressBands(dwState);
  1388. }
  1389. void CBands::UpdateTextSettings(DWORD dwTextState)
  1390. {
  1391. BOOL fText, fList;
  1392. switch (dwTextState)
  1393. {
  1394. case TBSTATE_FULLTEXT:
  1395. fList = FALSE;
  1396. fText = TRUE;
  1397. break;
  1398. case TBSTATE_PARTIALTEXT:
  1399. fList = TRUE;
  1400. fText = TRUE;
  1401. break;
  1402. case TBSTATE_NOTEXT:
  1403. fList = FALSE; // (but we really don't care)
  1404. fText = FALSE;
  1405. break;
  1406. }
  1407. DWORD dwStyle = GetWindowLong(m_hwndTools, GWL_STYLE);
  1408. SetWindowLong(m_hwndTools, GWL_STYLE, fList ? dwStyle | TBSTYLE_LIST : dwStyle & (~TBSTYLE_LIST));
  1409. SendMessage(m_hwndTools, TB_SETEXTENDEDSTYLE, TBSTYLE_EX_MIXEDBUTTONS, fList ? TBSTYLE_EX_MIXEDBUTTONS : 0);
  1410. CompressBands(dwTextState);
  1411. }
  1412. void CBands::SetIconSize(DWORD dwIconSize)
  1413. {
  1414. m_dwIconSize = dwIconSize;
  1415. ChangeImages();
  1416. SetMinDimensions();
  1417. ResizeBorderDW(NULL, NULL, FALSE);
  1418. }
  1419. DWORD CBands::_GetIconSize()
  1420. {
  1421. return m_dwIconSize;
  1422. }
  1423. LRESULT CBands::OnDropDown(HWND hwnd, LPNMHDR lpnmh)
  1424. {
  1425. HMENU hMenuPopup = NULL;
  1426. TBNOTIFY *ptbn = (TBNOTIFY *)lpnmh ;
  1427. UINT uiCmd = ptbn->iItem ;
  1428. RECT rc;
  1429. DWORD dwCmd = 0;
  1430. IAthenaBrowser *pBrowser;
  1431. BOOL fPostCmd = TRUE;
  1432. IOleCommandTarget *pTarget;
  1433. DWORD cAcctMenu = 0;
  1434. // Load and initialize the appropriate dropdown menu
  1435. switch (uiCmd)
  1436. {
  1437. case ID_POPUP_LANGUAGE:
  1438. {
  1439. // check IDockingWindowSite
  1440. if (m_ptbSite)
  1441. {
  1442. // get IAthenaBrowser interface
  1443. if (SUCCEEDED(m_ptbSite->QueryInterface(IID_IAthenaBrowser, (void**) &pBrowser)))
  1444. {
  1445. // get language menu from shell/browser
  1446. pBrowser->GetLanguageMenu(&hMenuPopup, 0);
  1447. pBrowser->Release();
  1448. if (SUCCEEDED(m_ptbSite->QueryInterface(IID_IOleCommandTarget, (void**) &pTarget)))
  1449. {
  1450. MenuUtil_EnablePopupMenu(hMenuPopup, pTarget);
  1451. pTarget->Release();
  1452. }
  1453. }
  1454. }
  1455. }
  1456. break;
  1457. case ID_NEW_MAIL_MESSAGE:
  1458. case ID_NEW_NEWS_MESSAGE:
  1459. GetStationeryMenu(&hMenuPopup);
  1460. // check IDockingWindowSite
  1461. if (m_ptbSite)
  1462. {
  1463. // get IAthenaBrowser interface
  1464. if (SUCCEEDED(m_ptbSite->QueryInterface(IID_IOleCommandTarget, (void**) &pTarget)))
  1465. {
  1466. MenuUtil_EnablePopupMenu(hMenuPopup, pTarget);
  1467. pTarget->Release();
  1468. }
  1469. }
  1470. break;
  1471. case ID_PREVIEW_PANE:
  1472. {
  1473. // Load the menu
  1474. hMenuPopup = LoadPopupMenu(IDR_PREVIEW_POPUP);
  1475. if (!hMenuPopup)
  1476. break;
  1477. // check IDockingWindowSite
  1478. if (m_ptbSite)
  1479. {
  1480. // get IAthenaBrowser interface
  1481. if (SUCCEEDED(m_ptbSite->QueryInterface(IID_IOleCommandTarget, (void**) &pTarget)))
  1482. {
  1483. MenuUtil_EnablePopupMenu(hMenuPopup, pTarget);
  1484. pTarget->Release();
  1485. }
  1486. }
  1487. break;
  1488. }
  1489. case ID_SEND_RECEIVE:
  1490. {
  1491. hMenuPopup = LoadPopupMenu(IDR_SEND_RECEIEVE_POPUP);
  1492. AcctUtil_CreateSendReceieveMenu(hMenuPopup, &cAcctMenu);
  1493. MenuUtil_SetPopupDefault(hMenuPopup, ID_SEND_RECEIVE);
  1494. // check IDockingWindowSite
  1495. if (m_ptbSite)
  1496. {
  1497. // get IAthenaBrowser interface
  1498. if (SUCCEEDED(m_ptbSite->QueryInterface(IID_IOleCommandTarget, (void**) &pTarget)))
  1499. {
  1500. MenuUtil_EnablePopupMenu(hMenuPopup, pTarget);
  1501. pTarget->Release();
  1502. }
  1503. }
  1504. break;
  1505. }
  1506. case ID_FIND_MESSAGE:
  1507. {
  1508. hMenuPopup = LoadPopupMenu(IDR_FIND_POPUP);
  1509. MenuUtil_SetPopupDefault(hMenuPopup, ID_FIND_MESSAGE);
  1510. // check IDockingWindowSite
  1511. if (m_ptbSite)
  1512. {
  1513. // get IAthenaBrowser interface
  1514. if (SUCCEEDED(m_ptbSite->QueryInterface(IID_IOleCommandTarget, (void**) &pTarget)))
  1515. {
  1516. MenuUtil_EnablePopupMenu(hMenuPopup, pTarget);
  1517. pTarget->Release();
  1518. }
  1519. }
  1520. break;
  1521. }
  1522. default:
  1523. AssertSz(FALSE, "CBands::OnDropDown() - Unhandled TBN_DROPDOWN notification");
  1524. return (TBDDRET_NODEFAULT);
  1525. }
  1526. // If we loaded a menu, then go ahead and display it
  1527. if (hMenuPopup)
  1528. {
  1529. rc = ((NMTOOLBAR *) lpnmh)->rcButton;
  1530. MapWindowRect(lpnmh->hwndFrom, HWND_DESKTOP, &rc);
  1531. SetFlag(TBSTATE_INMENULOOP);
  1532. dwCmd = TrackPopupMenuEx(hMenuPopup, TPM_RETURNCMD | TPM_LEFTALIGN,
  1533. IS_WINDOW_RTL_MIRRORED(lpnmh->hwndFrom)? rc.right : rc.left, rc.bottom, m_hwndParent, NULL);
  1534. ClearFlag(TBSTATE_INMENULOOP);
  1535. }
  1536. // Clean up anything needing to be cleaned up
  1537. switch (uiCmd)
  1538. {
  1539. case ID_LANGUAGE:
  1540. break;
  1541. case ID_NEW_MAIL_MESSAGE:
  1542. case ID_NEW_NEWS_MESSAGE:
  1543. {
  1544. // We can't just forward the normal command ID because we don't have
  1545. // seperate stationery ID's for mail and news.
  1546. if (m_ptbSite)
  1547. {
  1548. // get IAthenaBrowser interface
  1549. if (SUCCEEDED(m_ptbSite->QueryInterface(IID_IAthenaBrowser, (void**) &pBrowser)))
  1550. {
  1551. // Get the current folder ID
  1552. FOLDERID id;
  1553. if (SUCCEEDED(pBrowser->GetCurrentFolder(&id)))
  1554. {
  1555. MenuUtil_HandleNewMessageIDs(dwCmd, m_hwndSizer, id, uiCmd == ID_NEW_MAIL_MESSAGE,
  1556. FALSE, NULL);
  1557. // Clear this so we don't send the command twice.
  1558. dwCmd = 0;
  1559. }
  1560. pBrowser->Release();
  1561. pBrowser = 0;
  1562. }
  1563. }
  1564. break;
  1565. }
  1566. case ID_NEW_MSG_DEFAULT:
  1567. break;
  1568. case ID_SEND_RECEIVE:
  1569. {
  1570. MENUITEMINFO mii;
  1571. mii.cbSize = sizeof(MENUITEMINFO);
  1572. mii.fMask = MIIM_DATA;
  1573. mii.dwItemData = 0;
  1574. if (GetMenuItemInfo(hMenuPopup, dwCmd, FALSE, &mii))
  1575. {
  1576. if (mii.dwItemData)
  1577. {
  1578. g_pSpooler->StartDelivery(m_hwndSizer, (LPTSTR) mii.dwItemData, FOLDERID_INVALID,
  1579. DELIVER_MAIL_SEND | DELIVER_MAIL_RECV | DELIVER_NOSKIP | DELIVER_POLL | DELIVER_OFFLINE_FLAGS);
  1580. // Don't forward this command to the view since we've already handled it.
  1581. dwCmd = 0;
  1582. }
  1583. }
  1584. AcctUtil_FreeSendReceieveMenu(hMenuPopup, cAcctMenu);
  1585. break;
  1586. }
  1587. }
  1588. if (fPostCmd && dwCmd)
  1589. PostMessage(m_hwndSizer, WM_COMMAND, dwCmd, 0);
  1590. if(hMenuPopup)
  1591. {
  1592. //Bug #101338 - (erici) destroy leaked menu
  1593. DestroyMenu(hMenuPopup);
  1594. }
  1595. return (TBDDRET_DEFAULT);
  1596. }
  1597. void CBands::OnContextMenu(HWND hwndFrom, int xPos, int yPos)
  1598. {
  1599. HMENU hMenuContext;
  1600. HWND hwnd;
  1601. HWND hwndSizer = GetParent(hwndFrom);
  1602. POINT pt = {xPos, yPos};
  1603. BOOL fVisible[MAX_BANDS] = {0};
  1604. // Make sure the context menu only appears on the toolbar bars
  1605. hwnd = WindowFromPoint(pt);
  1606. //Load the default context menu which consists of Toolbar and Filter Bar
  1607. hMenuContext = LoadDefaultContextMenu(fVisible);
  1608. if (hMenuContext)
  1609. {
  1610. if (hwnd == m_hwndTools)
  1611. {
  1612. //Add a seperator and customize buttons
  1613. int Count;
  1614. MENUITEMINFO mii = {0};
  1615. TCHAR Str[CCHMAX_STRINGRES];
  1616. Count = GetMenuItemCount(hMenuContext);
  1617. //Insert seperator
  1618. mii.cbSize = sizeof(MENUITEMINFO);
  1619. mii.fMask = MIIM_TYPE;
  1620. mii.fType = MFT_SEPARATOR;
  1621. InsertMenuItem(hMenuContext, Count, TRUE, &mii);
  1622. //Insert customize button
  1623. ZeroMemory(Str, ARRAYSIZE(Str));
  1624. LoadString(g_hLocRes, idsTBCustomize, Str, ARRAYSIZE(Str));
  1625. ZeroMemory(&mii, sizeof(MENUITEMINFO));
  1626. mii.cbSize = sizeof(MENUITEMINFO);
  1627. mii.fMask = MIIM_ID | MIIM_TYPE;
  1628. mii.wID = ID_CUSTOMIZE;
  1629. mii.fType = MFT_STRING;
  1630. mii.dwTypeData = Str;
  1631. mii.cch = ARRAYSIZE(Str);
  1632. InsertMenuItem(hMenuContext, Count + 1, TRUE, &mii);
  1633. }
  1634. SetFlag(TBSTATE_INMENULOOP);
  1635. TrackPopupMenuEx(hMenuContext, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
  1636. xPos, yPos, hwndFrom, NULL);
  1637. ClearFlag(TBSTATE_INMENULOOP);
  1638. if (hMenuContext)
  1639. DestroyMenu(hMenuContext);
  1640. }
  1641. }
  1642. LRESULT CBands::OnGetInfoTip(LPNMTBGETINFOTIP lpnmtb)
  1643. {
  1644. int i;
  1645. for (i = 0; i < (int) m_pTBInfo->cAllButtons; i++)
  1646. {
  1647. if (m_pTBInfo->rgAllButtons[i].idCmd == (DWORD)lpnmtb->iItem)
  1648. {
  1649. AthLoadString(m_pTBInfo->rgAllButtons[i].idsTooltip,
  1650. lpnmtb->pszText, lpnmtb->cchTextMax);
  1651. return TRUE;
  1652. }
  1653. }
  1654. return FALSE;
  1655. }
  1656. //
  1657. // FUNCTION: CBands::OnGetButtonInfo()
  1658. //
  1659. // PURPOSE: Handles the TBN_GETBUTTONINFO notification by returning
  1660. // the buttons availble for the toolbar.
  1661. //
  1662. // PARAMETERS:
  1663. // ptbn - pointer to the TBNOTIFY struct we need to fill in.
  1664. //
  1665. // RETURN VALUE:
  1666. // Returns TRUE to tell the toolbar to use this button, or FALSE
  1667. // otherwise.
  1668. //
  1669. LRESULT CBands::OnGetButtonInfo(TBNOTIFY* ptbn)
  1670. {
  1671. UCHAR fState = 0;
  1672. GUID *pguidCmdGroup;
  1673. GUID guidCmdGroup = CMDSETID_OutlookExpress;
  1674. // Start by returning information for the first array of
  1675. // buttons
  1676. if (ptbn->iItem < (int) m_pTBInfo->cAllButtons && ptbn->iItem >= 0)
  1677. {
  1678. ptbn->tbButton.iBitmap = m_pTBInfo->rgAllButtons[ptbn->iItem].iImage;
  1679. ptbn->tbButton.idCommand = m_pTBInfo->rgAllButtons[ptbn->iItem].idCmd;
  1680. ptbn->tbButton.fsStyle = m_pTBInfo->rgAllButtons[ptbn->iItem].fStyle;
  1681. ptbn->tbButton.iString = ptbn->iItem;
  1682. ptbn->tbButton.fsState = TBSTATE_ENABLED;
  1683. // Return the string info from the string resource. Note,
  1684. // pszText already points to a buffer allocated by the
  1685. // control and cchText has the length of that buffer.
  1686. AthLoadString(m_pTBInfo->rgAllButtons[ptbn->iItem].idsButton,
  1687. ptbn->pszText, ptbn->cchText);
  1688. return (TRUE);
  1689. }
  1690. // No more buttons, so return FALSE
  1691. return (FALSE);
  1692. }
  1693. HRESULT CBands::ShowBrand(void)
  1694. {
  1695. REBARBANDINFO rbbi;
  1696. // create branding window
  1697. m_hwndBrand = CreateWindow(TEXT("button"), NULL,WS_CHILD | BS_OWNERDRAW,
  1698. 0, 0, 0, 0, m_hwndRebar, (HMENU) idcBrand,
  1699. g_hInst, NULL);
  1700. if (!m_hwndBrand)
  1701. {
  1702. DOUTL(1, TEXT("!!!ERROR!!! CITB:Show CreateWindow(BRANDING) failed"));
  1703. return(E_OUTOFMEMORY);
  1704. }
  1705. LoadBrandingBitmap();
  1706. m_fBrandLoaded = TRUE;
  1707. // add branding band
  1708. ZeroMemory(&rbbi, sizeof(rbbi));
  1709. rbbi.cbSize = sizeof(REBARBANDINFO);
  1710. rbbi.fMask = RBBIM_STYLE | RBBIM_COLORS | RBBIM_CHILD | RBBIM_ID;
  1711. rbbi.fStyle = RBBS_FIXEDSIZE;
  1712. rbbi.wID = CBTYPE_BRAND;
  1713. rbbi.clrFore = m_rgbUpperLeft;
  1714. rbbi.clrBack = m_rgbUpperLeft;
  1715. rbbi.hwndChild = m_hwndBrand;
  1716. SendMessage(m_hwndRebar, RB_INSERTBAND, (UINT) -1, (LPARAM) (LPREBARBANDINFO) &rbbi);
  1717. return (S_OK);
  1718. }
  1719. /*
  1720. Helper function for LoadBrandingBitmap
  1721. In IE 2.0, the busy indicator could be branded with a static bitmap.
  1722. This functionality has persisted through 5.0, but in 5.01, the reg
  1723. location for this information moved to HKCU.
  1724. */
  1725. HRESULT CBands::HandleStaticLogos(BOOL fSmallBrand)
  1726. {
  1727. BOOL fPath = FALSE;
  1728. DIBSECTION dib;
  1729. DWORD cb;
  1730. DWORD dwType;
  1731. HBITMAP hbmOld;
  1732. HDC hdcOld;
  1733. HKEY hkey = NULL;
  1734. HRESULT hr = S_FALSE;
  1735. LPCSTR pcszValue = fSmallBrand ? c_szValueSmallBitmap : c_szValueLargeBitmap;
  1736. LPSTR psz;
  1737. TCHAR szPath[MAX_PATH] = "";
  1738. TCHAR szExpanded[MAX_PATH] = "";
  1739. // **** Read path from registry
  1740. // 5.01 User location (OE5.01 Bug #79804)
  1741. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, c_szRegKeyCoolbar, 0, KEY_QUERY_VALUE, &hkey))
  1742. {
  1743. cb = sizeof(szPath);
  1744. if (ERROR_SUCCESS == RegQueryValueEx(hkey, pcszValue, NULL, &dwType, (LPBYTE)szPath, &cb))
  1745. fPath = TRUE;
  1746. RegCloseKey(hkey);
  1747. }
  1748. // **** Process the bitmap
  1749. if (fPath)
  1750. {
  1751. // Should be REG_(EXPAND_)SZ, but came from the IE's registry so protect ourself
  1752. if ((REG_EXPAND_SZ == dwType) || (REG_SZ == dwType))
  1753. {
  1754. // Expand the pathname if needed
  1755. if (REG_EXPAND_SZ == dwType)
  1756. {
  1757. ExpandEnvironmentStrings(szPath, szExpanded, ARRAYSIZE(szExpanded));
  1758. psz = szExpanded;
  1759. }
  1760. else
  1761. psz = szPath;
  1762. // Try to load the file
  1763. hbmOld = (HBITMAP) LoadImage(NULL, psz, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_CREATEDIBSECTION | LR_LOADFROMFILE);
  1764. if (hbmOld)
  1765. {
  1766. hdcOld = CreateCompatibleDC(m_hdc);
  1767. if (hdcOld)
  1768. {
  1769. SelectObject(hdcOld, hbmOld);
  1770. m_rgbUpperLeft = GetPixel(hdcOld, 1, 1);
  1771. GetObject(hbmOld, sizeof(dib), &dib);
  1772. StretchBlt(m_hdc, 0, 0, m_cxBrandExtent, m_cyBrand, hdcOld, 0, 0, dib.dsBm.bmWidth, dib.dsBm.bmHeight, SRCCOPY);
  1773. DeleteDC(hdcOld);
  1774. }
  1775. DeleteObject(hbmOld);
  1776. }
  1777. }
  1778. else
  1779. AssertSz(FALSE, "IE Branding of static bitmaps is not REG_SZ / REG_EXPAND_SZ");
  1780. }
  1781. return hr;
  1782. }
  1783. HRESULT CBands::LoadBrandingBitmap()
  1784. {
  1785. HKEY hKey;
  1786. DIBSECTION dib;
  1787. DWORD dwcbData;
  1788. DWORD dwType = 0;
  1789. BOOL fReg = FALSE;
  1790. BOOL fRegLoaded = FALSE;
  1791. LPTSTR psz;
  1792. TCHAR szScratch[MAX_PATH];
  1793. TCHAR szExpanded[MAX_PATH];
  1794. int ToolBandIndex;
  1795. int BrandBandIndex;
  1796. DWORD BrandSize;
  1797. REBARBANDINFO rbbi = {0};
  1798. BOOL fSmallBrand;
  1799. ToolBandIndex = (int) SendMessage(m_hwndRebar, RB_IDTOINDEX, CBTYPE_TOOLS, 0);
  1800. BrandBandIndex = (int) SendMessage(m_hwndRebar, RB_IDTOINDEX, CBTYPE_BRAND, 0);
  1801. if (ToolBandIndex != -1)
  1802. {
  1803. //If the toolbar is hidden we should show miniscule bitmap
  1804. rbbi.fMask = RBBIM_STYLE;
  1805. SendMessage(m_hwndRebar, RB_GETBANDINFO, ToolBandIndex, (LPARAM)&rbbi);
  1806. if (!!(rbbi.fStyle & RBBS_HIDDEN))
  1807. {
  1808. BrandSize = BRAND_SIZE_MINISCULE;
  1809. }
  1810. else
  1811. {
  1812. //toolbar band exists
  1813. if (((BrandBandIndex != -1) && (BrandBandIndex > ToolBandIndex)) ||
  1814. (BrandBandIndex == -1))
  1815. {
  1816. //If Brand exists and toolband index is less indicates that the toolbar is on the same row as the brand
  1817. //If Tool band exists and brand doesn't also indicates that the toolbar is on the same row and is just being added
  1818. //In both cases we follow toolbar's sizes.
  1819. BrandSize = ISFLAGSET(m_dwToolbarTextState, TBSTATE_FULLTEXT) ? BRAND_SIZE_LARGE : BRAND_SIZE_SMALL;
  1820. }
  1821. else
  1822. {
  1823. //We want to load smallest brand image
  1824. BrandSize = BRAND_SIZE_MINISCULE;
  1825. }
  1826. }
  1827. }
  1828. else
  1829. {
  1830. //We want to load small brand image
  1831. BrandSize = BRAND_SIZE_MINISCULE;
  1832. }
  1833. fSmallBrand = !(BrandSize == BRAND_SIZE_LARGE);
  1834. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, c_szRegKeyCoolbar, 0, KEY_QUERY_VALUE, &hKey))
  1835. {
  1836. fReg = TRUE;
  1837. dwcbData = MAX_PATH;
  1838. if (fReg && (ERROR_SUCCESS == RegQueryValueEx(hKey, fSmallBrand ? c_szValueSmBrandBitmap : c_szValueBrandBitmap, NULL, &dwType,
  1839. (LPBYTE)szScratch, &dwcbData)))
  1840. {
  1841. if (REG_EXPAND_SZ == dwType)
  1842. {
  1843. ExpandEnvironmentStrings(szScratch, szExpanded, ARRAYSIZE(szExpanded));
  1844. psz = szExpanded;
  1845. }
  1846. else
  1847. psz = szScratch;
  1848. if (m_hbmBrand)
  1849. {
  1850. DeleteObject(m_hbmBrand);
  1851. m_hbmBrand = NULL;
  1852. }
  1853. m_hbmBrand = (HBITMAP) LoadImage(NULL, psz, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_CREATEDIBSECTION | LR_LOADFROMFILE);
  1854. if (m_hbmBrand)
  1855. fRegLoaded = TRUE;
  1856. }
  1857. }
  1858. if ((!m_hbmBrand) || (!fRegLoaded))
  1859. {
  1860. if (m_fBrandLoaded)
  1861. {
  1862. if (BrandSize == m_dwBrandSize)
  1863. {
  1864. if (fReg && hKey)
  1865. {
  1866. RegCloseKey(hKey);
  1867. }
  1868. return S_OK;
  1869. }
  1870. }
  1871. if (m_hbmBrand)
  1872. {
  1873. DeleteObject(m_hbmBrand);
  1874. m_hbmBrand = NULL;
  1875. }
  1876. int id;
  1877. switch (BrandSize)
  1878. {
  1879. case BRAND_SIZE_LARGE:
  1880. id = (fIsWhistler() ? idbHiBrand38 : idbBrand38);
  1881. break;
  1882. case BRAND_SIZE_SMALL:
  1883. default:
  1884. id = (fIsWhistler() ? idbHiBrand26 : idbBrand26);
  1885. break;
  1886. case BRAND_SIZE_MINISCULE:
  1887. id = (fIsWhistler() ? idbHiBrand22 : idbBrand22);
  1888. break;
  1889. }
  1890. m_hbmBrand = (HBITMAP)LoadImage(g_hLocRes, MAKEINTRESOURCE(id), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_CREATEDIBSECTION);
  1891. m_dwBrandSize = BrandSize;
  1892. } // if (!m_hbmBrand)
  1893. GetObject(m_hbmBrand, sizeof(DIBSECTION), &dib);
  1894. m_cxBrandExtent = dib.dsBm.bmWidth;
  1895. m_cyBrandExtent = dib.dsBm.bmHeight;
  1896. m_cxBrand = m_cxBrandExtent;
  1897. dwcbData = sizeof(DWORD);
  1898. if (!fRegLoaded || (ERROR_SUCCESS != RegQueryValueEx(hKey, fSmallBrand ? c_szValueSmBrandHeight : c_szValueBrandHeight, NULL, &dwType,
  1899. (LPBYTE)&m_cyBrand, &dwcbData)))
  1900. m_cyBrand = m_cxBrandExtent;
  1901. if (!fRegLoaded || (ERROR_SUCCESS != RegQueryValueEx(hKey, fSmallBrand ? c_szValueSmBrandLeadIn : c_szValueBrandLeadIn, NULL, &dwType,
  1902. (LPBYTE)&m_cyBrandLeadIn, &dwcbData)))
  1903. m_cyBrandLeadIn = 4;
  1904. m_cyBrandLeadIn *= m_cyBrand;
  1905. SelectObject(m_hdc, m_hbmBrand);
  1906. m_rgbUpperLeft = GetPixel(m_hdc, 1, 1);
  1907. if (fReg)
  1908. RegCloseKey(hKey);
  1909. // Brand "Busy" indicator with static logos if specified
  1910. HandleStaticLogos(fSmallBrand);
  1911. return(S_OK);
  1912. }
  1913. void CBands::DrawBranding(LPDRAWITEMSTRUCT lpdis)
  1914. {
  1915. HPALETTE hpalPrev;
  1916. int x, y, cx, cy;
  1917. int yOrg = 0;
  1918. if (IsFlagSet(TBSTATE_ANIMATING))
  1919. yOrg = m_yOrg;
  1920. if (IsFlagSet(TBSTATE_FIRSTFRAME))
  1921. {
  1922. REBARBANDINFO rbbi;
  1923. int cBands = (int) SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  1924. ZeroMemory(&rbbi, sizeof(rbbi));
  1925. rbbi.cbSize = sizeof(REBARBANDINFO);
  1926. rbbi.fMask = RBBIM_ID;
  1927. for (int i = 0; i < cBands; i++)
  1928. {
  1929. SendMessage(m_hwndRebar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
  1930. if (CBTYPE_BRAND == rbbi.wID)
  1931. {
  1932. rbbi.fMask = RBBIM_COLORS;
  1933. rbbi.clrFore = m_rgbUpperLeft;
  1934. rbbi.clrBack = m_rgbUpperLeft;
  1935. SendMessage(m_hwndRebar, RB_SETBANDINFO, i, (LPARAM) &rbbi);
  1936. break;
  1937. }
  1938. }
  1939. ClearFlag(TBSTATE_FIRSTFRAME);
  1940. }
  1941. if (m_hpal)
  1942. {
  1943. hpalPrev = SelectPalette(lpdis->hDC, m_hpal, TRUE);
  1944. RealizePalette(lpdis->hDC);
  1945. }
  1946. x = lpdis->rcItem.left;
  1947. cx = lpdis->rcItem.right - x;
  1948. y = lpdis->rcItem.top;
  1949. cy = lpdis->rcItem.bottom - y;
  1950. if (m_cxBrand > m_cxBrandExtent)
  1951. {
  1952. HBRUSH hbrBack = CreateSolidBrush(m_rgbUpperLeft);
  1953. int xRight = lpdis->rcItem.right;
  1954. x += (m_cxBrand - m_cxBrandExtent) / 2;
  1955. cx = m_cxBrandExtent;
  1956. lpdis->rcItem.right = x;
  1957. FillRect(lpdis->hDC, &lpdis->rcItem, hbrBack);
  1958. lpdis->rcItem.right = xRight;
  1959. lpdis->rcItem.left = x + cx;
  1960. FillRect(lpdis->hDC, &lpdis->rcItem, hbrBack);
  1961. DeleteObject(hbrBack);
  1962. }
  1963. BitBlt(lpdis->hDC, x, y, cx, cy, m_hdc, 0, yOrg, IS_DC_RTL_MIRRORED(lpdis->hDC)
  1964. ? SRCCOPY | DONTMIRRORBITMAP : SRCCOPY);
  1965. if (m_hpal)
  1966. {
  1967. SelectPalette(lpdis->hDC, hpalPrev, TRUE);
  1968. RealizePalette(lpdis->hDC);
  1969. }
  1970. }
  1971. BOOL CBands::SetMinDimensions(void)
  1972. {
  1973. REBARBANDINFO rbbi;
  1974. LRESULT lButtonSize;
  1975. int i, cBands;
  1976. ZeroMemory(&rbbi, sizeof(rbbi));
  1977. rbbi.cbSize = sizeof(REBARBANDINFO);
  1978. cBands = (int) SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  1979. for (i = 0; i < cBands; i++)
  1980. {
  1981. rbbi.fMask = RBBIM_ID;
  1982. SendMessage(m_hwndRebar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
  1983. switch (rbbi.wID)
  1984. {
  1985. case CBTYPE_BRAND:
  1986. rbbi.cxMinChild = m_cxBrand;
  1987. rbbi.cyMinChild = m_cyBrand;
  1988. rbbi.fMask = RBBIM_CHILDSIZE;
  1989. SendMessage(m_hwndRebar, RB_SETBANDINFO, i, (LPARAM)&rbbi);
  1990. break;
  1991. case CBTYPE_TOOLS:
  1992. if (m_hwndTools)
  1993. {
  1994. SIZE size = {0};
  1995. RECT rc = {0};
  1996. lButtonSize = SendMessage(m_hwndTools, TB_GETBUTTONSIZE, 0, 0L);
  1997. GetClientRect(m_hwndTools, &rc);
  1998. // set height to be max of toolbar width and toolbar button width
  1999. size.cy = max(RECTHEIGHT(rc), HIWORD(lButtonSize));
  2000. // have toolbar calculate width given that height
  2001. SendMessage(m_hwndTools, TB_GETIDEALSIZE, FALSE, (LPARAM)&size);
  2002. rbbi.cxMinChild = LOWORD(lButtonSize);
  2003. rbbi.cyMinChild = HIWORD(lButtonSize);
  2004. rbbi.fMask = RBBIM_CHILDSIZE /*| RBBIM_IDEALSIZE*/;
  2005. rbbi.cxIdeal = size.cx;
  2006. SendMessage(m_hwndRebar, RB_SETBANDINFO, i, (LPARAM)&rbbi);
  2007. }
  2008. break;
  2009. }
  2010. }
  2011. return TRUE;
  2012. }
  2013. void CBands::CalcIdealSize()
  2014. {
  2015. SIZE size = {0};
  2016. RECT rc = {0};
  2017. LONG lButtonSize;
  2018. REBARBANDINFO rbbi = {0};
  2019. int Index;
  2020. if (m_hwndTools)
  2021. GetClientRect(m_hwndTools, &rc);
  2022. lButtonSize = (LONG) SendMessage(m_hwndTools, TB_GETBUTTONSIZE, 0, 0L);
  2023. // set height to be max of toolbar width and toolbar button width
  2024. //size.cy = max(RECTHEIGHT(rc), HIWORD(lButtonSize));
  2025. // have toolbar calculate width given that height
  2026. SendMessage(m_hwndTools, TB_GETIDEALSIZE, FALSE, (LPARAM)&size);
  2027. Index = (int) SendMessage(m_hwndRebar, RB_IDTOINDEX, CBTYPE_TOOLS, 0);
  2028. rbbi.cbSize = sizeof(REBARBANDINFO);
  2029. rbbi.fMask = RBBIM_IDEALSIZE;
  2030. rbbi.cxIdeal = size.cx;
  2031. SendMessage(m_hwndRebar, RB_SETBANDINFO, Index, (LPARAM)&rbbi);
  2032. }
  2033. BOOL CBands::CompressBands(DWORD dwText)
  2034. {
  2035. LRESULT lTBStyle = 0;
  2036. int i, cBands;
  2037. REBARBANDINFO rbbi;
  2038. if (_GetTextState() == dwText)
  2039. {
  2040. //No Change
  2041. return FALSE;
  2042. }
  2043. SetTextState(dwText);
  2044. m_yOrg = 0;
  2045. LoadBrandingBitmap();
  2046. cBands = (int) SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  2047. ZeroMemory(&rbbi, sizeof(rbbi));
  2048. rbbi.cbSize = sizeof(REBARBANDINFO);
  2049. for (i = 0; i < cBands; i++)
  2050. {
  2051. rbbi.fMask = RBBIM_ID;
  2052. SendMessage(m_hwndRebar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
  2053. if (dwText == TBSTATE_NOTEXT)
  2054. {
  2055. switch (rbbi.wID)
  2056. {
  2057. case CBTYPE_TOOLS:
  2058. SendMessage(m_hwndTools, TB_SETMAXTEXTROWS, 0, 0L);
  2059. SendMessage(m_hwndTools, TB_SETBUTTONWIDTH, 0, (LPARAM) MAKELONG(0,MAX_TB_COMPRESSED_WIDTH));
  2060. break;
  2061. }
  2062. }
  2063. else
  2064. {
  2065. switch (rbbi.wID)
  2066. {
  2067. case CBTYPE_TOOLS:
  2068. SendMessage(m_hwndTools, TB_SETMAXTEXTROWS, MAX_TB_TEXT_ROWS_HORZ, 0L);
  2069. SendMessage(m_hwndTools, TB_SETBUTTONWIDTH, 0, (LPARAM) MAKELONG(0, m_cxMaxButtonWidth));
  2070. break;
  2071. }
  2072. }
  2073. }
  2074. if (_GetTextState() == TBSTATE_PARTIALTEXT)
  2075. _ChangeSendReceiveText(idsSendReceive);
  2076. else
  2077. _ChangeSendReceiveText(idsSendReceiveBtn);
  2078. SetMinDimensions();
  2079. CalcIdealSize();
  2080. return(TRUE);
  2081. }
  2082. void CBands::_ChangeSendReceiveText(int ids)
  2083. {
  2084. TBBUTTONINFO ptbi = {0};
  2085. TCHAR szText[CCHMAX_STRINGRES];
  2086. ZeroMemory(szText, sizeof(szText));
  2087. LoadString(g_hLocRes, ids, szText, ARRAYSIZE(szText));
  2088. ptbi.cbSize = sizeof(TBBUTTONINFO);
  2089. ptbi.dwMask = TBIF_TEXT;
  2090. ptbi.pszText = szText;
  2091. ptbi.cchText = ARRAYSIZE(szText);
  2092. //if the text style is partial text, show the text of Send & Recv button as Send/Receive
  2093. SendMessage(m_hwndTools, TB_SETBUTTONINFO, ID_SEND_RECEIVE, (LPARAM)&ptbi);
  2094. }
  2095. #define ABS(x) (((x) < 0) ? -(x) : (x))
  2096. void CBands::TrackSliding(int x, int y)
  2097. {
  2098. int cBands = (int) SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0L);
  2099. int cRows = (int) SendMessage(m_hwndRebar, RB_GETROWCOUNT, 0, 0L);
  2100. int cyHalfRow = (int) SendMessage(m_hwndRebar, RB_GETROWHEIGHT, cBands - 1, 0L)/2;
  2101. RECT rc;
  2102. int cyBefore;
  2103. int Delta;
  2104. BOOL fChanged;
  2105. DWORD dwPrevState;
  2106. DWORD dwNewState;
  2107. // do this instead of GetClientRect so that we include borders
  2108. GetWindowRect(m_hwndRebar, &rc);
  2109. MapWindowPoints(HWND_DESKTOP, m_hwndRebar, (LPPOINT)&rc, 2);
  2110. cyBefore = rc.bottom - rc.top;
  2111. Delta = y - m_yCapture;
  2112. // was there enough change?
  2113. if (ABS(Delta) <= cyHalfRow)
  2114. return;
  2115. dwPrevState = _GetTextState();
  2116. if (Delta < -cyHalfRow)
  2117. {
  2118. dwNewState = TBSTATE_NOTEXT;
  2119. UpdateTextSettings(dwNewState);
  2120. }
  2121. else
  2122. {
  2123. dwNewState = m_dwPrevTextStyle;
  2124. UpdateTextSettings(dwNewState);
  2125. }
  2126. fChanged = (dwPrevState != dwNewState);
  2127. if (fChanged)
  2128. {
  2129. //Save the Text Labels into the registry
  2130. AthUserSetValue(NULL, c_szRegToolbarText, REG_DWORD, (LPBYTE)&m_dwToolbarTextState, sizeof(DWORD));
  2131. /*
  2132. if (m_dwParentType == PARENT_TYPE_NOTE)
  2133. {
  2134. CBands *pCoolbar = NULL;
  2135. //Inform the browser
  2136. g_pBrowser->GetCoolbar(&pCoolbar);
  2137. if (pCoolbar)
  2138. {
  2139. pCoolbar->UpdateTextSettings(m_dwToolbarTextState);
  2140. }
  2141. }
  2142. */
  2143. }
  2144. if (!fChanged)
  2145. {
  2146. // if the compressing bands didn't change anything, try to fit it to size
  2147. fChanged = !!SendMessage(m_hwndRebar, RB_SIZETORECT, 0, (LPARAM)&rc);
  2148. }
  2149. }
  2150. //
  2151. // FUNCTION: CBands::CreateRebar(BOOL fVisible)
  2152. //
  2153. // PURPOSE: Creates a new rebar and sizer window.
  2154. //
  2155. // RETURN VALUE:
  2156. // Returns S_OK if the bar was created and inserted correctly,
  2157. // hrAlreadyExists if a band already is in that position,
  2158. // E_OUTOFMEMORY if a window couldn't be created.
  2159. //
  2160. HRESULT CBands::CreateRebar(BOOL fVisible)
  2161. {
  2162. if (m_hwndSizer)
  2163. return (hrAlreadyExists);
  2164. m_hwndSizer = CreateWindowEx(0, SIZABLECLASS, NULL, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | (fVisible ? WS_VISIBLE : 0),
  2165. 0, 0, 100, 36, m_hwndParent, (HMENU) 0, g_hInst, NULL);
  2166. if (m_hwndSizer)
  2167. {
  2168. DOUTL(4, TEXT("Calling SetProp. AddRefing new m_cRef=%d"), m_cRef + 1);
  2169. AddRef(); // Note we Release in WM_DESTROY
  2170. SetProp(m_hwndSizer, TEXT("CBands"), this);
  2171. m_hwndRebar = CreateWindowEx(WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL,
  2172. RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_REGISTERDROP | RBS_DBLCLKTOGGLE |
  2173. WS_VISIBLE | WS_BORDER | WS_CHILD | WS_CLIPCHILDREN |
  2174. WS_CLIPSIBLINGS | CCS_NODIVIDER | CCS_NOPARENTALIGN,
  2175. 0, 0, 100, 136, m_hwndSizer, (HMENU) idcCoolbar, g_hInst, NULL);
  2176. if (m_hwndRebar)
  2177. {
  2178. SendMessage(m_hwndRebar, RB_SETTEXTCOLOR, 0, (LPARAM)GetSysColor(COLOR_BTNTEXT));
  2179. SendMessage(m_hwndRebar, RB_SETBKCOLOR, 0, (LPARAM)GetSysColor(COLOR_BTNFACE));
  2180. SendMessage(m_hwndRebar, CCM_SETVERSION, COMCTL32_VERSION, 0);
  2181. return (S_OK);
  2182. }
  2183. }
  2184. DestroyWindow(m_hwndSizer);
  2185. return (E_OUTOFMEMORY);
  2186. }
  2187. //
  2188. // FUNCTION: CBands::SaveSettings()
  2189. //
  2190. // PURPOSE: Called when we should save our state out to the specified reg
  2191. // key.
  2192. //
  2193. void CBands::SaveSettings(void)
  2194. {
  2195. char szSubKey[MAX_PATH], sz[MAX_PATH];
  2196. DWORD iBand;
  2197. REBARBANDINFO rbbi;
  2198. HKEY hKey;
  2199. DWORD cBands;
  2200. DWORD dwShowToolbar = 1;
  2201. // If we don't have the window, there is nothing to save.
  2202. if (!m_hwndRebar || !m_pTBInfo)
  2203. return;
  2204. ZeroMemory(&rbbi, sizeof(REBARBANDINFO));
  2205. cBands = (DWORD) SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  2206. m_pSavedBandInfo->dwVersion = c_DefaultTable[m_dwParentType].dwVersion;
  2207. m_pSavedBandInfo->cBands = cBands;
  2208. // Loop through the bands and save their information as well
  2209. rbbi.cbSize = sizeof(REBARBANDINFO);
  2210. rbbi.fMask = RBBIM_STYLE | RBBIM_CHILD | RBBIM_SIZE | RBBIM_ID;
  2211. for (iBand = 0; iBand < m_pSavedBandInfo->cBands; iBand++)
  2212. {
  2213. Assert(IsWindow(m_hwndRebar));
  2214. if (SendMessage(m_hwndRebar, RB_GETBANDINFO, iBand, (LPARAM) &rbbi))
  2215. {
  2216. // Save the information that we care about with this band
  2217. m_pSavedBandInfo->BandData[iBand].cx = rbbi.cx;
  2218. m_pSavedBandInfo->BandData[iBand].dwStyle = rbbi.fStyle;
  2219. m_pSavedBandInfo->BandData[iBand].wID = rbbi.wID;
  2220. if (rbbi.wID == CBTYPE_TOOLS)
  2221. {
  2222. dwShowToolbar = !(rbbi.fStyle & RBBS_HIDDEN);
  2223. }
  2224. // If this band has a toolbar, then we should instruct the toolbar
  2225. // to save it's information now
  2226. if (m_pSavedBandInfo->BandData[iBand].wID == CBTYPE_TOOLS)
  2227. {
  2228. SendSaveRestoreMessage(rbbi.hwndChild, TRUE);
  2229. }
  2230. }
  2231. else
  2232. {
  2233. // Default Values
  2234. m_pSavedBandInfo->BandData[iBand].wID = CBTYPE_NONE;
  2235. m_pSavedBandInfo->BandData[iBand].dwStyle = 0;
  2236. m_pSavedBandInfo->BandData[iBand].cx = 0;
  2237. }
  2238. }
  2239. // We have all the information collected, now save that to the specified
  2240. // registry location
  2241. AthUserSetValue(NULL, c_BandRegKeyInfo[m_dwParentType], REG_BINARY, (const LPBYTE)m_pSavedBandInfo,
  2242. m_cSavedBandInfo);
  2243. //This reg key is set by IEAK.
  2244. AthUserSetValue(NULL, c_szShowToolbarIEAK, REG_DWORD, (LPBYTE)&dwShowToolbar, sizeof(DWORD));
  2245. //Save Text Settings
  2246. AthUserSetValue(NULL, c_szRegToolbarText, REG_DWORD, (LPBYTE)&m_dwToolbarTextState, sizeof(DWORD));
  2247. //Save Icon Settings
  2248. AthUserSetValue(NULL, c_szRegToolbarIconSize, REG_DWORD, (LPBYTE)&m_dwIconSize, sizeof(DWORD));
  2249. AthUserSetValue(NULL, c_szRegPrevToolbarText, REG_DWORD, (LPBYTE)&m_dwPrevTextStyle, sizeof(DWORD));
  2250. }
  2251. //
  2252. // FUNCTION: CBands::AddTools()
  2253. //
  2254. // PURPOSE: Inserts the primary toolbar into the coolbar.
  2255. //
  2256. // PARAMETERS:
  2257. // pbs - Pointer to a PBANDSAVE struct with the styles and size of the
  2258. // band to insert.
  2259. //
  2260. // RETURN VALUE:
  2261. // Returns an HRESULT signifying success or failure.
  2262. //
  2263. HRESULT CBands::AddTools(PBANDSAVE pbs)
  2264. {
  2265. REBARBANDINFO rbbi;
  2266. // add tools band
  2267. ZeroMemory(&rbbi, sizeof(rbbi));
  2268. rbbi.cbSize = sizeof(REBARBANDINFO);
  2269. rbbi.fMask = RBBIM_SIZE | RBBIM_ID | RBBIM_STYLE;
  2270. rbbi.fStyle = pbs->dwStyle;
  2271. rbbi.cx = pbs->cx;
  2272. rbbi.wID = pbs->wID;
  2273. if (m_hbmBack)
  2274. {
  2275. rbbi.fMask |= RBBIM_BACKGROUND;
  2276. rbbi.fStyle |= RBBS_FIXEDBMP;
  2277. rbbi.hbmBack = m_hbmBack;
  2278. }
  2279. else
  2280. {
  2281. rbbi.fMask |= RBBIM_COLORS;
  2282. rbbi.clrFore = GetSysColor(COLOR_BTNTEXT);
  2283. rbbi.clrBack = GetSysColor(COLOR_BTNFACE);
  2284. }
  2285. SendMessage(m_hwndRebar, RB_INSERTBAND, (UINT) -1, (LPARAM) (LPREBARBANDINFO) &rbbi);
  2286. return(S_OK);
  2287. }
  2288. void CBands::LoadBackgroundImage()
  2289. {
  2290. int Count = 0;
  2291. REBARBANDINFO rbbi = {0};
  2292. TCHAR szBitMap[MAX_PATH] = {0};
  2293. DWORD dwType;
  2294. DWORD cbData;
  2295. BOOL fBranded = FALSE;
  2296. //First check if there is a customized background bitmap for us.
  2297. cbData = ARRAYSIZE(szBitMap);
  2298. if ((SHGetValue(HKEY_CURRENT_USER, c_szRegKeyCoolbar, c_szValueBackBitmapIE5, &dwType, szBitMap, &cbData)
  2299. == ERROR_SUCCESS) && (*szBitMap))
  2300. fBranded = TRUE;
  2301. // Could be old branding in place, so try that
  2302. else if ((SHGetValue(HKEY_CURRENT_USER, c_szRegKeyCoolbar, c_szValueBackBitmap, &dwType, szBitMap, &cbData)
  2303. == ERROR_SUCCESS) && (*szBitMap))
  2304. fBranded = TRUE;
  2305. if (fBranded)
  2306. {
  2307. ClearFlag(TBSTATE_NOBACKGROUND);
  2308. m_hbmBack = (HBITMAP)LoadImage(NULL, szBitMap, IMAGE_BITMAP, 0, 0,
  2309. LR_DEFAULTSIZE | LR_CREATEDIBSECTION | LR_LOADFROMFILE);
  2310. }
  2311. else
  2312. {
  2313. if (IsFlagClear(TBSTATE_NOBACKGROUND) && !m_hbmBack && m_idbBack)
  2314. {
  2315. m_hbmBack = (HBITMAP) LoadImage(g_hLocRes, MAKEINTRESOURCE(m_idbBack),
  2316. IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_CREATEDIBSECTION);
  2317. }
  2318. }
  2319. }
  2320. HRESULT CBands::SetFolderType(FOLDERTYPE ftType)
  2321. {
  2322. TCHAR szToolsText[(MAX_TB_TEXT_LENGTH+2) * MAX_TB_BUTTONS];
  2323. int i, cBands;
  2324. REBARBANDINFO rbbi;
  2325. HWND hwndDestroy = NULL;
  2326. // If we haven't created the rebar yet, this will fail. Call ShowDW() first.
  2327. if (!IsWindow(m_hwndRebar))
  2328. return (E_FAIL);
  2329. // Check to see if this would actually be a change
  2330. if (ftType == m_ftType)
  2331. return (S_OK);
  2332. // First find the band with the toolbar
  2333. cBands = (int) SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  2334. ZeroMemory(&rbbi, sizeof(rbbi));
  2335. rbbi.cbSize = sizeof(REBARBANDINFO);
  2336. rbbi.fMask = RBBIM_ID;
  2337. for (i = 0; i < cBands; i++)
  2338. {
  2339. SendMessage(m_hwndRebar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
  2340. if (CBTYPE_TOOLS == rbbi.wID)
  2341. break;
  2342. }
  2343. // We didn't find it.
  2344. if (i >= cBands)
  2345. return (E_FAIL);
  2346. // Destroy the old toolbar if it exists
  2347. if (IsWindow(m_hwndTools))
  2348. {
  2349. // Save it's button configuration
  2350. SendSaveRestoreMessage(m_hwndTools, TRUE);
  2351. CleanupImages(m_hwndTools);
  2352. hwndDestroy = m_hwndTools;
  2353. }
  2354. // Update our internal state information with the new folder type
  2355. Assert(((m_dwParentType == PARENT_TYPE_BROWSER) && (ftType < FOLDER_TYPESMAX)) ||
  2356. ((m_dwParentType == PARENT_TYPE_NOTE) && (ftType < NOTETYPES_MAX)));
  2357. m_ftType = ftType;
  2358. const TOOLBAR_INFO *ParentToolbarArrayInfo = c_DefButtonInfo[m_dwParentType];
  2359. m_pTBInfo = &(ParentToolbarArrayInfo[m_ftType]);
  2360. // Create a new toolbar
  2361. m_hwndTools = CreateWindowEx(WS_EX_TOOLWINDOW, TOOLBARCLASSNAME, NULL,
  2362. WS_CHILD | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS
  2363. | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
  2364. | CCS_NODIVIDER | CCS_NOPARENTALIGN
  2365. | CCS_ADJUSTABLE | CCS_NORESIZE,
  2366. 0, 0, 0, 0, m_hwndRebar, (HMENU) idcToolbar,
  2367. g_hInst, NULL);
  2368. Assert(m_hwndTools);
  2369. if (!m_hwndTools)
  2370. {
  2371. DOUTL(1, TEXT("CBands::SetFolderType() CreateWindow(TOOLBAR) failed"));
  2372. return(E_OUTOFMEMORY);
  2373. }
  2374. _InitToolbar(m_hwndTools);
  2375. // If we have previously save configuration info for this toolbar, load it
  2376. SendSaveRestoreMessage(m_hwndTools, FALSE);
  2377. // First find the band with the toolbar
  2378. cBands = (int) SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  2379. ZeroMemory(&rbbi, sizeof(rbbi));
  2380. rbbi.cbSize = sizeof(REBARBANDINFO);
  2381. rbbi.fMask = RBBIM_ID;
  2382. for (i = 0; i < cBands; i++)
  2383. {
  2384. SendMessage(m_hwndRebar, RB_GETBANDINFO, i, (LPARAM) &rbbi);
  2385. if (CBTYPE_TOOLS == rbbi.wID)
  2386. break;
  2387. }
  2388. POINT ptIdeal = {0};
  2389. SendMessage(m_hwndTools, TB_GETIDEALSIZE, FALSE, (LPARAM)&ptIdeal);
  2390. // Add the toolbar to the rebar
  2391. ZeroMemory(&rbbi, sizeof(rbbi));
  2392. rbbi.cbSize = sizeof(REBARBANDINFO);
  2393. rbbi.fMask = RBBIM_CHILD | RBBIM_IDEALSIZE;
  2394. rbbi.hwndChild = m_hwndTools;
  2395. rbbi.cxIdeal = ptIdeal.x;
  2396. SendMessage(m_hwndRebar, RB_SETBANDINFO, (UINT) i, (LPARAM) (LPREBARBANDINFO) &rbbi);
  2397. if (hwndDestroy)
  2398. DestroyWindow(hwndDestroy);
  2399. SetMinDimensions();
  2400. ResizeBorderDW(NULL, NULL, FALSE);
  2401. return (S_OK);
  2402. }
  2403. HRESULT CBands::UpdateViewState()
  2404. {
  2405. //Enable/disable the ViewsCombo box
  2406. OLECMD olecmd = {0};
  2407. olecmd.cmdID = ID_VIEW_APPLY;
  2408. if (SUCCEEDED(m_ptbSiteCT->QueryStatus(&CMDSETID_OutlookExpress, 1, &olecmd, NULL)))
  2409. {
  2410. EnableWindow(m_hwndFilterCombo, !!(olecmd.cmdf & OLECMDF_ENABLED));
  2411. }
  2412. //Enable/disable the ViewsToolbar buttons
  2413. return Update(m_hwndRulesToolbar);
  2414. }
  2415. void CBands::UpdateToolbarColors(void)
  2416. {
  2417. UpdateRebarBandColors(m_hwndRebar);
  2418. }
  2419. HRESULT CBands::OnConnectionNotify(CONNNOTIFY nCode,
  2420. LPVOID pvData,
  2421. CConnectionManager *pConMan)
  2422. {
  2423. if ((m_hwndTools) && (nCode == CONNNOTIFY_WORKOFFLINE))
  2424. {
  2425. SendMessage(m_hwndTools, TB_CHECKBUTTON, ID_WORK_OFFLINE, (LPARAM)MAKELONG(pvData, 0));
  2426. }
  2427. return S_OK;
  2428. }
  2429. HRESULT CBands::Update()
  2430. {
  2431. return Update(m_hwndTools);
  2432. }
  2433. HRESULT CBands::Update(HWND hwnd)
  2434. {
  2435. DWORD cButtons = 0;
  2436. OLECMD *rgCmds;
  2437. TBBUTTON tb;
  2438. DWORD cCmds = 0;
  2439. DWORD i;
  2440. DWORD dwState;
  2441. // It's possible to get this before the toolbar is created
  2442. if (!IsWindow(hwnd))
  2443. return (S_OK);
  2444. // Get the number of buttons on the toolbar
  2445. cButtons = (DWORD) SendMessage(hwnd, TB_BUTTONCOUNT, 0, 0);
  2446. if (0 == cButtons)
  2447. return (S_OK);
  2448. // Allocate an array of OLECMD structures for the buttons
  2449. if (!MemAlloc((LPVOID *) &rgCmds, sizeof(OLECMD) * cButtons))
  2450. return (E_OUTOFMEMORY);
  2451. // Loop through the buttons and get the ID for each
  2452. for (i = 0; i < cButtons; i++)
  2453. {
  2454. if (SendMessage(hwnd, TB_GETBUTTON, i, (LPARAM) &tb))
  2455. {
  2456. // Toolbar returns zero for seperators
  2457. if (tb.idCommand)
  2458. {
  2459. rgCmds[cCmds].cmdID = tb.idCommand;
  2460. rgCmds[cCmds].cmdf = 0;
  2461. cCmds++;
  2462. }
  2463. }
  2464. }
  2465. // I don't see how this can be false
  2466. Assert(m_ptbSite);
  2467. // Do the QueryStatus thing
  2468. if (m_ptbSiteCT)
  2469. {
  2470. if (SUCCEEDED(m_ptbSiteCT->QueryStatus(&CMDSETID_OutlookExpress, cCmds, rgCmds, NULL)))
  2471. {
  2472. // Go through the array now and do the enable / disable thing
  2473. for (i = 0; i < cCmds; i++)
  2474. {
  2475. // Get the current state of the button
  2476. dwState = (DWORD) SendMessage(hwnd, TB_GETSTATE, rgCmds[i].cmdID, 0);
  2477. // Update the state with the feedback we've been provided
  2478. if (rgCmds[i].cmdf & OLECMDF_ENABLED)
  2479. dwState |= TBSTATE_ENABLED;
  2480. else
  2481. dwState &= ~TBSTATE_ENABLED;
  2482. if (rgCmds[i].cmdf & OLECMDF_LATCHED)
  2483. dwState |= TBSTATE_CHECKED;
  2484. else
  2485. dwState &= ~TBSTATE_CHECKED;
  2486. // Radio check has no meaning here.
  2487. Assert(0 == (rgCmds[i].cmdf & OLECMDF_NINCHED));
  2488. SendMessage(hwnd, TB_SETSTATE, rgCmds[i].cmdID, dwState);
  2489. }
  2490. }
  2491. }
  2492. MemFree(rgCmds);
  2493. return (S_OK);
  2494. }
  2495. HRESULT CBands::CreateMenuBand(PBANDSAVE pbs)
  2496. {
  2497. HRESULT hres;
  2498. HWND hwndBrowser;
  2499. HMENU hMenu;
  2500. IShellMenu *pShellMenu;
  2501. DWORD dwFlags = 0;
  2502. //Cocreate menuband
  2503. hres = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER, IID_IShellMenu, (LPVOID*)&m_pShellMenu);
  2504. if ((hres != S_OK) || (m_pShellMenu == NULL))
  2505. {
  2506. return hres;
  2507. }
  2508. dwFlags = SMINIT_HORIZONTAL | SMINIT_TOPLEVEL | SMINIT_DEFAULTTOTRACKPOPUP;
  2509. /*
  2510. if (m_dwParentType == PARENT_TYPE_BROWSER)
  2511. dwFlags |= SMINIT_USEMESSAGEFILTER;
  2512. */
  2513. m_pShellMenu->Initialize(NULL, -1, ANCESTORDEFAULT, dwFlags);
  2514. m_pShellMenu->SetMenu(m_hMenu, m_hwndParent, SMSET_DONTOWN);
  2515. hres = AddMenuBand(pbs);
  2516. return hres;
  2517. }
  2518. HRESULT CBands::ResetMenu(HMENU hmenu)
  2519. {
  2520. if (m_pShellMenu)
  2521. {
  2522. m_hMenu = hmenu;
  2523. m_pShellMenu->SetMenu(m_hMenu, m_hwndParent, SMSET_DONTOWN | SMSET_MERGE);
  2524. }
  2525. MenuUtil_EnableMenu(m_hMenu, m_ptbSiteCT);
  2526. return(S_OK);
  2527. }
  2528. HRESULT CBands::AddMenuBand(PBANDSAVE pbs)
  2529. {
  2530. REBARBANDINFO rbbi;
  2531. HRESULT hres;
  2532. HWND hwndMenuBand = NULL;
  2533. IObjectWithSite *pObj;
  2534. //We don't get here if m_pShellMenu is null. But we want to be safe
  2535. if (m_pShellMenu)
  2536. {
  2537. hres = m_pShellMenu->QueryInterface(IID_IDeskBand, (LPVOID*)&m_pDeskBand);
  2538. if (FAILED(hres))
  2539. return hres;
  2540. hres = m_pShellMenu->QueryInterface(IID_IMenuBand, (LPVOID*)&m_pMenuBand);
  2541. if (FAILED(hres))
  2542. return hres;
  2543. hres = m_pDeskBand->QueryInterface(IID_IWinEventHandler, (LPVOID*)&m_pWinEvent);
  2544. if (FAILED(hres))
  2545. return hres;
  2546. hres = m_pDeskBand->QueryInterface(IID_IObjectWithSite, (LPVOID*)&pObj);
  2547. if (FAILED(hres))
  2548. return hres;
  2549. pObj->SetSite((IDockingWindow*)this);
  2550. pObj->Release();
  2551. m_pDeskBand->GetWindow(&m_hwndMenuBand);
  2552. DESKBANDINFO DeskBandInfo = {0};
  2553. m_pDeskBand->GetBandInfo(pbs->wID, 0, &DeskBandInfo);
  2554. ZeroMemory(&rbbi, sizeof(rbbi));
  2555. rbbi.cbSize = sizeof(REBARBANDINFO);
  2556. rbbi.fMask = RBBIM_SIZE | RBBIM_ID | RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE;
  2557. rbbi.fStyle = pbs->dwStyle;
  2558. rbbi.cx = pbs->cx;
  2559. rbbi.wID = pbs->wID;
  2560. rbbi.hwndChild = m_hwndMenuBand;
  2561. rbbi.cxMinChild = DeskBandInfo.ptMinSize.x;
  2562. rbbi.cyMinChild = DeskBandInfo.ptMinSize.y;
  2563. rbbi.cxIdeal = DeskBandInfo.ptActual.x;
  2564. if (m_hbmBack)
  2565. {
  2566. rbbi.fMask |= RBBIM_BACKGROUND;
  2567. rbbi.fStyle |= RBBS_FIXEDBMP;
  2568. rbbi.hbmBack = m_hbmBack;
  2569. }
  2570. SendMessage(m_hwndRebar, RB_INSERTBAND, (UINT)-1, (LPARAM)(LPREBARBANDINFO)&rbbi);
  2571. SetForegroundWindow(m_hwndParent);
  2572. m_pDeskBand->ShowDW(TRUE);
  2573. SetNotRealSite();
  2574. }
  2575. return S_OK;
  2576. }
  2577. HRESULT CBands::TranslateMenuMessage(MSG *pmsg, LRESULT *lpresult)
  2578. {
  2579. if (m_pMenuBand)
  2580. return m_pMenuBand->TranslateMenuMessage(pmsg, lpresult);
  2581. else
  2582. return S_FALSE;
  2583. }
  2584. HRESULT CBands::IsMenuMessage(MSG *lpmsg)
  2585. {
  2586. if (m_pMenuBand)
  2587. return m_pMenuBand->IsMenuMessage(lpmsg);
  2588. else
  2589. return S_FALSE;
  2590. }
  2591. void CBands::SetNotRealSite()
  2592. {
  2593. IOleCommandTarget *pOleCmd;
  2594. if (m_pDeskBand->QueryInterface(IID_IOleCommandTarget, (LPVOID*)&pOleCmd) == S_OK)
  2595. {
  2596. //pOleCmd->Exec(&CGID_MenuBand, MBANDCID_NOTAREALSITE, TRUE, NULL, NULL);
  2597. pOleCmd->Exec(&CLSID_MenuBand, 3, TRUE, NULL, NULL);
  2598. pOleCmd->Release();
  2599. }
  2600. }
  2601. HMENU CBands::LoadDefaultContextMenu(BOOL *fVisible)
  2602. {
  2603. // Load the context menu
  2604. HMENU hMenu = LoadPopupMenu(IDR_COOLBAR_POPUP);
  2605. if (m_dwParentType == PARENT_TYPE_NOTE)
  2606. {
  2607. //Remove filter bar from the menu
  2608. DeleteMenu(hMenu, ID_SHOW_FILTERBAR, MF_BYCOMMAND);
  2609. }
  2610. if (hMenu)
  2611. {
  2612. // Loop through the bands and see which ones are visible
  2613. DWORD cBands, iBand;
  2614. REBARBANDINFO rbbi = {0};
  2615. rbbi.cbSize = sizeof(REBARBANDINFO);
  2616. rbbi.fMask = RBBIM_STYLE | RBBIM_ID;
  2617. cBands = (DWORD) SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  2618. for (iBand = 0; iBand < cBands; iBand++)
  2619. {
  2620. if (SendMessage(m_hwndRebar, RB_GETBANDINFO, iBand, (LPARAM) &rbbi))
  2621. {
  2622. if (!(rbbi.fStyle & RBBS_HIDDEN))
  2623. {
  2624. switch (rbbi.wID)
  2625. {
  2626. case CBTYPE_TOOLS:
  2627. fVisible[CBTYPE_TOOLS - CBTYPE_BASE] = TRUE;
  2628. CheckMenuItem(hMenu, ID_SHOW_TOOLBAR, MF_BYCOMMAND | MF_CHECKED);
  2629. break;
  2630. case CBTYPE_RULESTOOLBAR:
  2631. fVisible[CBTYPE_RULESTOOLBAR - CBTYPE_BASE] = TRUE;
  2632. CheckMenuItem(hMenu, ID_SHOW_FILTERBAR, MF_BYCOMMAND | MF_CHECKED);
  2633. break;
  2634. }
  2635. }
  2636. }
  2637. }
  2638. }
  2639. return hMenu;
  2640. }
  2641. HWND CBands::GetToolbarWnd()
  2642. {
  2643. return m_hwndTools;
  2644. }
  2645. HWND CBands::GetRebarWnd()
  2646. {
  2647. return m_hwndRebar;
  2648. }
  2649. void CBands::SendSaveRestoreMessage(HWND hwnd, BOOL fSave)
  2650. {
  2651. TBSAVEPARAMS tbsp;
  2652. char szSubKey[MAX_PATH], sz[MAX_PATH];
  2653. DWORD dwType;
  2654. DWORD dwVersion;
  2655. DWORD cbData = sizeof(DWORD);
  2656. DWORD dwError;
  2657. if (m_pTBInfo == NULL)
  2658. return;
  2659. tbsp.hkr = AthUserGetKeyRoot();
  2660. AthUserGetKeyPath(sz, ARRAYSIZE(sz));
  2661. if (m_pTBInfo->pszRegKey != NULL)
  2662. {
  2663. wnsprintf(szSubKey, ARRAYSIZE(szSubKey), c_szPathFileFmt, sz, m_pTBInfo->pszRegKey);
  2664. tbsp.pszSubKey = szSubKey;
  2665. }
  2666. else
  2667. {
  2668. tbsp.pszSubKey = sz;
  2669. }
  2670. tbsp.pszValueName = m_pTBInfo->pszRegValue;
  2671. // First check to see if the version has changed
  2672. if (!fSave)
  2673. {
  2674. if (ERROR_SUCCESS == AthUserGetValue(m_pTBInfo->pszRegKey, c_szRegToolbarVersion, &dwType, (LPBYTE) &dwVersion, &cbData))
  2675. {
  2676. if (dwVersion == c_DefaultTable[m_dwParentType].dwVersion)
  2677. SendMessage(hwnd, TB_SAVERESTORE, (WPARAM)fSave, (LPARAM)&tbsp);
  2678. }
  2679. }
  2680. else
  2681. {
  2682. dwVersion = c_DefaultTable[m_dwParentType].dwVersion;
  2683. SendMessage(hwnd, TB_SAVERESTORE, (WPARAM)fSave, (LPARAM)&tbsp);
  2684. dwError = AthUserSetValue(m_pTBInfo->pszRegKey, c_szRegToolbarVersion, REG_DWORD, (LPBYTE) &dwVersion, cbData);
  2685. }
  2686. }
  2687. void CBands::InitRulesToolbar()
  2688. {
  2689. TCHAR szToolsText[(MAX_TB_TEXT_LENGTH+2) * MAX_TB_BUTTONS];
  2690. int idBmp;
  2691. TCHAR *szActual;
  2692. // Tell the toolbar some basic information
  2693. SendMessage(m_hwndRulesToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
  2694. SendMessage(m_hwndRulesToolbar, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DRAWDDARROWS | TBSTYLE_EX_HIDECLIPPEDBUTTONS);
  2695. // Tell the toolbar the number of rows of text and button width based
  2696. // on whether or not we're showing text below the buttons or not.
  2697. SendMessage(m_hwndRulesToolbar, TB_SETMAXTEXTROWS, 1, 0);
  2698. SendMessage(m_hwndRulesToolbar, TB_SETBUTTONWIDTH, 0, MAKELONG(0, MAX_TB_COMPRESSED_WIDTH));
  2699. // Now load the buttons into the toolbar
  2700. _SetImages(m_hwndRulesToolbar, (fIsWhistler() ?
  2701. ((GetCurColorRes() > 24) ? c_32RulesImageList : c_RulesImageList)
  2702. : c_NWRulesImageList ));
  2703. _LoadStrings(m_hwndRulesToolbar, (TOOLBAR_INFO *) c_rgRulesToolbarInfo);
  2704. _LoadDefaultButtons(m_hwndRulesToolbar, (TOOLBAR_INFO *) c_rgRulesToolbarInfo);
  2705. }
  2706. HRESULT CBands::AddRulesToolbar(PBANDSAVE pbs)
  2707. {
  2708. REBARBANDINFO rbbi = {0};
  2709. m_hwndRulesToolbar = CreateWindowEx(WS_EX_TOOLWINDOW, TOOLBARCLASSNAME, NULL,
  2710. WS_CHILD | TBSTYLE_LIST | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS
  2711. | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
  2712. | CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_NORESIZE,
  2713. 0, 0, 0, 0, m_hwndRebar, (HMENU) NULL,
  2714. g_hInst, NULL);
  2715. SendMessage(m_hwndRulesToolbar, TB_SETEXTENDEDSTYLE, TBSTYLE_EX_MIXEDBUTTONS, TBSTYLE_EX_MIXEDBUTTONS);
  2716. AddComboBox();
  2717. InitRulesToolbar();
  2718. LRESULT lButtonSize;
  2719. lButtonSize = SendMessage(m_hwndRulesToolbar, TB_GETBUTTONSIZE, 0, 0L);
  2720. TCHAR szBuf[CCHMAX_STRINGRES];
  2721. LoadString(g_hLocRes, idsRulesToolbarTitle, szBuf, ARRAYSIZE(szBuf));
  2722. rbbi.lpText = szBuf;
  2723. rbbi.cxMinChild = LOWORD(lButtonSize);
  2724. rbbi.cyMinChild = HIWORD(lButtonSize);
  2725. rbbi.wID = pbs->wID;
  2726. rbbi.cbSize = sizeof(REBARBANDINFO);
  2727. rbbi.fMask = RBBIM_STYLE | RBBIM_ID | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_TEXT | RBBIM_SIZE;
  2728. rbbi.cx = pbs->cx;
  2729. rbbi.fStyle = pbs->dwStyle;
  2730. rbbi.hwndChild = m_hwndRulesToolbar;
  2731. if (m_hbmBack)
  2732. {
  2733. rbbi.fMask |= RBBIM_BACKGROUND;
  2734. rbbi.fStyle |= RBBS_FIXEDBMP;
  2735. rbbi.hbmBack = m_hbmBack;
  2736. }
  2737. else
  2738. {
  2739. rbbi.fMask |= RBBIM_COLORS;
  2740. rbbi.clrFore = GetSysColor(COLOR_BTNTEXT);
  2741. rbbi.clrBack = GetSysColor(COLOR_BTNFACE);
  2742. }
  2743. SendMessage(m_hwndRebar, RB_INSERTBAND, (UINT)-1, (LPARAM)&rbbi);
  2744. return S_OK;
  2745. }
  2746. void CBands::FilterBoxFontChange()
  2747. {
  2748. int Count;
  2749. int MaxLen = 0;
  2750. int CurLen = 0;
  2751. LPTSTR szMaxName;
  2752. Count = ComboBox_GetCount(m_hwndFilterCombo);
  2753. if (Count != CB_ERR)
  2754. {
  2755. if (Count > 0)
  2756. {
  2757. if (MemAlloc((LPVOID*)&szMaxName, CCHMAX_STRINGRES))
  2758. {
  2759. ZeroMemory(szMaxName, CCHMAX_STRINGRES);
  2760. while (--Count >= 0)
  2761. {
  2762. CurLen = ComboBox_GetLBTextLen(m_hwndFilterCombo, Count);
  2763. if (CurLen > MaxLen)
  2764. {
  2765. if (CurLen > CCHMAX_STRINGRES)
  2766. {
  2767. if (MemRealloc((LPVOID*)&szMaxName, CurLen * sizeof(TCHAR)))
  2768. {
  2769. ZeroMemory(szMaxName, CurLen * sizeof(TCHAR));
  2770. }
  2771. else
  2772. szMaxName = NULL;
  2773. }
  2774. if (szMaxName)
  2775. {
  2776. ComboBox_GetLBText(m_hwndFilterCombo, Count, szMaxName);
  2777. MaxLen = CurLen;
  2778. }
  2779. }
  2780. }
  2781. if (szMaxName && *szMaxName)
  2782. FixComboBox(szMaxName);
  2783. }
  2784. }
  2785. }
  2786. }
  2787. void CBands::FixComboBox(LPTSTR szName)
  2788. {
  2789. HFONT hFont;
  2790. LOGFONT lgFont;
  2791. HDC hdc;
  2792. if (szName != NULL)
  2793. {
  2794. if (m_hComboBoxFont)
  2795. {
  2796. DeleteObject(m_hComboBoxFont);
  2797. m_hComboBoxFont = NULL;
  2798. }
  2799. //Figure out which font to use
  2800. SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lgFont, FALSE);
  2801. //Create the font
  2802. m_hComboBoxFont = CreateFontIndirect(&lgFont);
  2803. SendMessage(m_hwndFilterCombo, WM_SETFONT, (WPARAM)m_hComboBoxFont, TRUE);
  2804. //Get the metrics of this font
  2805. hdc = GetDC(m_hwndRebar);
  2806. SelectFont(hdc, m_hComboBoxFont);
  2807. SIZE s;
  2808. GetTextExtentPoint32(hdc, szName, lstrlen(szName) + 2, &s);
  2809. ReleaseDC(m_hwndRebar, hdc);
  2810. int cxDownButton;
  2811. cxDownButton = GetSystemMetrics(SM_CXVSCROLL) + GetSystemMetrics(SM_CXDLGFRAME);
  2812. int cyToolbarButton;
  2813. RECT rc;
  2814. SendMessage(m_hwndRulesToolbar, TB_GETITEMRECT, 0, (LPARAM) &rc);
  2815. cyToolbarButton = rc.bottom - rc.top + 1;
  2816. // Figure out size of expanded dropdown lists
  2817. int cyExpandedList;
  2818. cyExpandedList = 8 * cyToolbarButton;
  2819. SetWindowPos(m_hwndFilterCombo, NULL, 0, 1, cxDownButton + s.cx, cyExpandedList, SWP_NOACTIVATE | SWP_NOZORDER);
  2820. MemFree(szName);
  2821. }
  2822. }
  2823. HRESULT CBands::AddComboBox()
  2824. {
  2825. if (!m_hwndFilterCombo)
  2826. {
  2827. m_hwndFilterCombo = CreateWindow("ComboBox", NULL,
  2828. WS_CHILD | WS_VSCROLL | CBS_DROPDOWNLIST |
  2829. WS_VISIBLE | CBS_HASSTRINGS | CBS_SORT,
  2830. 0, 0, 100, 100,
  2831. m_hwndRulesToolbar,
  2832. (HMENU) NULL, g_hInst, NULL);
  2833. }
  2834. return S_OK;
  2835. }
  2836. void CBands::UpdateFilters(RULEID CurRuleID)
  2837. {
  2838. RULEINFO *pRuleInfo;
  2839. DWORD cRules = 0;
  2840. DWORD CurLen = 0;
  2841. DWORD MaxLen = 0;
  2842. DWORD dwFlags = 0;
  2843. LPSTR szMaxName = NULL;
  2844. // Set the proper flags
  2845. switch (m_ftType)
  2846. {
  2847. case FOLDER_LOCAL:
  2848. dwFlags = GETF_POP3;
  2849. break;
  2850. case FOLDER_NEWS:
  2851. dwFlags = GETF_NNTP;
  2852. break;
  2853. case FOLDER_HTTPMAIL:
  2854. dwFlags = GETF_HTTPMAIL;
  2855. break;
  2856. case FOLDER_IMAP:
  2857. dwFlags = GETF_IMAP;
  2858. break;
  2859. }
  2860. if (g_pRulesMan && (g_pRulesMan->GetRules(dwFlags, RULE_TYPE_FILTER, &pRuleInfo, &cRules) == S_OK) && (cRules))
  2861. {
  2862. PROPVARIANT pvarResult;
  2863. DWORD ItemIndex;
  2864. int Count;
  2865. if (((Count = ComboBox_GetCount(m_hwndFilterCombo)) != CB_ERR) && (Count > 0))
  2866. {
  2867. //empty the Combo Box
  2868. while (--Count >= 0)
  2869. {
  2870. ComboBox_DeleteString(m_hwndFilterCombo, Count);
  2871. }
  2872. }
  2873. do
  2874. {
  2875. cRules--;
  2876. pRuleInfo[cRules].pIRule->GetProp(RULE_PROP_NAME, 0, &pvarResult);
  2877. ItemIndex = ComboBox_AddString(m_hwndFilterCombo, pvarResult.pszVal);
  2878. if ((ItemIndex != CB_ERR) && (ItemIndex != CB_ERRSPACE))
  2879. ComboBox_SetItemData(m_hwndFilterCombo, ItemIndex, pRuleInfo[cRules].ridRule);
  2880. if (pRuleInfo[cRules].ridRule == CurRuleID)
  2881. {
  2882. ComboBox_SetCurSel(m_hwndFilterCombo, ItemIndex);
  2883. }
  2884. //figure out the longest string so we can set the width of the combo box
  2885. CurLen = strlen(pvarResult.pszVal);
  2886. if (CurLen > MaxLen)
  2887. {
  2888. SafeMemFree(szMaxName);
  2889. MaxLen = CurLen;
  2890. szMaxName = pvarResult.pszVal;
  2891. }
  2892. else
  2893. {
  2894. MemFree(pvarResult.pszVal);
  2895. }
  2896. pRuleInfo[cRules].pIRule->Release();
  2897. }while (cRules > 0);
  2898. //Adjust the width of the combo box to fit the widest string
  2899. FixComboBox(szMaxName);
  2900. MemFree(pRuleInfo);
  2901. }
  2902. }
  2903. BOOL LoadToolNames(const UINT *rgIds, const UINT cIds, TCHAR *szTools)
  2904. {
  2905. for (UINT i = 0; i < cIds; i++)
  2906. {
  2907. LoadString(g_hLocRes, rgIds[i], szTools, MAX_TB_TEXT_LENGTH);
  2908. szTools += lstrlen(szTools) + 1;
  2909. }
  2910. *szTools = TEXT('\0');
  2911. return(TRUE);
  2912. }
  2913. UINT GetCurColorRes(void)
  2914. {
  2915. HDC hdc;
  2916. UINT uColorRes;
  2917. hdc = GetDC(NULL);
  2918. uColorRes = GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL);
  2919. ReleaseDC(NULL, hdc);
  2920. return uColorRes;
  2921. }
  2922. BOOL CBands::_SetImages(HWND hwndToolbar, const int *pImageIdList)
  2923. {
  2924. TCHAR szValue[32];
  2925. DWORD cbValue = sizeof(szValue);
  2926. DWORD dw;
  2927. DWORD dwType;
  2928. DWORD idImages;
  2929. DWORD cx = (fIsWhistler() ? TB_BMP_CX : TB_BMP_CX_W2K);
  2930. if (m_dwIconSize == SMALL_ICONS)
  2931. {
  2932. idImages = pImageIdList[IMAGELIST_TYPE_SMALL];
  2933. cx = TB_SMBMP_CX;
  2934. }
  2935. // If the user is running with greater than 256 colors, give them the spiffy
  2936. // image list.
  2937. else if (GetCurColorRes() >= 8)
  2938. idImages = pImageIdList[IMAGELIST_TYPE_HI];
  2939. // Otherwise, give 'em the default.
  2940. else
  2941. idImages = pImageIdList[IMAGELIST_TYPE_LO];
  2942. CleanupImages(hwndToolbar);
  2943. // Load the new lists
  2944. HIMAGELIST himl;
  2945. himl = LoadMappedToolbarBitmap(g_hLocRes, idImages, cx);
  2946. if (himl)
  2947. SendMessage(hwndToolbar, TB_SETIMAGELIST, 0, (LPARAM) himl);
  2948. himl = LoadMappedToolbarBitmap(g_hLocRes, idImages+1, cx);
  2949. if (himl)
  2950. SendMessage(hwndToolbar, TB_SETHOTIMAGELIST, 0, (LPARAM) himl);
  2951. // Tell the toolbar the size of each bitmap
  2952. if (m_dwIconSize == SMALL_ICONS)
  2953. SendMessage(hwndToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(TB_SMBMP_CX, TB_SMBMP_CY));
  2954. else
  2955. SendMessage(hwndToolbar, TB_SETBITMAPSIZE, 0, MAKELONG((fIsWhistler() ? TB_BMP_CX : TB_BMP_CX_W2K), TB_BMP_CY));
  2956. return (TRUE);
  2957. }
  2958. BOOL CBands::_InitToolbar(HWND hwndToolbar)
  2959. {
  2960. // Tell the toolbar some basic information
  2961. SendMessage(hwndToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
  2962. SendMessage(m_hwndTools, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DRAWDDARROWS | TBSTYLE_EX_HIDECLIPPEDBUTTONS);
  2963. if (_GetTextState() == TBSTATE_PARTIALTEXT)
  2964. {
  2965. DWORD dwStyle = GetWindowLong(m_hwndTools, GWL_STYLE);
  2966. SetWindowLong(m_hwndTools, GWL_STYLE, dwStyle | TBSTYLE_LIST);
  2967. SendMessage(m_hwndTools, TB_SETEXTENDEDSTYLE, TBSTYLE_EX_MIXEDBUTTONS, TBSTYLE_EX_MIXEDBUTTONS);
  2968. }
  2969. // Tell the toolbar the number of rows of text and button width based
  2970. // on whether or not we're showing text below the buttons or not.
  2971. if (_GetTextState() == TBSTATE_NOTEXT)
  2972. {
  2973. SendMessage(hwndToolbar, TB_SETMAXTEXTROWS, 0, 0);
  2974. SendMessage(hwndToolbar, TB_SETBUTTONWIDTH, 0, MAKELONG(0, MAX_TB_COMPRESSED_WIDTH));
  2975. }
  2976. else
  2977. {
  2978. SendMessage(hwndToolbar, TB_SETMAXTEXTROWS, MAX_TB_TEXT_ROWS_HORZ, 0);
  2979. SendMessage(hwndToolbar, TB_SETBUTTONWIDTH, 0, MAKELONG(0, m_cxMaxButtonWidth));
  2980. }
  2981. // Now load the buttons into the toolbar
  2982. _SetImages(hwndToolbar, (fIsWhistler() ?
  2983. ((GetCurColorRes() > 24) ? c_32ImageListStruct[m_dwParentType].ImageListTable : c_ImageListStruct[m_dwParentType].ImageListTable)
  2984. : c_NWImageListStruct[m_dwParentType].ImageListTable ));
  2985. _LoadStrings(hwndToolbar, (TOOLBAR_INFO *) m_pTBInfo);
  2986. _LoadDefaultButtons(hwndToolbar, (TOOLBAR_INFO *) m_pTBInfo);
  2987. return (TRUE);
  2988. }
  2989. void CBands::_LoadStrings(HWND hwndToolbar, TOOLBAR_INFO *pti)
  2990. {
  2991. BUTTON_INFO *pInfo;
  2992. LPTSTR psz = 0;
  2993. LPTSTR pszT;
  2994. // Allocate an array big enough for all the strings
  2995. if (MemAlloc((LPVOID *) &psz, MAX_TB_TEXT_LENGTH * pti->cAllButtons))
  2996. {
  2997. ZeroMemory(psz, MAX_TB_TEXT_LENGTH * pti->cAllButtons);
  2998. pszT = psz;
  2999. // Zoom through the array adding each string in turn
  3000. pInfo = (BUTTON_INFO *) &(pti->rgAllButtons[0]);
  3001. for (UINT i = 0; i < pti->cAllButtons; i++, pInfo++)
  3002. {
  3003. if ((_GetTextState() == TBSTATE_PARTIALTEXT) && (pInfo->idCmd == ID_SEND_RECEIVE))
  3004. {
  3005. AthLoadString(idsSendReceive, pszT, MAX_TB_TEXT_LENGTH);
  3006. }
  3007. else
  3008. AthLoadString(pInfo->idsButton, pszT, MAX_TB_TEXT_LENGTH);
  3009. pszT += lstrlen(pszT) + 1;
  3010. }
  3011. // Must double-NULL terminate
  3012. *pszT = 0;
  3013. SendMessage(hwndToolbar, TB_ADDSTRING, NULL, (LPARAM) psz);
  3014. MemFree(psz);
  3015. }
  3016. }
  3017. BOOL CBands::_LoadDefaultButtons(HWND hwndToolbar, TOOLBAR_INFO *pti)
  3018. {
  3019. DWORD *pID;
  3020. TBBUTTON *rgBtn = 0;
  3021. TBBUTTON *pBtn;
  3022. DWORD cBtns = 0;
  3023. UINT i;
  3024. TCHAR sz[32];
  3025. DWORD cDefButtons;
  3026. DWORD *rgDefButtons;
  3027. // Figure out if we're using the intl toolbar defaults or the US
  3028. // toolbar defaults
  3029. AthLoadString(idsUseIntlToolbarDefaults, sz, ARRAYSIZE(sz));
  3030. if (0 != lstrcmpi(sz, "0"))
  3031. {
  3032. cDefButtons = pti->cDefButtonsIntl;
  3033. rgDefButtons = (DWORD *) pti->rgDefButtonsIntl;
  3034. }
  3035. else
  3036. {
  3037. cDefButtons = pti->cDefButtons;
  3038. rgDefButtons = (DWORD *) pti->rgDefButtons;
  3039. }
  3040. // Allocate an array big enough for all the strings
  3041. if (MemAlloc((LPVOID *) &rgBtn, sizeof(TBBUTTON) * cDefButtons))
  3042. {
  3043. ZeroMemory(rgBtn, sizeof(TBBUTTON) * cDefButtons);
  3044. pBtn = rgBtn;
  3045. // Zoom through the array adding each string in turn
  3046. pBtn = rgBtn;
  3047. for (i = 0, pID = (DWORD *) rgDefButtons;
  3048. i < cDefButtons;
  3049. i++, pID++, pBtn++)
  3050. {
  3051. if (_ButtonInfoFromID(*pID, pBtn, pti))
  3052. cBtns++;
  3053. }
  3054. SendMessage(hwndToolbar, TB_ADDBUTTONS, cBtns, (LPARAM) rgBtn);
  3055. MemFree(rgBtn);
  3056. }
  3057. return (TRUE);
  3058. }
  3059. BOOL CBands::_ButtonInfoFromID(DWORD id, TBBUTTON *pButton, TOOLBAR_INFO *pti)
  3060. {
  3061. BUTTON_INFO *pInfo;
  3062. UINT i;
  3063. // Validate
  3064. if (!pButton)
  3065. return FALSE;
  3066. // Special case any seperators
  3067. if (id == -1)
  3068. {
  3069. pButton->iBitmap = 0;
  3070. pButton->idCommand = 0;
  3071. pButton->fsState = TBSTATE_ENABLED;
  3072. pButton->fsStyle = TBSTYLE_SEP;
  3073. pButton->dwData = 0;
  3074. pButton->iString = 0;
  3075. return (TRUE);
  3076. }
  3077. // Zoom through the array looking for this id
  3078. for (i = 0, pInfo = (BUTTON_INFO *) pti->rgAllButtons; i < pti->cAllButtons; i++, pInfo++)
  3079. {
  3080. // Check to see if we found a match
  3081. if (id == pInfo->idCmd)
  3082. {
  3083. pButton->iBitmap = pInfo->iImage;
  3084. pButton->idCommand = pInfo->idCmd;
  3085. pButton->fsState = TBSTATE_ENABLED;
  3086. pButton->fsStyle = pInfo->fStyle;
  3087. pButton->dwData = 0;
  3088. pButton->iString = i;
  3089. return (TRUE);
  3090. }
  3091. }
  3092. return (FALSE);
  3093. }
  3094. inline DWORD CBands::_GetTextState()
  3095. {
  3096. return m_dwToolbarTextState;
  3097. }
  3098. void CBands::SetTextState(DWORD dw)
  3099. {
  3100. switch (dw)
  3101. {
  3102. case TBSTATE_PARTIALTEXT:
  3103. m_dwPrevTextStyle = TBSTATE_PARTIALTEXT;
  3104. break;
  3105. case TBSTATE_FULLTEXT:
  3106. m_dwPrevTextStyle = TBSTATE_FULLTEXT;
  3107. break;
  3108. }
  3109. m_dwToolbarTextState = dw;
  3110. if (m_pTextStyleNotify)
  3111. {
  3112. m_pTextStyleNotify->Lock(m_hwndSizer);
  3113. m_pTextStyleNotify->DoNotification(WM_OE_TOOLBAR_STYLE, (WPARAM)dw, 0, SNF_POSTMSG);
  3114. m_pTextStyleNotify->Unlock();
  3115. }
  3116. if ((dw == TBSTATE_PARTIALTEXT) || (dw == TBSTATE_FULLTEXT))
  3117. AthUserSetValue(NULL, c_szRegPrevToolbarText, REG_DWORD, (LPBYTE)&m_dwPrevTextStyle, sizeof(DWORD));
  3118. }