BtnST.cpp
上传用户:guanx8y8
上传日期:2007-07-30
资源大小:326k
文件大小:16k
开发平台:

Visual C++

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