示例图
一、公共文件
和这篇一样,就不写了(MFC-自绘控件(CButton篇) )
二、checkbox部分
头文件
#pragma once #include "Public.h" ////////////////////////////////////////////////////////////////////////// #define DEF_TEXT_FRAME_COLOR RGB(255,255,255) //默认颜色 #define DEF_TEXT_COLOR RGB(10,10,10) //默认颜色 #define TOOLTIP_ID 100 //提示 ID ////////////////////////////////////////////////////////////////////////// class CPngCheckBox : public CButton { public: CPngCheckBox(); virtual ~CPngCheckBox(); public: BOOL GetChecked() { return m_bChecked; } void SetChecked(BOOL bChecked = TRUE) { m_bChecked = bChecked; Invalidate(FALSE); } public: virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); protected: virtual void PreSubclassWindow(); public: // 初始化 void Init(UINT nBkImg, UINT nCkImg); void SetCheckBoxTextColor(COLORREF crTextColor); void SetBackColor(COLORREF crBack) { m_crBack = crBack; } //设置颜色 bool SetTextColor(COLORREF crTextColor, COLORREF crTextFrameColor = DEF_TEXT_FRAME_COLOR, bool bShowFrame = false); //设置字体大小及类型 void SetFontType(int fontSize, CString fontType); Image *ImageFromResource(HINSTANCE hInstance, UINT uImgID, LPCTSTR lpType); void DrawTextString(CDC * pDC, LPCTSTR pszString, COLORREF crText, COLORREF crFrame, LPRECT lpRect); void DrawTextString(CDC * pDC, LPCTSTR pszString, COLORREF crText, COLORREF crFrame, int nXPos, int nYPos); void PaintParent(); protected: BOOL m_bChecked; Image* m_ImageCheck; Image* m_ImageBack; COLORREF m_crBack; COLORREF m_crTextColor; CFont m_font; BOOL m_bShowTextFrame; COLORREF m_crTextFrameColor; BOOL m_bSetBack; afx_msg BOOL OnClicked(); afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor); afx_msg BOOL OnEraseBkgnd(CDC* pDC); DECLARE_MESSAGE_MAP() DECLARE_DYNAMIC(CPngCheckBox) };
#include "stdafx.h" #include "PngCheckBox.h" IMPLEMENT_DYNAMIC(CPngCheckBox, CButton) BEGIN_MESSAGE_MAP(CPngCheckBox, CButton) ON_WM_CREATE() ON_CONTROL_REFLECT_EX(BN_CLICKED, OnClicked) ON_WM_ERASEBKGND() ON_WM_CTLCOLOR_REFLECT() END_MESSAGE_MAP() ////////////////////////////////////////////////////////////////////////// CPngCheckBox::CPngCheckBox() { m_bChecked = FALSE; m_crTextColor = RGB(0, 0, 0); m_crBack = RGB(255, 255, 255); m_bSetBack = FALSE; m_bShowTextFrame = FALSE; m_crTextColor = DEF_TEXT_COLOR; m_crTextFrameColor = DEF_TEXT_FRAME_COLOR; } CPngCheckBox::~CPngCheckBox() { } void CPngCheckBox::PreSubclassWindow() { ModifyStyle(0, BS_OWNERDRAW); CButton::PreSubclassWindow(); } void CPngCheckBox::Init(UINT nBkImg, UINT nCkImg) { m_ImageCheck = ImageFromResource(AfxGetResourceHandle(), nCkImg, L"PNG"); m_ImageBack = ImageFromResource(AfxGetResourceHandle(), nBkImg, L"PNG"); if (m_ImageBack != NULL) { m_bSetBack = TRUE; } CRect rcButton; rcButton = CRect(0, 0, m_ImageCheck->GetWidth() / 4, m_ImageCheck->GetHeight()); SetWindowPos(NULL, 0, 0, rcButton.Width(), rcButton.Height(), SWP_NOACTIVATE | SWP_NOMOVE); } HBRUSH CPngCheckBox::CtlColor(CDC* pDC, UINT nCtlColor) { pDC->SetBkMode(TRANSPARENT); return (HBRUSH)GetStockObject(NULL_BRUSH); } void CPngCheckBox::SetFontType(int fontSize, CString fontType) { LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); lf.lfHeight = fontSize; _tcsncpy_s(lf.lfFaceName, LF_FACESIZE, fontType, fontType.GetLength()); VERIFY(m_font.CreateFontIndirect(&lf)); } void CPngCheckBox::DrawItem(LPDRAWITEMSTRUCT lpDIS) { CDC dc; dc.Attach(lpDIS->hDC); CRect rcItem(lpDIS->rcItem); if (m_bSetBack) { Graphics graph(lpDIS->hDC); graph.DrawImage(m_ImageBack, RectF(0, 0, rcItem.Width(), rcItem.Height()), rcItem.left, rcItem.top, rcItem.Width(), rcItem.Height(), UnitPixel); graph.ReleaseHDC(lpDIS->hDC); } if (m_ImageCheck != NULL) { CRect rcButton; int imgWidth = m_ImageCheck->GetWidth() / 4; int imgHeight = m_ImageCheck->GetHeight(); if (m_bChecked && IsWindowEnabled()) rcButton = CRect(0, 0, imgWidth, imgHeight); else if (m_bChecked && !IsWindowEnabled()) rcButton = CRect(2* imgWidth, 0, 3*imgWidth, imgHeight); else if (!m_bChecked && IsWindowEnabled()) rcButton = CRect(imgWidth, 0, 2*imgWidth, imgHeight); else rcButton = CRect(3* imgWidth, 0, 4*imgWidth, imgHeight); Graphics graph(dc.GetSafeHdc()); graph.DrawImage(m_ImageCheck, 0, 0, rcButton.left, rcButton.top, rcButton.Width(), rcButton.Height(), UnitPixel); graph.ReleaseHDC(dc.GetSafeHdc()); //绘画字体 CString szText; GetWindowText(szText); dc.SetBkMode(TRANSPARENT); CFont* oldFont = dc.SelectObject(m_font.GetSafeHandle() ? &m_font : GetFont()); DrawTextString(&dc, szText, m_crTextColor, m_crTextFrameColor, imgWidth + 4, 0); dc.SelectObject(oldFont); } dc.Detach(); } void CPngCheckBox::SetCheckBoxTextColor(COLORREF crTextColor) { m_crTextColor = crTextColor; } //设置颜色 bool CPngCheckBox::SetTextColor(COLORREF crTextColor, COLORREF crTextFrameColor, bool bShowFrame) { m_crTextColor = crTextColor; m_bShowTextFrame = bShowFrame; m_crTextFrameColor = crTextFrameColor; if (GetSafeHwnd()) Invalidate(FALSE); return true; } Image * CPngCheckBox::ImageFromResource(HINSTANCE hInstance, UINT uImgID, LPCTSTR lpType) { HRSRC hResInfo = ::FindResource(hInstance, MAKEINTRESOURCE(uImgID), lpType); if (hResInfo == NULL) return NULL; //fail DWORD dwSize; dwSize = SizeofResource(hInstance, hResInfo); //get resource size(bytes) HGLOBAL hResData; hResData = ::LoadResource(hInstance, hResInfo); if (hResData == NULL) return NULL; //fail HGLOBAL hMem; hMem = ::GlobalAlloc(GMEM_MOVEABLE, dwSize); if (hMem == NULL) { ::FreeResource(hResData); return NULL; } LPVOID lpResData, lpMem; lpResData = ::LockResource(hResData); lpMem = ::GlobalLock(hMem); ::CopyMemory(lpMem, lpResData, dwSize); //copy memory ::GlobalUnlock(hMem); ::FreeResource(hResData); //free memory IStream *pStream; HRESULT hr; hr = ::CreateStreamOnHGlobal(hMem, TRUE, &pStream);//create stream object Image *pImage = NULL; if (SUCCEEDED(hr)) { pImage = Image::FromStream(pStream);//get GDI+ pointer pStream->Release(); } ::GlobalFree(hMem); return pImage; } BOOL CPngCheckBox::OnClicked() { if (!m_bChecked) m_bChecked = TRUE; else m_bChecked = FALSE; PaintParent(); return FALSE; } BOOL CPngCheckBox::OnEraseBkgnd(CDC* pDC) { return TRUE; } void CPngCheckBox::PaintParent() { CRect rect; GetWindowRect(&rect); GetParent()->ScreenToClient(&rect); GetParent()->InvalidateRect(&rect); } //艺术字体 void CPngCheckBox::DrawTextString(CDC * pDC, LPCTSTR pszString, COLORREF crText, COLORREF crFrame, LPRECT lpRect) { //变量定义 int nStringLength = lstrlen(pszString); int nXExcursion[8] = { 1,1,1,0,-1,-1,-1,0 }; int nYExcursion[8] = { -1,0,1,1,1,0,-1,-1 }; CRect rcDraw; if (m_bShowTextFrame) { //绘画边框 pDC->SetTextColor(crFrame); for (int i = 0; i < sizeof(nXExcursion) / sizeof(nXExcursion[0]); ++i) { rcDraw.CopyRect(lpRect); rcDraw.OffsetRect(nXExcursion[i], nYExcursion[i]); pDC->DrawText(pszString, nStringLength, &rcDraw, DT_VCENTER | DT_CENTER | DT_SINGLELINE | DT_END_ELLIPSIS); } } //绘画字体 rcDraw.CopyRect(lpRect); pDC->SetTextColor(crText); pDC->DrawText(pszString, nStringLength, &rcDraw, DT_VCENTER | DT_CENTER | DT_SINGLELINE | DT_END_ELLIPSIS); return; } //艺术字体 void CPngCheckBox::DrawTextString(CDC * pDC, LPCTSTR pszString, COLORREF crText, COLORREF crFrame, int nXPos, int nYPos) { if (nYPos == 0) { LOGFONT lf; if (m_font.GetSafeHandle()) { m_font.GetLogFont(&lf); } else { GetFont()->GetLogFont(&lf); } nYPos = (m_ImageCheck->GetHeight()-abs(lf.lfHeight))/2; } //变量定义 int nStringLength = lstrlen(pszString); int nXExcursion[8] = { 1,1,1,0,-1,-1,-1,0 }; int nYExcursion[8] = { -1,0,1,1,1,0,-1,-1 }; if (m_bShowTextFrame) { //绘画边框 pDC->SetTextColor(crFrame); for (int i = 0; i < sizeof(nXExcursion) / sizeof(nXExcursion[0]); i++) { pDC->TextOut(nXPos + nXExcursion[i], nYPos + nYExcursion[i], pszString, nStringLength); } } //绘画字体 pDC->SetTextColor(crText); pDC->TextOut(nXPos, nYPos, pszString, nStringLength); return; }
m_checkb1.Init(IDB_PNG_CRBACK, IDB_PNG_CHECK); m_checkb1.SetBackColor(RGB(0, 200, 200)); m_checkb1.SetFontType(16, L"黑体"); m_checkb1.SetTextColor(RGB(0, 200, 0), RGB(100, 100, 0), TRUE);