BtnST.cpp
上传用户:sdgangtie
上传日期:2020-03-07
资源大小:7324k
文件大小:51k
开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "BtnST.h"
  3. #ifdef _DEBUG
  4. #define new DEBUG_NEW
  5. #undef THIS_FILE
  6. static char THIS_FILE[] = __FILE__;
  7. #endif
  8. /////////////////////////////////////////////////////////////////////////////
  9. // CButtonST
  10. // Mask for control's type
  11. #define BS_TYPEMASK SS_TYPEMASK
  12. CButtonST::CButtonST()
  13. {
  14. m_bIsPressed = FALSE;
  15. m_bIsFocused = FALSE;
  16. m_bIsDisabled = FALSE;
  17. m_bMouseOnButton = FALSE;
  18. FreeResources(FALSE);
  19. // Default type is "flat" button
  20. m_bIsFlat = TRUE;
  21. // Button will be tracked also if when the window is inactive (like Internet Explorer)
  22. m_bAlwaysTrack = TRUE;
  23.   
  24. // By default draw border in "flat" button 
  25. m_bDrawBorder = TRUE; 
  26.   
  27. // By default icon is aligned horizontally
  28. m_byAlign = ST_ALIGN_HORIZ; 
  29.   
  30. // By default, for "flat" button, don't draw the focus rect
  31. m_bDrawFlatFocus = FALSE;
  32. // By default the button is not the default button
  33. m_bIsDefault = FALSE;
  34. // Invalid value, since type still unknown
  35. m_nTypeStyle = BS_TYPEMASK;
  36. // By default the button is not a checkbox
  37. m_bIsCheckBox = FALSE;
  38. m_nCheck = 0;
  39. // Set default colors
  40. SetDefaultColors(FALSE);
  41. // No tooltip created
  42. m_ToolTip.m_hWnd = NULL;
  43. // Do not draw as a transparent button
  44. m_bDrawTransparent = FALSE;
  45. m_pbmpOldBk = NULL;
  46. // No URL defined
  47. SetURL(NULL);
  48. // No cursor defined
  49. m_hCursor = NULL;
  50. // No associated menu
  51. #ifndef BTNST_USE_BCMENU
  52. m_hMenu = NULL;
  53. #endif
  54. m_hParentWndMenu = NULL;
  55. m_bMenuDisplayed = FALSE;
  56. m_bShowDisabledBitmap = TRUE;
  57. } // End of CButtonST
  58. CButtonST::~CButtonST()
  59. {
  60. // Restore old bitmap (if any)
  61. if (m_dcBk.m_hDC && m_pbmpOldBk)
  62. {
  63. m_dcBk.SelectObject(m_pbmpOldBk);
  64. } // if
  65. FreeResources();
  66. // Destroy the cursor (if any)
  67. if (m_hCursor) ::DestroyCursor(m_hCursor);
  68. // Destroy the menu (if any)
  69. #ifdef BTNST_USE_BCMENU
  70. if (m_menuPopup.m_hMenu) m_menuPopup.DestroyMenu();
  71. #else
  72. if (m_hMenu) ::DestroyMenu(m_hMenu);
  73. #endif
  74. } // End of ~CButtonST
  75. BEGIN_MESSAGE_MAP(CButtonST, CButton)
  76.     //{{AFX_MSG_MAP(CButtonST)
  77. ON_WM_SETCURSOR()
  78. ON_WM_KILLFOCUS()
  79. ON_WM_MOUSEMOVE()
  80. ON_WM_SYSCOLORCHANGE()
  81. ON_CONTROL_REFLECT_EX(BN_CLICKED, OnClicked)
  82. ON_WM_ACTIVATE()
  83. ON_WM_ENABLE()
  84. ON_WM_CANCELMODE()
  85. ON_WM_GETDLGCODE()
  86. ON_WM_CTLCOLOR_REFLECT()
  87. //}}AFX_MSG_MAP
  88. #ifdef BTNST_USE_BCMENU
  89. ON_WM_MENUCHAR()
  90. ON_WM_MEASUREITEM()
  91. #endif
  92. ON_MESSAGE(BM_SETSTYLE, OnSetStyle)
  93. ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
  94. ON_MESSAGE(BM_SETCHECK, OnSetCheck)
  95. ON_MESSAGE(BM_GETCHECK, OnGetCheck)
  96. END_MESSAGE_MAP()
  97. void CButtonST::FreeResources(BOOL bCheckForNULL)
  98. {
  99. if (bCheckForNULL)
  100. {
  101. // Destroy icons
  102. // Note: the following two lines MUST be here! even if
  103. // BoundChecker says they are unnecessary!
  104. if (m_csIcons[0].hIcon) ::DestroyIcon(m_csIcons[0].hIcon);
  105. if (m_csIcons[1].hIcon) ::DestroyIcon(m_csIcons[1].hIcon);
  106. // Destroy bitmaps
  107. if (m_csBitmaps[0].hBitmap) ::DeleteObject(m_csBitmaps[0].hBitmap);
  108. if (m_csBitmaps[1].hBitmap) ::DeleteObject(m_csBitmaps[1].hBitmap);
  109. // Destroy mask bitmaps
  110. if (m_csBitmaps[0].hMask) ::DeleteObject(m_csBitmaps[0].hMask);
  111. if (m_csBitmaps[1].hMask) ::DeleteObject(m_csBitmaps[1].hMask);
  112. } // if
  113. ::ZeroMemory(&m_csIcons, sizeof(m_csIcons));
  114. ::ZeroMemory(&m_csBitmaps, sizeof(m_csBitmaps));
  115. } // End of FreeResources
  116. void CButtonST::PreSubclassWindow() 
  117. {
  118. UINT nBS;
  119. nBS = GetButtonStyle();
  120. // Set initial control type
  121. m_nTypeStyle = nBS & BS_TYPEMASK;
  122. // Check if this is a checkbox
  123. if (nBS & BS_CHECKBOX) m_bIsCheckBox = TRUE;
  124. // Set initial default state flag
  125. if (m_nTypeStyle == BS_DEFPUSHBUTTON)
  126. {
  127. // Set default state for a default button
  128. m_bIsDefault = TRUE;
  129. // Adjust style for default button
  130. m_nTypeStyle = BS_PUSHBUTTON;
  131. } // If
  132. // You should not set the Owner Draw before this call
  133. // (don't use the resource editor "Owner Draw" or
  134. // ModifyStyle(0, BS_OWNERDRAW) before calling PreSubclassWindow() )
  135. ASSERT(m_nTypeStyle != BS_OWNERDRAW);
  136. // Switch to owner-draw
  137. ModifyStyle(BS_TYPEMASK, BS_OWNERDRAW, SWP_FRAMECHANGED);
  138. CButton::PreSubclassWindow();
  139. } // End of PreSubclassWindow
  140. UINT CButtonST::OnGetDlgCode() 
  141. {
  142. UINT nCode = CButton::OnGetDlgCode();
  143. // Tell the system if we want default state handling
  144. // (losing default state always allowed)
  145. nCode |= (m_bIsDefault ? DLGC_DEFPUSHBUTTON : DLGC_UNDEFPUSHBUTTON);
  146. return nCode;
  147. } // End of OnGetDlgCode
  148. BOOL CButtonST::PreTranslateMessage(MSG* pMsg) 
  149. {
  150. InitToolTip();
  151. m_ToolTip.RelayEvent(pMsg);
  152. return CButton::PreTranslateMessage(pMsg);
  153. } // End of PreTranslateMessage
  154. LRESULT CButtonST::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
  155. {
  156. if (message == WM_LBUTTONDBLCLK)
  157. {
  158. message = WM_LBUTTONDOWN;
  159. } // if
  160. /*
  161. switch (message)
  162. {
  163. case WM_LBUTTONDBLCLK:
  164. message = WM_LBUTTONDOWN;
  165. break;
  166. case WM_MOVE:
  167. CRect rect;
  168. GetClientRect(&rect);
  169. if (::IsWindow(m_ToolTip.m_hWnd))
  170. {
  171. if (m_ToolTip.GetToolCount() != 0)
  172. m_ToolTip.SetToolRect(this, 1, &rect);
  173. } // if
  174. break;
  175. } // switch
  176. */
  177. return CButton::DefWindowProc(message, wParam, lParam);
  178. } // End of DefWindowProc
  179. HBRUSH CButtonST::CtlColor(CDC* pDC, UINT nCtlColor) 
  180. {
  181. return (HBRUSH)::GetStockObject(NULL_BRUSH); 
  182. } // End of CtlColor
  183. void CButtonST::OnSysColorChange() 
  184. {
  185. CButton::OnSysColorChange();
  186. m_dcBk.DeleteDC();
  187. m_bmpBk.DeleteObject();
  188. } // End of OnSysColorChange
  189. LRESULT CButtonST::OnSetStyle(WPARAM wParam, LPARAM lParam)
  190. {
  191. UINT nNewType = (wParam & BS_TYPEMASK);
  192. // Update default state flag
  193. if (nNewType == BS_DEFPUSHBUTTON)
  194. {
  195. m_bIsDefault = TRUE;
  196. } // if
  197. else if (nNewType == BS_PUSHBUTTON)
  198. {
  199. // Losing default state always allowed
  200. m_bIsDefault = FALSE;
  201. } // if
  202. // Can't change control type after owner-draw is set.
  203. // Let the system process changes to other style bits
  204. // and redrawing, while keeping owner-draw style
  205. return DefWindowProc(BM_SETSTYLE,
  206. (wParam & ~BS_TYPEMASK) | BS_OWNERDRAW, lParam);
  207. } // End of OnSetStyle
  208. LRESULT CButtonST::OnSetCheck(WPARAM wParam, LPARAM lParam)
  209. {
  210. ASSERT(m_bIsCheckBox);
  211. switch (wParam)
  212. {
  213. case BST_CHECKED:
  214. case BST_INDETERMINATE: // Indeterminate state is handled like checked state
  215. SetCheck(1);
  216. break;
  217. default:
  218. SetCheck(0);
  219. break;
  220. } // switch
  221. return 0;
  222. } // End of OnSetCheck
  223. LRESULT CButtonST::OnGetCheck(WPARAM wParam, LPARAM lParam)
  224. {
  225. ASSERT(m_bIsCheckBox);
  226. return GetCheck();
  227. } // End of OnGetCheck
  228. #ifdef BTNST_USE_BCMENU
  229. LRESULT CButtonST::OnMenuChar(UINT nChar, UINT nFlags, CMenu* pMenu) 
  230. {
  231. LRESULT lResult;
  232. if (BCMenu::IsMenu(pMenu))
  233. lResult = BCMenu::FindKeyboardShortcut(nChar, nFlags, pMenu);
  234. else
  235. lResult = CButton::OnMenuChar(nChar, nFlags, pMenu);
  236. return lResult;
  237. } // End of OnMenuChar
  238. #endif
  239. #ifdef BTNST_USE_BCMENU
  240. void CButtonST::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct) 
  241. {
  242. BOOL bSetFlag = FALSE;
  243. if (lpMeasureItemStruct->CtlType == ODT_MENU)
  244. {
  245. if (IsMenu((HMENU)lpMeasureItemStruct->itemID) && BCMenu::IsMenu((HMENU)lpMeasureItemStruct->itemID))
  246. {
  247. m_menuPopup.MeasureItem(lpMeasureItemStruct);
  248. bSetFlag = TRUE;
  249. } // if
  250. } // if
  251. if (!bSetFlag) CButton::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
  252. } // End of OnMeasureItem
  253. #endif
  254. void CButtonST::OnEnable(BOOL bEnable) 
  255. {
  256. CButton::OnEnable(bEnable);
  257. if (bEnable == FALSE)
  258. {
  259. CWnd* pWnd = GetParent()->GetNextDlgTabItem(this);
  260. if (pWnd)
  261. pWnd->SetFocus();
  262. else
  263. GetParent()->SetFocus();
  264. CancelHover();
  265. } // if
  266. } // End of OnEnable
  267. void CButtonST::OnKillFocus(CWnd * pNewWnd)
  268. {
  269. CButton::OnKillFocus(pNewWnd);
  270. CancelHover();
  271. } // End of OnKillFocus
  272. void CButtonST::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized) 
  273. {
  274. CButton::OnActivate(nState, pWndOther, bMinimized);
  275. if (nState == WA_INACTIVE) CancelHover();
  276. } // End of OnActivate
  277. void CButtonST::OnCancelMode() 
  278. {
  279. CButton::OnCancelMode();
  280. CancelHover();
  281. } // End of OnCancelMode
  282. BOOL CButtonST::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
  283. {
  284. // If a cursor was specified then use it!
  285. if (m_hCursor != NULL)
  286. {
  287. ::SetCursor(m_hCursor);
  288. return TRUE;
  289. } // if
  290. return CButton::OnSetCursor(pWnd, nHitTest, message);
  291. } // End of OnSetCursor
  292. void CButtonST::CancelHover()
  293. {
  294. // Only for flat buttons
  295. if (m_bIsFlat)
  296. {
  297. if (m_bMouseOnButton)
  298. {
  299. m_bMouseOnButton = FALSE;
  300. Invalidate();
  301. } // if
  302. } // if
  303. } // End of CancelHover
  304. void CButtonST::OnMouseMove(UINT nFlags, CPoint point)
  305. {
  306. CWnd* wndUnderMouse = NULL;
  307. CWnd* wndActive = this;
  308. TRACKMOUSEEVENT csTME;
  309. CButton::OnMouseMove(nFlags, point);
  310. ClientToScreen(&point);
  311. wndUnderMouse = WindowFromPoint(point);
  312. // If the mouse enter the button with the left button pressed then do nothing
  313. if (nFlags & MK_LBUTTON && m_bMouseOnButton == FALSE) return;
  314. // If our button is not flat then do nothing
  315. if (m_bIsFlat == FALSE) return;
  316. if (m_bAlwaysTrack == FALSE) wndActive = GetActiveWindow();
  317. if (wndUnderMouse && wndUnderMouse->m_hWnd == m_hWnd && wndActive)
  318. {
  319. if (!m_bMouseOnButton)
  320. {
  321. m_bMouseOnButton = TRUE;
  322. Invalidate();
  323. csTME.cbSize = sizeof(csTME);
  324. csTME.dwFlags = TME_LEAVE;
  325. csTME.hwndTrack = m_hWnd;
  326. ::_TrackMouseEvent(&csTME);
  327. } // if
  328. } else CancelHover();
  329. } // End of OnMouseMove
  330. // Handler for WM_MOUSELEAVE
  331. LRESULT CButtonST::OnMouseLeave(WPARAM wParam, LPARAM lParam)
  332. {
  333. CancelHover();
  334. return 0;
  335. } // End of OnMouseLeave
  336. BOOL CButtonST::OnClicked() 
  337. {
  338. SetFocus();
  339. if (m_bIsCheckBox)
  340. {
  341. m_nCheck = !m_nCheck;
  342. Invalidate();
  343. } // if
  344. else
  345. {
  346. // Handle the menu (if any)
  347. #ifdef BTNST_USE_BCMENU
  348. if (m_menuPopup.m_hMenu)
  349. #else
  350. if (m_hMenu)
  351. #endif
  352. {
  353. CRect rWnd;
  354. GetWindowRect(rWnd);
  355. m_bMenuDisplayed = TRUE;
  356. Invalidate();
  357. #ifdef BTNST_USE_BCMENU
  358. BCMenu *psub = (BCMenu*)m_menuPopup.GetSubMenu(0);
  359. DWORD dwRetValue = psub->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, rWnd.left, rWnd.bottom, this, NULL);
  360. #else
  361. HMENU hSubMenu = ::GetSubMenu(m_hMenu, 0);
  362. //DWORD dwRetValue = ::TrackPopupMenuEx(hSubMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON, rWnd.left, rWnd.bottom, m_hParentWndMenu, NULL);
  363. DWORD dwRetValue = ::TrackPopupMenuEx(hSubMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, rWnd.left, rWnd.bottom, m_hParentWndMenu, NULL);
  364. #endif
  365. m_bMenuDisplayed = FALSE;
  366. Invalidate();
  367. if (dwRetValue)
  368. ::PostMessage(m_hParentWndMenu, WM_COMMAND, MAKEWPARAM(dwRetValue, 0), (LPARAM)NULL);
  369. } // if
  370. else
  371. {
  372. // Handle the URL (if any)
  373. if (_tcslen(m_szURL) > 0)
  374. {
  375. SHELLEXECUTEINFO csSEI;
  376. memset(&csSEI, 0, sizeof(csSEI));
  377. csSEI.cbSize = sizeof(SHELLEXECUTEINFO);
  378. csSEI.fMask = SEE_MASK_FLAG_NO_UI;
  379. csSEI.lpVerb = _T("open");
  380. csSEI.lpFile = m_szURL;
  381. csSEI.nShow = SW_SHOWMAXIMIZED;
  382. ::ShellExecuteEx(&csSEI);
  383. } // if
  384. } // else
  385. } // else
  386. return FALSE;
  387. } // End of OnClicked
  388. void CButtonST::DrawItem(LPDRAWITEMSTRUCT lpDIS)
  389. {
  390. CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  391. CPen* pOldPen;
  392. // Checkbox?
  393. if (m_bIsCheckBox)
  394. {
  395. m_bIsPressed  =  (lpDIS->itemState & ODS_SELECTED) || (m_nCheck != 0);
  396. } // if
  397. else // Normal button OR other button style ...
  398. {
  399. m_bIsPressed = (lpDIS->itemState & ODS_SELECTED);
  400. // If there is a menu and it's displayed, draw the button as pressed
  401. if (
  402. #ifdef BTNST_USE_BCMENU
  403. m_menuPopup.m_hMenu 
  404. #else
  405. m_hMenu 
  406. #endif
  407. && m_bMenuDisplayed) m_bIsPressed = TRUE;
  408. } // else
  409. m_bIsFocused  = (lpDIS->itemState & ODS_FOCUS);
  410. m_bIsDisabled = (lpDIS->itemState & ODS_DISABLED);
  411. CRect itemRect = lpDIS->rcItem;
  412. pDC->SetBkMode(TRANSPARENT);
  413. if (m_bIsFlat == FALSE)
  414. {
  415. if (m_bIsFocused || m_bIsDefault)
  416. {
  417. CBrush br(RGB(0,0,0));  
  418. pDC->FrameRect(&itemRect, &br);
  419. itemRect.DeflateRect(1, 1);
  420. } // if
  421. } // if
  422. // Prepare draw... paint button background
  423. // Draw transparent?
  424. if (m_bDrawTransparent)
  425. PaintBk(pDC);
  426. else
  427. OnDrawBackground(pDC, &itemRect);
  428. // Draw pressed button
  429. if (m_bIsPressed)
  430. {
  431. if (m_bIsFlat)
  432. {
  433. if (m_bDrawBorder)
  434. OnDrawBorder(pDC, &itemRect);
  435. }
  436. else    
  437. {
  438. CBrush brBtnShadow(GetSysColor(COLOR_BTNSHADOW));
  439. pDC->FrameRect(&itemRect, &brBtnShadow);
  440. }
  441. }
  442. else // ...else draw non pressed button
  443. {
  444. CPen penBtnHiLight(PS_SOLID, 0, GetSysColor(COLOR_BTNHILIGHT)); // White
  445. CPen pen3DLight(PS_SOLID, 0, GetSysColor(COLOR_3DLIGHT));       // Light gray
  446. CPen penBtnShadow(PS_SOLID, 0, GetSysColor(COLOR_BTNSHADOW));   // Dark gray
  447. CPen pen3DDKShadow(PS_SOLID, 0, GetSysColor(COLOR_3DDKSHADOW)); // Black
  448. if (m_bIsFlat)
  449. {
  450. if (m_bMouseOnButton && m_bDrawBorder)
  451. OnDrawBorder(pDC, &itemRect);
  452. }
  453. else
  454. {
  455. // Draw top-left borders
  456. // White line
  457. pOldPen = pDC->SelectObject(&penBtnHiLight);
  458. pDC->MoveTo(itemRect.left, itemRect.bottom-1);
  459. pDC->LineTo(itemRect.left, itemRect.top);
  460. pDC->LineTo(itemRect.right, itemRect.top);
  461. // Light gray line
  462. pDC->SelectObject(pen3DLight);
  463. pDC->MoveTo(itemRect.left+1, itemRect.bottom-1);
  464. pDC->LineTo(itemRect.left+1, itemRect.top+1);
  465. pDC->LineTo(itemRect.right, itemRect.top+1);
  466. // Draw bottom-right borders
  467. // Black line
  468. pDC->SelectObject(pen3DDKShadow);
  469. pDC->MoveTo(itemRect.left, itemRect.bottom-1);
  470. pDC->LineTo(itemRect.right-1, itemRect.bottom-1);
  471. pDC->LineTo(itemRect.right-1, itemRect.top-1);
  472. // Dark gray line
  473. pDC->SelectObject(penBtnShadow);
  474. pDC->MoveTo(itemRect.left+1, itemRect.bottom-2);
  475. pDC->LineTo(itemRect.right-2, itemRect.bottom-2);
  476. pDC->LineTo(itemRect.right-2, itemRect.top);
  477. //
  478. pDC->SelectObject(pOldPen);
  479. } // else
  480. } // else
  481. // Read the button's title
  482. CString sTitle;
  483. GetWindowText(sTitle);
  484. CRect captionRect = lpDIS->rcItem;
  485. // Draw the icon
  486. if (m_csIcons[0].hIcon)
  487. {
  488. DrawTheIcon(pDC, !sTitle.IsEmpty(), &lpDIS->rcItem, &captionRect, m_bIsPressed, m_bIsDisabled);
  489. } // if
  490. if (m_csBitmaps[0].hBitmap)
  491. {
  492. pDC->SetBkColor(RGB(255,255,255));
  493. DrawTheBitmap(pDC, !sTitle.IsEmpty(), &lpDIS->rcItem, &captionRect, m_bIsPressed, m_bIsDisabled);
  494. } // if
  495. // Write the button title (if any)
  496. if (sTitle.IsEmpty() == FALSE)
  497. {
  498. // Draw the button's title
  499. // If button is pressed then "press" title also
  500. if (m_bIsPressed && m_bIsCheckBox == FALSE)
  501. captionRect.OffsetRect(1, 1);
  502.     
  503. // ONLY FOR DEBUG 
  504. //CBrush brBtnShadow(RGB(255, 0, 0));
  505. //pDC->FrameRect(&captionRect, &brBtnShadow);
  506. // Center text
  507. CRect centerRect = captionRect;
  508. pDC->DrawText(sTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER | DT_CALCRECT);
  509. captionRect.OffsetRect((centerRect.Width() - captionRect.Width())/2, (centerRect.Height() - captionRect.Height())/2);
  510. /* RFU
  511. captionRect.OffsetRect(0, (centerRect.Height() - captionRect.Height())/2);
  512. captionRect.OffsetRect((centerRect.Width() - captionRect.Width())-4, (centerRect.Height() - captionRect.Height())/2);
  513. */
  514. pDC->SetBkMode(TRANSPARENT);
  515. /*
  516. pDC->DrawState(captionRect.TopLeft(), captionRect.Size(), (LPCTSTR)sTitle, (bIsDisabled ? DSS_DISABLED : DSS_NORMAL), 
  517. TRUE, 0, (CBrush*)NULL);
  518. */
  519. if (m_bIsDisabled)
  520. {
  521. captionRect.OffsetRect(1, 1);
  522. pDC->SetTextColor(::GetSysColor(COLOR_3DHILIGHT));
  523. pDC->DrawText(sTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER);
  524. captionRect.OffsetRect(-1, -1);
  525. pDC->SetTextColor(::GetSysColor(COLOR_3DSHADOW));
  526. pDC->DrawText(sTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER);
  527. } // if
  528. else
  529. {
  530. if (m_bMouseOnButton || m_bIsPressed) 
  531. {
  532. pDC->SetTextColor(m_crColors[BTNST_COLOR_FG_IN]);
  533. pDC->SetBkColor(m_crColors[BTNST_COLOR_BK_IN]);
  534. } // if
  535. else 
  536. {
  537. pDC->SetTextColor(m_crColors[BTNST_COLOR_FG_OUT]);
  538. pDC->SetBkColor(m_crColors[BTNST_COLOR_BK_OUT]);
  539. } // else
  540. pDC->DrawText(sTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER);
  541. } // if
  542. } // if
  543. if (m_bIsFlat == FALSE || (m_bIsFlat && m_bDrawFlatFocus))
  544. {
  545. // Draw the focus rect
  546. if (m_bIsFocused)
  547. {
  548. CRect focusRect = itemRect;
  549. focusRect.DeflateRect(3, 3);
  550. pDC->DrawFocusRect(&focusRect);
  551. } // if
  552. } // if
  553. } // End of DrawItem
  554. void CButtonST::PaintBk(CDC* pDC)
  555. {
  556. CClientDC clDC(GetParent());
  557. CRect rect;
  558. CRect rect1;
  559. GetClientRect(rect);
  560. GetWindowRect(rect1);
  561. GetParent()->ScreenToClient(rect1);
  562. if (m_dcBk.m_hDC == NULL)
  563. {
  564. m_dcBk.CreateCompatibleDC(&clDC);
  565. m_bmpBk.CreateCompatibleBitmap(&clDC, rect.Width(), rect.Height());
  566. m_pbmpOldBk = m_dcBk.SelectObject(&m_bmpBk);
  567. m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), &clDC, rect1.left, rect1.top, SRCCOPY);
  568. } // if
  569. pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &m_dcBk, 0, 0, SRCCOPY);
  570. } // End of PaintBk
  571. HBITMAP CButtonST::CreateBitmapMask(HBITMAP hSourceBitmap, DWORD dwWidth, DWORD dwHeight, COLORREF crTransColor)
  572. {
  573. HBITMAP hMask = NULL;
  574. HDC hdcSrc = NULL;
  575. HDC hdcDest = NULL;
  576. HBITMAP hbmSrcT = NULL;
  577. HBITMAP hbmDestT = NULL;
  578. COLORREF crSaveBk;
  579. COLORREF crSaveDestText;
  580. hMask = ::CreateBitmap(dwWidth, dwHeight, 1, 1, NULL);
  581. if (hMask == NULL) return NULL;
  582. hdcSrc = ::CreateCompatibleDC(NULL);
  583. hdcDest = ::CreateCompatibleDC(NULL);
  584. hbmSrcT = (HBITMAP)::SelectObject(hdcSrc, hSourceBitmap);
  585. hbmDestT = (HBITMAP)::SelectObject(hdcDest, hMask);
  586. crSaveBk = ::SetBkColor(hdcSrc, crTransColor);
  587. ::BitBlt(hdcDest, 0, 0, dwWidth, dwHeight, hdcSrc, 0, 0, SRCCOPY);
  588. crSaveDestText = ::SetTextColor(hdcSrc, RGB(255, 255, 255));
  589. ::SetBkColor(hdcSrc,RGB(0, 0, 0));
  590. ::BitBlt(hdcSrc, 0, 0, dwWidth, dwHeight, hdcDest, 0, 0, SRCAND);
  591. SetTextColor(hdcDest, crSaveDestText);
  592. ::SetBkColor(hdcSrc, crSaveBk);
  593. ::SelectObject(hdcSrc, hbmSrcT);
  594. ::SelectObject(hdcDest, hbmDestT);
  595. ::DeleteDC(hdcSrc);
  596. ::DeleteDC(hdcDest);
  597. return hMask;
  598. } // End of CreateBitmapMask
  599. //
  600. // Parameters:
  601. // [IN] bHasTitle
  602. // TRUE if the button has a text
  603. // [IN] rpItem
  604. // A pointer to a RECT structure indicating the allowed paint area
  605. // [IN/OUT]rpTitle
  606. // A pointer to a CRect object indicating the paint area reserved for the
  607. // text. This structure will be modified if necessary.
  608. // [IN] bIsPressed
  609. // TRUE if the button is currently pressed
  610. // [IN] dwWidth
  611. // Width of the image (icon or bitmap)
  612. // [IN] dwHeight
  613. // Height of the image (icon or bitmap)
  614. // [OUT] rpImage
  615. // A pointer to a CRect object that will receive the area available to the image
  616. //
  617. void CButtonST::PrepareImageRect(BOOL bHasTitle, RECT* rpItem, CRect* rpTitle, BOOL bIsPressed, DWORD dwWidth, DWORD dwHeight, CRect* rpImage)
  618. {
  619. CRect rBtn;
  620. rpImage->CopyRect(rpItem);
  621. switch (m_byAlign)
  622. {
  623. case ST_ALIGN_HORIZ:
  624. if (bHasTitle == FALSE)
  625. {
  626. // Center image horizontally
  627. rpImage->left += ((rpImage->Width() - (long)dwWidth)/2);
  628. }
  629. else
  630. {
  631. // Image must be placed just inside the focus rect
  632. rpImage->left += 3;  
  633. rpTitle->left += dwWidth + 3;
  634. }
  635. // Center image vertically
  636. rpImage->top += ((rpImage->Height() - (long)dwHeight)/2);
  637. break;
  638. case ST_ALIGN_HORIZ_RIGHT:
  639. GetClientRect(&rBtn);
  640. if (bHasTitle == FALSE)
  641. {
  642. // Center image horizontally
  643. rpImage->left += ((rpImage->Width() - (long)dwWidth)/2);
  644. }
  645. else
  646. {
  647. // Image must be placed just inside the focus rect
  648. rpTitle->right = rpTitle->Width() - dwWidth - 3;
  649. rpTitle->left = 3;
  650. rpImage->left = rBtn.right - dwWidth - 3;
  651. // Center image vertically
  652. rpImage->top += ((rpImage->Height() - (long)dwHeight)/2);
  653. }
  654. break;
  655. case ST_ALIGN_VERT:
  656. // Center image horizontally
  657. rpImage->left += ((rpImage->Width() - (long)dwWidth)/2);
  658. if (bHasTitle == FALSE)
  659. {
  660. // Center image vertically
  661. rpImage->top += ((rpImage->Height() - (long)dwHeight)/2);           
  662. }
  663. else
  664. {
  665. rpImage->top = 3;
  666. rpTitle->top += dwHeight;
  667. }
  668. break;
  669. }
  670.     
  671. // If button is pressed then press image also
  672. if (bIsPressed && m_bIsCheckBox == FALSE)
  673. rpImage->OffsetRect(1, 1);
  674. } // End of PrepareImageRect
  675. void CButtonST::DrawTheIcon(CDC* pDC, BOOL bHasTitle, RECT* rpItem, CRect* rpTitle, BOOL bIsPressed, BOOL bIsDisabled)
  676. {
  677. BYTE byIndex = 0;
  678. // Select the icon to use
  679. if ((m_bIsCheckBox && bIsPressed) || (!m_bIsCheckBox && (bIsPressed || m_bMouseOnButton)))
  680. byIndex = 0;
  681. else
  682. byIndex = (m_csIcons[1].hIcon == NULL ? 0 : 1);
  683. CRect rImage;
  684. PrepareImageRect(bHasTitle, rpItem, rpTitle, bIsPressed, m_csIcons[byIndex].dwWidth, m_csIcons[byIndex].dwHeight, &rImage);
  685. // Ole'!
  686. pDC->DrawState( rImage.TopLeft(),
  687. rImage.Size(), 
  688. m_csIcons[byIndex].hIcon,
  689. (bIsDisabled ? DSS_DISABLED : DSS_NORMAL), 
  690. (CBrush*)NULL);
  691. } // End of DrawTheIcon
  692. void CButtonST::DrawTheBitmap(CDC* pDC, BOOL bHasTitle, RECT* rItem, CRect *rCaption, BOOL bIsPressed, BOOL bIsDisabled)
  693. {
  694. HDC hdcBmpMem = NULL;
  695. HBITMAP hbmOldBmp = NULL;
  696. HDC hdcMem = NULL;
  697. HBITMAP hbmT = NULL;
  698. BYTE byIndex = 0;
  699. // Select the bitmap to use
  700. if ((m_bIsCheckBox && bIsPressed) || (!m_bIsCheckBox && (bIsPressed || m_bMouseOnButton)))
  701. byIndex = 0;
  702. else
  703. byIndex = (m_csBitmaps[1].hBitmap == NULL ? 0 : 1);
  704. CRect rImage;
  705. PrepareImageRect(bHasTitle, rItem, rCaption, bIsPressed, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, &rImage);
  706. hdcBmpMem = ::CreateCompatibleDC(pDC->m_hDC);
  707. hbmOldBmp = (HBITMAP)::SelectObject(hdcBmpMem, m_csBitmaps[byIndex].hBitmap);
  708. hdcMem = ::CreateCompatibleDC(NULL);
  709. hbmT = (HBITMAP)::SelectObject(hdcMem, m_csBitmaps[byIndex].hMask);
  710. if (bIsDisabled && m_bShowDisabledBitmap)
  711. {
  712. HDC hDC = NULL;
  713. HBITMAP hBitmap = NULL;
  714. hDC = ::CreateCompatibleDC(pDC->m_hDC);
  715. hBitmap = ::CreateCompatibleBitmap(pDC->m_hDC, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight);
  716. HBITMAP hOldBmp2 = (HBITMAP)::SelectObject(hDC, hBitmap);
  717. RECT rRect;
  718. rRect.left = 0;
  719. rRect.top = 0;
  720. rRect.right = rImage.right + 1;
  721. rRect.bottom = rImage.bottom + 1;
  722. ::FillRect(hDC, &rRect, (HBRUSH)RGB(255, 255, 255));
  723. COLORREF crOldColor = ::SetBkColor(hDC, RGB(255,255,255));
  724. ::BitBlt(hDC, 0, 0, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, hdcMem, 0, 0, SRCAND);
  725. ::BitBlt(hDC, 0, 0, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, hdcBmpMem, 0, 0, SRCPAINT);
  726. ::SetBkColor(hDC, crOldColor);
  727. ::SelectObject(hDC, hOldBmp2);
  728. ::DeleteDC(hDC);
  729. pDC->DrawState( CPoint(rImage.left/*+1*/, rImage.top), 
  730. CSize(m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight), 
  731. hBitmap, DST_BITMAP | DSS_DISABLED);
  732. ::DeleteObject(hBitmap);
  733. } // if
  734. else
  735. {
  736. ::BitBlt(pDC->m_hDC, rImage.left, rImage.top, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, hdcMem, 0, 0, SRCAND);
  737. ::BitBlt(pDC->m_hDC, rImage.left, rImage.top, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, hdcBmpMem, 0, 0, SRCPAINT);
  738. } // else
  739. ::SelectObject(hdcMem, hbmT);
  740. ::DeleteDC(hdcMem);
  741. ::SelectObject(hdcBmpMem, hbmOldBmp);
  742. ::DeleteDC(hdcBmpMem);
  743. } // End of DrawTheBitmap
  744. // This function creates a grayscale icon starting from a given icon.
  745. // The resulting icon will have the same size of the original one.
  746. //
  747. // Parameters:
  748. // [IN] hIcon
  749. // Handle to the original icon.
  750. //
  751. // Return value:
  752. // If the function succeeds, the return value is the handle to the newly created
  753. // grayscale icon.
  754. // If the function fails, the return value is NULL.
  755. //
  756. HICON CButtonST::CreateGrayscaleIcon(HICON hIcon)
  757. {
  758. HICON hGrayIcon = NULL;
  759. HDC hMainDC = NULL, hMemDC1 = NULL, hMemDC2 = NULL;
  760. BITMAP bmp;
  761. HBITMAP hOldBmp1 = NULL, hOldBmp2 = NULL;
  762. ICONINFO csII, csGrayII;
  763. BOOL bRetValue = FALSE;
  764. bRetValue = ::GetIconInfo(hIcon, &csII);
  765. if (bRetValue == FALSE) return NULL;
  766. hMainDC = ::GetDC(m_hWnd);
  767. hMemDC1 = ::CreateCompatibleDC(hMainDC);
  768. hMemDC2 = ::CreateCompatibleDC(hMainDC);
  769. if (hMainDC == NULL || hMemDC1 == NULL || hMemDC2 == NULL) return NULL;
  770.   
  771. if (::GetObject(csII.hbmColor, sizeof(BITMAP), &bmp))
  772. {
  773. csGrayII.hbmColor = ::CreateBitmap(csII.xHotspot*2, csII.yHotspot*2, bmp.bmPlanes, bmp.bmBitsPixel, NULL);
  774. if (csGrayII.hbmColor)
  775. {
  776. hOldBmp1 = (HBITMAP)::SelectObject(hMemDC1, csII.hbmColor);
  777. hOldBmp2 = (HBITMAP)::SelectObject(hMemDC2, csGrayII.hbmColor);
  778. ::BitBlt(hMemDC2, 0, 0, csII.xHotspot*2, csII.yHotspot*2, hMemDC1, 0, 0, SRCCOPY);
  779. DWORD dwLoopY = 0, dwLoopX = 0;
  780. COLORREF crPixel = 0;
  781. BYTE byNewPixel = 0;
  782. for (dwLoopY = 0; dwLoopY < csII.yHotspot*2; dwLoopY++)
  783. {
  784. for (dwLoopX = 0; dwLoopX < csII.xHotspot*2; dwLoopX++)
  785. {
  786. crPixel = ::GetPixel(hMemDC2, dwLoopX, dwLoopY);
  787. byNewPixel = (BYTE)((GetRValue(crPixel) * 0.299) + (GetGValue(crPixel) * 0.587) + (GetBValue(crPixel) * 0.114));
  788. if (crPixel) ::SetPixel(hMemDC2, dwLoopX, dwLoopY, RGB(byNewPixel, byNewPixel, byNewPixel));
  789. } // for
  790. } // for
  791. ::SelectObject(hMemDC1, hOldBmp1);
  792. ::SelectObject(hMemDC2, hOldBmp2);
  793. csGrayII.hbmMask = csII.hbmMask;
  794. csGrayII.fIcon = TRUE;
  795. hGrayIcon = ::CreateIconIndirect(&csGrayII);
  796. } // if
  797. ::DeleteObject(csGrayII.hbmColor);
  798. //::DeleteObject(csGrayII.hbmMask);
  799. } // if
  800. ::DeleteObject(csII.hbmColor);
  801. ::DeleteObject(csII.hbmMask);
  802. ::DeleteDC(hMemDC1);
  803. ::DeleteDC(hMemDC2);
  804. ::ReleaseDC(m_hWnd, hMainDC);
  805. return hGrayIcon;
  806. } // End of CreateGrayscaleIcon
  807. // This function assigns icons to the button.
  808. // Any previous icon or bitmap will be removed.
  809. //
  810. // Parameters:
  811. // [IN] nIconIn
  812. // ID number of the icon resource to show when the mouse is over the button.
  813. // Pass NULL to remove any icon from the button.
  814. // [IN] nIconOut
  815. // ID number of the icon resource to show when the mouse is outside the button.
  816. // Can be NULL.
  817. //
  818. // Return value:
  819. // BTNST_OK
  820. // Function executed successfully.
  821. // BTNST_INVALIDRESOURCE
  822. // Failed loading the specified resource.
  823. //
  824. DWORD CButtonST::SetIcon(int nIconIn, int nIconOut)
  825. {
  826. HICON hIconIn = NULL;
  827. HICON hIconOut = NULL;
  828. HINSTANCE hInstResource = NULL;
  829. // Find correct resource handle
  830. hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nIconIn), RT_GROUP_ICON);
  831. // Set icon when the mouse is IN the button
  832. hIconIn = (HICON)::LoadImage(hInstResource, MAKEINTRESOURCE(nIconIn), IMAGE_ICON, 0, 0, 0);
  833.    // Set icon when the mouse is OUT the button
  834. if (nIconOut)
  835. {
  836. if (nIconOut == (int)BTNST_AUTO_GRAY)
  837. hIconOut = BTNST_AUTO_GRAY;
  838. else
  839. hIconOut = (HICON)::LoadImage(hInstResource, MAKEINTRESOURCE(nIconOut), IMAGE_ICON, 0, 0, 0);
  840. } // if
  841. return SetIcon(hIconIn, hIconOut);
  842. } // End of SetIcon
  843. // This function assigns icons to the button.
  844. // Any previous icon or bitmap will be removed.
  845. //
  846. // Parameters:
  847. // [IN] hIconIn
  848. // Handle fo the icon to show when the mouse is over the button.
  849. // Pass NULL to remove any icon from the button.
  850. // [IN] hIconOut
  851. // Handle to the icon to show when the mouse is outside the button.
  852. // Can be NULL.
  853. //
  854. // Return value:
  855. // BTNST_OK
  856. // Function executed successfully.
  857. // BTNST_INVALIDRESOURCE
  858. // Failed loading the specified resource.
  859. //
  860. DWORD CButtonST::SetIcon(HICON hIconIn, HICON hIconOut)
  861. {
  862. BOOL bRetValue;
  863. ICONINFO ii;
  864. // Free any loaded resource
  865. FreeResources();
  866. if (hIconIn)
  867. {
  868. // Icon when mouse over button?
  869. m_csIcons[0].hIcon = hIconIn;
  870. // Get icon dimension
  871. ::ZeroMemory(&ii, sizeof(ICONINFO));
  872. bRetValue = ::GetIconInfo(hIconIn, &ii);
  873. if (bRetValue == FALSE)
  874. {
  875. FreeResources();
  876. return BTNST_INVALIDRESOURCE;
  877. } // if
  878. m_csIcons[0].dwWidth = (DWORD)(ii.xHotspot * 2);
  879. m_csIcons[0].dwHeight = (DWORD)(ii.yHotspot * 2);
  880. ::DeleteObject(ii.hbmMask);
  881. ::DeleteObject(ii.hbmColor);
  882. // Icon when mouse outside button?
  883. if (hIconOut)
  884. {
  885. if (hIconOut == BTNST_AUTO_GRAY)
  886. {
  887. hIconOut = CreateGrayscaleIcon(hIconIn);
  888. } // if
  889. m_csIcons[1].hIcon = hIconOut;
  890. // Get icon dimension
  891. ::ZeroMemory(&ii, sizeof(ICONINFO));
  892. bRetValue = ::GetIconInfo(hIconOut, &ii);
  893. if (bRetValue == FALSE)
  894. {
  895. FreeResources();
  896. return BTNST_INVALIDRESOURCE;
  897. } // if
  898. m_csIcons[1].dwWidth = (DWORD)(ii.xHotspot * 2);
  899. m_csIcons[1].dwHeight = (DWORD)(ii.yHotspot * 2);
  900. ::DeleteObject(ii.hbmMask);
  901. ::DeleteObject(ii.hbmColor);
  902. } // if
  903. } // if
  904. Invalidate();
  905. return BTNST_OK;
  906. } // End of SetIcon
  907. // This function assigns bitmaps to the button.
  908. // Any previous icon or bitmap will be removed.
  909. //
  910. // Parameters:
  911. // [IN] nBitmapIn
  912. // ID number of the bitmap resource to show when the mouse is over the button.
  913. // Pass NULL to remove any bitmap from the button.
  914. // [IN] crTransColorIn
  915. // Color (inside nBitmapIn) to be used as transparent color.
  916. // [IN] nBitmapOut
  917. // ID number of the bitmap resource to show when the mouse is outside the button.
  918. // Can be NULL.
  919. // [IN] crTransColorOut
  920. // Color (inside nBitmapOut) to be used as transparent color.
  921. //
  922. // Return value:
  923. // BTNST_OK
  924. // Function executed successfully.
  925. // BTNST_INVALIDRESOURCE
  926. // Failed loading the specified resource.
  927. // BTNST_FAILEDMASK
  928. // Failed creating mask bitmap.
  929. //
  930. DWORD CButtonST::SetBitmaps(int nBitmapIn, COLORREF crTransColorIn, int nBitmapOut, COLORREF crTransColorOut)
  931. {
  932. HBITMAP hBitmapIn = NULL;
  933. HBITMAP hBitmapOut = NULL;
  934. HINSTANCE hInstResource = NULL;
  935. // Find correct resource handle
  936. hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nBitmapIn), RT_BITMAP);
  937. // Load bitmap In
  938. hBitmapIn = (HBITMAP)::LoadImage(hInstResource, MAKEINTRESOURCE(nBitmapIn), IMAGE_BITMAP, 0, 0, 0);
  939. // Load bitmap Out
  940. if (nBitmapOut)
  941. hBitmapOut = (HBITMAP)::LoadImage(hInstResource, MAKEINTRESOURCE(nBitmapOut), IMAGE_BITMAP, 0, 0, 0);
  942. return SetBitmaps(hBitmapIn, crTransColorIn, hBitmapOut, crTransColorOut);
  943. } // End of SetBitmaps
  944. // This function assigns bitmaps to the button.
  945. // Any previous icon or bitmap will be removed.
  946. //
  947. // Parameters:
  948. // [IN] hBitmapIn
  949. // Handle fo the bitmap to show when the mouse is over the button.
  950. // Pass NULL to remove any bitmap from the button.
  951. // [IN] crTransColorIn
  952. // Color (inside hBitmapIn) to be used as transparent color.
  953. // [IN] hBitmapOut
  954. // Handle to the bitmap to show when the mouse is outside the button.
  955. // Can be NULL.
  956. // [IN] crTransColorOut
  957. // Color (inside hBitmapOut) to be used as transparent color.
  958. //
  959. // Return value:
  960. // BTNST_OK
  961. // Function executed successfully.
  962. // BTNST_INVALIDRESOURCE
  963. // Failed loading the specified resource.
  964. // BTNST_FAILEDMASK
  965. // Failed creating mask bitmap.
  966. //
  967. DWORD CButtonST::SetBitmaps(HBITMAP hBitmapIn, COLORREF crTransColorIn, HBITMAP hBitmapOut, COLORREF crTransColorOut)
  968. {
  969. int nRetValue;
  970. BITMAP csBitmapSize;
  971. // Free any loaded resource
  972. FreeResources();
  973. if (hBitmapIn)
  974. {
  975. m_csBitmaps[0].hBitmap = hBitmapIn;
  976. m_csBitmaps[0].crTransparent = crTransColorIn;
  977. // Get bitmap size
  978. nRetValue = ::GetObject(hBitmapIn, sizeof(csBitmapSize), &csBitmapSize);
  979. if (nRetValue == 0)
  980. {
  981. FreeResources();
  982. return BTNST_INVALIDRESOURCE;
  983. } // if
  984. m_csBitmaps[0].dwWidth = (DWORD)csBitmapSize.bmWidth;
  985. m_csBitmaps[0].dwHeight = (DWORD)csBitmapSize.bmHeight;
  986. // Create mask for bitmap In
  987. m_csBitmaps[0].hMask = CreateBitmapMask(hBitmapIn, m_csBitmaps[0].dwWidth, m_csBitmaps[0].dwHeight, crTransColorIn);
  988. if (m_csBitmaps[0].hMask == NULL)
  989. {
  990. FreeResources();
  991. return BTNST_FAILEDMASK;
  992. } // if
  993. if (hBitmapOut)
  994. {
  995. m_csBitmaps[1].hBitmap = hBitmapOut;
  996. m_csBitmaps[1].crTransparent = crTransColorOut;
  997. // Get bitmap size
  998. nRetValue = ::GetObject(hBitmapOut, sizeof(csBitmapSize), &csBitmapSize);
  999. if (nRetValue == 0)
  1000. {
  1001. FreeResources();
  1002. return BTNST_INVALIDRESOURCE;
  1003. } // if
  1004. m_csBitmaps[1].dwWidth = (DWORD)csBitmapSize.bmWidth;
  1005. m_csBitmaps[1].dwHeight = (DWORD)csBitmapSize.bmHeight;
  1006. // Create mask for bitmap Out
  1007. m_csBitmaps[1].hMask = CreateBitmapMask(hBitmapOut, m_csBitmaps[1].dwWidth, m_csBitmaps[1].dwHeight, crTransColorOut);
  1008. if (m_csBitmaps[1].hMask == NULL)
  1009. {
  1010. FreeResources();
  1011. return BTNST_FAILEDMASK;
  1012. } // if
  1013. } // if
  1014. } // if
  1015. Invalidate();
  1016. return BTNST_OK;
  1017. } // End of SetBitmaps
  1018. // This functions sets the button to have a standard or flat style.
  1019. //
  1020. // Parameters:
  1021. // [IN] bFlat
  1022. // If TRUE the button will have a flat style, else
  1023. // will have a standard style.
  1024. // By default, CButtonST buttons are flat.
  1025. // [IN] bRepaint
  1026. // If TRUE the control will be repainted.
  1027. //
  1028. // Return value:
  1029. // BTNST_OK
  1030. // Function executed successfully.
  1031. //
  1032. DWORD CButtonST::SetFlat(BOOL bFlat, BOOL bRepaint)
  1033. {
  1034. m_bIsFlat = bFlat;
  1035. if (bRepaint) Invalidate();
  1036. return BTNST_OK;
  1037. } // End of SetFlat
  1038. // This function sets the alignment type between icon/bitmap and text.
  1039. //
  1040. // Parameters:
  1041. // [IN] byAlign
  1042. // Alignment type. Can be one of the following values:
  1043. // ST_ALIGN_HORIZ Icon/bitmap on the left, text on the right
  1044. // ST_ALIGN_VERT Icon/bitmap on the top, text on the bottom
  1045. // ST_ALIGN_HORIZ_RIGHT Icon/bitmap on the right, text on the left
  1046. // By default, CButtonST buttons have ST_ALIGN_HORIZ alignment.
  1047. // [IN] bRepaint
  1048. // If TRUE the control will be repainted.
  1049. //
  1050. // Return value:
  1051. // BTNST_OK
  1052. // Function executed successfully.
  1053. // BTNST_INVALIDALIGN
  1054. // Alignment type not supported.
  1055. //
  1056. DWORD CButtonST::SetAlign(BYTE byAlign, BOOL bRepaint)
  1057. {
  1058. switch (byAlign)
  1059. {    
  1060. case ST_ALIGN_HORIZ:
  1061. case ST_ALIGN_HORIZ_RIGHT:
  1062. case ST_ALIGN_VERT:
  1063. m_byAlign = byAlign;
  1064. if (bRepaint) Invalidate();
  1065. return BTNST_OK;
  1066. break;
  1067. } // switch
  1068. return BTNST_INVALIDALIGN;
  1069. } // End of SetAlign
  1070. // This function sets the state of the checkbox.
  1071. // If the button is not a checkbox, this function has no meaning.
  1072. //
  1073. // Parameters:
  1074. // [IN] nCheck
  1075. // 1 to check the checkbox.
  1076. // 0 to un-check the checkbox.
  1077. // [IN] bRepaint
  1078. // If TRUE the control will be repainted.
  1079. //
  1080. // Return value:
  1081. // BTNST_OK
  1082. // Function executed successfully.
  1083. //
  1084. DWORD CButtonST::SetCheck(int nCheck, BOOL bRepaint)
  1085. {
  1086. if (m_bIsCheckBox)
  1087. {
  1088. if (nCheck == 0) m_nCheck = 0;
  1089. else m_nCheck = 1;
  1090. if (bRepaint) Invalidate();
  1091. } // if
  1092. return BTNST_OK;
  1093. } // End of SetCheck
  1094. // This function returns the current state of the checkbox.
  1095. // If the button is not a checkbox, this function has no meaning.
  1096. //
  1097. // Return value:
  1098. // The current state of the checkbox.
  1099. // 1 if checked.
  1100. // 0 if not checked or the button is not a checkbox.
  1101. //
  1102. int CButtonST::GetCheck()
  1103. {
  1104. return m_nCheck;
  1105. } // End of GetCheck
  1106. // This function sets all colors to a default value.
  1107. //
  1108. // Parameters:
  1109. // [IN] bRepaint
  1110. // If TRUE the control will be repainted.
  1111. //
  1112. // Return value:
  1113. // BTNST_OK
  1114. // Function executed successfully.
  1115. //
  1116. DWORD CButtonST::SetDefaultColors(BOOL bRepaint)
  1117. {
  1118. m_crColors[BTNST_COLOR_BK_IN] = ::GetSysColor(COLOR_BTNFACE);
  1119. m_crColors[BTNST_COLOR_FG_IN] = ::GetSysColor(COLOR_BTNTEXT);
  1120. m_crColors[BTNST_COLOR_BK_OUT] = ::GetSysColor(COLOR_BTNFACE);
  1121. m_crColors[BTNST_COLOR_FG_OUT] = ::GetSysColor(COLOR_BTNTEXT);
  1122. m_crColors[BTNST_COLOR_BK_FOCUS] = ::GetSysColor(COLOR_BTNFACE);
  1123. m_crColors[BTNST_COLOR_FG_FOCUS] = ::GetSysColor(COLOR_BTNTEXT);
  1124. if (bRepaint) Invalidate();
  1125. return BTNST_OK;
  1126. } // End of SetDefaultColors
  1127. // This function sets the color to use for a particular state.
  1128. //
  1129. // Parameters:
  1130. // [IN] byColorIndex
  1131. // Index of the color to set. Can be one of the following values:
  1132. // BTNST_COLOR_BK_IN Background color when mouse is over the button
  1133. // BTNST_COLOR_FG_IN Text color when mouse is over the button
  1134. // BTNST_COLOR_BK_OUT Background color when mouse is outside the button
  1135. // BTNST_COLOR_FG_OUT Text color when mouse is outside the button
  1136. // BTNST_COLOR_BK_FOCUS Background color when the button is focused
  1137. // BTNST_COLOR_FG_FOCUS Text color when the button is focused
  1138. // [IN] crColor
  1139. // New color.
  1140. // [IN] bRepaint
  1141. // If TRUE the control will be repainted.
  1142. //
  1143. // Return value:
  1144. // BTNST_OK
  1145. // Function executed successfully.
  1146. // BTNST_INVALIDINDEX
  1147. // Invalid color index.
  1148. //
  1149. DWORD CButtonST::SetColor(BYTE byColorIndex, COLORREF crColor, BOOL bRepaint)
  1150. {
  1151. if (byColorIndex >= BTNST_MAX_COLORS) return BTNST_INVALIDINDEX;
  1152. // Set new color
  1153. m_crColors[byColorIndex] = crColor;
  1154. if (bRepaint) Invalidate();
  1155. return BTNST_OK;
  1156. } // End of SetColor
  1157. // This functions returns the color used for a particular state.
  1158. //
  1159. // Parameters:
  1160. // [IN] byColorIndex
  1161. // Index of the color to get.
  1162. // See SetColor for the list of available colors.
  1163. // [OUT] crpColor
  1164. // A pointer to a COLORREF that will receive the color.
  1165. //
  1166. // Return value:
  1167. // BTNST_OK
  1168. // Function executed successfully.
  1169. // BTNST_INVALIDINDEX
  1170. // Invalid color index.
  1171. //
  1172. DWORD CButtonST::GetColor(BYTE byColorIndex, COLORREF* crpColor)
  1173. {
  1174. if (byColorIndex >= BTNST_MAX_COLORS) return BTNST_INVALIDINDEX;
  1175. // Get color
  1176. *crpColor = m_crColors[byColorIndex];
  1177. return BTNST_OK;
  1178. } // End of GetColor
  1179. // This function applies an offset to the RGB components of the specified color.
  1180. // This function can be seen as an easy way to make a color darker or lighter than
  1181. // its default value.
  1182. //
  1183. // Parameters:
  1184. // [IN] byColorIndex
  1185. // Index of the color to set.
  1186. // See SetColor for the list of available colors.
  1187. // [IN] shOffsetColor
  1188. // A short value indicating the offset to apply to the color.
  1189. // This value must be between -255 and 255.
  1190. // [IN] bRepaint
  1191. // If TRUE the control will be repainted.
  1192. //
  1193. // Return value:
  1194. // BTNST_OK
  1195. // Function executed successfully.
  1196. // BTNST_INVALIDINDEX
  1197. // Invalid color index.
  1198. // BTNST_BADPARAM
  1199. // The specified offset is out of range.
  1200. //
  1201. DWORD CButtonST::OffsetColor(BYTE byColorIndex, short shOffset, BOOL bRepaint)
  1202. {
  1203. BYTE byRed = 0;
  1204. BYTE byGreen = 0;
  1205. BYTE byBlue = 0;
  1206. short shOffsetR = shOffset;
  1207. short shOffsetG = shOffset;
  1208. short shOffsetB = shOffset;
  1209. if (byColorIndex >= BTNST_MAX_COLORS) return BTNST_INVALIDINDEX;
  1210. if (shOffset < -255 || shOffset > 255) return BTNST_BADPARAM;
  1211. // Get RGB components of specified color
  1212. byRed = GetRValue(m_crColors[byColorIndex]);
  1213. byGreen = GetGValue(m_crColors[byColorIndex]);
  1214. byBlue = GetBValue(m_crColors[byColorIndex]);
  1215. // Calculate max. allowed real offset
  1216. if (shOffset > 0)
  1217. {
  1218. if (byRed + shOffset > 255) shOffsetR = 255 - byRed;
  1219. if (byGreen + shOffset > 255) shOffsetG = 255 - byGreen;
  1220. if (byBlue + shOffset > 255) shOffsetB = 255 - byBlue;
  1221. shOffset = min(min(shOffsetR, shOffsetG), shOffsetB);
  1222. } // if
  1223. else
  1224. {
  1225. if (byRed + shOffset < 0) shOffsetR = -byRed;
  1226. if (byGreen + shOffset < 0) shOffsetG = -byGreen;
  1227. if (byBlue + shOffset < 0) shOffsetB = -byBlue;
  1228. shOffset = max(max(shOffsetR, shOffsetG), shOffsetB);
  1229. } // else
  1230. // Set new color
  1231. m_crColors[byColorIndex] = RGB(byRed + shOffset, byGreen + shOffset, byBlue + shOffset);
  1232. if (bRepaint) Invalidate();
  1233. return BTNST_OK;
  1234. } // End of OffsetColor
  1235. // This function sets the hilight logic for the button.
  1236. // Applies only to flat buttons.
  1237. //
  1238. // Parameters:
  1239. // [IN] bAlwaysTrack
  1240. // If TRUE the button will be hilighted even if the window that owns it, is
  1241. // not the active window.
  1242. // If FALSE the button will be hilighted only if the window that owns it,
  1243. // is the active window.
  1244. //
  1245. // Return value:
  1246. // BTNST_OK
  1247. // Function executed successfully.
  1248. //
  1249. DWORD CButtonST::SetAlwaysTrack(BOOL bAlwaysTrack)
  1250. {
  1251. m_bAlwaysTrack = bAlwaysTrack;
  1252. return BTNST_OK;
  1253. } // End of SetAlwaysTrack
  1254. // This function sets the cursor to be used when the mouse is over the button.
  1255. //
  1256. // Parameters:
  1257. // [IN] nCursorId
  1258. // ID number of the cursor resource.
  1259. // Pass NULL to remove a previously loaded cursor.
  1260. // [IN] bRepaint
  1261. // If TRUE the control will be repainted.
  1262. //
  1263. // Return value:
  1264. // BTNST_OK
  1265. // Function executed successfully.
  1266. // BTNST_INVALIDRESOURCE
  1267. // Failed loading the specified resource.
  1268. //
  1269. DWORD CButtonST::SetBtnCursor(int nCursorId, BOOL bRepaint)
  1270. {
  1271. HINSTANCE hInstResource = NULL;
  1272. // Destroy any previous cursor
  1273. if (m_hCursor)
  1274. {
  1275. ::DestroyCursor(m_hCursor);
  1276. m_hCursor = NULL;
  1277. } // if
  1278. // Load cursor
  1279. if (nCursorId)
  1280. {
  1281. hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nCursorId), RT_GROUP_CURSOR);
  1282. // Load cursor resource
  1283. m_hCursor = (HCURSOR)::LoadImage(hInstResource, MAKEINTRESOURCE(nCursorId), IMAGE_CURSOR, 0, 0, 0);
  1284. // Repaint the button
  1285. if (bRepaint) Invalidate();
  1286. // If something wrong
  1287. if (m_hCursor == NULL) return BTNST_INVALIDRESOURCE;
  1288. } // if
  1289. return BTNST_OK;
  1290. } // End of SetBtnCursor
  1291. // This function sets if the button border must be drawn.
  1292. // Applies only to flat buttons.
  1293. //
  1294. // Parameters:
  1295. // [IN] bDrawBorder
  1296. // If TRUE the border will be drawn.
  1297. // [IN] bRepaint
  1298. // If TRUE the control will be repainted.
  1299. //
  1300. // Return value:
  1301. // BTNST_OK
  1302. // Function executed successfully.
  1303. //
  1304. DWORD CButtonST::DrawBorder(BOOL bDrawBorder, BOOL bRepaint)
  1305. {
  1306. m_bDrawBorder = bDrawBorder;
  1307. // Repaint the button
  1308. if (bRepaint) Invalidate();
  1309. return BTNST_OK;
  1310. } // End of DrawBorder
  1311. // This function sets if the focus rectangle must be drawn for flat buttons.
  1312. //
  1313. // Parameters:
  1314. // [IN] bDrawFlatFocus
  1315. // If TRUE the focus rectangle will be drawn also for flat buttons.
  1316. // [IN] bRepaint
  1317. // If TRUE the control will be repainted.
  1318. //
  1319. // Return value:
  1320. // BTNST_OK
  1321. // Function executed successfully.
  1322. //
  1323. DWORD CButtonST::DrawFlatFocus(BOOL bDrawFlatFocus, BOOL bRepaint)
  1324. {
  1325. m_bDrawFlatFocus = bDrawFlatFocus;
  1326. // Repaint the button
  1327. if (bRepaint) Invalidate();
  1328. return BTNST_OK;
  1329. } // End of DrawFlatFocus
  1330. void CButtonST::InitToolTip()
  1331. {
  1332. if (m_ToolTip.m_hWnd == NULL)
  1333. {
  1334. // Create ToolTip control
  1335. m_ToolTip.Create(this);
  1336. // Create inactive
  1337. m_ToolTip.Activate(FALSE);
  1338. // Enable multiline
  1339. m_ToolTip.SendMessage(TTM_SETMAXTIPWIDTH, 0, 400);
  1340. } // if
  1341. } // End of InitToolTip
  1342. // This function sets the text to show in the button tooltip.
  1343. //
  1344. // Parameters:
  1345. // [IN] nText
  1346. // ID number of the string resource containing the text to show.
  1347. // [IN] bActivate
  1348. // If TRUE the tooltip will be created active.
  1349. //
  1350. void CButtonST::SetTooltipText(int nText, BOOL bActivate)
  1351. {
  1352. CString sText;
  1353. // Load string resource
  1354. sText.LoadString(nText);
  1355. // If string resource is not empty
  1356. if (sText.IsEmpty() == FALSE) SetTooltipText((LPCTSTR)sText, bActivate);
  1357. } // End of SetTooltipText
  1358. // This function sets the text to show in the button tooltip.
  1359. //
  1360. // Parameters:
  1361. // [IN] lpszText
  1362. // Pointer to a null-terminated string containing the text to show.
  1363. // [IN] bActivate
  1364. // If TRUE the tooltip will be created active.
  1365. //
  1366. void CButtonST::SetTooltipText(LPCTSTR lpszText, BOOL bActivate)
  1367. {
  1368. // We cannot accept NULL pointer
  1369. if (lpszText == NULL) return;
  1370. // Initialize ToolTip
  1371. InitToolTip();
  1372. // If there is no tooltip defined then add it
  1373. if (m_ToolTip.GetToolCount() == 0)
  1374. {
  1375. CRect rectBtn; 
  1376. GetClientRect(rectBtn);
  1377. m_ToolTip.AddTool(this, lpszText, rectBtn, 1);
  1378. } // if
  1379. // Set text for tooltip
  1380. m_ToolTip.UpdateTipText(lpszText, this, 1);
  1381. m_ToolTip.Activate(bActivate);
  1382. } // End of SetTooltipText
  1383. // This function enables or disables the button tooltip.
  1384. //
  1385. // Parameters:
  1386. // [IN] bActivate
  1387. // If TRUE the tooltip will be activated.
  1388. //
  1389. void CButtonST::ActivateTooltip(BOOL bActivate)
  1390. {
  1391. // If there is no tooltip then do nothing
  1392. if (m_ToolTip.GetToolCount() == 0) return;
  1393. // Activate tooltip
  1394. m_ToolTip.Activate(bActivate);
  1395. } // End of EnableTooltip
  1396. // This function returns if the button is the default button.
  1397. //
  1398. // Return value:
  1399. // TRUE
  1400. // The button is the default button.
  1401. // FALSE
  1402. // The button is not the default button.
  1403. //
  1404. BOOL CButtonST::GetDefault()
  1405. {
  1406. return m_bIsDefault;
  1407. } // End of GetDefault
  1408. // This function enables the transparent mode.
  1409. // Note: this operation is not reversible.
  1410. // DrawTransparent should be called just after the button is created.
  1411. // Do not use trasparent buttons until you really need it (you have a bitmapped
  1412. // background) since each transparent button makes a copy in memory of its background.
  1413. // This may bring unnecessary memory use and execution overload.
  1414. //
  1415. // Parameters:
  1416. // [IN] bRepaint
  1417. // If TRUE the control will be repainted.
  1418. //
  1419. void CButtonST::DrawTransparent(BOOL bRepaint)
  1420. {
  1421. m_bDrawTransparent = TRUE;
  1422. // Restore old bitmap (if any)
  1423. if (m_dcBk.m_hDC != NULL && m_pbmpOldBk != NULL)
  1424. {
  1425. m_dcBk.SelectObject(m_pbmpOldBk);
  1426. } // if
  1427. m_bmpBk.DeleteObject();
  1428. m_dcBk.DeleteDC();
  1429. // Repaint the button
  1430. if (bRepaint) Invalidate();
  1431. } // End of DrawTransparent
  1432. // This function sets the URL that will be opened when the button is clicked.
  1433. //
  1434. // Parameters:
  1435. // [IN] lpszURL
  1436. // Pointer to a null-terminated string that contains the URL.
  1437. // Pass NULL to removed any previously specified URL.
  1438. //
  1439. // Return value:
  1440. // BTNST_OK
  1441. // Function executed successfully.
  1442. //
  1443. DWORD CButtonST::SetURL(LPCTSTR lpszURL)
  1444. {
  1445. // Remove any existing URL
  1446. memset(m_szURL, 0, sizeof(m_szURL));
  1447. if (lpszURL)
  1448. {
  1449. // Store the URL
  1450. _tcsncpy(m_szURL, lpszURL, _MAX_PATH);
  1451. } // if
  1452. return BTNST_OK;
  1453. } // End of SetURL
  1454. // This function associates a menu to the button.
  1455. // The menu will be displayed clicking the button.
  1456. //
  1457. // Parameters:
  1458. // [IN] nMenu
  1459. // ID number of the menu resource.
  1460. // Pass NULL to remove any menu from the button.
  1461. // [IN] hParentWnd
  1462. // Handle to the window that owns the menu.
  1463. // This window receives all messages from the menu.
  1464. // [IN] bRepaint
  1465. // If TRUE the control will be repainted.
  1466. //
  1467. // Return value:
  1468. // BTNST_OK
  1469. // Function executed successfully.
  1470. // BTNST_INVALIDRESOURCE
  1471. // Failed loading the specified resource.
  1472. //
  1473. #ifndef BTNST_USE_BCMENU
  1474. DWORD CButtonST::SetMenu(UINT nMenu, HWND hParentWnd, BOOL bRepaint)
  1475. {
  1476. HINSTANCE hInstResource = NULL;
  1477. // Destroy any previous menu
  1478. if (m_hMenu)
  1479. {
  1480. ::DestroyMenu(m_hMenu);
  1481. m_hMenu = NULL;
  1482. m_hParentWndMenu = NULL;
  1483. m_bMenuDisplayed = FALSE;
  1484. } // if
  1485. // Load menu
  1486. if (nMenu)
  1487. {
  1488. // Find correct resource handle
  1489. hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nMenu), RT_MENU);
  1490. // Load menu resource
  1491. m_hMenu = ::LoadMenu(hInstResource, MAKEINTRESOURCE(nMenu));
  1492. m_hParentWndMenu = hParentWnd;
  1493. // If something wrong
  1494. if (m_hMenu == NULL) return BTNST_INVALIDRESOURCE;
  1495. } // if
  1496. // Repaint the button
  1497. if (bRepaint) Invalidate();
  1498. return BTNST_OK;
  1499. } // End of SetMenu
  1500. #endif
  1501. // This function associates a menu to the button.
  1502. // The menu will be displayed clicking the button.
  1503. // The menu will be handled by the BCMenu class.
  1504. //
  1505. // Parameters:
  1506. // [IN] nMenu
  1507. // ID number of the menu resource.
  1508. // Pass NULL to remove any menu from the button.
  1509. // [IN] hParentWnd
  1510. // Handle to the window that owns the menu.
  1511. // This window receives all messages from the menu.
  1512. // [IN] bWinXPStyle
  1513. // If TRUE the menu will be displayed using the new Windows XP style.
  1514. // If FALSE the menu will be displayed using the standard style.
  1515. // [IN] nToolbarID
  1516. // Resource ID of the toolbar to be associated to the menu.
  1517. // [IN] sizeToolbarIcon
  1518. // A CSize object indicating the size (in pixels) of each icon into the toolbar.
  1519. // All icons into the toolbar must have the same size.
  1520. // [IN] crToolbarBk
  1521. // A COLORREF value indicating the color to use as background for the icons into the toolbar.
  1522. // This color will be used as the "transparent" color.
  1523. // [IN] bRepaint
  1524. // If TRUE the control will be repainted.
  1525. //
  1526. // Return value:
  1527. // BTNST_OK
  1528. // Function executed successfully.
  1529. // BTNST_INVALIDRESOURCE
  1530. // Failed loading the specified resource.
  1531. //
  1532. #ifdef BTNST_USE_BCMENU
  1533. DWORD CButtonST::SetMenu(UINT nMenu, HWND hParentWnd, BOOL bWinXPStyle, UINT nToolbarID, CSize sizeToolbarIcon, COLORREF crToolbarBk, BOOL bRepaint)
  1534. {
  1535. BOOL bRetValue = FALSE;
  1536. // Destroy any previous menu
  1537. if (m_menuPopup.m_hMenu)
  1538. {
  1539. m_menuPopup.DestroyMenu();
  1540. m_hParentWndMenu = NULL;
  1541. m_bMenuDisplayed = FALSE;
  1542. } // if
  1543. // Load menu
  1544. if (nMenu)
  1545. {
  1546. m_menuPopup.SetMenuDrawMode(bWinXPStyle);
  1547. // Load menu
  1548. bRetValue = m_menuPopup.LoadMenu(nMenu);
  1549. // If something wrong
  1550. if (bRetValue == FALSE) return BTNST_INVALIDRESOURCE;
  1551. // Load toolbar
  1552. if (nToolbarID)
  1553. {
  1554. m_menuPopup.SetBitmapBackground(crToolbarBk);
  1555. m_menuPopup.SetIconSize(sizeToolbarIcon.cx, sizeToolbarIcon.cy);
  1556. bRetValue = m_menuPopup.LoadToolbar(nToolbarID);
  1557. // If something wrong
  1558. if (bRetValue == FALSE) 
  1559. {
  1560. m_menuPopup.DestroyMenu();
  1561. return BTNST_INVALIDRESOURCE;
  1562. } // if
  1563. } // if
  1564. m_hParentWndMenu = hParentWnd;
  1565. } // if
  1566. // Repaint the button
  1567. if (bRepaint) Invalidate();
  1568. return BTNST_OK;
  1569. } // End of SetMenu
  1570. #endif
  1571. // This function is called every time the button background needs to be painted.
  1572. // If the button is in transparent mode this function will NOT be called.
  1573. // This is a virtual function that can be rewritten in CButtonST-derived classes
  1574. // to produce a whole range of buttons not available by default.
  1575. //
  1576. // Parameters:
  1577. // [IN] pDC
  1578. // Pointer to a CDC object that indicates the device context.
  1579. // [IN] pRect
  1580. // Pointer to a CRect object that indicates the bounds of the
  1581. // area to be painted.
  1582. //
  1583. // Return value:
  1584. // BTNST_OK
  1585. // Function executed successfully.
  1586. //
  1587. DWORD CButtonST::OnDrawBackground(CDC* pDC, LPCRECT pRect)
  1588. {
  1589. COLORREF crColor;
  1590. if (m_bMouseOnButton || m_bIsPressed)
  1591. crColor = m_crColors[BTNST_COLOR_BK_IN];
  1592. else
  1593. {
  1594. if (m_bIsFocused)
  1595. crColor = m_crColors[BTNST_COLOR_BK_FOCUS];
  1596. else
  1597. crColor = m_crColors[BTNST_COLOR_BK_OUT];
  1598. } // else
  1599. CBrush brBackground(crColor);
  1600. pDC->FillRect(pRect, &brBackground);
  1601. return BTNST_OK;
  1602. } // End of OnDrawBackground
  1603. // This function is called every time the button border needs to be painted.
  1604. // If the button is in standard (not flat) mode this function will NOT be called.
  1605. // This is a virtual function that can be rewritten in CButtonST-derived classes
  1606. // to produce a whole range of buttons not available by default.
  1607. //
  1608. // Parameters:
  1609. // [IN] pDC
  1610. // Pointer to a CDC object that indicates the device context.
  1611. // [IN] pRect
  1612. // Pointer to a CRect object that indicates the bounds of the
  1613. // area to be painted.
  1614. //
  1615. // Return value:
  1616. // BTNST_OK
  1617. // Function executed successfully.
  1618. //
  1619. DWORD CButtonST::OnDrawBorder(CDC* pDC, LPCRECT pRect)
  1620. {
  1621. if (m_bIsPressed)
  1622. pDC->Draw3dRect(pRect, ::GetSysColor(COLOR_BTNSHADOW), ::GetSysColor(COLOR_BTNHILIGHT));
  1623. else
  1624. pDC->Draw3dRect(pRect, ::GetSysColor(COLOR_BTNHILIGHT), ::GetSysColor(COLOR_BTNSHADOW));
  1625. return BTNST_OK;
  1626. } // End of OnDrawBorder
  1627. #undef BS_TYPEMASK