自绘列表头部 原理

1. 继承 CHeaderCtrl, 重载 OnPaint();

 

class CSkinHeaderCtrl : public CHeaderCtrl { public: CSkinHeaderCtrl(); public: virtual ~CSkinHeaderCtrl(); protected: afx_msg void OnPaint(); afx_msg BOOL OnEraseBkgnd(CDC* pDC); DECLARE_MESSAGE_MAP() public: };

 

2. 子类化 列表的表头控件

  mlstHeader.SubclassWindow( mlist1.GetHeaderCtrl()->m_hWnd);

 

我们只拦截 WM_PATIN, 即 自己实现了 OnPaint();

 

void CSkinHeaderCtrl::OnPaint() { CPaintDC dc(this); CRect rect, rectItem, clientRect; GetClientRect(&rect); GetClientRect(&clientRect); CMemDC memDC(&dc, rect); CDC bitmapDC; bitmapDC.CreateCompatibleDC(&dc); memDC.FillSolidRect(&rect, RGB(76,85,118)); // 获取列数 int nItems = GetItemCount(); CBitmap bmpBK; bmpBK.LoadBitmap(IDB_COLUMNHEADER_SPAN); for(int i = 0; i <nItems; i++) { TCHAR buf1[256]; HD_ITEM hditem1; // 取得文本, 格式, 索引(第几列的头部) hditem1.mask = HDI_TEXT | HDI_FORMAT | HDI_ORDER; hditem1.pszText = buf1; hditem1.cchTextMax = 255; GetItem( i, &hditem1 ); // 取得该列头部的区域 GetItemRect(i, &rect); rectItem = rect; // 在区域中画背景 rect.DeflateRect(1,0,1,0); CBitmap *lpOldbmp = bitmapDC.SelectObject( &bmpBK ); memDC.StretchBlt(rect.left, rect.top, rect.Width(), rect.Height(), &bitmapDC, 0, 0, 1, 12, SRCCOPY ); bitmapDC.SelectObject(lpOldbmp); // 创建字体, 画文本 CFont font; LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); lf.lfHeight = 12; strcpy(lf.lfFaceName, "宋体"); font.CreateFontIndirect(&lf); CFont* def_font = memDC.SelectObject(&font); memDC.SetBkMode(TRANSPARENT); UINT uFormat = DT_SINGLELINE | DT_NOPREFIX | DT_TOP |DT_CENTER | DT_END_ELLIPSIS | DT_VCENTER; memDC.DrawText(buf1, &rectItem, uFormat); memDC.SelectObject(def_font); font.DeleteObject(); } }

 

你可能感兴趣的:(自绘列表头部 原理)