基本上实现和CButtonEx差不多,稍微改进了一下绘制的算法。不会有重影。
CheckBoxEx.h
CheckBoxEx.cpp
CheckBoxEx.h
#pragma once #include "atltypes.h" // CCheckBoxEx class CCheckBoxEx : public CButton { DECLARE_DYNAMIC(CCheckBoxEx) public: char szTitle[MAX_PATH]; UINT m_frameCount; Image *m_pImage; Image* m_pTemp; CSize m_sizeImage; enumButtonState m_buttonState; BOOL m_bCheck; CCheckBoxEx(); virtual ~CCheckBoxEx(); BOOL GetCheck(); void SetCheck(BOOL bCheck, BOOL bRepaint=TRUE); protected: DECLARE_MESSAGE_MAP() virtual void PreSubclassWindow(); public: virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/); CRect m_rc; afx_msg BOOL OnEraseBkgnd(CDC* pDC); void DrawContent(CDC& MemDC); void SetBitmap(UINT nResourceID=IDB_PNG_CHECKBOX, UINT nFrameCount=6); afx_msg void OnLButtonUp(UINT nFlags, CPoint point); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnMouseLeave(); afx_msg void OnMouseMove(UINT nFlags, CPoint point); protected: afx_msg LRESULT OnBmGetcheck(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnBmSetcheck(WPARAM wParam, LPARAM lParam); public: afx_msg void OnBnClicked(); };
CheckBoxEx.cpp
// CheckBoxEx.cpp : 实现文件 // #include "stdafx.h" #include "QQRobot.h" #include "CheckBoxEx.h" // CCheckBoxEx IMPLEMENT_DYNAMIC(CCheckBoxEx, CButton) CCheckBoxEx::CCheckBoxEx() : m_pTemp(NULL) { m_buttonState = bsNormal; m_pImage = NULL; } CCheckBoxEx::~CCheckBoxEx() { } BEGIN_MESSAGE_MAP(CCheckBoxEx, CButton) ON_WM_ERASEBKGND() ON_WM_LBUTTONUP() ON_WM_LBUTTONDOWN() ON_WM_MOUSELEAVE() ON_WM_MOUSEMOVE() ON_MESSAGE(BM_GETCHECK, &CCheckBoxEx::OnBmGetcheck) ON_MESSAGE(BM_SETCHECK, &CCheckBoxEx::OnBmSetcheck) ON_CONTROL_REFLECT(BN_CLICKED, &CCheckBoxEx::OnBnClicked) END_MESSAGE_MAP() // CCheckBoxEx 消息处理程序 void CCheckBoxEx::PreSubclassWindow() { // TODO: 在此添加专用代码和/或调用基类 SetButtonStyle(GetButtonStyle()|BS_OWNERDRAW);//修改为自绘模式 GetClientRect(&m_rc); GetWindowTextA(szTitle,sizeof(szTitle));//复制内容 SetBitmap(); CButton::PreSubclassWindow(); } void CCheckBoxEx::DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/) { // TODO: 添加您的代码以绘制指定项 CDC *pDc = GetDC(); // TODO: 在此处添加消息处理程序代码 // 不为绘图消息调用 CButton::OnPaint() CRect rcClient; GetClientRect(&rcClient); CDC MemDC; MemDC.CreateCompatibleDC(pDc); MemDC.SetBkMode(TRANSPARENT);//不设置透明文字会有背景 CBitmap memBmp; memBmp.CreateCompatibleBitmap(pDc, rcClient.Width(), rcClient.Height()); CBitmap *pOldmap = MemDC.SelectObject(&memBmp); //先填充一下原先的背景 //MemDC.BitBlt(rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(), pDc, 0, 0, SRCCOPY); //绘制内容 DrawContent(MemDC); //复制到原来的CDC pDc->BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &MemDC, 0, 0, SRCCOPY); //MemDC.SelectObject(pOldmap); //旧图应该是不存在的,直接删除 pOldmap->DeleteObject(); MemDC.DeleteDC(); memBmp.DeleteObject(); ReleaseDC(pDc); } BOOL CCheckBoxEx::OnEraseBkgnd(CDC* pDC) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CDC MemDC; CBitmap memBmp; MemDC.CreateCompatibleDC(pDC); memBmp.CreateCompatibleBitmap(pDC, m_rc.Width(), m_rc.Height()); CBitmap *pOldmap = MemDC.SelectObject(&memBmp); //先填充一下原先的背景 MemDC.BitBlt(m_rc.left, m_rc.top, m_rc.Width(), m_rc.Height(), pDC, 0, 0, SRCCOPY); //绘制内容 if(m_pTemp == NULL) BitmapToImage(&memBmp,m_pTemp); //旧图应该是黑的无用,直接删除 pOldmap->DeleteObject(); MemDC.DeleteDC(); memBmp.DeleteObject(); ReleaseDC(&MemDC); return TRUE; } void CCheckBoxEx::DrawContent(CDC& MemDC) { Graphics g(MemDC); g.DrawImage(m_pTemp,0,0); if((UINT)m_buttonState < m_frameCount) g.DrawImage(m_pImage, RectF((REAL)m_rc.left,(REAL)m_rc.top,(REAL)m_sizeImage.cx,(REAL)m_sizeImage.cy), m_buttonState * (REAL)m_sizeImage.cx, 0, (REAL)m_sizeImage.cx, (REAL)m_sizeImage.cy, UnitPixel); COLORREF clrOld = MemDC.SetTextColor(RGB(0, 28, 48)); CFont *pOldFont = MemDC.SelectObject(GetFont()); CRect temp_rc = m_rc; temp_rc.left += 6; temp_rc.top -= 2; MemDC.DrawText(szTitle, &temp_rc, DT_VCENTER | DT_CENTER | DT_SINGLELINE | DT_WORD_ELLIPSIS); MemDC.SelectObject(pOldFont); MemDC.SetTextColor(clrOld); } void CCheckBoxEx::SetBitmap(UINT nResourceID, UINT nFrameCount) { ImageFromID(nResourceID,m_pImage); this->m_frameCount = nFrameCount; m_sizeImage.SetSize(m_pImage->GetWidth() / m_frameCount, m_pImage->GetHeight()); } void CCheckBoxEx::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CWnd::OnLButtonUp(nFlags, point); if (m_buttonState == bsDown) { if(GetCheck() == BST_CHECKED) m_buttonState = bsHoverDown; else m_buttonState = bsHover; Invalidate(); } } void CCheckBoxEx::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CWnd::OnLButtonDown(nFlags, point); if(GetCheck() == BST_CHECKED) m_buttonState = bsHoverDown; else m_buttonState = bsHover; Invalidate(); } void CCheckBoxEx::OnMouseLeave() { // TODO: 在此添加消息处理程序代码和/或调用默认值 CButton::OnMouseLeave(); if(m_bCheck) m_buttonState = bsDown; else m_buttonState = bsNormal; Invalidate(); } void CCheckBoxEx::OnMouseMove(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CButton::OnMouseMove(nFlags, point); TRACKMOUSEEVENT tme; tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.hwndTrack = this->m_hWnd; tme.dwFlags = TME_LEAVE | TME_HOVER; _TrackMouseEvent(&tme); if(m_bCheck) m_buttonState = bsHoverDown; else m_buttonState = bsHover; Invalidate(); } afx_msg LRESULT CCheckBoxEx::OnBmGetcheck(WPARAM wParam, LPARAM lParam) { return GetCheck(); } afx_msg LRESULT CCheckBoxEx::OnBmSetcheck(WPARAM wParam, LPARAM lParam) { if(wParam == BST_CHECKED) SetCheck(BST_CHECKED); else SetCheck(BST_UNCHECKED); return 0; } BOOL CCheckBoxEx::GetCheck() { return m_bCheck; } void CCheckBoxEx::SetCheck(BOOL bCheck, BOOL bRepaint/* =TRUE */) { this->m_bCheck = bCheck; if(m_bCheck) m_buttonState = bsDown; else m_buttonState = bsNormal; if(bRepaint) Invalidate(); } void CCheckBoxEx::OnBnClicked() { // TODO: 在此添加控件通知处理程序代码 this->m_bCheck = !this->m_bCheck; }
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2300
- 用户1336
- 访客10853847
每日一句
Challenges spark life; conquering them gives purpose.
挑战点亮生活,征服赋予意义。
挑战点亮生活,征服赋予意义。
新会员