VC++ CStatic自绘篇

头文件声明(CSWStatic.h):

#pragma once


// CSWStatic

class CSWStatic : public CStatic
{
	DECLARE_DYNAMIC(CSWStatic)

public:
	CSWStatic();
	virtual ~CSWStatic();

	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;			// 字体

protected:
	virtual BOOL PreTranslateMessage(MSG* pMsg);
	virtual void PreSubclassWindow();
	
protected:
	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);
	DECLARE_MESSAGE_MAP()

public:
	// 字体设置
	void SetFont(LPCTSTR lpszFontName, int nFontSize, COLORREF crFont, BOOL bBold = FALSE, BOOL bItalic = FALSE);
	// 设置鼠标
	void SetCursor(HCURSOR hCursor = NULL);
};

源码实现(CSWStatic.cpp):

#include "stdafx.h"
#include "CSWStatic.h"

/*
	如果30帧/秒刷新,还是会存在闪烁问题
*/

// CSWStatic

IMPLEMENT_DYNAMIC(CSWStatic, CStatic)
CSWStatic::CSWStatic()
{
	CommonConstruct();
}

CSWStatic::~CSWStatic()
{
}

void CSWStatic::CommonConstruct()
{
	m_ToolTip.m_hWnd = NULL;
	m_crFont = RGB(0, 0, 0);
	m_bTransParent = TRUE;
	m_hCursor = NULL;
	LOGFONT logfont;
	::GetObject((HFONT)GetStockObject(DEFAULT_GUI_FONT), sizeof(logfont), &logfont);
	m_font.CreateFontIndirect(&logfont);
}

void CSWStatic::InitToolTip()
{
	if (m_ToolTip.m_hWnd == NULL)
	{
		m_ToolTip.Create(this, TTS_ALWAYSTIP | TTS_BALLOON);
		m_ToolTip.Activate(FALSE);
	}
}

void CSWStatic::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 CSWStatic::ActivateTooltip(BOOL bActivate/* = TRUE*/)
{
	if (m_ToolTip.GetToolCount() == 0)
		return;

	m_ToolTip.Activate(bActivate);
}

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

	return CStatic::PreTranslateMessage(pMsg);
}

BEGIN_MESSAGE_MAP(CSWStatic, CStatic)
	ON_WM_CTLCOLOR_REFLECT()
	ON_WM_ERASEBKGND()
	ON_WM_SETCURSOR()
	ON_MESSAGE(WM_SETTEXT, OnSetText)
END_MESSAGE_MAP()
// CSWStatic message handlers

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

void CSWStatic::PreSubclassWindow()
{
	// TODO: 在此添加专用代码和/或调用基类
	DWORD dwExStyle = GetWindowLong(m_hWnd, GWL_EXSTYLE);
	if (dwExStyle & WS_EX_TRANSPARENT)
		m_bTransParent = TRUE;
	
	CStatic::PreSubclassWindow();
}

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

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

		InvalidateRect(NULL, FALSE);
	}
}

BOOL CSWStatic::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;// CButton::OnEraseBkgnd(pDC);
}

// 字体设置
void CSWStatic::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);
	InvalidateRect(NULL);
}

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

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

	return FALSE;
}

 

你可能感兴趣的:(VC++,设计模式,VC++(日积月累篇),VC++(控件篇))