coolbtn.cpp

来自「一个支持FTP,SFTP的客户端程序」· C++ 代码 · 共 838 行 · 第 1/2 页

CPP
838
字号
// CoolBtn.cpp : implementation file
//

#include "stdafx.h"
#include "CoolBtn.h"
#include "VisualStylesXP.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

const int nDropBtnWidth =  14;
/////////////////////////////////////////////////////////////////////////////
// CCoolBtn
// ========
// 
// To Use:
// 1. Create a Bitmap resource 16x15 Pixels normal default size for a toolbar
//    bitmap.
//
// 2. Call CCoolBtns on Create function.
//
// 3. Call SetButtonImage specificing the Transparency color reference.
//    (Usally RGB(255, 0, 255) magenta)
// 
// 4. Add menu items with AddMenuItem using nMenuFlags to add disabled and
///   seperator menu items
//
// 5. Add the appropiate ON_COMMAND handlers in the parent windows message map
//
// 6. Enjoy...
////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:	  CCoolBtn
//
// DESCRIPTION:	
//
// NOTES:			
//
// MAINTENANCE:
// Name:		  Date:	  Version:	Notes:
// NT ALMOND	210100	1.0			  Origin
//
////////////////////////////////////////////////////////////////////////////////
CCoolBtn::CCoolBtn()
{
  m_bPushed = FALSE;
  m_bLoaded = FALSE;
  m_bMenuPushed = FALSE;
  m_bMenuLoaded = FALSE;
  m_bMouseMovedOut = FALSE;
  m_bHovering = FALSE;
  m_bHoveringDropdown = FALSE;

  ZeroMemory(&m_bm, sizeof m_bm);
  m_menu.CreatePopupMenu();

}

////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:	  ~CCoolBtn
//
// DESCRIPTION:	
//
// NOTES:			
//
// MAINTENANCE:
// Name:		  Date:	  Version:	Notes:
// NT ALMOND	210100	1.0			  Origin
//
////////////////////////////////////////////////////////////////////////////////
CCoolBtn::~CCoolBtn()
{
}


BEGIN_MESSAGE_MAP(CCoolBtn, CButton)
	//{{AFX_MSG_MAP(CCoolBtn)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_SETFOCUS()
	ON_WM_KILLFOCUS()
	ON_WM_SYSCOLORCHANGE()
	ON_WM_LBUTTONDBLCLK()
	ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCoolBtn message handlers

////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:	  Create
//
// DESCRIPTION:	Create the button
//
// NOTES:			
//
// MAINTENANCE:
// Name:		  Date:	  Version:	Notes:
// NT ALMOND	210100	1.0			  Origin
//
////////////////////////////////////////////////////////////////////////////////
BOOL CCoolBtn::Create( LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID )
{
  dwStyle |= BS_OWNERDRAW; // Enforce
  m_pParentWnd = pParentWnd;
  return CButton::Create(lpszCaption, dwStyle, rect, pParentWnd, nID );	;
}



