头文件定义(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;
}
}