1.设置背景图片 #ifndef __BITMAPBKGND_H__ #define __BITMAPBKGND_H__ template <class T, UINT uBitmapID> class CBitmapBkgnd : public CMessageMap { public: CBitmapBkgnd() { m_Bitmap.LoadBitmap(uBitmapID); } ~CBitmapBkgnd() { m_Bitmap.DeleteObject(); } BEGIN_MSG_MAP(CPaintBkgnd) MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd) END_MSG_MAP() LRESULT OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { T* pT = static_cast<T*>(this); HDC hDC = (HDC) wParam; RECT rcClient; pT->GetClientRect ( &rcClient ); BITMAP bm; m_Bitmap.GetBitmap(&bm); CDC memDC; memDC.CreateCompatibleDC(hDC); HBITMAP hOldBmp = memDC.SelectBitmap(m_Bitmap); StretchBlt(hDC,0,0,rcClient.right - rcClient.left,rcClient.bottom - rcClient.top,memDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY); memDC.SelectBitmap(hOldBmp); memDC.DeleteDC(); return 1; // we painted the background } protected: CBitmap m_Bitmap; }; #endif //__BITMAPBKGND_H__ 用法: 1.包含类的头文件; 2.让对话框类公有继承:public CBitmapBkgnd<CMainDlg, IDB_MAIN_BKGND>; 3.在消息映射之前:typedef CBitmapBkgnd<CMainDlg,IDB_MAIN_BKGND> CBmpBkgndBase; 4.在消息映射内:CHAIN_MSG_MAP(CBmpBkgndBase) 2.设置背景颜色以及字体颜色 #ifndef __CTRLCOLOR_H__ #define __CTRLCOLOR_H__ template <class T, COLORREF t_crTextColor = RGB(0, 0, 0), COLORREF t_crBkgnd = RGB(255,255,255)> class CCtrlColor { public: CCtrlColor() { m_brBkgnd = CreateSolidBrush(t_crBkgnd);} ~CCtrlColor() { DeleteObject(m_brBkgnd);} BEGIN_MSG_MAP(CCtrlColor) MESSAGE_HANDLER(WM_CTLCOLORDLG, OnCtlColor) MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnCtlColor) END_MSG_MAP() LRESULT OnCtlColor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { HDC hDC = (HDC)wParam; HWND hWnd = (HWND)lParam; if(uMsg == WM_CTLCOLORDLG) { bHandled = TRUE; return (LRESULT)m_brBkgnd; } else if(uMsg == WM_CTLCOLORSTATIC) { SetBkMode(hDC,TRANSPARENT); SetTextColor(hDC,t_crTextColor); bHandled = TRUE; return (LRESULT)m_brBkgnd; } else return 0; } protected: HBRUSH m_brBkgnd; }; #endif //__CTRLCOLOR_H__ 3.自定义静态文本控件 #ifndef _MYSTATIC_H_ #define _MYSTATIC_H_ template<class T, class TBase = CStatic, class TWinTraits = CControlWinTraits> class ATL_NO_VTABLE CMyStatic : public CWindowImpl<T, TBase, TWinTraits> { public: typedef CMyStatic<T, TBase, TWinTraits> thisClass; COLORREF m_clrText; COLORREF m_bkColor; COLORREF m_clrLine; BOOL m_bHorizontal; BOOL m_bActive; BOOL m_bUnderLine; CFont m_font; CBitmap m_bmp; CMyStatic(void) : m_clrText(RGB(104, 115, 122)), m_bkColor(RGB(255, 255, 255)), m_clrLine(RGB(104, 115, 122)), m_bActive(FALSE), m_bHorizontal(FALSE), m_bUnderLine(FALSE){ } ~CMyStatic(void){ } BOOL SubclassWindow(HWND hwnd) { ATLASSERT(m_hWnd == NULL); ATLASSERT(::IsWindow(hwnd)); BOOL bRet = CWindowImpl<T, TBase>::SubclassWindow(hwnd); if (bRet) { InitMyStatic(); } return bRet; } void SetTextColor(COLORREF clrText) { m_clrText = clrText; if (IsWindow()) { Invalidate(); } } void SetLabelBkColor(COLORREF clrBk) { m_bkColor = clrBk; if (IsWindow()) { Invalidate(); } } void SetActive(BOOL bActive = FALSE) { m_bActive = bActive; if (IsWindow()) { Invalidate(); } } void SetHorizontalFill(BOOL bHoriz = FALSE) { m_bHorizontal = bHoriz; if (IsWindow()) { Invalidate(); } } void SetUnderLine(COLORREF clrLine, BOOL bUnderLine = FALSE) { m_clrLine = clrLine; m_bUnderLine = bUnderLine; if (IsWindow()) { Invalidate(); } } void InitMyStatic() { ATLASSERT(::IsWindow(m_hWnd)); TCHAR lpszBuffer[10] = { 0 }; if( ::GetClassName(m_hWnd, lpszBuffer, 9) ) { if( ::lstrcmpi(lpszBuffer, TBase::GetWndClassName()) == 0 ) { ModifyStyle(0, SS_NOTIFY); // We need this DWORD dwStyle = GetStyle() & 0x000000FF; if( dwStyle == SS_ICON || dwStyle == SS_BLACKRECT || dwStyle == SS_GRAYRECT || dwStyle == SS_WHITERECT || dwStyle == SS_BLACKFRAME || dwStyle == SS_GRAYFRAME || dwStyle == SS_WHITEFRAME || dwStyle == SS_OWNERDRAW || dwStyle == SS_BITMAP || dwStyle == SS_ENHMETAFILE ) { ATLASSERT("Invalid static style for gradient label"==NULL); } } } CWindow wnd = GetParent(); CFontHandle font = wnd.GetFont(); if (!font.IsNull()) { LOGFONT lf; font.GetLogFont(&lf); lf.lfWeight = FW_BOLD; //lf.lfUnderline = TRUE; m_font.CreateFontIndirect(&lf); SetFont(m_font); } } BEGIN_MSG_MAP(thisClass) MESSAGE_HANDLER(WM_CREATE, OnCreate) MESSAGE_HANDLER(WM_PAINT, OnPaint) MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor) MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove) MESSAGE_HANDLER(WM_MOUSEHOVER, OnMouseHover) MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseLeave) DEFAULT_REFLECTION_HANDLER() END_MSG_MAP() LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { InitMyStatic(); return 0; } LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { return 1; } LRESULT OnSetCursor(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { HCURSOR hcur = LoadCursor(NULL, IDC_HAND); ::SetCursor(hcur); return 0; } LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) { T* pt = static_cast<T*>(this); if (wParam != NULL) { pt->DoPaint((HDC)wParam); } else { CPaintDC dc(m_hWnd); pt->DoPaint((HDC)dc); } return 0; } LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& hHandled) { int xPos = LOWORD(lParam); int yPos = HIWORD(lParam); TRACKMOUSEEVENT tme; tme.cbSize = sizeof(tme); tme.hwndTrack = m_hWnd; tme.dwFlags = TME_LEAVE | TME_HOVER; tme.dwHoverTime = 1; _TrackMouseEvent(&tme); return 0; } LRESULT OnMouseHover(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& hHandled) { SetUnderLine(RGB(104, 115, 122), TRUE); return 0; } LRESULT OnMouseLeave(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& hHandled) { SetUnderLine(RGB(255, 255, 255), TRUE); return 0; } void DoPaint(CDCHandle dc) { int nTextLeft; int nTextBottom; TEXTMETRIC tm; CPen underLinePen, oldLinePen; HPEN hLinePen; RECT rcClient; GetClientRect(&rcClient); if (m_bActive) { DoBkFill(dc, rcClient); } dc.GetTextMetricsW(&tm); dc.SetBkMode(TRANSPARENT); dc.SetTextColor(m_clrText == CLR_INVALID ? ::GetSysColor(COLOR_CAPTIONTEXT) : m_clrText); HFONT hOldFont = dc.SelectFont(GetFont()); int nLen = GetWindowTextLength(); if (nLen > 0) { LPTSTR lpszText = (LPTSTR)_alloca((nLen + 1) * sizeof(TCHAR)); if (GetWindowText(lpszText, nLen + 1)) { DWORD dwStyle = GetStyle(); int nDrawStyle = DT_LEFT; if (dwStyle & SS_CENTER) { nDrawStyle = DT_CENTER; } else if (dwStyle & SS_RIGHT) { nDrawStyle = DT_RIGHT; } if( dwStyle & SS_SIMPLE) { nDrawStyle = DT_VCENTER | DT_SINGLELINE; } dc.DrawText(lpszText, -1, &rcClient, nDrawStyle | DT_WORDBREAK); } } dc.SelectFont(hOldFont); if (m_bUnderLine) { //SetMyFont(); nTextLeft = rcClient.left - 2; nTextBottom = rcClient.bottom - 3; hLinePen = underLinePen.CreatePen(PS_SOLID, 1, m_clrLine); oldLinePen = dc.SelectPen(hLinePen); dc.MoveTo(nTextLeft, nTextBottom); dc.LineTo(nTextLeft + tm.tmAveCharWidth * nLen * 2, nTextBottom); dc.SelectPen(oldLinePen); } } void DoBkFill(CDCHandle& dc, const RECT& rc) { int nShift = 6; int nSteps = 1 << nShift; //for (int i = 0; i < nSteps; i++) //{ // CBrush br; // br.CreateSolidBrush(m_bkColor); // RECT r2 = rc; // if (m_bHorizontal) // { // r2.bottom =rc.bottom - ((i * (rc.bottom - rc.top)) >> nShift); // r2.top = rc.bottom - (((i + 1) * (rc.bottom - rc.top)) >> nShift); // if ((r2.bottom - r2.top) > 0) // { // dc.FillRect(&r2, br); // } // } // else // { // r2.left = rc.left + ((i * (rc.right - rc.left)) >> nShift); // r2.right = rc.left + (((i + 1) * (rc.right - rc.left)) >> nShift); // if ((r2.right - r2.left) > 0) // { // dc.FillRect(&r2, br); // } // } //} //BITMAP bm; //m_bmp.LoadBitmap(IDB_BITMAP1); //m_bmp.GetBitmap(&bm); //CDC memDC; //memDC.CreateCompatibleDC(dc); //HBITMAP hOldBmp = memDC.SelectBitmap(m_bmp); //dc.BitBlt(0, 0, rc.right - rc.left, rc.bottom - rc.top, memDC, 0, 0, SRCCOPY); //memDC.SelectBitmap(hOldBmp); //memDC.DeleteDC(); } }; class CCoolLabel : public CMyStatic<CCoolLabel> { public: DECLARE_WND_CLASS(L"WTL_CoolLabel"); }; #endif //_MYSTATIC_H_