BtnST.cpp
上传用户:zslianheng
上传日期:2013-04-03
资源大小:946k
文件大小:41k
源码类别:

Linux/Unix编程

开发平台:

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; // @@ I change this default value to 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. m_hMenu = NULL;
  52. m_hParentWndMenu = NULL;
  53. m_bMenuDisplayed = FALSE;
  54. } // End of CButtonST
  55. CButtonST::~CButtonST()
  56. {
  57. // Restore old bitmap (if any)
  58. if (m_dcBk.m_hDC && m_pbmpOldBk)
  59. {
  60. m_dcBk.SelectObject(m_pbmpOldBk);
  61. } // if
  62. FreeResources();
  63. // Destroy the cursor (if any)
  64. if (m_hCursor) ::DestroyCursor(m_hCursor);
  65. // Destroy the menu (if any)
  66. if (m_hMenu) ::DestroyMenu(m_hMenu);
  67. } // End of ~CButtonST
  68. BEGIN_MESSAGE_MAP(CButtonST, CButton)
  69.     //{{AFX_MSG_MAP(CButtonST)
  70. ON_WM_SETCURSOR()
  71. ON_WM_KILLFOCUS()
  72. ON_WM_MOUSEMOVE()
  73. ON_WM_SYSCOLORCHANGE()
  74. ON_CONTROL_REFLECT_EX(BN_CLICKED, OnClicked)
  75. ON_WM_ACTIVATE()
  76. ON_WM_ENABLE()
  77. ON_WM_CANCELMODE()
  78. ON_WM_GETDLGCODE()
  79. ON_WM_CTLCOLOR_REFLECT()
  80. //}}AFX_MSG_MAP
  81. ON_MESSAGE(BM_SETSTYLE, OnSetStyle)
  82. ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
  83. END_MESSAGE_MAP()
  84. void CButtonST::FreeResources(BOOL bCheckForNULL)
  85. {
  86. if (bCheckForNULL)
  87. {
  88. // Destroy icons
  89. // Note: the following two lines MUST be here! even if
  90. // BoundChecker says they are unnecessary!
  91. if (m_csIcons[0].hIcon) ::DestroyIcon(m_csIcons[0].hIcon);
  92. if (m_csIcons[1].hIcon) ::DestroyIcon(m_csIcons[1].hIcon);
  93. // Destroy bitmaps
  94. if (m_csBitmaps[0].hBitmap) ::DeleteObject(m_csBitmaps[0].hBitmap);
  95. if (m_csBitmaps[1].hBitmap) ::DeleteObject(m_csBitmaps[1].hBitmap);
  96. // Destroy mask bitmaps
  97. if (m_csBitmaps[0].hMask) ::DeleteObject(m_csBitmaps[0].hMask);
  98. if (m_csBitmaps[1].hMask) ::DeleteObject(m_csBitmaps[1].hMask);
  99. } // if
  100. ::ZeroMemory(&m_csIcons, sizeof(m_csIcons));
  101. ::ZeroMemory(&m_csBitmaps, sizeof(m_csBitmaps));
  102. } // End of FreeResources
  103. void CButtonST::PreSubclassWindow() 
  104. {
  105. UINT nBS;
  106. nBS = GetButtonStyle();
  107. // Set initial control type
  108. m_nTypeStyle = nBS & BS_TYPEMASK;
  109. // Check if this is a checkbox
  110. if (nBS & BS_CHECKBOX) m_bIsCheckBox = TRUE;
  111. // Set initial default state flag
  112. if (m_nTypeStyle == BS_DEFPUSHBUTTON)
  113. {
  114. // Set default state for a default button
  115. m_bIsDefault = TRUE;
  116. // Adjust style for default button
  117. m_nTypeStyle = BS_PUSHBUTTON;
  118. } // If
  119. // You should not set the Owner Draw before this call
  120. // (don't use the resource editor "Owner Draw" or
  121. // ModifyStyle(0, BS_OWNERDRAW) before calling PreSubclassWindow() )
  122. ASSERT(m_nTypeStyle != BS_OWNERDRAW);
  123. // Switch to owner-draw
  124. ModifyStyle(BS_TYPEMASK, BS_OWNERDRAW, SWP_FRAMECHANGED);
  125. CButton::PreSubclassWindow();
  126. } // End of PreSubclassWindow
  127. UINT CButtonST::OnGetDlgCode() 
  128. {
  129. UINT nCode = CButton::OnGetDlgCode();
  130. // Tell the system if we want default state handling
  131. // (losing default state always allowed)
  132. nCode |= (m_bIsDefault ? DLGC_DEFPUSHBUTTON : DLGC_UNDEFPUSHBUTTON);
  133. return nCode;
  134. } // End of OnGetDlgCode
  135. BOOL CButtonST::PreTranslateMessage(MSG* pMsg) 
  136. {
  137. InitToolTip();
  138. m_ToolTip.RelayEvent(pMsg);
  139. return CButton::PreTranslateMessage(pMsg);
  140. } // End of PreTranslateMessage
  141. LRESULT CButtonST::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
  142. {
  143. if (message == WM_LBUTTONDBLCLK)
  144. {
  145. message = WM_LBUTTONDOWN;
  146. } // if
  147. return CButton::DefWindowProc(message, wParam, lParam);
  148. } // End of DefWindowProc
  149. HBRUSH CButtonST::CtlColor(CDC* pDC, UINT nCtlColor) 
  150. {
  151. return (HBRUSH)::GetStockObject(NULL_BRUSH); 
  152. } // End of CtlColor
  153. void CButtonST::OnSysColorChange() 
  154. {
  155. CButton::OnSysColorChange();
  156. m_dcBk.DeleteDC();
  157. m_bmpBk.DeleteObject();
  158. } // End of OnSysColorChange
  159. LRESULT CButtonST::OnSetStyle(WPARAM wParam, LPARAM lParam)
  160. {
  161. UINT nNewType = (wParam & BS_TYPEMASK);
  162. // Update default state flag
  163. if (nNewType == BS_DEFPUSHBUTTON)
  164. {
  165. m_bIsDefault = TRUE;
  166. } // if
  167. else if (nNewType == BS_PUSHBUTTON)
  168. {
  169. // Losing default state always allowed
  170. m_bIsDefault = FALSE;
  171. } // if
  172. // Can't change control type after owner-draw is set.
  173. // Let the system process changes to other style bits
  174. // and redrawing, while keeping owner-draw style
  175. return DefWindowProc(BM_SETSTYLE,
  176. (wParam & ~BS_TYPEMASK) | BS_OWNERDRAW, lParam);
  177. } // End of OnSetStyle
  178. void CButtonST::OnEnable(BOOL bEnable) 
  179. {
  180. CButton::OnEnable(bEnable);
  181. if (bEnable == FALSE)
  182. {
  183. CWnd* pWnd = GetParent()->GetNextDlgTabItem(this);
  184. if (pWnd)
  185. pWnd->SetFocus();
  186. else
  187. GetParent()->SetFocus();
  188. CancelHover();
  189. } // if
  190. } // End of OnEnable
  191. void CButtonST::OnKillFocus(CWnd * pNewWnd)
  192. {
  193. CButton::OnKillFocus(pNewWnd);
  194. CancelHover();
  195. } // End of OnKillFocus
  196. void CButtonST::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized) 
  197. {
  198. CButton::OnActivate(nState, pWndOther, bMinimized);
  199. if (nState == WA_INACTIVE) CancelHover();
  200. } // End of OnActivate
  201. void CButtonST::OnCancelMode() 
  202. {
  203. CButton::OnCancelMode();
  204. CancelHover();
  205. } // End of OnCancelMode
  206. BOOL CButtonST::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
  207. {
  208. // If a cursor was specified then use it!
  209. if (m_hCursor != NULL)
  210. {
  211. ::SetCursor(m_hCursor);
  212. return TRUE;
  213. } // if
  214. return CButton::OnSetCursor(pWnd, nHitTest, message);
  215. } // End of OnSetCursor
  216. void CButtonST::CancelHover()
  217. {
  218. // Only for flat buttons
  219. if (m_bIsFlat)
  220. {
  221. if (m_bMouseOnButton)
  222. {
  223. m_bMouseOnButton = FALSE;
  224. Invalidate();
  225. } // if
  226. } // if
  227. } // End of CancelHover
  228. void CButtonST::OnMouseMove(UINT nFlags, CPoint point)
  229. {
  230. CWnd* wndUnderMouse = NULL;
  231. CWnd* wndActive = this;
  232. TRACKMOUSEEVENT csTME;
  233. CButton::OnMouseMove(nFlags, point);
  234. ClientToScreen(&point);
  235. wndUnderMouse = WindowFromPoint(point);
  236. // If the mouse enter the button with the left button pressed then do nothing
  237. if (nFlags & MK_LBUTTON && m_bMouseOnButton == FALSE) return;
  238. // If our button is not flat then do nothing
  239. if (m_bIsFlat == FALSE) return;
  240. if (m_bAlwaysTrack == FALSE) wndActive = GetActiveWindow();
  241. if (wndUnderMouse && wndUnderMouse->m_hWnd == m_hWnd && wndActive)
  242. {
  243. if (!m_bMouseOnButton)
  244. {
  245. m_bMouseOnButton = TRUE;
  246. Invalidate();
  247. csTME.cbSize = sizeof(csTME);
  248. csTME.dwFlags = TME_LEAVE;
  249. csTME.hwndTrack = m_hWnd;
  250. ::_TrackMouseEvent(&csTME);
  251. } // if
  252. } else CancelHover();
  253. } // End of OnMouseMove
  254. // Handler for WM_MOUSELEAVE
  255. LRESULT CButtonST::OnMouseLeave(WPARAM wParam, LPARAM lParam)
  256. {
  257. CancelHover();
  258. return 0;
  259. } // End of OnMouseLeave
  260. BOOL CButtonST::OnClicked() 
  261. {
  262. if (m_bIsCheckBox)
  263. {
  264. m_nCheck = !m_nCheck;
  265. Invalidate();
  266. } // if
  267. else
  268. {
  269. // Handle the menu (if any)
  270. if (m_hMenu)
  271. {
  272. HMENU hSubMenu = NULL;
  273. CRect rWnd;
  274. hSubMenu = ::GetSubMenu(m_hMenu, 0);
  275. GetWindowRect(rWnd);
  276. m_bMenuDisplayed = TRUE;
  277. Invalidate();
  278. ::TrackPopupMenuEx(hSubMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON, rWnd.left, rWnd.bottom, m_hParentWndMenu, NULL);
  279. m_bMenuDisplayed = FALSE;
  280. Invalidate();
  281. } // if
  282. else
  283. {
  284. // Handle the URL (if any)
  285. if (_tcslen(m_szURL) > 0)
  286. {
  287. SHELLEXECUTEINFO csSEI;
  288. memset(&csSEI, 0, sizeof(csSEI));
  289. csSEI.cbSize = sizeof(SHELLEXECUTEINFO);
  290. csSEI.fMask = SEE_MASK_FLAG_NO_UI;
  291. csSEI.lpVerb = _T("open");
  292. csSEI.lpFile = m_szURL;
  293. csSEI.nShow = SW_SHOWMAXIMIZED;
  294. ::ShellExecuteEx(&csSEI);
  295. } // if
  296. } // else
  297. } // else
  298. return FALSE;
  299. } // End of OnClicked
  300. void CButtonST::DrawItem(LPDRAWITEMSTRUCT lpDIS)
  301. {
  302. CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  303. CPen* pOldPen;
  304. // Checkbox?
  305. if (m_bIsCheckBox)
  306. {
  307. m_bIsPressed  =  (lpDIS->itemState & ODS_SELECTED) || (m_nCheck != 0);
  308. } // if
  309. else // Normal button OR other button style ...
  310. {
  311. m_bIsPressed = (lpDIS->itemState & ODS_SELECTED);
  312. // If there is a menu and it's displayed, draw the button as pressed
  313. if (m_hMenu && m_bMenuDisplayed) m_bIsPressed = TRUE;
  314. } // else
  315. m_bIsFocused  = (lpDIS->itemState & ODS_FOCUS);
  316. m_bIsDisabled = (lpDIS->itemState & ODS_DISABLED);
  317. CRect itemRect = lpDIS->rcItem;
  318. pDC->SetBkMode(TRANSPARENT);
  319. if (m_bIsFlat == FALSE)
  320. {
  321. if (m_bIsFocused || m_bIsDefault)
  322. {
  323. CBrush br(RGB(0,0,0));  
  324. pDC->FrameRect(&itemRect, &br);
  325. // itemRect.DeflateRect(1, 1); // @@
  326. } // if
  327. } // if
  328. // Prepare draw... paint button background
  329. // Draw transparent?
  330. if (m_bDrawTransparent)
  331. PaintBk(pDC);
  332. else
  333. OnDrawBackground(pDC, &itemRect);
  334. // Draw pressed button
  335. if (m_bIsPressed)
  336. {
  337. if (m_bIsFlat)
  338. {
  339. if (m_bDrawBorder)
  340. OnDrawBorder(pDC, &itemRect);
  341. }
  342. else    
  343. {
  344. CBrush brBtnShadow(GetSysColor(COLOR_BTNSHADOW));
  345. pDC->FrameRect(&itemRect, &brBtnShadow);
  346. }
  347. }
  348. else // ...else draw non pressed button
  349. {
  350. CPen penBtnHiLight(PS_SOLID, 0, GetSysColor(COLOR_BTNHILIGHT)); // White
  351. CPen pen3DLight(PS_SOLID, 0, GetSysColor(COLOR_3DLIGHT));       // Light gray
  352. CPen penBtnShadow(PS_SOLID, 0, GetSysColor(COLOR_BTNSHADOW));   // Dark gray
  353. CPen pen3DDKShadow(PS_SOLID, 0, GetSysColor(COLOR_3DDKSHADOW)); // Black
  354. if (m_bIsFlat)
  355. {
  356. if (m_bMouseOnButton && m_bDrawBorder)
  357. OnDrawBorder(pDC, &itemRect);
  358. }
  359. else
  360. {
  361. // Draw top-left borders
  362. // White line
  363. pOldPen = pDC->SelectObject(&penBtnHiLight);
  364. pDC->MoveTo(itemRect.left, itemRect.bottom-1);
  365. pDC->LineTo(itemRect.left, itemRect.top);
  366. pDC->LineTo(itemRect.right, itemRect.top);
  367. // Light gray line
  368. pDC->SelectObject(pen3DLight);
  369. pDC->MoveTo(itemRect.left+1, itemRect.bottom-1);
  370. pDC->LineTo(itemRect.left+1, itemRect.top+1);
  371. pDC->LineTo(itemRect.right, itemRect.top+1);
  372. // Draw bottom-right borders
  373. // Black line
  374. pDC->SelectObject(pen3DDKShadow);
  375. pDC->MoveTo(itemRect.left, itemRect.bottom-1);
  376. pDC->LineTo(itemRect.right-1, itemRect.bottom-1);
  377. pDC->LineTo(itemRect.right-1, itemRect.top-1);
  378. // Dark gray line
  379. pDC->SelectObject(penBtnShadow);
  380. pDC->MoveTo(itemRect.left+1, itemRect.bottom-2);
  381. pDC->LineTo(itemRect.right-2, itemRect.bottom-2);
  382. pDC->LineTo(itemRect.right-2, itemRect.top);
  383. //
  384. pDC->SelectObject(pOldPen);
  385. } // else
  386. } // else
  387. // Read the button's title
  388. CString sTitle;
  389. GetWindowText(sTitle);
  390. CRect captionRect = lpDIS->rcItem;
  391. // Draw the icon
  392. if (m_csIcons[0].hIcon)
  393. {
  394. DrawTheIcon(pDC, !sTitle.IsEmpty(), &lpDIS->rcItem, &captionRect, m_bIsPressed, m_bIsDisabled);
  395. } // if
  396. if (m_csBitmaps[0].hBitmap)
  397. {
  398. pDC->SetBkColor(RGB(255,255,255));
  399. DrawTheBitmap(pDC, !sTitle.IsEmpty(), &lpDIS->rcItem, &captionRect, m_bIsPressed, m_bIsDisabled);
  400. } // if
  401. // Write the button title (if any)
  402. if (sTitle.IsEmpty() == FALSE)
  403. {
  404. // Draw the button's title
  405. // If button is pressed then "press" title also
  406. if (m_bIsPressed && m_bIsCheckBox == FALSE)
  407. captionRect.OffsetRect(1, 1);
  408.     
  409. // ONLY FOR DEBUG 
  410. //CBrush brBtnShadow(RGB(255, 0, 0));
  411. //pDC->FrameRect(&captionRect, &brBtnShadow);
  412. // @@
  413. CSize szText = pDC->GetTextExtent(sTitle);
  414. if (szText.cx <= captionRect.Width()) {
  415. // Center text
  416. CRect centerRect = captionRect;
  417. pDC->DrawText(sTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER | DT_CALCRECT);
  418. captionRect.OffsetRect((centerRect.Width() - captionRect.Width())/2, (centerRect.Height() - captionRect.Height())/2);
  419. /* RFU
  420. captionRect.OffsetRect(0, (centerRect.Height() - captionRect.Height())/2);
  421. captionRect.OffsetRect((centerRect.Width() - captionRect.Width())-4, (centerRect.Height() - captionRect.Height())/2);
  422. */
  423. pDC->SetBkMode(TRANSPARENT);
  424. /*
  425. pDC->DrawState(captionRect.TopLeft(), captionRect.Size(), (LPCTSTR)sTitle, (bIsDisabled ? DSS_DISABLED : DSS_NORMAL), 
  426. TRUE, 0, (CBrush*)NULL);
  427. */
  428. if (m_bIsDisabled)
  429. {
  430. captionRect.OffsetRect(1, 1);
  431. pDC->SetTextColor(::GetSysColor(COLOR_3DHILIGHT));
  432. pDC->DrawText(sTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER);
  433. captionRect.OffsetRect(-1, -1);
  434. pDC->SetTextColor(::GetSysColor(COLOR_3DSHADOW));
  435. pDC->DrawText(sTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER);
  436. } // if
  437. else
  438. {
  439. if (m_bMouseOnButton || m_bIsPressed) 
  440. {
  441. pDC->SetTextColor(m_crColors[BTNST_COLOR_FG_IN]);
  442. pDC->SetBkColor(m_crColors[BTNST_COLOR_BK_IN]);
  443. } // if
  444. else 
  445. {
  446. pDC->SetTextColor(m_crColors[BTNST_COLOR_FG_OUT]);
  447. pDC->SetBkColor(m_crColors[BTNST_COLOR_BK_OUT]);
  448. } // else
  449. pDC->DrawText(sTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER);
  450. } // if
  451. }
  452. } // if
  453. if (m_bIsFlat == FALSE || (m_bIsFlat && m_bDrawFlatFocus))
  454. {
  455. // Draw the focus rect
  456. if (m_bIsFocused)
  457. {
  458. CRect focusRect = itemRect;
  459. focusRect.DeflateRect(3, 3);
  460. // pDC->DrawFocusRect(&focusRect); // @@
  461. } // if
  462. } // if
  463. } // End of DrawItem
  464. void CButtonST::PaintBk(CDC* pDC)
  465. {
  466. CClientDC clDC(GetParent());
  467. CRect rect;
  468. CRect rect1;
  469. GetClientRect(rect);
  470. GetWindowRect(rect1);
  471. GetParent()->ScreenToClient(rect1);
  472. if (m_dcBk.m_hDC == NULL)
  473. {
  474. m_dcBk.CreateCompatibleDC(&clDC);
  475. m_bmpBk.CreateCompatibleBitmap(&clDC, rect.Width(), rect.Height());
  476. m_pbmpOldBk = m_dcBk.SelectObject(&m_bmpBk);
  477. m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), &clDC, rect1.left, rect1.top, SRCCOPY);
  478. } // if
  479. pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &m_dcBk, 0, 0, SRCCOPY);
  480. } // End of PaintBk
  481. HBITMAP CButtonST::CreateBitmapMask(HBITMAP hSourceBitmap, DWORD dwWidth, DWORD dwHeight, COLORREF crTransColor)
  482. {
  483. HBITMAP hMask = NULL;
  484. HDC hdcSrc = NULL;
  485. HDC hdcDest = NULL;
  486. HBITMAP hbmSrcT = NULL;
  487. HBITMAP hbmDestT = NULL;
  488. COLORREF crSaveBk;
  489. COLORREF crSaveDestText;
  490. hMask = ::CreateBitmap(dwWidth, dwHeight, 1, 1, NULL);
  491. if (hMask == NULL) return NULL;
  492. hdcSrc = ::CreateCompatibleDC(NULL);
  493. hdcDest = ::CreateCompatibleDC(NULL);
  494. hbmSrcT = (HBITMAP)::SelectObject(hdcSrc, hSourceBitmap);
  495. hbmDestT = (HBITMAP)::SelectObject(hdcDest, hMask);
  496. crSaveBk = ::SetBkColor(hdcSrc, crTransColor);
  497. ::BitBlt(hdcDest, 0, 0, dwWidth, dwHeight, hdcSrc, 0, 0, SRCCOPY);
  498. crSaveDestText = ::SetTextColor(hdcSrc, RGB(255, 255, 255));
  499. ::SetBkColor(hdcSrc,RGB(0, 0, 0));
  500. ::BitBlt(hdcSrc, 0, 0, dwWidth, dwHeight, hdcDest, 0, 0, SRCAND);
  501. SetTextColor(hdcDest, crSaveDestText);
  502. ::SetBkColor(hdcSrc, crSaveBk);
  503. ::SelectObject(hdcSrc, hbmSrcT);
  504. ::SelectObject(hdcDest, hbmDestT);
  505. ::DeleteDC(hdcSrc);
  506. ::DeleteDC(hdcDest);
  507. return hMask;
  508. } // End of CreateBitmapMask
  509. //
  510. // Parameters:
  511. // [IN] bHasTitle
  512. // TRUE if the button has a text
  513. // [IN] rpItem
  514. // A pointer to a RECT structure indicating the allowed paint area
  515. // [IN/OUT]rpTitle
  516. // A pointer to a CRect object indicating the paint area reserved for the
  517. // text. This structure will be modified if necessary.
  518. // [IN] bIsPressed
  519. // TRUE if the button is currently pressed
  520. // [IN] dwWidth
  521. // Width of the image (icon or bitmap)
  522. // [IN] dwHeight
  523. // Height of the image (icon or bitmap)
  524. // [OUT] rpImage
  525. // A pointer to a CRect object that will receive the area available to the image
  526. //
  527. void CButtonST::PrepareImageRect(BOOL bHasTitle, RECT* rpItem, CRect* rpTitle, BOOL bIsPressed, DWORD dwWidth, DWORD dwHeight, CRect* rpImage)
  528. {
  529. CRect rBtn;
  530. rpImage->CopyRect(rpItem);
  531. switch (m_byAlign)
  532. {
  533. case ST_ALIGN_HORIZ:
  534. if (bHasTitle == FALSE)
  535. {
  536. // Center image horizontally
  537. rpImage->left += ((rpImage->Width() - dwWidth)/2);
  538. }
  539. else
  540. {
  541. // Image must be placed just inside the focus rect
  542. rpImage->left += 3;  
  543. rpTitle->left += dwWidth + 3;
  544. }
  545. // Center image vertically
  546. rpImage->top += ((rpImage->Height() - dwHeight)/2);
  547. break;
  548. case ST_ALIGN_HORIZ_RIGHT:
  549. GetClientRect(&rBtn);
  550. if (bHasTitle == FALSE)
  551. {
  552. // Center image horizontally
  553. rpImage->left += ((rpImage->Width() - dwWidth)/2);
  554. }
  555. else
  556. {
  557. // Image must be placed just inside the focus rect
  558. rpTitle->right = rpTitle->Width() - dwWidth - 3;
  559. rpTitle->left = 3;
  560. rpImage->left = rBtn.right - dwWidth - 3;
  561. // Center image vertically
  562. rpImage->top += ((rpImage->Height() - dwHeight)/2);
  563. }
  564. break;
  565. case ST_ALIGN_VERT:
  566. // Center image horizontally
  567. rpImage->left += ((rpImage->Width() - dwWidth)/2);
  568. if (bHasTitle == FALSE)
  569. {
  570. // Center image vertically
  571. rpImage->top += ((rpImage->Height() - dwHeight)/2);           
  572. }
  573. else
  574. {
  575. rpImage->top = 3;
  576. rpTitle->top += dwHeight;
  577. }
  578. break;
  579. }
  580.     
  581. // If button is pressed then press image also
  582. if (bIsPressed && m_bIsCheckBox == FALSE)
  583. rpImage->OffsetRect(1, 1);
  584. } // End of PrepareImageRect
  585. void CButtonST::DrawTheIcon(CDC* pDC, BOOL bHasTitle, RECT* rpItem, CRect* rpTitle, BOOL bIsPressed, BOOL bIsDisabled)
  586. {
  587. BYTE byIndex = 0;
  588. // Select the icon to use
  589. if ((m_bIsCheckBox && bIsPressed) || (!m_bIsCheckBox && (bIsPressed || m_bMouseOnButton)))
  590. byIndex = 0;
  591. else
  592. byIndex = (m_csIcons[1].hIcon == NULL ? 0 : 1);
  593. CRect rImage;
  594. PrepareImageRect(bHasTitle, rpItem, rpTitle, bIsPressed, m_csIcons[byIndex].dwWidth, m_csIcons[byIndex].dwHeight, &rImage);
  595. // Ole'!
  596. pDC->DrawState( rImage.TopLeft(),
  597. rImage.Size(), 
  598. m_csIcons[byIndex].hIcon,
  599. (bIsDisabled ? DSS_DISABLED : DSS_NORMAL), 
  600. (CBrush*)NULL);
  601. } // End of DrawTheIcon
  602. void CButtonST::DrawTheBitmap(CDC* pDC, BOOL bHasTitle, RECT* rItem, CRect *rCaption, BOOL bIsPressed, BOOL bIsDisabled)
  603. {
  604. HDC hdcBmpMem = NULL;
  605. HBITMAP hbmOldBmp = NULL;
  606. HDC hdcMem = NULL;
  607. HBITMAP hbmT = NULL;
  608. BYTE byIndex = 0;
  609. // Select the bitmap to use
  610. if ((m_bIsCheckBox && bIsPressed) || (!m_bIsCheckBox && (bIsPressed || m_bMouseOnButton)))
  611. byIndex = 0;
  612. else
  613. byIndex = (m_csBitmaps[1].hBitmap == NULL ? 0 : 1);
  614. CRect rImage;
  615. PrepareImageRect(bHasTitle, rItem, rCaption, bIsPressed, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, &rImage);
  616. hdcBmpMem = ::CreateCompatibleDC(pDC->m_hDC);
  617. hbmOldBmp = (HBITMAP)::SelectObject(hdcBmpMem, m_csBitmaps[byIndex].hBitmap);
  618. hdcMem = ::CreateCompatibleDC(NULL);
  619. hbmT = (HBITMAP)::SelectObject(hdcMem, m_csBitmaps[byIndex].hMask);
  620. ::BitBlt(pDC->m_hDC, rImage.left, rImage.top, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, hdcMem, 0, 0, SRCAND);
  621. ::BitBlt(pDC->m_hDC, rImage.left, rImage.top, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, hdcBmpMem, 0, 0, SRCPAINT);
  622. ::SelectObject(hdcMem, hbmT);
  623. ::DeleteDC(hdcMem);
  624. ::SelectObject(hdcBmpMem, hbmOldBmp);
  625. ::DeleteDC(hdcBmpMem);
  626. } // End of DrawTheBitmap
  627. // This function assigns icons to the button.
  628. // Any previous icon or bitmap will be removed.
  629. //
  630. // Parameters:
  631. // [IN] nIconIn
  632. // ID number of the icon resource to show when the mouse is over the button.
  633. // Pass NULL to remove any icon from the button.
  634. // [IN] nIconOut
  635. // ID number of the icon resource to show when the mouse is outside the button.
  636. // Can be NULL.
  637. //
  638. // Return value:
  639. // BTNST_OK
  640. // Function executed successfully.
  641. // BTNST_INVALIDRESOURCE
  642. // Failed loading the specified resource.
  643. //
  644. DWORD CButtonST::SetIcon(int nIconIn, int nIconOut)
  645. {
  646. HICON hIconIn = NULL;
  647. HICON hIconOut = NULL;
  648. HINSTANCE hInstResource = NULL;
  649. // Find correct resource handle
  650. hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nIconIn), RT_GROUP_ICON);
  651. // Set icon when the mouse is IN the button
  652. hIconIn = (HICON)::LoadImage(hInstResource, MAKEINTRESOURCE(nIconIn), IMAGE_ICON, 0, 0, 0);
  653.    // Set icon when the mouse is OUT the button
  654. if (nIconOut)
  655. hIconOut = (HICON)::LoadImage(hInstResource, MAKEINTRESOURCE(nIconOut), IMAGE_ICON, 0, 0, 0);
  656. return SetIcon(hIconIn, hIconOut);
  657. } // End of SetIcon
  658. // This function assigns icons to the button.
  659. // Any previous icon or bitmap will be removed.
  660. //
  661. // Parameters:
  662. // [IN] hIconIn
  663. // Handle fo the icon to show when the mouse is over the button.
  664. // Pass NULL to remove any icon from the button.
  665. // [IN] hIconOut
  666. // Handle to the icon to show when the mouse is outside the button.
  667. // Can be NULL.
  668. //
  669. // Return value:
  670. // BTNST_OK
  671. // Function executed successfully.
  672. // BTNST_INVALIDRESOURCE
  673. // Failed loading the specified resource.
  674. //
  675. DWORD CButtonST::SetIcon(HICON hIconIn, HICON hIconOut)
  676. {
  677. BOOL bRetValue;
  678. ICONINFO ii;
  679. // Free any loaded resource
  680. // @@
  681. //FreeResources();
  682. if (hIconIn)
  683. {
  684. // Icon when mouse over button?
  685. m_csIcons[0].hIcon = hIconIn;
  686. // Get icon dimension
  687. ::ZeroMemory(&ii, sizeof(ICONINFO));
  688. bRetValue = ::GetIconInfo(hIconIn, &ii);
  689. if (bRetValue == FALSE)
  690. {
  691. FreeResources();
  692. return BTNST_INVALIDRESOURCE;
  693. } // if
  694. m_csIcons[0].dwWidth = (DWORD)(ii.xHotspot * 2);
  695. m_csIcons[0].dwHeight = (DWORD)(ii.yHotspot * 2);
  696. ::DeleteObject(ii.hbmMask);
  697. ::DeleteObject(ii.hbmColor);
  698. // Icon when mouse outside button?
  699. if (hIconOut)
  700. {
  701. m_csIcons[1].hIcon = hIconOut;
  702. // Get icon dimension
  703. ::ZeroMemory(&ii, sizeof(ICONINFO));
  704. bRetValue = ::GetIconInfo(hIconOut, &ii);
  705. if (bRetValue == FALSE)
  706. {
  707. FreeResources();
  708. return BTNST_INVALIDRESOURCE;
  709. } // if
  710. m_csIcons[1].dwWidth = (DWORD)(ii.xHotspot * 2);
  711. m_csIcons[1].dwHeight = (DWORD)(ii.yHotspot * 2);
  712. ::DeleteObject(ii.hbmMask);
  713. ::DeleteObject(ii.hbmColor);
  714. } // if
  715. } // if
  716. Invalidate();
  717. return BTNST_OK;
  718. } // End of SetIcon
  719. // This function assigns bitmaps to the button.
  720. // Any previous icon or bitmap will be removed.
  721. //
  722. // Parameters:
  723. // [IN] nBitmapIn
  724. // ID number of the bitmap resource to show when the mouse is over the button.
  725. // Pass NULL to remove any bitmap from the button.
  726. // [IN] crTransColorIn
  727. // Color (inside nBitmapIn) to be used as transparent color.
  728. // [IN] nBitmapOut
  729. // ID number of the bitmap resource to show when the mouse is outside the button.
  730. // Can be NULL.
  731. // [IN] crTransColorOut
  732. // Color (inside nBitmapOut) to be used as transparent color.
  733. //
  734. // Return value:
  735. // BTNST_OK
  736. // Function executed successfully.
  737. // BTNST_INVALIDRESOURCE
  738. // Failed loading the specified resource.
  739. // BTNST_FAILEDMASK
  740. // Failed creating mask bitmap.
  741. //
  742. DWORD CButtonST::SetBitmaps(int nBitmapIn, COLORREF crTransColorIn, int nBitmapOut, COLORREF crTransColorOut)
  743. {
  744. HBITMAP hBitmapIn = NULL;
  745. HBITMAP hBitmapOut = NULL;
  746. HINSTANCE hInstResource = NULL;
  747. // Find correct resource handle
  748. hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nBitmapIn), RT_BITMAP);
  749. // Load bitmap In
  750. hBitmapIn = (HBITMAP)::LoadImage(hInstResource, MAKEINTRESOURCE(nBitmapIn), IMAGE_BITMAP, 0, 0, 0);
  751. // Load bitmap Out
  752. if (nBitmapOut)
  753. hBitmapOut = (HBITMAP)::LoadImage(hInstResource, MAKEINTRESOURCE(nBitmapOut), IMAGE_BITMAP, 0, 0, 0);
  754. return SetBitmaps(hBitmapIn, crTransColorIn, hBitmapOut, crTransColorOut);
  755. } // End of SetBitmaps
  756. // This function assigns bitmaps to the button.
  757. // Any previous icon or bitmap will be removed.
  758. //
  759. // Parameters:
  760. // [IN] hBitmapIn
  761. // Handle fo the bitmap to show when the mouse is over the button.
  762. // Pass NULL to remove any bitmap from the button.
  763. // [IN] crTransColorIn
  764. // Color (inside hBitmapIn) to be used as transparent color.
  765. // [IN] hBitmapOut
  766. // Handle to the bitmap to show when the mouse is outside the button.
  767. // Can be NULL.
  768. // [IN] crTransColorOut
  769. // Color (inside hBitmapOut) to be used as transparent color.
  770. //
  771. // Return value:
  772. // BTNST_OK
  773. // Function executed successfully.
  774. // BTNST_INVALIDRESOURCE
  775. // Failed loading the specified resource.
  776. // BTNST_FAILEDMASK
  777. // Failed creating mask bitmap.
  778. //
  779. DWORD CButtonST::SetBitmaps(HBITMAP hBitmapIn, COLORREF crTransColorIn, HBITMAP hBitmapOut, COLORREF crTransColorOut)
  780. {
  781. int nRetValue;
  782. BITMAP csBitmapSize;
  783. // Free any loaded resource
  784. FreeResources();
  785. if (hBitmapIn)
  786. {
  787. m_csBitmaps[0].hBitmap = hBitmapIn;
  788. m_csBitmaps[0].crTransparent = crTransColorIn;
  789. // Get bitmap size
  790. nRetValue = ::GetObject(hBitmapIn, sizeof(csBitmapSize), &csBitmapSize);
  791. if (nRetValue == 0)
  792. {
  793. FreeResources();
  794. return BTNST_INVALIDRESOURCE;
  795. } // if
  796. m_csBitmaps[0].dwWidth = (DWORD)csBitmapSize.bmWidth;
  797. m_csBitmaps[0].dwHeight = (DWORD)csBitmapSize.bmHeight;
  798. // Create mask for bitmap In
  799. m_csBitmaps[0].hMask = CreateBitmapMask(hBitmapIn, m_csBitmaps[0].dwWidth, m_csBitmaps[0].dwHeight, crTransColorIn);
  800. if (m_csBitmaps[0].hMask == NULL)
  801. {
  802. FreeResources();
  803. return BTNST_FAILEDMASK;
  804. } // if
  805. if (hBitmapOut)
  806. {
  807. m_csBitmaps[1].hBitmap = hBitmapOut;
  808. m_csBitmaps[1].crTransparent = crTransColorOut;
  809. // Get bitmap size
  810. nRetValue = ::GetObject(hBitmapOut, sizeof(csBitmapSize), &csBitmapSize);
  811. if (nRetValue == 0)
  812. {
  813. FreeResources();
  814. return BTNST_INVALIDRESOURCE;
  815. } // if
  816. m_csBitmaps[1].dwWidth = (DWORD)csBitmapSize.bmWidth;
  817. m_csBitmaps[1].dwHeight = (DWORD)csBitmapSize.bmHeight;
  818. // Create mask for bitmap Out
  819. m_csBitmaps[1].hMask = CreateBitmapMask(hBitmapOut, m_csBitmaps[1].dwWidth, m_csBitmaps[1].dwHeight, crTransColorOut);
  820. if (m_csBitmaps[1].hMask == NULL)
  821. {
  822. FreeResources();
  823. return BTNST_FAILEDMASK;
  824. } // if
  825. } // if
  826. } // if
  827. Invalidate();
  828. return BTNST_OK;
  829. } // End of SetBitmaps
  830. // This functions sets the button to have a standard or flat style.
  831. //
  832. // Parameters:
  833. // [IN] bFlat
  834. // If TRUE the button will have a flat style, else
  835. // will have a standard style.
  836. // By default, CButtonST buttons are flat.
  837. // [IN] bRepaint
  838. // If TRUE the control will be repainted.
  839. //
  840. // Return value:
  841. // BTNST_OK
  842. // Function executed successfully.
  843. //
  844. DWORD CButtonST::SetFlat(BOOL bFlat, BOOL bRepaint)
  845. {
  846. m_bIsFlat = bFlat;
  847. if (bRepaint) Invalidate();
  848. return BTNST_OK;
  849. } // End of SetFlat
  850. // This function sets the alignment type between icon/bitmap and text.
  851. //
  852. // Parameters:
  853. // [IN] byAlign
  854. // Alignment type. Can be one of the following values:
  855. // ST_ALIGN_HORIZ Icon/bitmap on the left, text on the right
  856. // ST_ALIGN_VERT Icon/bitmap on the top, text on the bottom
  857. // ST_ALIGN_HORIZ_RIGHT Icon/bitmap on the right, text on the left
  858. // By default, CButtonST buttons have ST_ALIGN_HORIZ alignment.
  859. // [IN] bRepaint
  860. // If TRUE the control will be repainted.
  861. //
  862. // Return value:
  863. // BTNST_OK
  864. // Function executed successfully.
  865. // BTNST_INVALIDALIGN
  866. // Alignment type not supported.
  867. //
  868. DWORD CButtonST::SetAlign(BYTE byAlign, BOOL bRepaint)
  869. {
  870. switch (byAlign)
  871. {    
  872. case ST_ALIGN_HORIZ:
  873. case ST_ALIGN_HORIZ_RIGHT:
  874. case ST_ALIGN_VERT:
  875. m_byAlign = byAlign;
  876. if (bRepaint) Invalidate();
  877. return BTNST_OK;
  878. break;
  879. } // switch
  880. return BTNST_INVALIDALIGN;
  881. } // End of SetAlign
  882. // This function sets the state of the checkbox.
  883. // If the button is not a checkbox, this function has no meaning.
  884. //
  885. // Parameters:
  886. // [IN] nCheck
  887. // 1 to check the checkbox.
  888. // 0 to un-check the checkbox.
  889. // [IN] bRepaint
  890. // If TRUE the control will be repainted.
  891. //
  892. // Return value:
  893. // BTNST_OK
  894. // Function executed successfully.
  895. //
  896. DWORD CButtonST::SetCheck(int nCheck, BOOL bRepaint)
  897. {
  898. if (m_bIsCheckBox)
  899. {
  900. if (nCheck == 0) m_nCheck = 0;
  901. else m_nCheck = 1;
  902. if (bRepaint) Invalidate();
  903. } // if
  904. return BTNST_OK;
  905. } // End of SetCheck
  906. // This function returns the current state of the checkbox.
  907. // If the button is not a checkbox, this function has no meaning.
  908. //
  909. // Return value:
  910. // The current state of the checkbox.
  911. // 1 if checked.
  912. // 0 if not checked or the button is not a checkbox.
  913. //
  914. int CButtonST::GetCheck()
  915. {
  916. return m_nCheck;
  917. } // End of GetCheck
  918. // This function sets all colors to a default value.
  919. //
  920. // Parameters:
  921. // [IN] bRepaint
  922. // If TRUE the control will be repainted.
  923. //
  924. // Return value:
  925. // BTNST_OK
  926. // Function executed successfully.
  927. //
  928. DWORD CButtonST::SetDefaultColors(BOOL bRepaint)
  929. {
  930. m_crColors[BTNST_COLOR_BK_IN] = ::GetSysColor(COLOR_BTNFACE);
  931. m_crColors[BTNST_COLOR_FG_IN] = ::GetSysColor(COLOR_BTNTEXT);
  932. m_crColors[BTNST_COLOR_BK_OUT] = ::GetSysColor(COLOR_BTNFACE);
  933. m_crColors[BTNST_COLOR_FG_OUT] = ::GetSysColor(COLOR_BTNTEXT);
  934. m_crColors[BTNST_COLOR_BK_FOCUS] = ::GetSysColor(COLOR_BTNFACE);
  935. m_crColors[BTNST_COLOR_FG_FOCUS] = ::GetSysColor(COLOR_BTNTEXT);
  936. if (bRepaint) Invalidate();
  937. return BTNST_OK;
  938. } // End of SetDefaultColors
  939. // This function sets the color to use for a particular state.
  940. //
  941. // Parameters:
  942. // [IN] byColorIndex
  943. // Index of the color to set. Can be one of the following values:
  944. // BTNST_COLOR_BK_IN Background color when mouse is over the button
  945. // BTNST_COLOR_FG_IN Text color when mouse is over the button
  946. // BTNST_COLOR_BK_OUT Background color when mouse is outside the button
  947. // BTNST_COLOR_FG_OUT Text color when mouse is outside the button
  948. // BTNST_COLOR_BK_FOCUS Background color when the button is focused
  949. // BTNST_COLOR_FG_FOCUS Text color when the button is focused
  950. // [IN] crColor
  951. // New color.
  952. // [IN] bRepaint
  953. // If TRUE the control will be repainted.
  954. //
  955. // Return value:
  956. // BTNST_OK
  957. // Function executed successfully.
  958. // BTNST_INVALIDINDEX
  959. // Invalid color index.
  960. //
  961. DWORD CButtonST::SetColor(BYTE byColorIndex, COLORREF crColor, BOOL bRepaint)
  962. {
  963. if (byColorIndex >= BTNST_MAX_COLORS) return BTNST_INVALIDINDEX;
  964. // Set new color
  965. m_crColors[byColorIndex] = crColor;
  966. if (bRepaint) Invalidate();
  967. return BTNST_OK;
  968. } // End of SetColor
  969. // This functions returns the color used for a particular state.
  970. //
  971. // Parameters:
  972. // [IN] byColorIndex
  973. // Index of the color to get. Can be one of the following values:
  974. // BTNST_COLOR_BK_IN Background color when mouse is over the button
  975. // BTNST_COLOR_FG_IN Text color when mouse is over the button
  976. // BTNST_COLOR_BK_OUT Background color when mouse is outside the button
  977. // BTNST_COLOR_FG_OUT Text color when mouse is outside the button
  978. // BTNST_COLOR_BK_FOCUS Background color when the button is focused
  979. // BTNST_COLOR_FG_FOCUS Text color when the button is focused
  980. // [OUT] crpColor
  981. // A pointer to a COLORREF that will receive the color.
  982. //
  983. // Return value:
  984. // BTNST_OK
  985. // Function executed successfully.
  986. // BTNST_INVALIDINDEX
  987. // Invalid color index.
  988. //
  989. DWORD CButtonST::GetColor(BYTE byColorIndex, COLORREF* crpColor)
  990. {
  991. if (byColorIndex >= BTNST_MAX_COLORS) return BTNST_INVALIDINDEX;
  992. // Get color
  993. *crpColor = m_crColors[byColorIndex];
  994. return BTNST_OK;
  995. } // End of GetColor
  996. // This function sets the hilight logic for the button.
  997. // Applies only to flat buttons.
  998. //
  999. // Parameters:
  1000. // [IN] bAlwaysTrack
  1001. // If TRUE the button will be hilighted even if the window that owns it, is
  1002. // not the active window.
  1003. // If FALSE the button will be hilighted only if the window that owns it,
  1004. // is the active window.
  1005. //
  1006. // Return value:
  1007. // BTNST_OK
  1008. // Function executed successfully.
  1009. //
  1010. DWORD CButtonST::SetAlwaysTrack(BOOL bAlwaysTrack)
  1011. {
  1012. m_bAlwaysTrack = bAlwaysTrack;
  1013. return BTNST_OK;
  1014. } // End of SetAlwaysTrack
  1015. // This function sets the cursor to be used when the mouse is over the button.
  1016. //
  1017. // Parameters:
  1018. // [IN] nCursorId
  1019. // ID number of the cursor resource.
  1020. // Pass NULL to remove a previously loaded cursor.
  1021. // [IN] bRepaint
  1022. // If TRUE the control will be repainted.
  1023. //
  1024. // Return value:
  1025. // BTNST_OK
  1026. // Function executed successfully.
  1027. // BTNST_INVALIDRESOURCE
  1028. // Failed loading the specified resource.
  1029. //
  1030. DWORD CButtonST::SetBtnCursor(int nCursorId, BOOL bRepaint)
  1031. {
  1032. HINSTANCE hInstResource = NULL;
  1033. // Destroy any previous cursor
  1034. if (m_hCursor)
  1035. {
  1036. ::DestroyCursor(m_hCursor);
  1037. m_hCursor = NULL;
  1038. } // if
  1039. // Load cursor
  1040. if (nCursorId)
  1041. {
  1042. hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nCursorId), RT_GROUP_CURSOR);
  1043. // Load cursor resource
  1044. m_hCursor = (HCURSOR)::LoadImage(hInstResource, MAKEINTRESOURCE(nCursorId), IMAGE_CURSOR, 0, 0, 0);
  1045. // Repaint the button
  1046. if (bRepaint) Invalidate();
  1047. // If something wrong
  1048. if (m_hCursor == NULL) return BTNST_INVALIDRESOURCE;
  1049. } // if
  1050. return BTNST_OK;
  1051. } // End of SetBtnCursor
  1052. // This function sets if the button border must be drawn.
  1053. // Applies only to flat buttons.
  1054. //
  1055. // Parameters:
  1056. // [IN] bDrawBorder
  1057. // If TRUE the border will be drawn.
  1058. // [IN] bRepaint
  1059. // If TRUE the control will be repainted.
  1060. //
  1061. // Return value:
  1062. // BTNST_OK
  1063. // Function executed successfully.
  1064. //
  1065. DWORD CButtonST::DrawBorder(BOOL bDrawBorder, BOOL bRepaint)
  1066. {
  1067. m_bDrawBorder = bDrawBorder;
  1068. // Repaint the button
  1069. if (bRepaint) Invalidate();
  1070. return BTNST_OK;
  1071. } // End of DrawBorder
  1072. // This function sets if the focus rectangle must be drawn for flat buttons.
  1073. //
  1074. // Parameters:
  1075. // [IN] bDrawFlatFocus
  1076. // If TRUE the focus rectangle will be drawn also for flat buttons.
  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::DrawFlatFocus(BOOL bDrawFlatFocus, BOOL bRepaint)
  1085. {
  1086. m_bDrawFlatFocus = bDrawFlatFocus;
  1087. // Repaint the button
  1088. if (bRepaint) Invalidate();
  1089. return BTNST_OK;
  1090. } // End of DrawFlatFocus
  1091. void CButtonST::InitToolTip()
  1092. {
  1093. if (m_ToolTip.m_hWnd == NULL)
  1094. {
  1095. // Create ToolTip control
  1096. m_ToolTip.Create(this);
  1097. // Create inactive
  1098. m_ToolTip.Activate(FALSE);
  1099. // Enable multiline
  1100. m_ToolTip.SendMessage(TTM_SETMAXTIPWIDTH, 0, 400);
  1101. } // if
  1102. } // End of InitToolTip
  1103. // This function sets the text to show in the button tooltip.
  1104. //
  1105. // Parameters:
  1106. // [IN] nText
  1107. // ID number of the string resource containing the text to show.
  1108. // [IN] bActivate
  1109. // If TRUE the tooltip will be created active.
  1110. //
  1111. void CButtonST::SetTooltipText(int nText, BOOL bActivate)
  1112. {
  1113. CString sText;
  1114. // Load string resource
  1115. sText.LoadString(nText);
  1116. // If string resource is not empty
  1117. if (sText.IsEmpty() == FALSE) SetTooltipText((LPCTSTR)sText, bActivate);
  1118. } // End of SetTooltipText
  1119. // This function sets the text to show in the button tooltip.
  1120. //
  1121. // Parameters:
  1122. // [IN] lpszText
  1123. // Pointer to a null-terminated string containing the text to show.
  1124. // [IN] bActivate
  1125. // If TRUE the tooltip will be created active.
  1126. //
  1127. void CButtonST::SetTooltipText(LPCTSTR lpszText, BOOL bActivate)
  1128. {
  1129. // We cannot accept NULL pointer
  1130. if (lpszText == NULL) return;
  1131. // Initialize ToolTip
  1132. InitToolTip();
  1133. // If there is no tooltip defined then add it
  1134. if (m_ToolTip.GetToolCount() == 0)
  1135. {
  1136. CRect rectBtn; 
  1137. GetClientRect(rectBtn);
  1138. m_ToolTip.AddTool(this, lpszText, rectBtn, 1);
  1139. } // if
  1140. // Set text for tooltip
  1141. m_ToolTip.UpdateTipText(lpszText, this, 1);
  1142. m_ToolTip.Activate(bActivate);
  1143. } // End of SetTooltipText
  1144. // This function enables or disables the button tooltip.
  1145. //
  1146. // Parameters:
  1147. // [IN] bActivate
  1148. // If TRUE the tooltip will be activated.
  1149. //
  1150. void CButtonST::ActivateTooltip(BOOL bActivate)
  1151. {
  1152. // If there is no tooltip then do nothing
  1153. if (m_ToolTip.GetToolCount() == 0) return;
  1154. // Activate tooltip
  1155. m_ToolTip.Activate(bActivate);
  1156. } // End of EnableTooltip
  1157. // This function returns if the button is the default button.
  1158. //
  1159. // Return value:
  1160. // TRUE
  1161. // The button is the default button.
  1162. // FALSE
  1163. // The button is not the default button.
  1164. //
  1165. BOOL CButtonST::GetDefault()
  1166. {
  1167. return m_bIsDefault;
  1168. } // End of GetDefault
  1169. // This function enables the transparent mode.
  1170. // Note: this operation is not reversible.
  1171. // DrawTransparent should be called just after the button is created.
  1172. // Do not use trasparent buttons until you really need it (you have a bitmapped
  1173. // background) since each transparent button makes a copy in memory of its background.
  1174. // This may bring unnecessary memory use and execution overload.
  1175. //
  1176. // Parameters:
  1177. // [IN] bRepaint
  1178. // If TRUE the control will be repainted.
  1179. //
  1180. void CButtonST::DrawTransparent(BOOL bRepaint)
  1181. {
  1182. m_bDrawTransparent = TRUE;
  1183. // Restore old bitmap (if any)
  1184. if (m_dcBk.m_hDC != NULL && m_pbmpOldBk != NULL)
  1185. {
  1186. m_dcBk.SelectObject(m_pbmpOldBk);
  1187. } // if
  1188. m_bmpBk.DeleteObject();
  1189. m_dcBk.DeleteDC();
  1190. // Repaint the button
  1191. if (bRepaint) Invalidate();
  1192. } // End of DrawTransparent
  1193. // This function sets the URL that will be opened when the button is clicked.
  1194. //
  1195. // Parameters:
  1196. // [IN] lpszURL
  1197. // Pointer to a null-terminated string that contains the URL.
  1198. // Pass NULL to removed any previously specified URL.
  1199. //
  1200. // Return value:
  1201. // BTNST_OK
  1202. // Function executed successfully.
  1203. //
  1204. DWORD CButtonST::SetURL(LPCTSTR lpszURL)
  1205. {
  1206. // Remove any existing URL
  1207. memset(m_szURL, 0, sizeof(m_szURL));
  1208. if (lpszURL)
  1209. {
  1210. // Store the URL
  1211. _tcsncpy(m_szURL, lpszURL, _MAX_PATH);
  1212. } // if
  1213. return BTNST_OK;
  1214. } // End of SetURL
  1215. // This function associates a menu to the button.
  1216. // The menu will be displayed clicking the button.
  1217. //
  1218. // Parameters:
  1219. // [IN] nMenu
  1220. // ID number of the menu resource.
  1221. // Pass NULL to remove any menu from the button.
  1222. // [IN] hParentWnd
  1223. // Handle to the window that owns the menu.
  1224. // This window receives all messages from the menu.
  1225. // [IN] bRepaint
  1226. // If TRUE the control will be repainted.
  1227. //
  1228. // Return value:
  1229. // BTNST_OK
  1230. // Function executed successfully.
  1231. // BTNST_INVALIDRESOURCE
  1232. // Failed loading the specified resource.
  1233. //
  1234. DWORD CButtonST::SetMenu(UINT nMenu, HWND hParentWnd, BOOL bRepaint)
  1235. {
  1236. HINSTANCE hInstResource = NULL;
  1237. // Destroy any previous menu
  1238. if (m_hMenu)
  1239. {
  1240. ::DestroyMenu(m_hMenu);
  1241. m_hMenu = NULL;
  1242. m_hParentWndMenu = NULL;
  1243. m_bMenuDisplayed = FALSE;
  1244. } // if
  1245. // Load menu
  1246. if (nMenu)
  1247. {
  1248. // Find correct resource handle
  1249. hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nMenu), RT_MENU);
  1250. // Load menu resource
  1251. m_hMenu = ::LoadMenu(hInstResource, MAKEINTRESOURCE(nMenu));
  1252. m_hParentWndMenu = hParentWnd;
  1253. // If something wrong
  1254. if (m_hMenu == NULL) return BTNST_INVALIDRESOURCE;
  1255. } // if
  1256. // Repaint the button
  1257. if (bRepaint) Invalidate();
  1258. return BTNST_OK;
  1259. } // End of SetMenu
  1260. // This function is called every time the button background needs to be painted.
  1261. // If the button is in transparent mode this function will NOT be called.
  1262. // This is a virtual function that can be rewritten in CButtonST-derived classes
  1263. // to produce a whole range of buttons not available by default.
  1264. //
  1265. // Parameters:
  1266. // [IN] pDC
  1267. // Pointer to a CDC object that indicates the device context.
  1268. // [IN] pRect
  1269. // Pointer to a CRect object that indicates the bounds of the
  1270. // area to be painted.
  1271. //
  1272. // Return value:
  1273. // BTNST_OK
  1274. // Function executed successfully.
  1275. //
  1276. DWORD CButtonST::OnDrawBackground(CDC* pDC, LPCRECT pRect)
  1277. {
  1278. COLORREF crColor;
  1279. if (m_bMouseOnButton || m_bIsPressed)
  1280. crColor = m_crColors[BTNST_COLOR_BK_IN];
  1281. else
  1282. {
  1283. if (m_bIsFocused)
  1284. crColor = m_crColors[BTNST_COLOR_BK_FOCUS];
  1285. else
  1286. crColor = m_crColors[BTNST_COLOR_BK_OUT];
  1287. } // else
  1288. CBrush brBackground(crColor);
  1289. pDC->FillRect(pRect, &brBackground);
  1290. return BTNST_OK;
  1291. } // End of OnDrawBackground
  1292. // This function is called every time the button border needs to be painted.
  1293. // If the button is in standard (not flat) mode this function will NOT be called.
  1294. // This is a virtual function that can be rewritten in CButtonST-derived classes
  1295. // to produce a whole range of buttons not available by default.
  1296. //
  1297. // Parameters:
  1298. // [IN] pDC
  1299. // Pointer to a CDC object that indicates the device context.
  1300. // [IN] pRect
  1301. // Pointer to a CRect object that indicates the bounds of the
  1302. // area to be painted.
  1303. //
  1304. // Return value:
  1305. // BTNST_OK
  1306. // Function executed successfully.
  1307. //
  1308. DWORD CButtonST::OnDrawBorder(CDC* pDC, LPCRECT pRect)
  1309. {
  1310. if (m_bIsPressed)
  1311. pDC->Draw3dRect(pRect, ::GetSysColor(COLOR_BTNSHADOW), ::GetSysColor(COLOR_BTNHILIGHT));
  1312. else
  1313. pDC->Draw3dRect(pRect, ::GetSysColor(COLOR_BTNHILIGHT), ::GetSysColor(COLOR_BTNSHADOW));
  1314. return BTNST_OK;
  1315. } // End of OnDrawBorder
  1316. #undef BS_TYPEMASK
  1317. void CButtonST::setText(UINT nID)
  1318. {
  1319. CString str;
  1320. str.LoadString(nID);
  1321. SetWindowText(str);
  1322. }