BtnST.cpp
上传用户:shyhzl888
上传日期:2007-01-07
资源大小:35k
文件大小:16k
源码类别:

行业应用

开发平台:

Visual C++

  1. // BtnST.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "BtnST.h"
  5. #ifdef _DEBUG
  6. #define new DEBUG_NEW
  7. #undef THIS_FILE
  8. static char THIS_FILE[] = __FILE__;
  9. #endif
  10. #define TOOLTIP_ID 1
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CButtonST
  13. CButtonST::CButtonST()
  14. {
  15.   m_MouseOnButton = FALSE;
  16.   m_hIconIn = NULL;
  17.   m_hIconOut = NULL;
  18.   m_cxIcon = 0;
  19.   m_cyIcon = 0;
  20.   m_hCursor = NULL;
  21.   
  22.   // Default type is "flat" button
  23.   m_bIsFlat = TRUE; 
  24.   
  25.   // By default draw border in "flat" button 
  26.   m_bDrawBorder = TRUE; 
  27.   
  28.   // By default icon is aligned horizontally
  29.   m_nAlign = ST_ALIGN_HORIZ; 
  30.   
  31.   // By default show the text button
  32.   m_bShowText = TRUE; 
  33.   
  34.   // By default, for "flat" button, don't draw the focus rect
  35.   m_bDrawFlatFocus = FALSE;
  36.   // By default, the "flat" button, has a tip ""
  37.   m_strToolTip.Empty();
  38.   SetDefaultInactiveBgColor();
  39.   SetDefaultInactiveFgColor();
  40.   SetDefaultActiveBgColor();
  41.   SetDefaultActiveFgColor();
  42. } // End of CButtonST
  43. CButtonST::~CButtonST()
  44. {
  45. // Destroy the icons (if any)
  46. if (m_hIconIn != NULL) ::DeleteObject(m_hIconIn);
  47. if (m_hIconOut != NULL) ::DeleteObject(m_hIconOut);
  48. // Destroy the cursor (if any)
  49. if (m_hCursor != NULL) ::DestroyCursor(m_hCursor);
  50. } // End of ~CButtonST
  51. BEGIN_MESSAGE_MAP(CButtonST, CButton)
  52.     //{{AFX_MSG_MAP(CButtonST)
  53. ON_WM_CAPTURECHANGED()
  54. ON_WM_SETCURSOR()
  55. ON_WM_KILLFOCUS()
  56. ON_WM_MOUSEMOVE()
  57. //}}AFX_MSG_MAP
  58. END_MESSAGE_MAP()
  59. void CButtonST::SetIcon(int nIconInId, int nIconOutId, BYTE cx, BYTE cy)
  60. {
  61. HINSTANCE hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nIconInId),
  62. RT_GROUP_ICON);
  63. // Set icon when the mouse is IN the button
  64. m_hIconIn = (HICON)::LoadImage(hInstResource/*AfxGetApp()->m_hInstance*/, MAKEINTRESOURCE(nIconInId), IMAGE_ICON, 0, 0, 0);
  65.   
  66. // Set icon when the mouse is OUT the button
  67. m_hIconOut = (nIconOutId == NULL) ? m_hIconIn : (HICON)::LoadImage(hInstResource/*AfxGetApp()->m_hInstance*/, MAKEINTRESOURCE(nIconOutId), IMAGE_ICON, 0, 0, 0);
  68.   
  69. m_cxIcon = cx;
  70. m_cyIcon = cy;
  71. RedrawWindow();
  72. } // End of SetIcon
  73. BOOL CButtonST::SetBtnCursor(int nCursorId)
  74. {
  75. HINSTANCE hInstResource;
  76. // Destroy any previous cursor
  77. if (m_hCursor != NULL) ::DestroyCursor(m_hCursor);
  78. m_hCursor = NULL;
  79. // If we want a cursor
  80. if (nCursorId != -1)
  81. {
  82. hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nCursorId),
  83. RT_GROUP_CURSOR);
  84. // Load icon resource
  85. m_hCursor = (HCURSOR)::LoadImage(hInstResource/*AfxGetApp()->m_hInstance*/, MAKEINTRESOURCE(nCursorId), IMAGE_CURSOR, 0, 0, 0);
  86. // If something wrong then return FALSE
  87. if (m_hCursor == NULL) return FALSE;
  88. }
  89. return TRUE;
  90. } // End of SetBtnCursor
  91. void CButtonST::SetFlat(BOOL bState)
  92. {
  93.   m_bIsFlat = bState;
  94.   Invalidate();
  95. } // End of SetFlat
  96. BOOL CButtonST::GetFlat()
  97. {
  98.   return m_bIsFlat;
  99. } // End of GetFlat
  100. void CButtonST::SetAlign(int nAlign)
  101. {
  102.   switch (nAlign)
  103.   {    
  104.     case ST_ALIGN_HORIZ:
  105.          m_nAlign = ST_ALIGN_HORIZ;
  106.          break;
  107.     case ST_ALIGN_VERT:
  108.          m_nAlign = ST_ALIGN_VERT;
  109.          break;
  110.   }
  111.   Invalidate();
  112. } // End of SetAlign
  113. int CButtonST::GetAlign()
  114. {
  115.   return m_nAlign;
  116. } // End of GetAlign
  117. void CButtonST::DrawBorder(BOOL bEnable)
  118. {
  119.   m_bDrawBorder = bEnable;
  120. } // End of DrawBorder
  121. const char* CButtonST::GetVersionC()
  122. {
  123.   return "2.3";
  124. } // End of GetVersionC
  125. const short CButtonST::GetVersionI()
  126. {
  127.   return 23; // Divide by 10 to get actual version
  128. } // End of GetVersionI
  129. void CButtonST::SetShowText(BOOL bShow)
  130. {
  131.   m_bShowText = bShow;
  132.   Invalidate();
  133. } // End of SetShowText
  134. BOOL CButtonST::GetShowText()
  135. {
  136.   return m_bShowText;
  137. } // End of GetShowText
  138. void CButtonST::OnMouseMove(UINT nFlags, CPoint point)
  139. {
  140.   CWnd* pWnd;  // Finestra attiva
  141.   CWnd* pParent; // Finestra che contiene il bottone
  142.   CButton::OnMouseMove(nFlags, point);
  143.   // If the mouse enter the button with the left button pressed
  144.   // then do nothing
  145.   if (nFlags & MK_LBUTTON && m_MouseOnButton == FALSE) return;
  146.   // If our button is not flat then do nothing
  147.   if (m_bIsFlat == FALSE) return;
  148.   pWnd = GetActiveWindow();
  149.   pParent = GetOwner();
  150. if ((GetCapture() != this) && 
  151. (
  152. #ifndef ST_LIKEIE
  153. pWnd != NULL && 
  154. #endif
  155. pParent != NULL)) 
  156. {
  157. m_MouseOnButton = TRUE;
  158. //SetFocus(); // Thanks Ralph!
  159. SetCapture();
  160. Invalidate();
  161. }
  162. else
  163.   {
  164.     CRect rc;
  165.     GetClientRect(&rc);
  166.     if (!rc.PtInRect(point))
  167.     {
  168.       // Redraw only if mouse goes out
  169.       if (m_MouseOnButton == TRUE)
  170.       {
  171.         m_MouseOnButton = FALSE;
  172.         Invalidate();
  173.       }
  174.       // If user is NOT pressing left button then release capture!
  175.       if (!(nFlags & MK_LBUTTON)) ReleaseCapture();
  176.     }
  177.   }
  178. } // End of OnMouseMove
  179. void CButtonST::OnKillFocus(CWnd * pNewWnd)
  180. {
  181.   CButton::OnKillFocus(pNewWnd);
  182.   // If our button is not flat then do nothing
  183.   if (m_bIsFlat == FALSE) return;
  184.   if (m_MouseOnButton == TRUE)
  185.   {
  186.     m_MouseOnButton = FALSE;
  187.     Invalidate();
  188.   }
  189. } // End of OnKillFocus
  190. void CButtonST::OnCaptureChanged(CWnd *pWnd) 
  191. {
  192. if (m_MouseOnButton == TRUE)
  193. {
  194. ReleaseCapture();
  195. Invalidate();
  196. }
  197. // Call base message handler
  198. CButton::OnCaptureChanged(pWnd);
  199. } // End of OnCaptureChanged
  200. void CButtonST::DrawItem(LPDRAWITEMSTRUCT lpDIS)
  201. {
  202. #ifdef ST_USE_MEMDC
  203.   CDC  *pdrawDC = CDC::FromHandle(lpDIS->hDC);
  204.   CMemDC memDC(pdrawDC);
  205.   CDC  *pDC = &memDC;
  206. #else
  207.   CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  208. #endif
  209.   CPen *pOldPen;
  210.   BOOL bIsPressed  = (lpDIS->itemState & ODS_SELECTED);
  211.   BOOL bIsFocused  = (lpDIS->itemState & ODS_FOCUS);
  212.   BOOL bIsDisabled = (lpDIS->itemState & ODS_DISABLED);
  213.   CRect itemRect = lpDIS->rcItem;
  214.   if (m_bIsFlat == FALSE)
  215.   {
  216.     if (bIsFocused)
  217.     {
  218.       CBrush br(RGB(0,0,0));  
  219.       pDC->FrameRect(&itemRect, &br);
  220.       itemRect.DeflateRect(1, 1);
  221.     }
  222.   }
  223.   // Prepare draw... paint button's area with background color
  224.   COLORREF bgColor;
  225.   if ((m_MouseOnButton == TRUE) || (bIsPressed))
  226.     bgColor = GetActiveBgColor();
  227.   else
  228.     bgColor = GetInactiveBgColor();
  229.   CBrush br(bgColor);
  230.   pDC->FillRect(&itemRect, &br);
  231. // Disegno lo sfondo del bottone
  232. //CBrush br(GetSysColor(COLOR_BTNFACE));  
  233. //pDC->FillRect(&itemRect, &br);
  234.   // Draw pressed button
  235.   if (bIsPressed)
  236.   {
  237.     if (m_bIsFlat == TRUE)
  238.     {
  239.       if (m_bDrawBorder == TRUE)
  240.       {
  241.     CPen penBtnHiLight(PS_SOLID, 0, GetSysColor(COLOR_BTNHILIGHT)); // Bianco
  242.         CPen penBtnShadow(PS_SOLID, 0, GetSysColor(COLOR_BTNSHADOW));   // Grigio scuro
  243.         // Disegno i bordi a sinistra e in alto
  244.         // Dark gray line
  245.         pOldPen = pDC->SelectObject(&penBtnShadow);
  246.         pDC->MoveTo(itemRect.left, itemRect.bottom-1);
  247.         pDC->LineTo(itemRect.left, itemRect.top);
  248.         pDC->LineTo(itemRect.right, itemRect.top);
  249.         // Disegno i bordi a destra e in basso
  250.         // White line
  251.         pDC->SelectObject(penBtnHiLight);
  252.         pDC->MoveTo(itemRect.left, itemRect.bottom-1);
  253.         pDC->LineTo(itemRect.right-1, itemRect.bottom-1);
  254.         pDC->LineTo(itemRect.right-1, itemRect.top-1);
  255.         //
  256.         pDC->SelectObject(pOldPen);
  257.       }
  258.     }
  259.     else    
  260.     {
  261.       CBrush brBtnShadow(GetSysColor(COLOR_BTNSHADOW));
  262.       pDC->FrameRect(&itemRect, &brBtnShadow);
  263.     }
  264.   }
  265.   else // ...else draw non pressed button
  266.   {
  267.     CPen penBtnHiLight(PS_SOLID, 0, GetSysColor(COLOR_BTNHILIGHT)); // White
  268.     CPen pen3DLight(PS_SOLID, 0, GetSysColor(COLOR_3DLIGHT));       // Light gray
  269.     CPen penBtnShadow(PS_SOLID, 0, GetSysColor(COLOR_BTNSHADOW));   // Dark gray
  270.     CPen pen3DDKShadow(PS_SOLID, 0, GetSysColor(COLOR_3DDKSHADOW)); // Black
  271.     if (m_bIsFlat == TRUE)
  272.     {
  273.       if (m_MouseOnButton == TRUE && m_bDrawBorder == TRUE)
  274.       {
  275.        // Disegno i bordi a sinistra e in alto
  276.         // White line
  277.         pOldPen = pDC->SelectObject(&penBtnHiLight);
  278.         pDC->MoveTo(itemRect.left, itemRect.bottom-1);
  279.         pDC->LineTo(itemRect.left, itemRect.top);
  280.         pDC->LineTo(itemRect.right, itemRect.top);
  281.         // Disegno i bordi a destra e in basso
  282.         // Dark gray line
  283.         pDC->SelectObject(penBtnShadow);
  284.         pDC->MoveTo(itemRect.left, itemRect.bottom-1);
  285.         pDC->LineTo(itemRect.right-1, itemRect.bottom-1);
  286.         pDC->LineTo(itemRect.right-1, itemRect.top-1);
  287.         //
  288.         pDC->SelectObject(pOldPen);
  289.       }
  290.     }
  291.     else
  292.     {
  293.       // Disegno i bordi a sinistra e in alto
  294.       // White line
  295.       pOldPen = pDC->SelectObject(&penBtnHiLight);
  296.       pDC->MoveTo(itemRect.left, itemRect.bottom-1);
  297.       pDC->LineTo(itemRect.left, itemRect.top);
  298.       pDC->LineTo(itemRect.right, itemRect.top);
  299.       // Light gray line
  300.       pDC->SelectObject(pen3DLight);
  301.       pDC->MoveTo(itemRect.left+1, itemRect.bottom-1);
  302.       pDC->LineTo(itemRect.left+1, itemRect.top+1);
  303.       pDC->LineTo(itemRect.right, itemRect.top+1);
  304.       // Disegno i bordi a destra e in basso
  305.       // Black line
  306.       pDC->SelectObject(pen3DDKShadow);
  307.       pDC->MoveTo(itemRect.left, itemRect.bottom-1);
  308.       pDC->LineTo(itemRect.right-1, itemRect.bottom-1);
  309.       pDC->LineTo(itemRect.right-1, itemRect.top-1);
  310.       // Dark gray line
  311.       pDC->SelectObject(penBtnShadow);
  312.       pDC->MoveTo(itemRect.left+1, itemRect.bottom-2);
  313.       pDC->LineTo(itemRect.right-2, itemRect.bottom-2);
  314.       pDC->LineTo(itemRect.right-2, itemRect.top);
  315.       //
  316.       pDC->SelectObject(pOldPen);
  317.     }
  318.   }
  319.   // Read the button title
  320.   CString sTitle;
  321.   GetWindowText(sTitle);
  322.   // If we don't want the title displayed
  323.   if (m_bShowText == FALSE) sTitle.Empty();
  324.   CRect captionRect = lpDIS->rcItem;
  325.   // Draw the icon
  326.   if (m_hIconIn != NULL)
  327.   {
  328.     DrawTheIcon(pDC, &sTitle, &lpDIS->rcItem, &captionRect, bIsPressed, bIsDisabled);
  329.   }
  330.   // Write the button title (if any)
  331.   if (sTitle.IsEmpty() == FALSE)
  332.   {
  333.     // Disegno la caption del bottone
  334.     // Se il bottone e' premuto muovo la captionRect di conseguenza
  335.     if (bIsPressed)
  336.       captionRect.OffsetRect(1, 1);
  337.     
  338.     // ONLY FOR DEBUG 
  339.     // Evidenzia il rettangolo in cui verra' centrata la caption 
  340.     //CBrush brBtnShadow(RGB(255, 0, 0));
  341.     //pDC->FrameRect(&captionRect, &brBtnShadow);
  342. #ifdef ST_USE_MEMDC
  343. // Get dialog's font
  344.     CFont *pCurrentFont = GetFont(); 
  345.     CFont *pOldFont = pDC->SelectObject(pCurrentFont);
  346. #endif
  347.     if ((m_MouseOnButton == TRUE) || (bIsPressed)) 
  348. {
  349.       pDC->SetTextColor(GetActiveFgColor());
  350.       pDC->SetBkColor(GetActiveBgColor());
  351.     } 
  352. else 
  353. {
  354.       pDC->SetTextColor(GetInactiveFgColor());
  355.       pDC->SetBkColor(GetInactiveBgColor());
  356.     }
  357.     // Center text
  358.     CRect centerRect = captionRect;
  359.     pDC->DrawText(sTitle, -1, captionRect, DT_SINGLELINE|DT_CALCRECT);
  360.     captionRect.OffsetRect((centerRect.Width() - captionRect.Width())/2, (centerRect.Height() - captionRect.Height())/2);
  361. /* RFU
  362.     captionRect.OffsetRect(0, (centerRect.Height() - captionRect.Height())/2);
  363.     captionRect.OffsetRect((centerRect.Width() - captionRect.Width())-4, (centerRect.Height() - captionRect.Height())/2);
  364. */
  365.     pDC->DrawState(captionRect.TopLeft(), captionRect.Size(), (LPCTSTR)sTitle, (bIsDisabled ? DSS_DISABLED : DSS_NORMAL), 
  366.                    TRUE, 0, (CBrush*)NULL);
  367. #ifdef ST_USE_MEMDC
  368.     pDC->SelectObject(pOldFont);
  369. #endif
  370.   }
  371.   if (m_bIsFlat == FALSE || (m_bIsFlat == TRUE && m_bDrawFlatFocus == TRUE))
  372.   {
  373.     // Draw the focus rect
  374.     if (bIsFocused)
  375.     {
  376.       CRect focusRect = itemRect;
  377.       focusRect.DeflateRect(3, 3);
  378.       pDC->DrawFocusRect(&focusRect);
  379.     }
  380.   }
  381. } // End of DrawItem
  382. void CButtonST::DrawTheIcon(CDC* pDC, CString* title, RECT* rcItem, CRect* captionRect, BOOL IsPressed, BOOL IsDisabled)
  383. {
  384.   CRect iconRect = rcItem;
  385.   switch (m_nAlign)
  386.   {
  387.     case ST_ALIGN_HORIZ:
  388.          if (title->IsEmpty())
  389.          {
  390.            // Center the icon horizontally
  391.            iconRect.left += ((iconRect.Width() - m_cxIcon)/2);
  392.          }
  393.          else
  394.          {
  395.            // L'icona deve vedersi subito dentro il focus rect
  396.            iconRect.left += 3;  
  397.            captionRect->left += m_cxIcon + 3;
  398.          }
  399.          // Center the icon vertically
  400.          iconRect.top += ((iconRect.Height() - m_cyIcon)/2);
  401.          break;
  402.     case ST_ALIGN_VERT:
  403.          // Center the icon horizontally
  404.          iconRect.left += ((iconRect.Width() - m_cxIcon)/2);
  405.          if (title->IsEmpty())
  406.          {
  407.            // Center the icon vertically
  408.            iconRect.top += ((iconRect.Height() - m_cyIcon)/2);           
  409.          }
  410.          else
  411.          {
  412.            captionRect->top += m_cyIcon;
  413.          }
  414.          break;
  415.   }
  416.     
  417.   // If button is pressed then press the icon also
  418.   if (IsPressed) iconRect.OffsetRect(1, 1);
  419.   // Ole'!
  420.   pDC->DrawState(iconRect.TopLeft(), 
  421.                iconRect.Size(), 
  422.          (m_MouseOnButton == TRUE || IsPressed) ? m_hIconIn : m_hIconOut, 
  423.          (IsDisabled ? DSS_DISABLED : DSS_NORMAL), 
  424.                  (CBrush*)NULL);
  425. } // End of DrawTheIcon
  426. void CButtonST::PreSubclassWindow() 
  427. {
  428.   CRect rect;
  429.   GetClientRect ( &rect );
  430.   // Add BS_OWNERDRAW style
  431.   SetButtonStyle(GetButtonStyle() | BS_OWNERDRAW);
  432.   // Create tooltips
  433.   m_ctrlToolTip.Create ( this );
  434.   m_ctrlToolTip.AddTool ( this, m_strToolTip, rect, TOOLTIP_ID );
  435.   
  436.   CButton::PreSubclassWindow();
  437. } // End of PreSubclassWindow
  438. void CButtonST::SetDefaultInactiveBgColor(BOOL bRepaint)
  439. {
  440. m_crInactiveBg = ::GetSysColor(COLOR_BTNFACE); 
  441. if (bRepaint == TRUE) Invalidate();
  442. } // End of SetDefaultInactiveBgColor
  443. void CButtonST::SetInactiveBgColor(COLORREF crNew, BOOL bRepaint)
  444. {
  445. m_crInactiveBg = crNew; 
  446. if (bRepaint == TRUE) Invalidate();
  447. } // End of SetInactiveBgColor
  448. const COLORREF CButtonST::GetInactiveBgColor()
  449. {
  450. return m_crInactiveBg;
  451. } // End of GetInactiveBgColor
  452. void CButtonST::SetDefaultInactiveFgColor(BOOL bRepaint)
  453. {
  454. m_crInactiveFg = ::GetSysColor(COLOR_BTNTEXT); 
  455. if (bRepaint == TRUE) Invalidate();
  456. } // End of SetDefaultInactiveFgColor
  457. void CButtonST::SetInactiveFgColor(COLORREF crNew, BOOL bRepaint)
  458. {
  459. m_crInactiveFg = crNew; 
  460. if (bRepaint == TRUE) Invalidate();
  461. } // End of SetInactiveFgColor
  462. const COLORREF CButtonST::GetInactiveFgColor()
  463. {
  464. return m_crInactiveFg;
  465. } // End of GetInactiveFgColor
  466. void CButtonST::SetDefaultActiveBgColor(BOOL bRepaint)
  467. {
  468. m_crActiveBg = ::GetSysColor(COLOR_BTNFACE); 
  469. if (bRepaint == TRUE) Invalidate();
  470. } // End of SetDefaultActiveBgColor
  471. void CButtonST::SetActiveBgColor(COLORREF crNew, BOOL bRepaint)
  472. {
  473. m_crActiveBg = crNew; 
  474. if (bRepaint == TRUE) Invalidate();
  475. } // End of SetActiveBgColor
  476. const COLORREF CButtonST::GetActiveBgColor()
  477. {
  478. return m_crActiveBg;
  479. } // End of GetActiveBgColor
  480. void CButtonST::SetDefaultActiveFgColor(BOOL bRepaint)
  481. {
  482. m_crActiveFg = ::GetSysColor(COLOR_BTNTEXT); 
  483. if (bRepaint == TRUE) Invalidate();
  484. } // End of SetDefaultActiveFgColor
  485. void CButtonST::SetActiveFgColor(COLORREF crNew, BOOL bRepaint)
  486. {
  487. m_crActiveFg = crNew; 
  488. if (bRepaint == TRUE) Invalidate();
  489. } // End of SetActiveFgColor
  490. const COLORREF CButtonST::GetActiveFgColor()
  491. {
  492. return m_crActiveFg;
  493. } // End of GetActiveFgColor
  494. void CButtonST::SetFlatFocus(BOOL bDrawFlatFocus, BOOL bRepaint)
  495. {
  496. m_bDrawFlatFocus = bDrawFlatFocus;
  497. // Repaint the button
  498. if (bRepaint == TRUE) Invalidate();
  499. } // End of SetFlatFocus
  500. BOOL CButtonST::GetFlatFocus()
  501. {
  502. return m_bDrawFlatFocus;
  503. } // End of GetFlatFocus
  504. BOOL CButtonST::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
  505. {
  506. // If a cursor was specified then use it!
  507. if (m_hCursor != NULL)
  508. {
  509. ::SetCursor(m_hCursor);
  510. return TRUE;
  511. }
  512. return CButton::OnSetCursor(pWnd, nHitTest, message);
  513. } // End of OnSetCursor
  514. #undef ST_USE_MEMDC
  515. #undef ST_LIKE
  516. BOOL CButtonST::PreTranslateMessage(MSG* pMsg) 
  517. {
  518. // TODO: Add your specialized code here and/or call the base class
  519. m_ctrlToolTip.RelayEvent ( pMsg );
  520. return CButton::PreTranslateMessage(pMsg);
  521. }
  522. void CButtonST::AddToolTip(CString strTip)
  523. {
  524. m_ctrlToolTip.UpdateTipText ( strTip, this, TOOLTIP_ID );
  525. }