////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:	  DrawItem
//
// DESCRIPTION:	Called in response to draw the button
//
// NOTES:			
//
// MAINTENANCE:
// Name:		  Date:	  Version:	Notes:
// NT ALMOND	210100	1.0			  Origin
//
////////////////////////////////////////////////////////////////////////////////
void CCoolBtn::DrawItemXP(DRAWITEMSTRUCT* lpDIS) 
{
	if (lpDIS->CtlType != ODT_BUTTON)
		return;

	CFont *pFont = CFont::FromHandle((HFONT)GetStockObject(DEFAULT_GUI_FONT));

	CDC dcMem;
	CBitmap bmp;
	
	CRect trueRect(lpDIS->rcItem);
	CRect btnRect(trueRect);
	btnRect.right -= nDropBtnWidth-2;
	
	CDC *pDC = CDC::FromHandle(lpDIS->hDC);
	
	UINT state = lpDIS->itemState;

	BOOL	bPressed = state & ODS_SELECTED;
	BOOL	bGotFocus = state & ODS_FOCUS;
	BOOL	bDisabled = state & ODS_DISABLED;

	// BOOL	bFocusRect = !(state & ODS_NOFOCUSRECT);	// Win2K/XP

	int		iMode;
	
    if (m_bHovering)
	{
		if (bPressed)
		{
			iMode = PBS_PRESSED;
		}
		else
		{
			iMode = PBS_HOT;
		}
	}
	else
	{
		if (bDisabled)
		{
			iMode = PBS_DISABLED;
		}
		else if (bGotFocus || GetWindowLong(m_hWnd, GWL_STYLE) & BS_DEFPUSHBUTTON)
		{
			iMode = PBS_DEFAULTED;
		}
		else if (!bGotFocus)
		{
			iMode = PBS_NORMAL;
		}
	}
	
	CVisualStylesXP xp;
	HTHEME hTheme = xp.OpenThemeData(GetSafeHwnd(), L"Button");
	btnRect.DeflateRect(1, 1);
	xp.DrawThemeBackground(hTheme, *pDC, BP_PUSHBUTTON, iMode, btnRect, btnRect);
	xp.CloseThemeData(hTheme);

	
	if (bDisabled)
		iMode = CBXS_DISABLED;
	else if (m_bMenuPushed)
		iMode = CBXS_PRESSED;
	else if (m_bHoveringDropdown)
		iMode = CBXS_HOT;
	else
		iMode = CBXS_NORMAL;
	
	trueRect.DeflateRect(2, 2);
	CRect dropButtonRect = trueRect;
	dropButtonRect.right++;
	dropButtonRect.left = dropButtonRect.right - nDropBtnWidth +1;
	hTheme = xp.OpenThemeData(GetSafeHwnd(), L"Combobox");
	xp.DrawThemeBackground(hTheme, *pDC, CP_DROPDOWNBUTTON, iMode, dropButtonRect, dropButtonRect);
	xp.CloseThemeData(hTheme);

	
	CRect rectFocus(btnRect);
	rectFocus.DeflateRect(3,3);

	////////////////////////////////////////
	// State Focus                        //
	////////////////////////////////////////
	if (lpDIS->itemState & ODS_FOCUS || m_bPushed) 
		if (!m_bMenuPushed)
			pDC->DrawFocusRect(&rectFocus);
		
		
	////////////////////////////////////////
	// Action Focus                       //
	////////////////////////////////////////
	if ((lpDIS->itemAction & ODA_FOCUS))
		if (!m_bMenuPushed)
			pDC->DrawFocusRect(&rectFocus);

	////////////////////////////////////////
	// Draw out text                      //
	////////////////////////////////////////
	CFont *pOldFont=pDC->SelectObject(pFont);
	CRect rectText(rectFocus);
	rectFocus.left += m_bm.bmWidth + 2;
	
	CString strCaption;
	GetWindowText(strCaption);
	pDC->SetBkMode(TRANSPARENT);
	pDC->SetBkColor(GetSysColor(COLOR_BTNFACE));
	
	rectFocus.top++;
	if (ODS_DISABLED & lpDIS->itemState)
	{
		rectFocus.OffsetRect(1,1);
		pDC->SetTextColor(GetSysColor(COLOR_WINDOW));
		pDC->DrawText(strCaption, rectFocus,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
		
		rectFocus.OffsetRect(-1,-1);
		pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
		pDC->DrawText(strCaption, rectFocus,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
	}
	else
	{
		pDC->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
		pDC->DrawText(strCaption, rectFocus,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
	}
}

void CCoolBtn::DrawItem(DRAWITEMSTRUCT* lpDIS) 
{
	CVisualStylesXP xp;
	if (xp.IsAppThemed())
	{
		DrawItemXP(lpDIS);
		return;
	}
	
	if (lpDIS->CtlType != ODT_BUTTON)
		return;
	
	CFont *pFont = CFont::FromHandle((HFONT)GetStockObject(DEFAULT_GUI_FONT));
	
	CDC dcMem;
	CBitmap bmp;
	
	CRect btnRect(lpDIS->rcItem);
	CRect trueRect(btnRect);
	
	CDC *pDC = CDC::FromHandle(lpDIS->hDC);

  ////////////////////////////////////////
  // Button Background                  //
  ////////////////////////////////////////
  pDC->FillRect(trueRect,&CBrush(GetSysColor(COLOR_BTNFACE)));

  BOOL bDefaultBtn = GetWindowLong(m_hWnd,GWL_STYLE) & BS_DEFPUSHBUTTON;
  BOOL bDisabled = ODS_DISABLED & lpDIS->itemState;
 
  if (bDefaultBtn)
    btnRect.DeflateRect(1,1);

  CRect rectFocus(btnRect);

  rectFocus.DeflateRect(3,3);

  rectFocus.right -= nDropBtnWidth+1;


  ////////////////////////////////////////
  // Button in a normal state           //
  ////////////////////////////////////////
  if (!m_bPushed || m_bMenuPushed)
    pDC->DrawFrameControl(&btnRect,DFC_BUTTON,DFCS_BUTTONPUSH);
  

  ////////////////////////////////////////
  // Default Button State               //
  ////////////////////////////////////////
  if ((bDefaultBtn || m_bPushed) && !bDisabled)
  {
    pDC->FrameRect(&lpDIS->rcItem,CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH)));
    if (m_bPushed && !m_bMenuPushed)
      pDC->FrameRect(&btnRect,CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH))); 
  }


  ////////////////////////////////////////
  // State Focus                        //
  ////////////////////////////////////////
   if (lpDIS->itemState & ODS_FOCUS || m_bPushed) 
     if (!m_bMenuPushed)
        pDC->DrawFocusRect(&rectFocus);


  ////////////////////////////////////////
  // Action Focus                       //
  ////////////////////////////////////////
  if ((lpDIS->itemAction & ODA_FOCUS))
     if (!m_bMenuPushed)
        pDC->DrawFocusRect(&rectFocus);


  ////////////////////////////////////////
  // Draw out bitmap                    //
  ////////////////////////////////////////
 
  // Draw out bitmap
  if (m_bLoaded)
  {
    if (!bDisabled)
    {
	   m_IL.DrawIndirect(pDC,0,CPoint(6+m_bPushed,6+m_bPushed), CSize(m_bm.bmWidth, m_bm.bmHeight), CPoint(0,0),ILD_NORMAL);
    }
    else
    {
  	  pDC->DrawState(CPoint(6+m_bPushed,6+m_bPushed), CSize(m_bm.bmWidth, m_bm.bmHeight), m_hbmpDisabled, DST_BITMAP | DSS_DISABLED);
    }
  }


  ////////////////////////////////////////
  // Draw out text                      //
  ////////////////////////////////////////
  CFont *pOldFont=pDC->SelectObject(pFont);
  CRect rectText(rectFocus);
  rectFocus.left += m_bm.bmWidth + 2;
 
  CString strCaption;
  GetWindowText(strCaption);
  pDC->SetBkMode(TRANSPARENT);
  pDC->SetBkColor(GetSysColor(COLOR_BTNFACE));

  rectFocus.top++;
  if (ODS_DISABLED & lpDIS->itemState)
  {
    rectFocus.OffsetRect(1,1);
    pDC->SetTextColor(GetSysColor(COLOR_WINDOW));
    pDC->DrawText(strCaption,rectFocus,DT_SINGLELINE|DT_CENTER|DT_VCENTER);

    rectFocus.OffsetRect(-1,-1);
    pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
    pDC->DrawText(strCaption,rectFocus,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
  }
  else
  {
    pDC->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
    pDC->DrawText(strCaption,rectFocus,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
  }


  CRect rectSplit(btnRect);
  rectSplit.DeflateRect(2, 2);
  rectSplit.right -= nDropBtnWidth;

  ////////////////////////////////////////
  // Drop down split                    //
  ////////////////////////////////////////
  CPen brFace(PS_SOLID,1,GetSysColor(COLOR_3DSHADOW));
  CPen *pOldPen=pDC->SelectObject(&brFace);
  pDC->MoveTo(rectSplit.right+(m_bPushed?1:0), rectSplit.top);
  pDC->LineTo(rectSplit.right+(m_bPushed?1:0), rectSplit.bottom);
  

  CPen brLite(PS_SOLID,1,GetSysColor(COLOR_3DHILIGHT));
  pDC->SelectObject(&brLite);
  pDC->MoveTo(rectSplit.right+1+(m_bPushed?1:0), rectSplit.top);
  pDC->LineTo(rectSplit.right+1+(m_bPushed?1:0), rectSplit.bottom);


  rectSplit.left = rectSplit.right;
  rectSplit.right += nDropBtnWidth;

  CPoint pt(rectSplit.CenterPoint());
  pt += CPoint(m_bPushed, m_bPushed+1);

  CPen penBlack(PS_SOLID, 1, bDisabled ? GetSysColor(COLOR_GRAYTEXT) : GetSysColor(COLOR_WINDOWTEXT));
  pDC->SelectObject(&penBlack);
  DrawArrow(pDC,pt);
  
  ////////////////////////////////////////
  // Drop down state                    //
  ////////////////////////////////////////
  if (m_bMenuPushed && !bDisabled)
  {    
    rectSplit.InflateRect(1, 1);
    rectSplit.left+=2;
    pDC->DrawEdge(rectSplit,BDR_SUNKENOUTER, BF_RECT);
    
  }
	pDC->SelectObject(pOldPen);
	pDC->SelectObject(pOldFont);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?