VC++ CEdit自绘篇

头文件定义(CSWEdit.h):

#pragma once


// CSWEdit

class CSWEdit : public CEdit
{
	DECLARE_DYNAMIC(CSWEdit)

public:
	CSWEdit();
	virtual ~CSWEdit();

	void SetToolTipText(LPCSTR lpszToolTipText, BOOL bActivate = TRUE);
	void ActivateTooltip(BOOL bActivate = TRUE);
	void NoticeBkgrRefresh();

private:
	void CommonConstruct(); // 初始化
	void InitToolTip();

private:
	COLORREF			m_crFont;		// 字体颜色
	CToolTipCtrl		m_ToolTip;		// 鼠标停留提醒
	CDC					m_dcBkgr;		// 背景DC(保持了父窗体背景图像)
	BOOL				m_bTransParent;	// 背景透明
	HCURSOR				m_hCursor;		// 鼠标手势
	CFont				m_font;			// 字体
	CBrush				m_brBkgr;		// 背景画刷
	CPen				m_penEdge;		// 边框颜色
	BOOL				m_bSingleLine;	// 单行文本

protected:
	virtual BOOL PreTranslateMessage(MSG* pMsg);
	virtual void PreSubclassWindow();

protected:
	afx_msg void OnNcPaint();
	afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
	afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
	afx_msg LRESULT OnSetText(WPARAM wParam, LPARAM lParam);
	afx_msg void OnEnChange();
	afx_msg void OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp);
	DECLARE_MESSAGE_MAP()

public:
	// 设置窗口背景图片
	void SetBackgroundColor(COLORREF crBkgr, COLORREF cdEdge = RGB(128, 128, 128), BOOL bRepaint = TRUE);
	// 字体设置
	void SetFont(LPCTSTR lpszFontName, int nFontSize, COLORREF crFont, BOOL bBold = FALSE, BOOL bItalic = FALSE);
	// 设置鼠标
	void SetCursor(HCURSOR hCursor = NULL);
};

源码实现(CSWEdit.cpp):

// .\Controls\SWEdit.cpp : 实现文件
//

#include "stdafx.h"
#include "CSWEdit.h"


// CSWEdit
CSWEdit::CSWEdit()
{
	CommonConstruct();
}

CSWEdit::~CSWEdit()
{
	m_font.DeleteObject();
	m_penEdge.DeleteObject();
	m_brBkgr.DeleteObject();
}

// CSWEdit 消息处理程序
IMPLEMENT_DYNAMIC(CSWEdit, CEdit)
BEGIN_MESSAGE_MAP(CSWEdit, CEdit)
	ON_WM_CTLCOLOR_REFLECT()
	ON_WM_ERASEBKGND()
	ON_WM_SETCURSOR()
	ON_WM_NCPAINT()
	ON_MESSAGE(WM_SETTEXT, OnSetText)
	ON_CONTROL_REFLECT(EN_CHANGE, &CSWEdit::OnEnChange)
	ON_WM_NCCALCSIZE()
END_MESSAGE_MAP()

void CSWEdit::CommonConstruct()
{
	m_bSingleLine = TRUE;
	m_ToolTip.m_hWnd = NULL;
	m_crFont = ::GetSysColor(COLOR_WINDOWTEXT);
	m_brBkgr.CreateSolidBrush(::GetSysColor(CTLCOLOR_EDIT));
	m_bTransParent = FALSE;
	m_hCursor = NULL;
	LOGFONT logfont;
	::GetObject((HFONT)GetStockObject(DEFAULT_GUI_FONT), sizeof(logfont), &logfont);
	m_font.CreateFontIndirect(&logfont);
	COLORREF cr = ::GetSysColor(COLOR_WINDOWTEXT);;
	m_penEdge.CreatePen(PS_DOT, 2, RGB(255, 255, 255));
}

void CSWEdit::InitToolTip()
{
	if (m_ToolTip.m_hWnd == NULL)
	{
		m_ToolTip.Create(this);
		m_ToolTip.Activate(FALSE);
	}
}

