CListCtrl修改表头颜色出错问题
今天参考http://www.vckbase.com/document/viewdoc/?id=1855 关于改变 CListCtrl、CHeaderCtrl 高度、字体、颜色和背景的代码。想实现一个改变Header的表头颜色的类, 自己手工根据提示Copy了主要代码如下:
但是在对话框中每次调用该类,程序能够编译通过,但是在运行中程序总是提示出错,然后程序挂掉。
#if !defined(AFX_MYHEADERCTRL_H__7E415591_2104_47CA_A43B_C68D8E5A3148__INCLUDED_)#define AFX_MYHEADERCTRL_H__7E415591_2104_47CA_A43B_C68D8E5A3148__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000// MyHeaderCtrl.h : header file///////////////////////////////////////////////////////////////////////////////// CMyHeaderCtrl windowclass CMyHeaderCtrl : public CHeaderCtrl{// Constructionpublic: CMyHeaderCtrl();// Attributespublic: CStringArray m_HChar; CString m_Format; //表示对齐类型的整型数组,0表示左对齐,1表示中间对齐,2表示右对齐 int m_R; int m_G; int m_B; int m_Gradient; // 画立体背景,渐变系数 float m_Height; //表头高度,这是倍数, int m_fontHeight; //字体高度 int m_fontWith; //字体宽度 COLORREF m_color;// Operationspublic: LRESULT OnLayout( WPARAM wParam, LPARAM lParam );// Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMyHeaderCtrl) //}}AFX_VIRTUAL// Implementationpublic: virtual ~CMyHeaderCtrl(); // Generated message map functionsprotected: //{{AFX_MSG(CMyHeaderCtrl) afx_msg void OnPaint(); //}}AFX_MSG DECLARE_MESSAGE_MAP()};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_MYHEADERCTRL_H__7E415591_2104_47CA_A43B_C68D8E5A3148__INCLUDED_)
// MyHeaderCtrl.cpp : implementation file//#include "stdafx.h"#include "MyTest4.h"#include "MyHeaderCtrl.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CMyHeaderCtrlCMyHeaderCtrl::CMyHeaderCtrl(): m_R(171), m_G(199), m_B(235), m_Gradient(8){ m_Format = "0"; m_Height = 1; m_fontHeight = 15; m_fontWith = 0; m_color = RGB(0,0,0);}CMyHeaderCtrl::~CMyHeaderCtrl(){}BEGIN_MESSAGE_MAP(CMyHeaderCtrl, CHeaderCtrl) //{{AFX_MSG_MAP(CMyHeaderCtrl) ON_WM_PAINT() //}}AFX_MSG_MAP ON_MESSAGE(HDM_LAYOUT, OnLayout)END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CMyHeaderCtrl message handlersvoid CMyHeaderCtrl::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here int nItem; nItem = GetItemCount();//得到有几个单元 for(int i = 0; i<nItem;i ++) { CRect tRect; GetItemRect(i, &tRect); //得到Item的尺寸 int R = m_R, G = m_G, B = m_B; CRect nRect(tRect); //拷贝尺寸到新的容器中 nRect.left++; //留出分割线的地方 //绘制立体背景 for(int j = tRect.top; j<=tRect.bottom; j++) { nRect.bottom = nRect.top + 1; CBrush _brush; _brush.CreateSolidBrush(RGB(R, G, B)); //创建画刷 dc.FillRect(&nRect, &_brush); //填充背景 _brush.DeleteObject(); //释放画刷 R -= m_Gradient; G -= m_Gradient; B -= m_Gradient; if (R < 0) { R = 0; } if (G < 0) { G = 0; } if (B < 0) { B= 0; } nRect.top = nRect.bottom; } dc.SetBkMode(TRANSPARENT); CFont nFont , *nOldFont; dc.SetTextColor(m_color); nFont.CreateFont(m_fontHeight, m_fontWith, 0, 0, 0, FALSE, FALSE, 0, 0, 0, 0, 0, 0, _TEXT("宋体")); //创建字体 nOldFont = dc.SelectObject(&nFont); UINT nFormat = 1; if (m_Format[i] == '0') { nFormat = DT_LEFT; tRect.left += 3; } else if (m_Format[i]=='1') { nFormat = DT_CENTER; } else if (m_Format[i] == '2') { nFormat = DT_RIGHT; tRect.right -= 3; } TEXTMETRIC metric; dc.GetTextMetrics(&metric); int ofst = 0; ofst = tRect.Height() - metric.tmHeight; tRect.OffsetRect(0, ofst/2); dc.DrawText(m_HChar[i], &tRect, nFormat); dc.SelectObject(nOldFont); nFont.DeleteObject(); //释放字体 } //画头部剩余部分 CRect rtRect; CRect clientRect; GetItemRect(nItem - 1, rtRect); GetClientRect(clientRect); rtRect.left = rtRect.right + 1; rtRect.right = clientRect.right; int R = m_R, G = m_G, B = m_B; CRect nRect(rtRect); //绘制立体背景 for(int j = rtRect.top; j <= rtRect.bottom; j++) { nRect.bottom = nRect.top+1; CBrush brush; brush.CreateSolidBrush(RGB(R, G, B)); //创建画刷 dc.FillRect(&nRect, &brush); //填充背景 brush.DeleteObject(); //释放画刷 R -= m_Gradient; G -= m_Gradient; B -= m_Gradient; if (R < 0) { R = 0; } if (G < 0) { G = 0; } if (B < 0) { B = 0; } nRect.top = nRect.bottom; } // Do not call CHeaderCtrl::OnPaint() for painting messages}LRESULT CMyHeaderCtrl::OnLayout( WPARAM wParam, LPARAM lParam ){ LRESULT lResult = CHeaderCtrl::DefWindowProc(HDM_LAYOUT, 0, lParam); HD_LAYOUT &hdl = *( HD_LAYOUT * ) lParam; RECT *prc = hdl.prc; WINDOWPOS *pwpos = hdl.pwpos; int nHeight = (int)(pwpos->cy * m_Height); //改变高度,m_Height为倍数 pwpos->cy = nHeight; prc->top = nHeight; return lResult; }
#if !defined(AFX_MYLISTCTRL_H__086D3B87_F5CE_4983_8AFD_A4D5BE7DB114__INCLUDED_)#define AFX_MYLISTCTRL_H__086D3B87_F5CE_4983_8AFD_A4D5BE7DB114__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000// MyListCtrl.h : header file//#include "MyHeaderCtrl.h"/////////////////////////////////////////////////////////////////////////////// CMyListCtrl windowclass CMyListCtrl : public CListCtrl{// Constructionpublic: CMyListCtrl();// Attributespublic: CMyHeaderCtrl m_headerCtrl;// Operationspublic:// Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMyListCtrl) protected: virtual void PreSubclassWindow(); //}}AFX_VIRTUAL// Implementationpublic: virtual ~CMyListCtrl(); // Generated message map functionsprotected: //{{AFX_MSG(CMyListCtrl) afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct); //}}AFX_MSG DECLARE_MESSAGE_MAP()};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_MYLISTCTRL_H__086D3B87_F5CE_4983_8AFD_A4D5BE7DB114__INCLUDED_)
// MyListCtrl.cpp : implementation file//#include "stdafx.h"#include "MyTest4.h"#include "MyListCtrl.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CMyListCtrlCMyListCtrl::CMyListCtrl(){}CMyListCtrl::~CMyListCtrl(){}BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl) //{{AFX_MSG_MAP(CMyListCtrl) ON_WM_DRAWITEM() //}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CMyListCtrl message handlersvoid CMyListCtrl::PreSubclassWindow() { // TODO: Add your specialized code here and/or call the base class ModifyStyle(0, LVS_OWNERDRAWFIXED); CListCtrl::PreSubclassWindow(); CHeaderCtrl *pHeader = GetHeaderCtrl(); m_headerCtrl.SubclassWindow(pHeader->GetSafeHwnd());}void CMyListCtrl::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct) { CListCtrl::OnDrawItem(nIDCtl, lpDrawItemStruct);}