这是一个实现自绘CButton的类,期望对大家有点帮助,我提供这个类,只是为大家提供一个自绘控件的思路,你可以在此基础上,随意地修改代码,直到它能完成你所需要的功能.其它控件的自绘,原理了和这个差不多.
- #if !defined(AFX_BUTTONST_H__1271FF9C_E28C_4D3B_B429_AFE65924A5D0__INCLUDED_)
- #define AFX_BUTTONST_H__1271FF9C_E28C_4D3B_B429_AFE65924A5D0__INCLUDED_
- #if _MSC_VER > 1000
- #pragma once
- #endif // _MSC_VER > 1000
- // ButtonST.h : header file
- //
- /
- // CButtonST window
- class CButtonST : public CButton
- {
- // Construction
- public:
- CButtonST();
- // Attributes
- public:
- // Operations
- public:
- //设置背景颜色
- void SetBkColor(COLORREF BkColor);
- //设置鼠标在按钮上的偏移颜色
- void SetShOffset(int nShOffset);
- //设置字体颜色
- void SetTextColor(COLORREF TextColor);
- //设置网页链接
- void SetURL(CString strURL);
- //设置背景图片
- void SetBkPicture(CBitmap *pBitMap);
- // Overrides
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(CButtonST)
- public:
- virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
- virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
- protected:
- virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
- virtual void PreSubclassWindow();
- //}}AFX_VIRTUAL
- // Implementation
- public:
- virtual ~CButtonST();
- void DrawItem1(LPDRAWITEMSTRUCT lpDrawItemStruct);
- // Generated message map functions
- protected:
- //{{AFX_MSG(CButtonST)
- afx_msg void OnMouseMove(UINT nFlags, CPoint point);
- afx_msg BOOL OnNcActivate(BOOL bActive);
- afx_msg void OnNcMouseMove(UINT nHitTest, CPoint point);
- afx_msg void OnKillFocus(CWnd* pNewWnd);
- afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
- //}}AFX_MSG
- protected:
- //鼠标是否在按钮上面
- BOOL m_IsPressed;
- COLORREF m_BkColor;
- int m_nShOffset;
- COLORREF m_TextColor;
- CString m_strURL;
- CBitmap *m_pBitMapBK;
- protected:
- //背景颜色偏移
- COLORREF OffsetColor(COLORREF color,int nOffset);
- //鼠标离开
- LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);
- DECLARE_MESSAGE_MAP()
- };
- /
- //{{AFX_INSERT_LOCATION}}
- // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
- #endif // !defined(AFX_BUTTONST_H__1271FF9C_E28C_4D3B_B429_AFE65924A5D0__INCLUDED_)
- // ButtonST.cpp : implementation file
- //
- #include "stdafx.h"
- #include "ContrlST.h"
- #include "ButtonST.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- #define BS_TYPEMASK SS_TYPEMASK
- /
- // CButtonST
- CButtonST::CButtonST()
- {
- m_IsPressed = FALSE;
- m_BkColor = RGB(216,233,216);
- m_nShOffset = 30;
- m_TextColor = RGB(0,0,0);
- m_strURL = "";
- m_pBitMapBK = NULL;
- }
- CButtonST::~CButtonST()
- {
- if(m_pBitMapBK!=NULL)
- {
- delete m_pBitMapBK;
- m_pBitMapBK = NULL;
- }
- }
- BEGIN_MESSAGE_MAP(CButtonST, CButton)
- //{{AFX_MSG_MAP(CButtonST)
- ON_WM_MOUSEMOVE()
- ON_WM_NCACTIVATE()
- ON_WM_NCMOUSEMOVE()
- ON_WM_KILLFOCUS()
- ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
- ON_WM_LBUTTONDOWN()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /
- // CButtonST message handlers
- //设置背景颜色
- void CButtonST::SetBkColor(COLORREF BkColor)
- {
- m_BkColor = BkColor;
- this->Invalidate();
- }
- //设置鼠标在按钮上的偏移颜色
- void CButtonST::SetShOffset(int nShOffset)
- {
- m_nShOffset = nShOffset;
- this->Invalidate();
- }
- //设置字体颜色
- void CButtonST::SetTextColor(COLORREF TextColor)
- {
- m_TextColor = TextColor;
- this->Invalidate();
- }
- //设置网页链接
- void CButtonST::SetURL(CString strURL)
- {
- m_strURL = strURL;
- }
- //设置背景图片
- void CButtonST::SetBkPicture(CBitmap *pBitMap)
- {
- if(m_pBitMapBK==pBitMap)
- return;
- if(m_pBitMapBK!=NULL)
- {
- delete m_pBitMapBK;
- m_pBitMapBK = pBitMap;
- }
- m_pBitMapBK = pBitMap;
- this->Invalidate();
- }
- //背景颜色偏移
- COLORREF CButtonST::OffsetColor(COLORREF color,int nOffset)
- {
- BYTE byRed = 0;
- BYTE byGreen = 0;
- BYTE byBlue = 0;
- short shOffsetR = nOffset;
- short shOffsetG = nOffset;
- short shOffsetB = nOffset;
- if (nOffset < -255 || nOffset > 255)
- {
- nOffset = 30;
- }
- // Get RGB components of specified color
- byRed = GetRValue(color);
- byGreen = GetGValue(color);
- byBlue = GetBValue(color);
- // Calculate max. allowed real offset
- if (nOffset > 0)
- {
- if (byRed + nOffset > 255) shOffsetR = 255 - byRed;
- if (byGreen + nOffset > 255) shOffsetG = 255 - byGreen;
- if (byBlue + nOffset > 255) shOffsetB = 255 - byBlue;
- nOffset = min(min(shOffsetR, shOffsetG), shOffsetB);
- }
- else
- {
- if (byRed + nOffset < 0) shOffsetR = -byRed;
- if (byGreen + nOffset < 0) shOffsetG = -byGreen;
- if (byBlue + nOffset < 0) shOffsetB = -byBlue;
- nOffset = max(max(shOffsetR, shOffsetG), shOffsetB);
- }
- int r,g,b;
- r = byRed + nOffset;
- g =byGreen + nOffset;
- b =byBlue + nOffset;
- return RGB(r,g,b);
- }
- void CButtonST::DrawItem1(LPDRAWITEMSTRUCT lpDrawItemStruct)
- {
- // TODO: Add your code to draw the specified item
- CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
- CRect rect = lpDrawItemStruct->rcItem;
- CRect offRect = rect;
- int ndist = 2;
- offRect.left+= ndist;
- offRect.right -=ndist;
- offRect.top += ndist;
- offRect.bottom -=ndist;
- pDC->SetBkMode(TRANSPARENT);
- pDC->SetTextColor(m_TextColor);
- //绘制背景
- if(m_pBitMapBK!=NULL)
- {
- CDC* pNewDC = new CDC;
- pNewDC->CreateCompatibleDC(pDC);
- pNewDC->SelectObject(m_pBitMapBK);
- BITMAP bmp;
- m_pBitMapBK->GetBitmap(&bmp);
- if(m_IsPressed)
- {
- pDC->StretchBlt(0,0,rect.Width(),rect.Height(),pNewDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
- }
- else
- {
- CBrush brush(RGB(220,220,220));//RGB(m_nShOffset,m_nShOffset,m_nShOffset));
- pDC->FillRect(&rect,&brush);
- pDC->StretchBlt(0,0,rect.Width(),rect.Height(),pNewDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCAND);
- }
- delete pNewDC;
- pNewDC = NULL;
- }
- else
- {
- if(m_IsPressed)
- {
- CBrush brush(OffsetColor(m_BkColor,m_nShOffset));
- pDC->FillRect(rect,&brush);
- CBrush brush1(RGB(128,128,128));
- pDC->FrameRect(rect,&brush1);
- pDC->FrameRect(offRect,&brush1);
- }
- else
- {
- CBrush brush(m_BkColor);
- pDC->FillRect(rect,&brush);
- CBrush brush1(RGB(128,128,128));
- pDC->FrameRect(offRect,&brush1);
- }
- }
- CString sTitle;
- GetWindowText(sTitle);
- offRect.OffsetRect(0,rect.Height()/2-8);
- // pDC->DrawText(sTitle, sTitle.GetLength(),offRect, DT_WORDBREAK | DT_CENTER);
- pDC->DrawText(sTitle, sTitle.GetLength(),offRect, DT_WORDBREAK|DT_CENTER);
- }
- void CButtonST::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
- {
- // TODO: Add your code to draw the specified item
- DrawItem1(lpDrawItemStruct);
- return;
- CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
- CRect rect = lpDrawItemStruct->rcItem;
- CRect offRect = rect;
- int ndist = 2;
- offRect.left+= ndist;
- offRect.right -=ndist;
- offRect.top += ndist;
- offRect.bottom -=ndist;
- CDC* pResetDC=new CDC();
- pResetDC->CreateCompatibleDC(pDC);
- CBitmap bitmap;
- bitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());
- pResetDC->SelectObject(&bitmap);
- pResetDC->SetBkMode(TRANSPARENT);
- pResetDC->SetTextColor(m_TextColor);
- //绘制背景
- if(m_pBitMapBK!=NULL)
- {
- CDC* pNewDC = new CDC;
- pNewDC->CreateCompatibleDC(pResetDC);
- pNewDC->SelectObject(m_pBitMapBK);
- BITMAP bmp;
- m_pBitMapBK->GetBitmap(&bmp);
- if(m_IsPressed)
- {
- pResetDC->StretchBlt(0,0,rect.Width(),rect.Height(),pNewDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
- }
- else
- {
- CBrush brush(RGB(220,220,220));//RGB(m_nShOffset,m_nShOffset,m_nShOffset));
- pResetDC->FillRect(&rect,&brush);
- pResetDC->StretchBlt(0,0,rect.Width(),rect.Height(),pNewDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCAND);
- }
- delete pNewDC;
- pNewDC = NULL;
- }
- else
- {
- if(m_IsPressed)
- {
- CBrush brush(OffsetColor(m_BkColor,m_nShOffset));
- pResetDC->FillRect(rect,&brush);
- CBrush brush1(RGB(128,128,128));
- pResetDC->FrameRect(rect,&brush1);
- pResetDC->FrameRect(offRect,&brush1);
- }
- else
- {
- CBrush brush(m_BkColor);
- pResetDC->FillRect(rect,&brush);
- CBrush brush1(RGB(128,128,128));
- pResetDC->FrameRect(offRect,&brush1);
- }
- }
- CString sTitle;
- GetWindowText(sTitle);
- offRect.OffsetRect(0,rect.Height()/2-8);
- // pDC->DrawText(sTitle, sTitle.GetLength(),offRect, DT_WORDBREAK | DT_CENTER);
- pResetDC->DrawText(sTitle, sTitle.GetLength(),offRect, DT_CENTER);
- pDC->StretchBlt(0,0,rect.Width(),rect.Height(),pResetDC,0,0,rect.Width(),rect.Height(),SRCCOPY);
- delete pResetDC;
- }
- void CButtonST::OnMouseMove(UINT nFlags, CPoint point)
- {
- // TODO: Add your message handler code here and/or call default
- TRACKMOUSEEVENT csTME;
- csTME.cbSize = sizeof(csTME);
- csTME.dwFlags = TME_LEAVE;
- csTME.hwndTrack = m_hWnd;
- ::_TrackMouseEvent(&csTME);
- if(m_IsPressed==FALSE)
- {
- m_IsPressed = TRUE;
- this->Invalidate();
- }
- CButton::OnMouseMove(nFlags, point);
- }
- BOOL CButtonST::OnNcActivate(BOOL bActive)
- {
- // TODO: Add your message handler code here and/or call default
- return CButton::OnNcActivate(bActive);
- }
- void CButtonST::OnNcMouseMove(UINT nHitTest, CPoint point)
- {
- // TODO: Add your message handler code here and/or call default
- CButton::OnNcMouseMove(nHitTest, point);
- }
- void CButtonST::OnKillFocus(CWnd* pNewWnd)
- {
- CButton::OnKillFocus(pNewWnd);
- // TODO: Add your message handler code here
- }
- LRESULT CButtonST::OnMouseLeave(WPARAM wParam, LPARAM lParam)
- {
- m_IsPressed = FALSE;
- this->Invalidate();
- return 0;
- } // End of OnMouseLeave
- BOOL CButtonST::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
- {
- // TODO: Add your specialized code here and/or call the base class
- dwStyle |= BS_OWNERDRAW;
- return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
- }
- void CButtonST::OnLButtonDown(UINT nFlags, CPoint point)
- {
- // TODO: Add your message handler code here and/or call default
- if(m_strURL.IsEmpty()==FALSE)
- {
- SHELLEXECUTEINFO csSEI;
- memset(&csSEI, 0, sizeof(csSEI));
- csSEI.cbSize = sizeof(SHELLEXECUTEINFO);
- csSEI.fMask = SEE_MASK_FLAG_NO_UI;
- csSEI.lpVerb = _T("open");
- csSEI.lpFile = m_strURL;
- csSEI.nShow = SW_SHOWMAXIMIZED;
- ::ShellExecuteEx(&csSEI);
- }
- CButton::OnLButtonDown(nFlags, point);
- }
- BOOL CButtonST::PreCreateWindow(CREATESTRUCT& cs)
- {
- // TODO: Add your specialized code here and/or call the base class
- return CButton::PreCreateWindow(cs);
- }
- void CButtonST::PreSubclassWindow()
- {
- // TODO: Add your specialized code here and/or call the base class
- ModifyStyle(BS_TYPEMASK, BS_OWNERDRAW, SWP_FRAMECHANGED);
- CButton::PreSubclassWindow();
- }