void CSWEdit::SetToolTipText(LPCSTR lpszToolTipText, BOOL bActivate/* = TRUE*/)
{
	if (lpszToolTipText == NULL)
		return;

	InitToolTip();
	if (m_ToolTip.GetToolCount() == 0)
	{
		CRect rcClient;
		GetClientRect(rcClient);
		m_ToolTip.AddTool(this, (LPCTSTR)lpszToolTipText, rcClient, 1);
	}
	m_ToolTip.UpdateTipText((LPCTSTR)lpszToolTipText, this, 1);
	m_ToolTip.Activate(bActivate);
}

void CSWEdit::ActivateTooltip(BOOL bActivate/* = TRUE*/)
{
	if (m_ToolTip.GetToolCount() == 0)
		return;

	m_ToolTip.Activate(bActivate);
}

BOOL CSWEdit::PreTranslateMessage(MSG* pMsg)
{
	// TODO: 在此添加专用代码和/或调用基类
	InitToolTip();
	m_ToolTip.RelayEvent(pMsg);

	return CEdit::PreTranslateMessage(pMsg);
}

void CSWEdit::OnNcPaint()
{
	CDC* pDC = GetWindowDC();
	CRect rcWindow;
	GetWindowRect(rcWindow);
	ScreenToClient(rcWindow);
	rcWindow.OffsetRect(-rcWindow.left, -rcWindow.top);
	if (m_brBkgr.GetSafeHandle() != NULL)
	{
		LOGBRUSH logBrush;
		m_brBkgr.GetLogBrush(&logBrush);
		pDC->FillSolidRect(&rcWindow, logBrush.lbColor);
	}

	if (m_penEdge.GetSafeHandle() != NULL)
	{
		// 方法1
		LOGPEN logPen;
		m_penEdge.GetLogPen(&logPen);
		pDC->Draw3dRect(rcWindow, logPen.lopnColor, logPen.lopnColor);

		// 方法二
// 		HBRUSH hOldBrush = (HBRUSH)::SelectObject(pDC->GetSafeHdc(), (HBRUSH)::GetStockObject(HOLLOW_BRUSH)); // 选择一个空的画刷
// 		HPEN hOldPen = (HPEN)::SelectObject(pDC->GetSafeHdc(), (HPEN)m_penEdge.GetSafeHandle());
// 		pDC->Rectangle(rcWindow);
// 		::SelectObject(pDC->GetSafeHdc(), hOldBrush);
// 		::SelectObject(pDC->GetSafeHdc(), hOldPen);

// 		// 方法三
// 		CBrush brush; brush.CreateSolidBrush(logPen.lopnColor); // 选择一个空的画刷
// 		pDC->FrameRect(&rcWindow, &brush);
// 		brush.DeleteObject();
	}

	ReleaseDC(pDC);
}

void CSWEdit::SetBackgroundColor(COLORREF crBkgr, COLORREF cdEdge, BOOL bRepaint)
{
	if (m_brBkgr.GetSafeHandle() != NULL)
	{
		m_brBkgr.DeleteObject();
	}

	if (crBkgr != (COLORREF)-1)
	{
		m_brBkgr.CreateSolidBrush(crBkgr);
	}

	if (m_penEdge.GetSafeHandle() != NULL)
	{
		m_penEdge.DeleteObject();
	}

	if (cdEdge != (COLORREF)-1)
	{
		m_penEdge.CreatePen(PS_DOT, 2, cdEdge);
	}
	else
	{
		m_penEdge.CreatePen(PS_DOT, 2, RGB(255, 255, 255));
	}

	if (!m_bTransParent && bRepaint && GetSafeHwnd() != NULL)
	{
		SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_DRAWFRAME);
	}
}

LRESULT CSWEdit::OnSetText(WPARAM wParam, LPARAM lParam)
{
	LRESULT Result = Default();
	InvalidateRect(NULL, TRUE);
	return Result;
}

void CSWEdit::PreSubclassWindow()
{
	// TODO: 在此添加专用代码和/或调用基类
	DWORD dwStyle = GetWindowLong(m_hWnd, GWL_STYLE);// GetButtonStyle();
	if ((dwStyle & ES_MULTILINE) || (dwStyle & ES_AUTOVSCROLL) || (dwStyle & ES_WANTRETURN))
		m_bSingleLine = FALSE;

	DWORD dwExStyle = GetWindowLong(m_hWnd, GWL_EXSTYLE);
	if (dwExStyle & WS_EX_TRANSPARENT)
		m_bTransParent = TRUE;

	CEdit::PreSubclassWindow();
}

