MFC-自绘控件(CEdit篇)

示例图(可以设置左右图标,字体颜色,圆角)

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

一、公共文件

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

二、CEdit

头文件

#pragma once
#include "Public.h"

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

#define TRANS_BACK RGB(255,0,0)
#define DEFAULT_COLOR RGB(40,138,228)

///////////////////////////////////////////////////////////////////////
class CPngEdit :
	public CStatic
{
public:
	CPngEdit();
	~CPngEdit();
	
public:
	// 初始化,左侧图标,右侧图标,圆角,内距
	void Init(UINT left_icon, UINT right_icon, int radian = 0, int padding = 0);
	// 设置内框、外框、字体颜色
	void setNormalColor(COLORREF inColor, COLORREF outColor, COLORREF textColor = RGB(0,0,0));
public:
	BOOL m_bTracking;
	BOOL m_bHover;
	Image*	m_left_icon;
	Image*	m_right_icon;
	int		m_radian;
	int		m_padding;
	COLORREF m_normal_in_color;
	COLORREF m_normal_out_color;
	COLORREF m_text_color;
	CEdit m_edit;
protected:
	void OnNcPaint();
	void OnPaint();
	DECLARE_DYNAMIC(CPngEdit)
	DECLARE_MESSAGE_MAP()
	virtual void PreSubclassWindow();
	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
	void DrawBorder(CDC* dc, CRect &rc);
	Image *ImageFromResource(HINSTANCE hInstance, UINT uImgID, LPCTSTR lpType);
};


cpp源文件

#include "stdafx.h"
#include "PngEdit.h"

IMPLEMENT_DYNAMIC(CPngEdit, CStatic)

CPngEdit::CPngEdit()
{
	m_bTracking = m_bHover = FALSE;
	m_normal_in_color = DEFAULT_COLOR;
	m_normal_out_color = DEFAULT_COLOR;
	m_text_color = RGB(0,0,0);
	m_left_icon = NULL;
	m_right_icon = NULL;
}

CPngEdit::~CPngEdit()
{
}


BEGIN_MESSAGE_MAP(CPngEdit, CStatic)
	ON_WM_NCPAINT()
	ON_WM_ERASEBKGND()
	ON_WM_CTLCOLOR()
END_MESSAGE_MAP()

void CPngEdit::Init(UINT left_icon, UINT right_icon, int radian, int padding) {
	m_left_icon = ImageFromResource(AfxGetResourceHandle(), left_icon, L"PNG");
	m_right_icon = ImageFromResource(AfxGetResourceHandle(), right_icon, L"PNG");
	m_radian = radian;
	m_padding = padding;
}
void CPngEdit::PreSubclassWindow()
{
	
	DWORD dwStyle = GetStyle();
	SetWindowLong(GetSafeHwnd(), GWL_STYLE, dwStyle | SS_OWNERDRAW | SS_NOTIFY);
	CStatic::PreSubclassWindow();
}

void CPngEdit::OnNcPaint()
{
	CStatic::OnNcPaint();
}
void CPngEdit::OnPaint()
{
	CStatic::OnPaint();
}
void CPngEdit::setNormalColor(COLORREF inColor, COLORREF outColor, COLORREF textColor) {
	m_normal_in_color = inColor;
	m_normal_out_color = outColor;
	m_text_color = textColor;
}
Image * CPngEdit::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;
}
void CPngEdit::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	
	CRect rc;
	rc = lpDrawItemStruct->rcItem;
	
	CDC dc;
	dc.Attach(lpDrawItemStruct->hDC);
	DrawBorder(&dc,rc);

	rc.DeflateRect(m_padding, m_padding);
	if (m_left_icon) {
		rc.left += m_left_icon->GetWidth();
	}
	if (m_right_icon) {
		rc.right -= m_right_icon->GetWidth();
	}
	if (m_edit.GetSafeHwnd()) {
        m_edit.ShowWindow(SW_SHOW);
    }
    else {
        m_edit.Create(WS_CHILD | WS_VISIBLE | ES_LEFT | ES_AUTOHSCROLL, rc, this, 1);
        m_edit.SetFont(GetFont());
    }
	ReleaseDC(&dc);
}
void CPngEdit::DrawBorder(CDC* dc,CRect &rc) {
	CPen inpen(PS_SOLID, 1, m_normal_out_color);
	CPen outpen(PS_SOLID, 1, m_normal_in_color);
	CPen * oldPen = dc->SelectObject(&inpen);
	dc->RoundRect(rc, CPoint(m_radian, m_radian));
	rc.InflateRect(-1, -1);
	dc->SelectObject(&outpen);
	dc->RoundRect(rc, CPoint(m_radian, m_radian));
	dc->SelectObject(oldPen);
	oldPen->Detach();
	oldPen = NULL;
	Graphics graph(dc->GetSafeHdc());
	if (m_left_icon) {
		graph.DrawImage(m_left_icon, 0, 0, 0, 0, m_left_icon->GetWidth(), m_left_icon->GetHeight(), UnitPixel);
	}
	if (m_right_icon) {
		graph.DrawImage(m_right_icon, rc.Width()- m_right_icon->GetWidth(), 0, 0, 0, m_right_icon->GetWidth(), m_right_icon->GetHeight(), UnitPixel);
	}
	graph.ReleaseHDC(dc->GetSafeHdc());
}

BOOL CPngEdit::OnEraseBkgnd(CDC* pDC)
{
	return TRUE;
}


HBRUSH CPngEdit::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	HBRUSH hbr = CStatic::OnCtlColor(pDC, pWnd, nCtlColor);
	// TODO:  在此更改 DC 的任何特性
	pDC->SetTextColor(m_text_color);
	// TODO:  如果默认的不是所需画笔,则返回另一个画笔
	return hbr;
}

调用方法

1、新建一个CStatic控件,绑定到自绘控件类上

	CPngEdit m_edit_user;
	DDX_Control(pDX, IDC_NEWEDIT, m_edit_user);
	m_edit_user.Init(IDB_PNG_CRBACK, IDB_PNG_CRBACK,8,2);
	m_edit_user.setNormalColor(RGB(255, 255, 0), RGB(255, 255, 0), RGB(255, 0, 0));


你可能感兴趣的:(CC++)