头文件声明(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;
}