HBRUSH CSWEdit::CtlColor(CDC* pDC, UINT /*nCtlColor*/)
{
	pDC->SetTextColor(m_crFont);
	pDC->SelectObject(&m_font);
	pDC->SetBkMode(TRANSPARENT);
	if (m_bTransParent)
	{		
		return (HBRUSH)GetStockObject(NULL_BRUSH);
	}
	else
	{
		return m_brBkgr;
	}
}

void CSWEdit::NoticeBkgrRefresh()
{
	if (m_bTransParent)
	{
		if (m_dcBkgr.m_hDC != NULL)
			m_dcBkgr.DeleteDC();

		InvalidateRect(NULL, FALSE);
	}
}

BOOL CSWEdit::OnEraseBkgnd(CDC* pDC)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (m_bTransParent)
	{
		CRect rcClient;
		GetClientRect(&rcClient);
		CRect rcWindow;	GetWindowRect(rcWindow);
		GetParent()->ScreenToClient(rcWindow);
		if (m_dcBkgr.m_hDC == NULL)
		{
			// 复制父窗口背景
			CClientDC dcParentBkgr(GetParent());
			m_dcBkgr.CreateCompatibleDC(&dcParentBkgr);
			HBITMAP hBmp = ::CreateCompatibleBitmap(dcParentBkgr.GetSafeHdc(), rcClient.Width(), rcClient.Height());
			HBITMAP hOldBmp = (HBITMAP)m_dcBkgr.SelectObject(hBmp);
			m_dcBkgr.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &dcParentBkgr, rcWindow.left, rcWindow.top, SRCCOPY);
			DeleteObject(hBmp);
		}

		pDC->BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &m_dcBkgr, 0, 0, SRCCOPY);
	}

	return TRUE;// CEdit::OnEraseBkgnd(pDC);
}

// 字体设置
void CSWEdit::SetFont(LPCTSTR lpszFontName, int nFontSize, COLORREF crFont, BOOL bBold, BOOL bItalic)
{
	m_font.DeleteObject();
	LOGFONT logfont;
	::GetObject((HFONT)GetStockObject(DEFAULT_GUI_FONT), sizeof(logfont), &logfont);
	memset(logfont.lfFaceName, 32, 0);
	strcpy_s(logfont.lfFaceName, lpszFontName);
	logfont.lfHeight = nFontSize;
	logfont.lfWeight = bBold ? 700 : 400;
	logfont.lfItalic = bItalic;
	m_font.CreateFontIndirect(&logfont);
	SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_DRAWFRAME);
}

void CSWEdit::SetCursor(HCURSOR hCursor)
{
	m_hCursor = hCursor;
	if (m_hCursor == NULL)
	{
		m_hCursor = ::LoadCursor(NULL, IDC_HAND);
	}
}

BOOL CSWEdit::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
	if (m_hCursor)
	{
		::SetCursor(m_hCursor);
		return TRUE;
	}

	return FALSE;
}

void CSWEdit::OnEnChange()
{
	// TODO:  如果该控件是 RICHEDIT 控件,它将不
	// 发送此通知,除非重写 CEdit::OnInitDialog()
	// 函数并调用 CRichEditCtrl().SetEventMask(),
	// 同时将 ENM_CHANGE 标志“或”运算到掩码中。

	// TODO:  在此添加控件通知处理程序代码
	LRESULT Result = Default();
	InvalidateRect(NULL, TRUE);
}

void CSWEdit::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	CEdit::OnNcCalcSize(bCalcValidRects, lpncsp);

	if (m_bSingleLine)
	{
		int cx = ::GetSystemMetrics(SM_CXFRAME);
		int cy = ::GetSystemMetrics(SM_CYFRAME);
		CClientDC dc(this);
		TEXTMETRIC tm;
		dc.GetTextMetrics(&tm);
		int nHeight = tm.tmHeight + tm.tmExternalLeading;
		int nYOffset = max(0, (lpncsp->rgrc[0].bottom - lpncsp->rgrc[0].top - nHeight) / 2);
		lpncsp->rgrc[0].top += nYOffset + cy / 2;
		lpncsp->rgrc[0].bottom -= nYOffset;
		lpncsp->rgrc[0].left += cx / 2;
		lpncsp->rgrc[0].right -= cy / 2;
	}
}

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值