MFC-自绘控件(CRadio篇)

示例图

MFC-自绘控件(CRadio篇)_第1张图片


一、公共文件

和这篇一样,就不写了(MFC-自绘控件(CButton篇))

二、Radio

头文件

#pragma once
#include "Public.h"
#include <vector>
//////////////////////////////////////////////////////////////////////////

#define DEF_TEXT_FRAME_COLOR			RGB(255,255,255)				//默认颜色
#define DEF_TEXT_COLOR					RGB(10,10,10)					//默认颜色
#define TOOLTIP_ID						100								//提示 ID

//////////////////////////////////////////////////////////////////////////
class CPngRadio : public CButton
{
public:
	CPngRadio();
	virtual ~CPngRadio();

public:
	// 初始化背景图片,及选中图片
	void Init(UINT nBkImg, UINT nCkImg);
	// 获取当前选中状态
	BOOL GetChecked() { return m_bChecked; }
	// 设置选中状态
	void SetChecked(BOOL bChecked = TRUE);
	// 设置背景颜色
	void SetBackColor(COLORREF crBack) { m_crBack = crBack; }
	//设置字体大小及类型
	void SetFontType(int fontSize, CString fontType);
	//设置字体颜色
	bool SetTextColor(COLORREF crTextColor, COLORREF crTextFrameColor = DEF_TEXT_FRAME_COLOR, bool bShowFrame = false);
	// 添加所有的radio到一组
	static void AddGroup(std::vector<CPngRadio*> vcRadio);
protected:
	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
	virtual void PreSubclassWindow();
	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 SetGroup(std::vector<CPngRadio*> vcRadio);
	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;
	std::vector<CPngRadio*>				m_vcRadio;

	afx_msg BOOL OnClicked();
	afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);

	DECLARE_MESSAGE_MAP()
	DECLARE_DYNAMIC(CPngRadio)
};

cpp文件


#include "stdafx.h"
#include "PngRadio.h"


IMPLEMENT_DYNAMIC(CPngRadio, CButton)

BEGIN_MESSAGE_MAP(CPngRadio, CButton)
	ON_WM_CREATE()
	ON_CONTROL_REFLECT_EX(BN_CLICKED, OnClicked)
	ON_WM_ERASEBKGND()
	ON_WM_CTLCOLOR_REFLECT()
END_MESSAGE_MAP()


//////////////////////////////////////////////////////////////////////////

CPngRadio::CPngRadio()
{
	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;
}

CPngRadio::~CPngRadio()
{
}


void CPngRadio::PreSubclassWindow()
{
	ModifyStyle(0, BS_OWNERDRAW);
	CButton::PreSubclassWindow();
}

void CPngRadio::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 CPngRadio::CtlColor(CDC* pDC, UINT nCtlColor)
{
	pDC->SetBkMode(TRANSPARENT);
	return (HBRUSH)GetStockObject(NULL_BRUSH);
}
void CPngRadio::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 CPngRadio::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();
}
//设置颜色
bool CPngRadio::SetTextColor(COLORREF crTextColor, COLORREF crTextFrameColor, bool bShowFrame)
{
	m_crTextColor = crTextColor;
	m_bShowTextFrame = bShowFrame;
	m_crTextFrameColor = crTextFrameColor;

	if (GetSafeHwnd()) Invalidate(FALSE);
	return true;
}
Image * CPngRadio::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 CPngRadio::OnClicked()
{
	SetChecked();
	return FALSE;
}
void CPngRadio::SetChecked(BOOL bChecked)
{ 
	if (bChecked) {
		if (!m_vcRadio.empty()) {
			for (CPngRadio* e : m_vcRadio)
			{
				e->SetChecked(FALSE);
			}
		}
	}
	m_bChecked = bChecked;
	PaintParent();
	Invalidate(FALSE);
}
BOOL CPngRadio::OnEraseBkgnd(CDC* pDC)
{
	return TRUE;
}
void CPngRadio::PaintParent()
{
	CRect   rect;
	GetWindowRect(&rect);
	GetParent()->ScreenToClient(&rect);
	GetParent()->InvalidateRect(&rect);
}
//艺术字体
void CPngRadio::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 CPngRadio::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;
}
void CPngRadio::AddGroup(std::vector<CPngRadio*> vcRadio) {
	for (CPngRadio* e : vcRadio)
	{
		e->SetGroup(vcRadio);
	}
}
void CPngRadio::SetGroup(std::vector<CPngRadio*> vcRadio) {
	m_vcRadio = vcRadio;
}

调用方法

	CPngRadio m_radio1;
	CPngRadio m_radio2;
	CPngRadio m_radio3;
	--------------------
	DDX_Control(pDX, IDC_RADIO1, m_radio1);
	DDX_Control(pDX, IDC_RADIO2, m_radio2);
	DDX_Control(pDX, IDC_RADIO3, m_radio3);
	--------------------
	m_radio1.Init(IDB_PNG_CRBACK, IDB_PNG_CHECK);
	m_radio2.Init(IDB_PNG_CRBACK, IDB_PNG_CHECK);
	m_radio3.Init(IDB_PNG_CRBACK, IDB_PNG_CHECK);
	std::vector<CPngRadio*> vc;
	vc.push_back(&m_radio1);
	vc.push_back(&m_radio2);
	vc.push_back(&m_radio3);
	CPngRadio::AddGroup(vc);
	m_radio1.SetChecked();






你可能感兴趣的:(MFC-自绘控件(CRadio篇))