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.

1960 lines
53 KiB

  1. //
  2. // bbar.cpp
  3. //
  4. // Implementation of CBBar
  5. // Drop down connection status + utility bar
  6. //
  7. // Copyright(C) Microsoft Corporation 2000
  8. // Author: Nadim Abdo (nadima)
  9. //
  10. //
  11. #include "adcg.h"
  12. #ifdef USE_BBAR
  13. #define TRC_GROUP TRC_GROUP_UI
  14. #define TRC_FILE "bbar"
  15. #include <atrcapi.h>
  16. #include "bbar.h"
  17. #include "commctrl.h"
  18. #ifndef OS_WINCE
  19. #define BBAR_CLASSNAME _TEXT("BBARCLASS")
  20. #else
  21. #define BBAR_CLASSNAME _T("BBARCLASS")
  22. #endif
  23. #define IDM_MINIMIZE 101
  24. #define IDM_RESTORE 102
  25. #define IDM_CLOSE 103
  26. #define IDM_PIN 104
  27. //
  28. // BBar is 50% of parent's width
  29. //
  30. #define BBAR_PERCENT_WIDTH 50
  31. #define BBAR_NUM_BUTTONS 3
  32. #define BBAR_BUTTON_WIDTH 12
  33. #define BBAR_BUTTON_HEIGHT 11
  34. #define BBAR_BUTTON_SPACE 3
  35. #define BBAR_MIN_HEIGHT 16
  36. //
  37. // Two pixels of vertical space are
  38. // unavailable (due to lines at bottom)
  39. //
  40. #define BBAR_VERT_SPACE_NO_USE 3
  41. #define COLOR_BLACK RGB(0,0,0)
  42. #define COLOR_DKGREY RGB(128,128,128)
  43. #ifndef OS_WINCE
  44. #define BBAR_TIMERID_ANIM 0
  45. #else
  46. #define BBAR_TIMERID_ANIM (WM_USER + 1001)
  47. #endif
  48. #define BBAR_TIMERID_AUTOHIDE 1
  49. //
  50. // Total animation period for animation (E.g lower)
  51. // in milliseconds
  52. //
  53. #define BBAR_ANIM_TIME 300
  54. #define BBAR_AUTOHIDE_TIME 1400
  55. #define BBAR_FIRST_AUTOHIDE_TIME 5000
  56. CBBar::CBBar(HWND hwndParent, HINSTANCE hInstance, CUI* pUi,
  57. BOOL fBBarEnabled)
  58. {
  59. DC_BEGIN_FN("CBBar");
  60. _hwndBBar = NULL;
  61. _hwndParent = hwndParent;
  62. _hInstance = hInstance;
  63. _state = bbarNotInit;
  64. _pUi = pUi;
  65. _fBlockZOrderChanges = FALSE;
  66. _nBBarVertOffset = 0;
  67. _ptLastAutoHideMousePos.x = -0x0FF;
  68. _ptLastAutoHideMousePos.y = -0x0FF;
  69. _nBBarAutoHideTime = 0;
  70. _hwndPinBar = NULL;
  71. _hwndWinControlsBar = NULL;
  72. _fPinned = FALSE;
  73. _nPinUpImage = 0;
  74. _nPinDownImage = 0;
  75. _hbmpLeftImage = NULL;
  76. _hbmpRightImage = NULL;
  77. _fBBarEnabled = fBBarEnabled;
  78. _fLocked = FALSE;
  79. _fShowMinimize = TRUE;
  80. _fShowRestore = TRUE;
  81. SetDisplayedText(_T(""));
  82. DC_END_FN();
  83. }
  84. CBBar::~CBBar()
  85. {
  86. }
  87. BOOL CBBar::StartupBBar(int desktopX, int desktopY, BOOL fStartRaised)
  88. {
  89. BOOL bRet = FALSE;
  90. DC_BEGIN_FN("StartupBBar");
  91. if(bbarNotInit == _state)
  92. {
  93. // First drop interval is long
  94. _nBBarAutoHideTime = BBAR_FIRST_AUTOHIDE_TIME;
  95. bRet = Initialize( desktopX, desktopY, fStartRaised );
  96. if(!bRet)
  97. {
  98. return FALSE;
  99. }
  100. }
  101. else
  102. {
  103. // First drop interval is long
  104. _nBBarAutoHideTime = BBAR_AUTOHIDE_TIME;
  105. //re-init existing bbar
  106. BringWindowToTop( _hwndBBar );
  107. ShowWindow( _hwndBBar, SW_SHOWNOACTIVATE);
  108. //
  109. // Bring the window to the TOP of the Z order
  110. //
  111. SetWindowPos( _hwndBBar,
  112. HWND_TOPMOST,
  113. 0, 0, 0, 0,
  114. SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE );
  115. bRet = TRUE;
  116. }
  117. //
  118. // Note: The bbar is used as a security feature so we do the initial
  119. // drop even if the bbar feature is not enabled. It's only subsequent
  120. // drops (e.g. on the timer) that are disabled if bbar is OFF
  121. //
  122. if(_pUi->UI_IsFullScreen())
  123. {
  124. //First autohide interval is long
  125. //to make sure user gets to notice the bbar
  126. StartLowerBBar();
  127. }
  128. DC_END_FN();
  129. return bRet;
  130. }
  131. //
  132. // Destroy the window and reset bbar state
  133. // for another session
  134. //
  135. BOOL CBBar::KillAndCleanupBBar()
  136. {
  137. BOOL fRet = TRUE;
  138. DC_BEGIN_FN("KillAndCleanupBBar");
  139. if(_state != bbarNotInit)
  140. {
  141. TRC_NRM((TB,_T("Cleaning up the bbar")));
  142. if(_hwndBBar)
  143. {
  144. if(::DestroyWindow( _hwndBBar ))
  145. {
  146. _state = bbarNotInit;
  147. _hwndBBar = NULL;
  148. _fBlockZOrderChanges = FALSE;
  149. if(!UnregisterClass( BBAR_CLASSNAME, _hInstance ))
  150. {
  151. TRC_ERR((TB,_T("UnregisterClass bbar class failed 0x%x"),
  152. GetLastError()));
  153. }
  154. }
  155. else
  156. {
  157. TRC_ERR((TB,_T("DestroyWindow bbar failed 0x%x"),
  158. GetLastError()));
  159. fRet = FALSE;
  160. }
  161. if (_hbmpLeftImage)
  162. {
  163. DeleteObject(_hbmpLeftImage);
  164. _hbmpLeftImage = NULL;
  165. }
  166. if (_hbmpRightImage)
  167. {
  168. DeleteObject(_hbmpRightImage);
  169. _hbmpRightImage = NULL;
  170. }
  171. }
  172. }
  173. DC_END_FN();
  174. return fRet;
  175. }
  176. BOOL CBBar::StartLowerBBar()
  177. {
  178. INT parentWidth = 0;
  179. RECT rc;
  180. DC_BEGIN_FN("StartLowerBBar");
  181. if(_state == bbarRaised)
  182. {
  183. //
  184. // Kick off a timer to lower the bar
  185. //
  186. TRC_ASSERT(0 == _nBBarVertOffset,
  187. (TB,_T("_nBBarVertOffset (%d) should be 0"),
  188. _nBBarVertOffset));
  189. TRC_ASSERT(_hwndBBar,
  190. (TB,_T("_hwndBBar is NULL")));
  191. //
  192. // Set the last cursor pos at the time
  193. // the bbar is lowered to prevent it from being
  194. // autohidden if the mouse doesn't move
  195. //
  196. GetCursorPos(&_ptLastAutoHideMousePos);
  197. //
  198. // Main window size could have changed
  199. // so make sure the bbar is centered
  200. // before lowering it.
  201. // (keep constant bbar width)
  202. if(_pUi->_UI.hwndMain)
  203. {
  204. GetClientRect(_pUi->_UI.hwndMain, &rc);
  205. parentWidth = rc.right - rc.left;
  206. if(!parentWidth)
  207. {
  208. return FALSE;
  209. }
  210. _rcBBarLoweredAspect.left = parentWidth / 2 - _sizeLoweredBBar.cx / 2;
  211. _rcBBarLoweredAspect.right = parentWidth / 2 + _sizeLoweredBBar.cx / 2;
  212. #ifdef DISABLE_SHADOW_IN_FULLSCREEN
  213. _pUi->UI_OnNotifyBBarRectChange(&_rcBBarLoweredAspect);
  214. _pUi->UI_OnNotifyBBarVisibleChange(1);
  215. #endif
  216. }
  217. #ifndef OS_WINCE
  218. if(!SetTimer( _hwndBBar, BBAR_TIMERID_ANIM,
  219. BBAR_ANIM_TIME / _sizeLoweredBBar.cy,
  220. NULL ))
  221. {
  222. TRC_ERR((TB,_T("SetTimer failed - 0x%x"),
  223. GetLastError()));
  224. return FALSE;
  225. }
  226. _state = bbarLowering;
  227. #else
  228. ImmediateLowerBBar();
  229. #endif
  230. return TRUE;
  231. }
  232. else
  233. {
  234. TRC_NRM((TB,_T("StartLowerBBar called when bar in wrong state 0x%x"),
  235. _state));
  236. return FALSE;
  237. }
  238. DC_END_FN();
  239. }
  240. BOOL CBBar::StartRaiseBBar()
  241. {
  242. DC_BEGIN_FN("StartRaiseBBar");
  243. if(_state == bbarLowered && !_fPinned && !_fLocked)
  244. {
  245. //
  246. // Kick off a timer to lower the bar
  247. //
  248. TRC_ASSERT(_sizeLoweredBBar.cy == _nBBarVertOffset,
  249. (TB,_T("_nBBarVertOffset (%d) should be %d"),
  250. _nBBarVertOffset,
  251. _sizeLoweredBBar.cy));
  252. TRC_ASSERT(_hwndBBar,
  253. (TB,_T("_hwndBBar is NULL")));
  254. #ifndef OS_WINCE
  255. if(!SetTimer( _hwndBBar, BBAR_TIMERID_ANIM,
  256. BBAR_ANIM_TIME / _sizeLoweredBBar.cy,
  257. NULL ))
  258. {
  259. TRC_ERR((TB,_T("SetTimer failed - 0x%x"),
  260. GetLastError()));
  261. return FALSE;
  262. }
  263. _state = bbarRaising;
  264. #else
  265. ImmediateRaiseBBar();
  266. #endif
  267. return TRUE;
  268. }
  269. else
  270. {
  271. TRC_NRM((TB,_T("StartRaiseBBar called when bar in wrong state 0x%x"),
  272. _state));
  273. return FALSE;
  274. }
  275. DC_END_FN();
  276. return TRUE;
  277. }
  278. BOOL CBBar::Initialize(int desktopX, int desktopY, BOOL fStartRaised)
  279. {
  280. #ifndef OS_WINCE
  281. RECT rc;
  282. #endif
  283. HWND hwndBBar;
  284. int parentWidth = desktopX;
  285. int bbarHeight = 0;
  286. int bbarWidth = 0;
  287. DC_BEGIN_FN("Initialize");
  288. TRC_ASSERT( bbarNotInit == _state,
  289. (TB,_T("bbar already initialized - state:0x%x"),
  290. _state));
  291. //
  292. // Compute BBAR position based on remote desktop size
  293. //
  294. #ifndef OS_WINCE
  295. bbarHeight = GetSystemMetrics( SM_CYMENUSIZE ) + 2;
  296. #else
  297. bbarHeight = GetSystemMetrics( SM_CYMENU ) + 2;
  298. #endif
  299. bbarHeight = max(bbarHeight, BBAR_MIN_HEIGHT);
  300. _rcBBarLoweredAspect.bottom = bbarHeight;
  301. _rcBBarLoweredAspect.left = (LONG)( (100 - BBAR_PERCENT_WIDTH) / 200.0 *
  302. parentWidth );
  303. _rcBBarLoweredAspect.right = parentWidth - _rcBBarLoweredAspect.left;
  304. _rcBBarLoweredAspect.top = 0;
  305. bbarWidth = _rcBBarLoweredAspect.right - _rcBBarLoweredAspect.left;
  306. _sizeLoweredBBar.cx = bbarWidth;
  307. _sizeLoweredBBar.cy = bbarHeight;
  308. hwndBBar = CreateWnd( _hInstance, _hwndParent,
  309. &_rcBBarLoweredAspect );
  310. if(hwndBBar)
  311. {
  312. if( fStartRaised )
  313. {
  314. //
  315. // Move the bar up by it's height to raise it
  316. //
  317. if(SetWindowPos(hwndBBar,
  318. NULL,
  319. _rcBBarLoweredAspect.left, //x
  320. -_sizeLoweredBBar.cy, //y
  321. 0,0,
  322. SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE ))
  323. {
  324. TRC_NRM((TB,_T("BBAR SetWindowPos failed - 0x%x"),
  325. GetLastError()));
  326. }
  327. }
  328. BringWindowToTop( hwndBBar );
  329. ShowWindow( hwndBBar, SW_SHOWNOACTIVATE);
  330. //
  331. // Create the polygon region for the bounds of the BBar window
  332. // This cuts the corners off the edges.
  333. //
  334. POINT pts[4];
  335. int xOffset = parentWidth / 2 - _rcBBarLoweredAspect.left;
  336. pts[3].x = -bbarWidth/2 + xOffset;
  337. pts[3].y = 0;
  338. pts[2].x = bbarWidth/2 + xOffset;
  339. pts[2].y = 0;
  340. pts[1].x = bbarWidth/2 - bbarHeight + xOffset;
  341. pts[1].y = bbarHeight;
  342. pts[0].x = -bbarWidth/2 + bbarHeight + xOffset;
  343. pts[0].y = bbarHeight;
  344. #ifndef OS_WINCE
  345. //
  346. // Polygon does not self intersect so winding mode is not
  347. // relevant
  348. //
  349. HRGN hRgn = CreatePolygonRgn( pts,
  350. 4,
  351. ALTERNATE );
  352. #else
  353. HRGN hRgn = GetBBarRgn(pts);
  354. #endif
  355. if(hRgn)
  356. {
  357. if(!SetWindowRgn( hwndBBar, hRgn, TRUE))
  358. {
  359. TRC_ERR((TB,_T("SetWindowRgn failed - 0x%x"),
  360. GetLastError()));
  361. //
  362. // In the success case the system will free
  363. // the region handle when it is done with it.
  364. // Here however, the call failed...
  365. //
  366. DeleteObject( hRgn );
  367. }
  368. }
  369. else
  370. {
  371. //
  372. // Not fatal, continue
  373. //
  374. TRC_ERR((TB,_T("CreatePolygonRgn failed - 0x%x"),
  375. GetLastError()));
  376. }
  377. //
  378. // Bring the window to the TOP of the Z order
  379. //
  380. if(!SetWindowPos( hwndBBar,
  381. HWND_TOPMOST,
  382. 0, 0, 0, 0,
  383. SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE ))
  384. {
  385. TRC_ERR((TB,_T("SetWindowPos failed - 0x%x"),
  386. GetLastError()));
  387. return FALSE;
  388. }
  389. //
  390. // Compute the rectangle for displayed text
  391. //
  392. // First figure out how much space to trim in the
  393. // x direction
  394. //
  395. int xDelta = _sizeLoweredBBar.cy * 2 + //diagonal corners
  396. BBAR_NUM_BUTTONS *
  397. (BBAR_BUTTON_WIDTH + BBAR_BUTTON_SPACE); //button space
  398. GetClientRect( hwndBBar, &_rcBBarDisplayTextArea);
  399. if(!InflateRect( &_rcBBarDisplayTextArea,
  400. -xDelta,
  401. 0 ))
  402. {
  403. TRC_ABORT((TB,_T("InflateRect failed 0x%x"),
  404. GetLastError()));
  405. return FALSE;
  406. }
  407. // Shave off from the bottom
  408. _rcBBarDisplayTextArea.bottom -= 1;
  409. if (!CreateToolbars())
  410. {
  411. TRC_ERR((TB,_T("CreateToolbars failed")));
  412. return FALSE;
  413. }
  414. //
  415. // Trigger a repaint of the background
  416. //
  417. InvalidateRect( hwndBBar, NULL, TRUE);
  418. }
  419. else
  420. {
  421. TRC_ERR((TB,_T("CreateWnd for BBar failed")));
  422. return FALSE;
  423. }
  424. if( fStartRaised )
  425. {
  426. SetState( bbarRaised );
  427. _nBBarVertOffset = 0;
  428. }
  429. else
  430. {
  431. SetState( bbarLowered );
  432. _nBBarVertOffset = _sizeLoweredBBar.cy;
  433. }
  434. DC_END_FN();
  435. return TRUE;
  436. }
  437. //
  438. // DIBs use RGBQUAD format:
  439. // 0xbb 0xgg 0xrr 0x00
  440. //
  441. // Reasonably efficient code to convert a COLORREF into an
  442. // RGBQUAD.
  443. //
  444. #define RGB_TO_RGBQUAD(r,g,b) (RGB(b,g,r))
  445. #define CLR_TO_RGBQUAD(clr) (RGB(GetBValue(clr), GetGValue(clr), GetRValue(clr)))
  446. //
  447. // Internal helper that loads a bitmap and remaps it's colors
  448. // to the system colors. Use this instead of LoadImage with the
  449. // LR_LOADMAP3DCOLORS flag because that fn doesn't work well on NT4.
  450. //
  451. HBITMAP _LoadSysColorBitmap(HINSTANCE hInst, HRSRC hRsrc, BOOL bMono)
  452. {
  453. struct COLORMAP
  454. {
  455. // use DWORD instead of RGBQUAD so we can compare two RGBQUADs easily
  456. DWORD rgbqFrom;
  457. int iSysColorTo;
  458. };
  459. static const COLORMAP sysColorMap[] =
  460. {
  461. // mapping from color in DIB to system color
  462. { RGB_TO_RGBQUAD(0x00, 0x00, 0x00), COLOR_BTNTEXT }, // black
  463. { RGB_TO_RGBQUAD(0x80, 0x80, 0x80), COLOR_BTNSHADOW }, // dark grey
  464. { RGB_TO_RGBQUAD(0xC0, 0xC0, 0xC0), COLOR_BTNFACE }, // bright grey
  465. { RGB_TO_RGBQUAD(0xFF, 0xFF, 0xFF), COLOR_BTNHIGHLIGHT } // white
  466. };
  467. const int nMaps = 4;
  468. HGLOBAL hglb;
  469. if ((hglb = LoadResource(hInst, hRsrc)) == NULL)
  470. return NULL;
  471. LPBITMAPINFOHEADER lpBitmap = (LPBITMAPINFOHEADER)LockResource(hglb);
  472. if (lpBitmap == NULL)
  473. return NULL;
  474. // make copy of BITMAPINFOHEADER so we can modify the color table
  475. const int nColorTableSize = 16;
  476. UINT nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
  477. LPBITMAPINFOHEADER lpBitmapInfo = (LPBITMAPINFOHEADER)
  478. LocalAlloc(LPTR, nSize);
  479. if (lpBitmapInfo == NULL)
  480. return NULL;
  481. memcpy(lpBitmapInfo, lpBitmap, nSize);
  482. // color table is in RGBQUAD DIB format
  483. DWORD* pColorTable =
  484. (DWORD*)(((LPBYTE)lpBitmapInfo) + (UINT)lpBitmapInfo->biSize);
  485. for (int iColor = 0; iColor < nColorTableSize; iColor++)
  486. {
  487. // look for matching RGBQUAD color in original
  488. for (int i = 0; i < nMaps; i++)
  489. {
  490. if (pColorTable[iColor] == sysColorMap[i].rgbqFrom)
  491. {
  492. if (bMono)
  493. {
  494. // all colors except text become white
  495. if (sysColorMap[i].iSysColorTo != COLOR_BTNTEXT)
  496. pColorTable[iColor] = RGB_TO_RGBQUAD(255, 255, 255);
  497. }
  498. else
  499. pColorTable[iColor] =
  500. CLR_TO_RGBQUAD(
  501. GetSysColor(sysColorMap[i].iSysColorTo));
  502. break;
  503. }
  504. }
  505. }
  506. int nWidth = (int)lpBitmapInfo->biWidth;
  507. int nHeight = (int)lpBitmapInfo->biHeight;
  508. HDC hDCScreen = GetDC(NULL);
  509. HBITMAP hbm = CreateCompatibleBitmap(hDCScreen, nWidth, nHeight);
  510. if (hbm != NULL)
  511. {
  512. HDC hDCGlyphs = CreateCompatibleDC(hDCScreen);
  513. HBITMAP hbmOld = (HBITMAP)SelectObject(hDCGlyphs, hbm);
  514. LPBYTE lpBits;
  515. lpBits = (LPBYTE)(lpBitmap + 1);
  516. lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
  517. StretchDIBits(hDCGlyphs, 0, 0, nWidth,
  518. nHeight, 0, 0, nWidth, nHeight,
  519. lpBits, (LPBITMAPINFO)lpBitmapInfo,
  520. DIB_RGB_COLORS, SRCCOPY);
  521. SelectObject(hDCGlyphs, hbmOld);
  522. DeleteDC(hDCGlyphs);
  523. }
  524. ReleaseDC(NULL, hDCScreen);
  525. // free copy of bitmap info struct and resource itself
  526. LocalFree(lpBitmapInfo);
  527. #ifndef OS_WINCE
  528. FreeResource(hglb);
  529. #endif
  530. return hbm;
  531. }
  532. BOOL CBBar::CreateToolbars()
  533. {
  534. DC_BEGIN_FN("CreateToolbars");
  535. //
  536. // Create toolbars
  537. //
  538. INT ret = 0;
  539. UINT imgIdx = 0;
  540. INITCOMMONCONTROLSEX icex;
  541. icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
  542. icex.dwICC = ICC_BAR_CLASSES;
  543. if(!InitCommonControlsEx( &icex ))
  544. {
  545. TRC_ERR((TB,_T("InitCommonControlsEx failed 0x%x"),
  546. GetLastError()));
  547. return FALSE;
  548. }
  549. //
  550. // Right bar (close window,disconnect etc)
  551. //
  552. {
  553. TBBUTTON tbButtons [] = {
  554. {0, IDM_MINIMIZE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  555. #ifndef OS_WINCE
  556. {0, IDM_RESTORE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
  557. #endif
  558. {0, IDM_CLOSE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}
  559. };
  560. TBBUTTON tbRealButtons[3];
  561. HWND hwndRightToolbar = CreateToolbarEx( GetHwnd(),
  562. WS_CHILD | WS_VISIBLE |
  563. TBSTYLE_FLAT |
  564. CCS_NODIVIDER | CCS_NORESIZE,
  565. IDB_BBAR_TOOLBAR_RIGHT,
  566. 0,
  567. _hInstance,
  568. 0,
  569. NULL,
  570. 0,
  571. 12,
  572. 12,
  573. 16,
  574. 16,
  575. sizeof(TBBUTTON) );
  576. if(!hwndRightToolbar)
  577. {
  578. TRC_ERR((TB,_T("CreateToolbarEx failed 0x%x"),
  579. GetLastError()));
  580. return FALSE;
  581. }
  582. //
  583. // Add images
  584. //
  585. if (!AddReplaceImage(hwndRightToolbar,
  586. IDB_BBAR_TOOLBAR_RIGHT,
  587. #ifndef OS_WINCE
  588. 3, //image makes up 3 buttons
  589. #else
  590. 2, //2 buttons on CE
  591. #endif
  592. &_hbmpRightImage,
  593. &imgIdx))
  594. {
  595. TRC_ERR((TB,_T("AddReplaceImage for rt toolbar failed")));
  596. return FALSE;
  597. }
  598. //
  599. // Associate images with buttons
  600. //
  601. tbButtons[0].iBitmap = imgIdx;
  602. tbButtons[1].iBitmap = imgIdx + 1;
  603. #ifndef OS_WINCE
  604. tbButtons[2].iBitmap = imgIdx + 2;
  605. #endif
  606. //
  607. // Not all buttons are to be added, figure out which here
  608. // and setup the real buttons array
  609. //
  610. ULONG nNumButtons = 0;
  611. if (_fShowMinimize) {
  612. tbRealButtons[nNumButtons++] = tbButtons[0];
  613. }
  614. if (_fShowRestore) {
  615. tbRealButtons[nNumButtons++] = tbButtons[1];
  616. }
  617. // Always show the close button
  618. #ifndef OS_WINCE
  619. tbRealButtons[nNumButtons++] = tbButtons[2];
  620. #endif
  621. //
  622. // Add the buttons
  623. //
  624. ret = SendMessage( hwndRightToolbar,
  625. TB_ADDBUTTONS,
  626. nNumButtons,
  627. (LPARAM)(LPTBBUTTON) &tbRealButtons );
  628. if(-1 == ret)
  629. {
  630. TRC_ERR((TB,_T("TB_ADDBUTTONS failed")));
  631. return FALSE;
  632. }
  633. //
  634. // Move the toolbar
  635. //
  636. if(!MoveWindow( hwndRightToolbar,
  637. _sizeLoweredBBar.cx - _sizeLoweredBBar.cy -
  638. ((BBAR_BUTTON_SPACE + BBAR_BUTTON_WIDTH)*(nNumButtons+1)),
  639. 0,
  640. ((BBAR_BUTTON_SPACE + BBAR_BUTTON_WIDTH)*(nNumButtons+1)),
  641. BBAR_BUTTON_HEIGHT*2,
  642. TRUE))
  643. {
  644. TRC_ERR((TB,_T("MoveWindow failed")));
  645. return FALSE;
  646. }
  647. if(!ShowWindow ( hwndRightToolbar,
  648. SW_SHOWNORMAL) )
  649. {
  650. TRC_ERR((TB,_T("ShowWindow failed")));
  651. return FALSE;
  652. }
  653. _hwndWinControlsBar = hwndRightToolbar;
  654. }
  655. //
  656. // Left bar (pin)
  657. //
  658. {
  659. TBBUTTON tbButtons [] = {
  660. {0, IDM_PIN,
  661. TBSTATE_ENABLED | (_fPinned ? TBSTATE_PRESSED : 0),
  662. TBSTYLE_BUTTON, 0L, 0}
  663. };
  664. HWND hwndLeftToolbar = CreateToolbarEx( GetHwnd(),
  665. WS_CHILD | WS_VISIBLE |
  666. TBSTYLE_FLAT |
  667. CCS_NODIVIDER | CCS_NORESIZE,
  668. IDB_BBAR_TOOLBAR_LEFT,
  669. 0,
  670. _hInstance,
  671. 0,
  672. NULL,
  673. 0,
  674. 12,
  675. 12,
  676. 16,
  677. 16,
  678. sizeof(TBBUTTON) );
  679. if(!hwndLeftToolbar)
  680. {
  681. TRC_ERR((TB,_T("CreateToolbarEx failed 0x%x"),
  682. GetLastError()));
  683. return FALSE;
  684. }
  685. //
  686. // Add images
  687. //
  688. if (!AddReplaceImage(hwndLeftToolbar,
  689. IDB_BBAR_TOOLBAR_LEFT,
  690. 2, //image makes up 2 buttons
  691. &_hbmpLeftImage,
  692. &imgIdx))
  693. {
  694. TRC_ERR((TB,_T("AddReplaceImage for lt toolbar failed")));
  695. return FALSE;
  696. }
  697. _nPinUpImage = imgIdx;
  698. _nPinDownImage = imgIdx + 1;
  699. //
  700. // Associate images with buttons
  701. //
  702. tbButtons[0].iBitmap = _fPinned ? _nPinDownImage : _nPinUpImage;
  703. //
  704. // Add the button
  705. //
  706. ret = SendMessage( hwndLeftToolbar,
  707. TB_ADDBUTTONS,
  708. 1,
  709. (LPARAM)(LPTBBUTTON) &tbButtons );
  710. if(-1 == ret)
  711. {
  712. TRC_ERR((TB,_T("TB_ADDBUTTONS failed")));
  713. return FALSE;
  714. }
  715. //
  716. // Move the toolbar
  717. //
  718. if(!MoveWindow( hwndLeftToolbar,
  719. _sizeLoweredBBar.cy + BBAR_BUTTON_SPACE,
  720. 0,
  721. (BBAR_BUTTON_SPACE + BBAR_BUTTON_WIDTH) * 2,
  722. BBAR_BUTTON_HEIGHT*2,
  723. TRUE))
  724. {
  725. TRC_ERR((TB,_T("MoveWindow failed")));
  726. return FALSE;
  727. }
  728. if(!ShowWindow ( hwndLeftToolbar,
  729. SW_SHOWNORMAL) )
  730. {
  731. TRC_ERR((TB,_T("ShowWindow failed")));
  732. return FALSE;
  733. }
  734. _hwndPinBar = hwndLeftToolbar;
  735. }
  736. DC_END_FN();
  737. return TRUE;
  738. }
  739. //
  740. // ReloadImages for the toolbar including
  741. // refreshing the colors
  742. //
  743. BOOL CBBar::ReloadImages()
  744. {
  745. BOOL rc = FALSE;
  746. #ifndef OS_WINCE
  747. INT ret;
  748. #endif
  749. DC_BEGIN_FN("ReloadImages");
  750. if (!_hwndWinControlsBar || !_hwndPinBar)
  751. {
  752. TRC_ERR((TB,_T("Toolbars not initialized")));
  753. DC_QUIT;
  754. }
  755. //
  756. // Replace images
  757. //
  758. if (!AddReplaceImage(_hwndWinControlsBar,
  759. IDB_BBAR_TOOLBAR_RIGHT,
  760. 3, //image makes up 3 buttons
  761. &_hbmpRightImage,
  762. NULL))
  763. {
  764. TRC_ERR((TB,_T("AddReplaceImage for rt toolbar failed")));
  765. return FALSE;
  766. }
  767. if (!AddReplaceImage(_hwndPinBar,
  768. IDB_BBAR_TOOLBAR_LEFT,
  769. 2, //image makes up 3 buttons
  770. &_hbmpLeftImage,
  771. NULL))
  772. {
  773. TRC_ERR((TB,_T("AddReplaceImage for lt toolbar failed")));
  774. return FALSE;
  775. }
  776. DC_EXIT_POINT:
  777. DC_END_FN();
  778. return rc;
  779. }
  780. //
  781. // Adds or replaces an image to a toolbar
  782. // Params:
  783. // hwndToolbar - toolbar to act on
  784. // rsrcId - resource ID of the bitmap
  785. // nCells - number of image cells
  786. // phbmpOldImage - [IN/OUT] handle to previous image, on return is
  787. // set to current image
  788. // pImgIndex - [OUT] index to the first image added
  789. //
  790. BOOL CBBar::AddReplaceImage(HWND hwndToolbar,
  791. UINT rsrcId,
  792. UINT nCells,
  793. HBITMAP* phbmpOldImage,
  794. PUINT pImgIndex)
  795. {
  796. BOOL rc = FALSE;
  797. INT ret = 0;
  798. HBITMAP hbmpNew = NULL;
  799. HRSRC hBmpRsrc = NULL;
  800. DC_BEGIN_FN("AddReplaceImage");
  801. //
  802. // Replace images
  803. //
  804. hBmpRsrc = FindResource(_hInstance,
  805. MAKEINTRESOURCE(rsrcId),
  806. RT_BITMAP);
  807. if (hBmpRsrc)
  808. {
  809. hbmpNew = _LoadSysColorBitmap(_hInstance, hBmpRsrc, FALSE);
  810. if (hbmpNew)
  811. {
  812. if (NULL == *phbmpOldImage)
  813. {
  814. TBADDBITMAP tbAddBitmap;
  815. tbAddBitmap.hInst = NULL;
  816. tbAddBitmap.nID = (UINT_PTR)hbmpNew;
  817. ret = SendMessage( hwndToolbar,
  818. TB_ADDBITMAP,
  819. nCells,
  820. (LPARAM)(LPTBADDBITMAP)&tbAddBitmap );
  821. }
  822. else
  823. {
  824. TBREPLACEBITMAP tbRplBitmap;
  825. tbRplBitmap.hInstOld = NULL;
  826. tbRplBitmap.nIDOld = (UINT_PTR)*phbmpOldImage;
  827. tbRplBitmap.hInstNew = NULL;
  828. tbRplBitmap.nIDNew = (UINT_PTR)hbmpNew;
  829. tbRplBitmap.nButtons = nCells;
  830. ret = SendMessage(hwndToolbar,
  831. TB_REPLACEBITMAP,
  832. 0,
  833. (LPARAM)(LPTBADDBITMAP)&tbRplBitmap);
  834. }
  835. if (-1 != ret)
  836. {
  837. //Delete the old bitmap
  838. if (*phbmpOldImage)
  839. {
  840. DeleteObject(*phbmpOldImage);
  841. }
  842. *phbmpOldImage = hbmpNew;
  843. if (pImgIndex)
  844. {
  845. *pImgIndex = ret;
  846. }
  847. }
  848. else
  849. {
  850. TRC_ERR((TB,_T("TB_ADDBITMAP failed")));
  851. DC_QUIT;
  852. }
  853. }
  854. else
  855. {
  856. TRC_ERR((TB,_T("LoadSysColorBitmap failed rsrcid:%d"), rsrcId));
  857. DC_QUIT;
  858. }
  859. }
  860. else
  861. {
  862. TRC_ERR((TB,_T("Unable to find rsrc: %d"), rsrcId));
  863. DC_QUIT;
  864. }
  865. rc = TRUE;
  866. DC_EXIT_POINT:
  867. DC_END_FN();
  868. return rc;
  869. }
  870. //
  871. // Create the window
  872. // params:
  873. // hInstance - app instance
  874. // _hwndBBarParent - parent window
  875. // szClassName - window class name (will create)
  876. // dwStyle - window style
  877. // returns:
  878. // window handle
  879. //
  880. HWND CBBar::CreateWnd(HINSTANCE hInstance,HWND _hwndBBarParent,
  881. LPRECT lpInitialRect)
  882. {
  883. BOOL rc = FALSE;
  884. #ifndef OS_WINCE
  885. WNDCLASSEX wndclass;
  886. #else
  887. WNDCLASS wndclass;
  888. #endif
  889. WNDCLASS tmpwc;
  890. DC_BEGIN_FN("CreateWnd");
  891. TRC_ASSERT(hInstance, (TB, _T("hInstance is null")));
  892. TRC_ASSERT(lpInitialRect, (TB, _T("lpInitialRect is null")));
  893. if(!hInstance || !lpInitialRect)
  894. {
  895. return NULL;
  896. }
  897. TRC_ASSERT(!_hwndBBar, (TB,_T("Double create window. Could be leaking!!!")));
  898. _hInstance = hInstance;
  899. #ifndef OS_WINCE
  900. wndclass.cbSize = sizeof (wndclass);
  901. #endif
  902. wndclass.style = CS_DBLCLKS;
  903. wndclass.lpfnWndProc = CBBar::StaticBBarWndProc;
  904. wndclass.cbClsExtra = 0;
  905. wndclass.cbWndExtra = 0;
  906. wndclass.hInstance = hInstance;
  907. wndclass.hIcon = NULL;
  908. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  909. wndclass.hbrBackground = (HBRUSH) GetSysColorBrush(COLOR_INFOBK);
  910. wndclass.lpszMenuName = NULL;
  911. wndclass.lpszClassName = BBAR_CLASSNAME;
  912. #ifndef OS_WINCE
  913. wndclass.hIconSm = NULL;
  914. #endif
  915. SetLastError(0);
  916. if(!GetClassInfo( hInstance, BBAR_CLASSNAME, &tmpwc))
  917. {
  918. #ifndef OS_WINCE
  919. if ((0 == RegisterClassEx(&wndclass)) &&
  920. #else
  921. if ((0 == RegisterClass(&wndclass)) &&
  922. #endif
  923. (ERROR_CLASS_ALREADY_EXISTS != GetLastError()))
  924. {
  925. TRC_ERR((TB,_T("RegisterClassEx failed: %d"),GetLastError()));
  926. return NULL;
  927. }
  928. }
  929. _hwndBBar = CreateWindowEx(0,
  930. BBAR_CLASSNAME,
  931. NULL,
  932. WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
  933. lpInitialRect->left,
  934. lpInitialRect->top,
  935. lpInitialRect->right - lpInitialRect->left,
  936. lpInitialRect->bottom - lpInitialRect->top,
  937. _hwndBBarParent,
  938. NULL,
  939. hInstance,
  940. this);
  941. if(_hwndBBar)
  942. {
  943. // put a reference to the current object into the hwnd
  944. // so we can access the object from the WndProc
  945. SetLastError(0);
  946. if(!SetWindowLongPtr(_hwndBBar, GWLP_USERDATA, (LONG_PTR)this))
  947. {
  948. if(GetLastError())
  949. {
  950. TRC_ERR((TB,_T("SetWindowLongPtr failed 0x%x"),
  951. GetLastError()));
  952. return NULL;
  953. }
  954. }
  955. }
  956. else
  957. {
  958. TRC_ERR((TB,_T("CreateWindow failed 0x%x"), GetLastError()));
  959. return NULL;
  960. }
  961. DC_END_FN();
  962. return _hwndBBar;
  963. }
  964. LRESULT CALLBACK CBBar::StaticBBarWndProc(HWND hwnd,
  965. UINT uMsg,
  966. WPARAM wParam,
  967. LPARAM lParam)
  968. {
  969. DC_BEGIN_FN("StatiCBBarProc");
  970. // pull out the pointer to the container object associated with this hwnd
  971. CBBar *pwnd = (CBBar *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  972. if(pwnd)
  973. {
  974. return pwnd->BBarWndProc( hwnd, uMsg, wParam, lParam);
  975. }
  976. else
  977. {
  978. return DefWindowProc (hwnd, uMsg, wParam, lParam);
  979. }
  980. DC_END_FN();
  981. }
  982. LRESULT CALLBACK CBBar::BBarWndProc(HWND hwnd,
  983. UINT uMsg,
  984. WPARAM wParam,
  985. LPARAM lParam)
  986. {
  987. DC_BEGIN_FN("BBarWndProc");
  988. switch (uMsg)
  989. {
  990. case WM_ERASEBKGND:
  991. {
  992. return OnEraseBkgnd(hwnd, uMsg, wParam, lParam);
  993. }
  994. break;
  995. case WM_LBUTTONDBLCLK:
  996. {
  997. OnCmdRestore();
  998. return 0L;
  999. }
  1000. break;
  1001. case WM_PAINT:
  1002. {
  1003. return OnPaint(hwnd, uMsg, wParam, lParam);
  1004. }
  1005. break;
  1006. case WM_SYSCOLORCHANGE:
  1007. {
  1008. InvalidateRect( hwnd, NULL, TRUE);
  1009. return 0L;
  1010. }
  1011. break;
  1012. case WM_TIMER:
  1013. {
  1014. if( BBAR_TIMERID_ANIM == wParam)
  1015. {
  1016. #ifndef OS_WINCE
  1017. if(_state == bbarLowering ||
  1018. _state == bbarRaising)
  1019. {
  1020. BOOL fReachedEndOfAnimation = FALSE;
  1021. int delta = (bbarLowering == _state ) ? 1 : -1;
  1022. _nBBarVertOffset+= delta;
  1023. if(SetWindowPos(_hwndBBar,
  1024. NULL,
  1025. _rcBBarLoweredAspect.left, //x
  1026. _nBBarVertOffset - _sizeLoweredBBar.cy, //y
  1027. 0,0,
  1028. SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE ))
  1029. {
  1030. TRC_ALT((TB,_T("SetWindowPos failed - 0x%x"),
  1031. GetLastError()));
  1032. }
  1033. if(_state == bbarLowering)
  1034. {
  1035. if(_nBBarVertOffset >= _sizeLoweredBBar.cy)
  1036. {
  1037. _nBBarVertOffset = _sizeLoweredBBar.cy;
  1038. _state = bbarLowered;
  1039. fReachedEndOfAnimation = TRUE;
  1040. OnBBarLowered();
  1041. }
  1042. }
  1043. else if(_state == bbarRaising)
  1044. {
  1045. if(_nBBarVertOffset <= 0)
  1046. {
  1047. _nBBarVertOffset = 0;
  1048. _state = bbarRaised;
  1049. fReachedEndOfAnimation = TRUE;
  1050. OnBBarRaised();
  1051. }
  1052. }
  1053. if(fReachedEndOfAnimation)
  1054. {
  1055. if(!KillTimer( _hwndBBar, BBAR_TIMERID_ANIM ))
  1056. {
  1057. TRC_ERR((TB,_T("KillTimer failed - 0x%x"),
  1058. GetLastError()));
  1059. }
  1060. }
  1061. }
  1062. #endif
  1063. }
  1064. else if (BBAR_TIMERID_AUTOHIDE == wParam)
  1065. {
  1066. //
  1067. // If the mouse is within the hotzone
  1068. // then don't autohide. Otherwise kill the autohide
  1069. // timer and kick off a bbar raise
  1070. //
  1071. if(_state == bbarLowered)
  1072. {
  1073. POINT pt;
  1074. RECT rc;
  1075. GetCursorPos(&pt);
  1076. //
  1077. // Don't hide if mouse hasn't moved
  1078. //
  1079. if(_ptLastAutoHideMousePos.x != pt.x &&
  1080. _ptLastAutoHideMousePos.y != pt.y)
  1081. {
  1082. _ptLastAutoHideMousePos.x = pt.x;
  1083. _ptLastAutoHideMousePos.y = pt.y;
  1084. //
  1085. // Get window rect in screen coordinates
  1086. //
  1087. GetWindowRect( _hwndBBar, &rc);
  1088. //
  1089. // Don't hide if the cursor is within
  1090. // the bbar rect
  1091. //
  1092. if(!PtInRect(&rc, pt))
  1093. {
  1094. // Stop the autohide timer because we're going
  1095. // to hide
  1096. if(!KillTimer( _hwndBBar, BBAR_TIMERID_AUTOHIDE ))
  1097. {
  1098. TRC_ERR((TB,_T("KillTimer failed - 0x%x"),
  1099. GetLastError()));
  1100. }
  1101. StartRaiseBBar();
  1102. }
  1103. }
  1104. else
  1105. {
  1106. //
  1107. // Don't autohide the bbar because the mouse
  1108. // has not moved, this prevents the raise/lower
  1109. // loop problem because the hotzone (see IH) region and
  1110. // auto-hide prevention regions are different
  1111. // (by design).
  1112. //
  1113. TRC_NRM((TB,
  1114. _T("Autohide timer fired but mouse not moved")));
  1115. }
  1116. }
  1117. }
  1118. return 0L;
  1119. }
  1120. break;
  1121. #ifndef OS_WINCE
  1122. case WM_WINDOWPOSCHANGING:
  1123. {
  1124. if(_fBlockZOrderChanges)
  1125. {
  1126. LPWINDOWPOS lpwp = (LPWINDOWPOS) lParam;
  1127. lpwp->flags |= SWP_NOZORDER;
  1128. }
  1129. return 0L;
  1130. }
  1131. break;
  1132. #endif
  1133. case WM_COMMAND:
  1134. {
  1135. switch(LOWORD(wParam))
  1136. {
  1137. case IDM_MINIMIZE:
  1138. {
  1139. OnCmdMinimize();
  1140. }
  1141. break;
  1142. case IDM_RESTORE:
  1143. {
  1144. OnCmdRestore();
  1145. }
  1146. break;
  1147. case IDM_CLOSE:
  1148. {
  1149. OnCmdClose();
  1150. }
  1151. break;
  1152. case IDM_PIN:
  1153. {
  1154. OnCmdPin();
  1155. }
  1156. break;
  1157. }
  1158. return 0L;
  1159. }
  1160. break;
  1161. default:
  1162. {
  1163. return DefWindowProc( hwnd, uMsg, wParam, lParam);
  1164. }
  1165. break;
  1166. }
  1167. DC_END_FN();
  1168. }
  1169. VOID CBBar::SetState(BBarState newState)
  1170. {
  1171. DC_BEGIN_FN("SetState");
  1172. TRC_NRM((TB,_T("BBar old state: 0x%x - new state: 0x%x"),
  1173. _state, newState));
  1174. _state = newState;
  1175. DC_END_FN();
  1176. }
  1177. LRESULT CBBar::OnEraseBkgnd(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1178. {
  1179. RECT rc;
  1180. HDC hDC = NULL;
  1181. HBRUSH hBrToolTipBgCol = NULL;
  1182. #ifndef OS_WINCE
  1183. HGDIOBJ hPrevBr = NULL;
  1184. COLORREF prevCol;
  1185. #endif
  1186. HPEN hPenNew = NULL, hPenOld = NULL, hPenOri = NULL;
  1187. DC_BEGIN_FN("OnEraseBkgnd");
  1188. hDC = (HDC)wParam;
  1189. GetClientRect( hwnd, &rc );
  1190. //
  1191. // Repaint the background as follows
  1192. // 1) fill the window with the TOOLTIP bg color
  1193. // 2) draw the edges in solid black
  1194. // 3) add a grey line to the bottom horizontal edge because it looks
  1195. // really cool
  1196. //
  1197. hBrToolTipBgCol = (HBRUSH) GetSysColorBrush(COLOR_INFOBK);
  1198. FillRect(hDC, &rc, hBrToolTipBgCol);
  1199. #ifdef OS_WINCE
  1200. //On CE, the toolbar sends an extra WM_ERASEBKGND message to the parent with its DC in wParam.
  1201. //The origin of that DC, is the where the toolbar is located. So we want to use supplied DC for FillRect
  1202. //but not for drawing lines
  1203. hDC = GetDC(hwnd);
  1204. #endif
  1205. hPenNew = CreatePen( PS_SOLID, 0 , COLOR_BLACK);
  1206. if (NULL != hPenNew) {
  1207. hPenOri = SelectPen(hDC, hPenNew);
  1208. }
  1209. //
  1210. // Left diagonal corner (assumes 45degree line)
  1211. //
  1212. MoveToEx( hDC, 0, 0, NULL);
  1213. LineTo( hDC,
  1214. _sizeLoweredBBar.cy,
  1215. _sizeLoweredBBar.cy );
  1216. //
  1217. // Right diagonal corner (assumes 45degree line)
  1218. // (bias by one pixel to end up inside the clipping region)
  1219. //
  1220. MoveToEx( hDC, _sizeLoweredBBar.cx - 1, 0, NULL);
  1221. LineTo( hDC,
  1222. _sizeLoweredBBar.cx - _sizeLoweredBBar.cy -1,
  1223. _sizeLoweredBBar.cy );
  1224. //
  1225. // Bottom black line
  1226. // bias by 1 pixel up to lie inside clip region
  1227. //
  1228. MoveToEx( hDC, _sizeLoweredBBar.cy,
  1229. _sizeLoweredBBar.cy - 1, NULL);
  1230. LineTo( hDC,
  1231. _sizeLoweredBBar.cx - _sizeLoweredBBar.cy,
  1232. _sizeLoweredBBar.cy - 1);
  1233. if (NULL != hPenOri) {
  1234. SelectPen(hDC, hPenOri);
  1235. }
  1236. if (NULL != hPenNew) {
  1237. DeleteObject(hPenNew);
  1238. hPenNew = NULL;
  1239. }
  1240. //
  1241. // Thin grey line above bottom gray line
  1242. //
  1243. hPenNew = CreatePen( PS_SOLID, 0 , COLOR_DKGREY);
  1244. if (NULL != hPenNew) {
  1245. hPenOri = SelectPen(hDC, hPenNew);
  1246. }
  1247. MoveToEx( hDC, _sizeLoweredBBar.cy - 1,
  1248. _sizeLoweredBBar.cy - 2, NULL);
  1249. LineTo( hDC,
  1250. _sizeLoweredBBar.cx - _sizeLoweredBBar.cy + 1,
  1251. _sizeLoweredBBar.cy - 2);
  1252. //
  1253. // Restore DC
  1254. //
  1255. #ifndef OS_WINCE
  1256. if (NULL != hPenOri) {
  1257. SelectPen( hDC, hPenOri);
  1258. }
  1259. #else
  1260. SelectPen( hDC, GetStockObject(BLACK_PEN));
  1261. #endif
  1262. if (NULL != hPenNew) {
  1263. DeleteObject( hPenNew);
  1264. hPenNew = NULL;
  1265. }
  1266. #ifdef OS_WINCE
  1267. ReleaseDC(hwnd, hDC);
  1268. #endif
  1269. DC_END_FN();
  1270. return TRUE;
  1271. }
  1272. VOID CBBar::SetDisplayedText(LPTSTR szText)
  1273. {
  1274. HRESULT hr;
  1275. DC_BEGIN_FN("SetDisplayedText");
  1276. if(szText) {
  1277. hr = StringCchCopy(_szDisplayedText,
  1278. SIZE_TCHARS(_szDisplayedText),
  1279. szText);
  1280. if (FAILED(hr)) {
  1281. TRC_ERR((TB,_T("StringCopy for dispayed text failed: 0x%x"),hr));
  1282. }
  1283. }
  1284. else {
  1285. _szDisplayedText[0] = NULL;
  1286. }
  1287. if(_hwndBBar && _state != bbarNotInit) {
  1288. //Trigger a repaint
  1289. InvalidateRect( _hwndBBar, NULL, TRUE);
  1290. }
  1291. DC_END_FN();
  1292. }
  1293. LRESULT CBBar::OnPaint(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1294. {
  1295. PAINTSTRUCT ps;
  1296. DC_BEGIN_FN("OnPaint");
  1297. if(_state != bbarNotInit)
  1298. {
  1299. COLORREF oldCol;
  1300. INT oldMode;
  1301. HFONT hOldFont;
  1302. COLORREF oldTextCol;
  1303. //
  1304. // Draw the displayed text
  1305. //
  1306. BeginPaint( hwnd, &ps);
  1307. oldCol = SetBkColor( ps.hdc, GetSysColor(COLOR_INFOBK));
  1308. oldMode = SetBkMode( ps.hdc, OPAQUE);
  1309. oldTextCol = SetTextColor( ps.hdc, GetSysColor(COLOR_INFOTEXT));
  1310. hOldFont = (HFONT)SelectObject( ps.hdc,
  1311. #ifndef OS_WINCE
  1312. GetStockObject( DEFAULT_GUI_FONT));
  1313. #else
  1314. GetStockObject( SYSTEM_FONT));
  1315. #endif
  1316. DrawText(ps.hdc,
  1317. _szDisplayedText,
  1318. _tcslen(_szDisplayedText),
  1319. &_rcBBarDisplayTextArea,
  1320. DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  1321. SetBkColor( ps.hdc, oldCol);
  1322. SetBkMode( ps.hdc, oldMode);
  1323. SetTextColor( ps.hdc, oldTextCol);
  1324. SelectObject( ps.hdc, hOldFont);
  1325. EndPaint( hwnd, &ps);
  1326. }
  1327. DC_END_FN();
  1328. return 0;
  1329. }
  1330. //
  1331. // Internal event handler for bbar lowered
  1332. //
  1333. VOID CBBar::OnBBarLowered()
  1334. {
  1335. DC_BEGIN_FN("OnBBarLowered");
  1336. //
  1337. // Kick off the autohide timer
  1338. //
  1339. TRC_ASSERT(_state == bbarLowered,
  1340. (TB,_T("_state should be lowered...0x%x"),
  1341. _state));
  1342. TRC_ASSERT(_nBBarAutoHideTime,
  1343. (TB,_T("_nBBarAutoHideTime is 0")));
  1344. if(bbarLowered == _state)
  1345. {
  1346. if (!_fPinned || !_fLocked)
  1347. {
  1348. if(!SetTimer( _hwndBBar, BBAR_TIMERID_AUTOHIDE,
  1349. _nBBarAutoHideTime, NULL ))
  1350. {
  1351. TRC_ERR((TB,_T("SetTimer failed - 0x%x"),
  1352. GetLastError()));
  1353. //
  1354. // Bail out
  1355. //
  1356. return;
  1357. }
  1358. // After bbar has lowered once reset
  1359. // the autohide interval time to the shorter
  1360. // interval.
  1361. _nBBarAutoHideTime = BBAR_AUTOHIDE_TIME;
  1362. }
  1363. }
  1364. DC_END_FN();
  1365. }
  1366. //
  1367. // Internal event handler for bbar raised
  1368. //
  1369. VOID CBBar::OnBBarRaised()
  1370. {
  1371. DC_BEGIN_FN("OnBBarRaised");
  1372. #ifdef DISABLE_SHADOW_IN_FULLSCREEN
  1373. _pUi->UI_OnNotifyBBarVisibleChange(0);
  1374. #endif
  1375. DC_END_FN();
  1376. }
  1377. VOID CBBar::OnBBarHotzoneFired()
  1378. {
  1379. DC_BEGIN_FN("OnBBarHotzoneFired");
  1380. //
  1381. // Only allow the bbar to drop on the timer if it's enabled
  1382. //
  1383. if (_fBBarEnabled &&
  1384. _state == bbarRaised &&
  1385. _pUi->UI_IsFullScreen())
  1386. {
  1387. StartLowerBBar();
  1388. }
  1389. DC_END_FN();
  1390. }
  1391. VOID CBBar::OnCmdMinimize()
  1392. {
  1393. DC_BEGIN_FN("OnCmdLock");
  1394. TRC_NRM((TB,_T("BBAR Command Minimize")));
  1395. TRC_ASSERT( bbarNotInit != _state,
  1396. (TB,_T("bbar not initalized - state:0x%x"),
  1397. _state));
  1398. if(bbarNotInit != _state &&
  1399. _pUi->UI_IsFullScreen())
  1400. {
  1401. _pUi->UI_RequestMinimize();
  1402. }
  1403. DC_END_FN();
  1404. }
  1405. VOID CBBar::OnCmdRestore()
  1406. {
  1407. DC_BEGIN_FN("OnCmdLock");
  1408. TRC_NRM((TB,_T("BBAR Command Restore")));
  1409. TRC_ASSERT( bbarNotInit != _state,
  1410. (TB,_T("bbar not initalized - state:0x%x"),
  1411. _state));
  1412. if(bbarNotInit != _state)
  1413. {
  1414. _pUi->UI_ToggleFullScreenMode();
  1415. }
  1416. DC_END_FN();
  1417. }
  1418. VOID CBBar::OnCmdClose()
  1419. {
  1420. DC_BEGIN_FN("OnCmdClose");
  1421. TRC_NRM((TB,_T("BBAR Command Close")));
  1422. TRC_ASSERT( bbarNotInit != _state,
  1423. (TB,_T("bbar not initalized - state:0x%x"),
  1424. _state));
  1425. if (bbarNotInit != _state)
  1426. {
  1427. //
  1428. // Dispatch a close request to the core
  1429. //
  1430. if (!_pUi->UI_UserRequestedClose())
  1431. {
  1432. // Request for clean close down (including firing of events
  1433. // asking container if they really want to close) has failed
  1434. // so trigger an immediate disconnection without user prompts
  1435. TRC_ALT((TB,_T("UI_UserRequestedClose failed, disconnect now!")));
  1436. _pUi->UI_UserInitiatedDisconnect(NL_DISCONNECT_LOCAL);
  1437. }
  1438. }
  1439. DC_END_FN();
  1440. }
  1441. VOID CBBar::OnCmdPin()
  1442. {
  1443. DC_BEGIN_FN("OnCmdPin");
  1444. TRC_NRM((TB,_T("BBAR Command Pin")));
  1445. TRC_ASSERT( bbarNotInit != _state,
  1446. (TB,_T("bbar not initalized - state:0x%x"),
  1447. _state));
  1448. TRC_ASSERT(_hwndPinBar, (TB,_T("Left bar not created")));
  1449. if (bbarNotInit != _state)
  1450. {
  1451. //
  1452. // The pin button acts like a toggle
  1453. //
  1454. _fPinned = !_fPinned;
  1455. SendMessage(_hwndPinBar, TB_PRESSBUTTON,
  1456. IDM_PIN, MAKELONG(_fPinned,0));
  1457. SendMessage(_hwndPinBar, TB_CHANGEBITMAP,
  1458. IDM_PIN,
  1459. MAKELPARAM( _fPinned ?_nPinDownImage : _nPinUpImage, 0));
  1460. if(!_fPinned && bbarLowered == _state )
  1461. {
  1462. // We just unpinned trigger an OnLowered event
  1463. // to startup the autohide timers
  1464. OnBBarLowered();
  1465. }
  1466. }
  1467. DC_END_FN();
  1468. }
  1469. //
  1470. // Notification from core that we entered fullscreen mode
  1471. //
  1472. VOID CBBar::OnNotifyEnterFullScreen()
  1473. {
  1474. DC_BEGIN_FN("OnNotifyEnterFullScreen");
  1475. //
  1476. // Lower bbar to give a visual cue
  1477. //
  1478. if(_state != bbarNotInit)
  1479. {
  1480. StartLowerBBar();
  1481. }
  1482. DC_END_FN();
  1483. }
  1484. //
  1485. // Notification from core that we left fullscreen mode
  1486. //
  1487. VOID CBBar::OnNotifyLeaveFullScreen()
  1488. {
  1489. DC_BEGIN_FN("OnNotifyLeaveFullScreen");
  1490. //
  1491. // Disable the bbar in windowed mode
  1492. //
  1493. if(_state != bbarNotInit)
  1494. {
  1495. //Kill timers
  1496. KillTimer( _hwndBBar, BBAR_TIMERID_AUTOHIDE);
  1497. KillTimer( _hwndBBar, BBAR_TIMERID_ANIM);
  1498. //Immediate raise of the bbar
  1499. if(_state != bbarRaised)
  1500. {
  1501. ImmediateRaiseBBar();
  1502. }
  1503. }
  1504. DC_END_FN();
  1505. }
  1506. //
  1507. // Raise the bbar without much fanfare (i.e animations)
  1508. // this is used to quickly 'hide' the bbar
  1509. //
  1510. BOOL CBBar::ImmediateRaiseBBar()
  1511. {
  1512. DC_BEGIN_FN("ImmediateRaiseBBar");
  1513. if(_state != bbarNotInit &&
  1514. _state != bbarRaised)
  1515. {
  1516. _nBBarVertOffset = 0;
  1517. _state = bbarRaised;
  1518. if(SetWindowPos(_hwndBBar,
  1519. NULL,
  1520. _rcBBarLoweredAspect.left, //x
  1521. _nBBarVertOffset - _sizeLoweredBBar.cy, //y
  1522. 0,0,
  1523. SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE ))
  1524. {
  1525. TRC_ALT((TB,_T("SetWindowPos failed - 0x%x"),
  1526. GetLastError()));
  1527. }
  1528. OnBBarRaised();
  1529. }
  1530. DC_END_FN();
  1531. return TRUE;
  1532. }
  1533. #ifdef OS_WINCE
  1534. //
  1535. // Lower the bbar without much fanfare (i.e animations)
  1536. // this is used to quickly 'show' the bbar
  1537. //
  1538. BOOL CBBar::ImmediateLowerBBar()
  1539. {
  1540. DC_BEGIN_FN("ImmediateLowerBBar");
  1541. if(_state != bbarNotInit &&
  1542. _state != bbarLowered)
  1543. {
  1544. _nBBarVertOffset = _sizeLoweredBBar.cy;
  1545. _state = bbarLowered;
  1546. if(!SetWindowPos(_hwndBBar,
  1547. NULL,
  1548. _rcBBarLoweredAspect.left, //x
  1549. _nBBarVertOffset - _sizeLoweredBBar.cy, //y
  1550. 0,0,
  1551. SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE ))
  1552. {
  1553. TRC_ALT((TB,_T("SetWindowPos failed - 0x%x"),
  1554. GetLastError()));
  1555. }
  1556. OnBBarLowered();
  1557. }
  1558. DC_END_FN();
  1559. return TRUE;
  1560. }
  1561. #endif
  1562. VOID CBBar::OnSysColorChange()
  1563. {
  1564. DC_BEGIN_FN("OnSysColorChange");
  1565. if (_state != bbarNotInit)
  1566. {
  1567. //
  1568. // Force a reload of the images
  1569. // so they get updated for the new system colors
  1570. //
  1571. ReloadImages();
  1572. }
  1573. DC_END_FN();
  1574. }
  1575. #ifdef OS_WINCE
  1576. //Assumes four points in the array
  1577. HRGN CBBar::GetBBarRgn(POINT *pts)
  1578. {
  1579. DC_BEGIN_FN("CBBar::GetBBarRgn");
  1580. HRGN hRgn=NULL, hRgn1=NULL;
  1581. int nRect, nTotalRects, nStart;
  1582. RGNDATA *pRgnData = NULL;
  1583. RECT *pRect = NULL;
  1584. BOOL bSuccess = FALSE;
  1585. TRC_ASSERT((pts[2].x - pts[1].x == pts[0].x - pts[3].x), (TB,_T("Invalid points!")));
  1586. nTotalRects = (pts[2].x - pts[1].x + 1) /2;
  1587. pRgnData = (RGNDATA *)LocalAlloc(0, sizeof(RGNDATAHEADER) + (sizeof(RECT)*nTotalRects));
  1588. if (!pRgnData)
  1589. return NULL;
  1590. pRgnData->rdh.dwSize = sizeof(RGNDATAHEADER);
  1591. pRgnData->rdh.iType = RDH_RECTANGLES;
  1592. pRgnData->rdh.nCount = nTotalRects;
  1593. pRgnData->rdh.nRgnSize = (sizeof(RECT)*nTotalRects);
  1594. pRect = (RECT *)pRgnData->Buffer;
  1595. hRgn = CreateRectRgn(pts[0].x + 1, pts[3].y, pts[1].x, pts[1].y);
  1596. if (!hRgn)
  1597. DC_QUIT;
  1598. SetRect(&(pRgnData->rdh.rcBound), 0, 0, pts[0].x, pts[0].y);
  1599. //The left triangle
  1600. nStart = pts[3].x + 1;
  1601. for (nRect = 0; nRect < nTotalRects; nRect++)
  1602. {
  1603. SetRect(&pRect[nRect], nStart, pts[3].y, nStart + 1, nStart);
  1604. TRC_DBG((TB,_T("pRect[%d]={%d,%d,%d,%d}"), nRect, pRect[nRect].left, pRect[nRect].top, pRect[nRect].right, pRect[nRect].bottom));
  1605. nStart += 2;
  1606. }
  1607. hRgn1 = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT)*nTotalRects), pRgnData);
  1608. if (!hRgn1)
  1609. DC_QUIT;
  1610. if (ERROR == CombineRgn(hRgn, hRgn, hRgn1, RGN_OR))
  1611. DC_QUIT;
  1612. DeleteObject(hRgn1);
  1613. //The left triangle offset by one pixel to avoid a striped triangle
  1614. nStart = pts[3].x + 2;
  1615. for (nRect = 0; nRect < nTotalRects; nRect++)
  1616. {
  1617. SetRect(&pRect[nRect], nStart, pts[3].y, nStart + 1, nStart);
  1618. TRC_DBG((TB,_T("pRect[%d]={%d,%d,%d,%d}"), nRect, pRect[nRect].left, pRect[nRect].top, pRect[nRect].right, pRect[nRect].bottom));
  1619. nStart += 2;
  1620. }
  1621. hRgn1 = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT)*nTotalRects), pRgnData);
  1622. if (!hRgn1)
  1623. DC_QUIT;
  1624. if (ERROR == CombineRgn(hRgn, hRgn, hRgn1, RGN_OR))
  1625. DC_QUIT;
  1626. DeleteObject(hRgn1);
  1627. //The right triangle
  1628. nStart = pts[1].x - 1;
  1629. for (nRect = 0; nRect < nTotalRects; nRect++)
  1630. {
  1631. SetRect(&pRect[nRect], nStart, pts[3].y, nStart + 1, pts[2].x - nStart);
  1632. TRC_DBG((TB,_T("pRect[%d]={%d,%d,%d,%d}"), nRect, pRect[nRect].left, pRect[nRect].top, pRect[nRect].right, pRect[nRect].bottom));
  1633. nStart += 2;
  1634. }
  1635. hRgn1 = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT)*nTotalRects), pRgnData);
  1636. if (!hRgn1)
  1637. DC_QUIT;
  1638. if (ERROR == CombineRgn(hRgn, hRgn, hRgn1, RGN_OR))
  1639. DC_QUIT;
  1640. DeleteObject(hRgn1);
  1641. //The right triangle offset by one pixel to avoid a striped triangle
  1642. nStart = pts[1].x;
  1643. for (nRect = 0; nRect < nTotalRects; nRect++)
  1644. {
  1645. SetRect(&pRect[nRect], nStart, pts[3].y, nStart + 1, pts[2].x - nStart);
  1646. TRC_DBG((TB,_T("pRect[%d]={%d,%d,%d,%d}"), nRect, pRect[nRect].left, pRect[nRect].top, pRect[nRect].right, pRect[nRect].bottom));
  1647. nStart += 2;
  1648. }
  1649. hRgn1 = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT)*nTotalRects), pRgnData);
  1650. if (!hRgn1)
  1651. DC_QUIT;
  1652. if (ERROR == CombineRgn(hRgn, hRgn, hRgn1, RGN_OR))
  1653. DC_QUIT;
  1654. DeleteObject(hRgn1);
  1655. hRgn1 = NULL;
  1656. bSuccess = TRUE;
  1657. DC_EXIT_POINT:
  1658. LocalFree(pRgnData);
  1659. if (hRgn1)
  1660. DeleteObject(hRgn1);
  1661. if (!bSuccess && hRgn)
  1662. {
  1663. DeleteObject(hRgn);
  1664. hRgn = NULL;
  1665. }
  1666. DC_END_FN();
  1667. return hRgn;
  1668. }
  1669. #endif //OS_WINCE
  1670. #endif // USE_BBAR