自定义MFC ClistCtrl控件的示例代码

Author: kagula@20150401

环境:  vs2013sp1 


自定义行高、字体、颜色。


如何引用的示例代码

初始化

BOOL CTestListCtrlDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	{
		DWORD dwStyle = m_list.GetExtendedStyle();                    //添加列表框的网格线!!!

		dwStyle |= LVS_EX_FULLROWSELECT;            
		dwStyle |= LVS_EX_GRIDLINES;                
		m_list.SetExtendedStyle(dwStyle);

		m_list.InsertColumn(0,L"编号",LVCFMT_LEFT,32);              //添加列标题!!!!  这里的80,40,90用以设置列的宽度。!!!LVCFMT_LEFT用来设置对齐方式!!!
		m_list.InsertColumn(1,L"商品名称",LVCFMT_LEFT,256);
		m_list.InsertColumn(2,L"颜色",LVCFMT_CENTER,32);
		m_list.InsertColumn(3,L"尺码",LVCFMT_CENTER,32);
		m_list.InsertColumn(4,L"数量",LVCFMT_CENTER,32);

		InitList();
	}

	//m_list.SetFontSelf(15,L"黑体");//设定表体中的字体

	int nRow = m_list.InsertItem(0,L"");
	m_list.SetItemText(nRow,0,L"编号");
	m_list.SetItemText(nRow,1,L"商品名称");
	m_list.SetItemText(nRow,2,L"颜色");
	m_list.SetItemText(nRow,3,L"尺码");
	m_list.SetItemText(nRow,4,L"数量");

	nRow = m_list.InsertItem(1,L"");
	m_list.SetItemText(nRow,0,L"编号2");
	m_list.SetItemText(nRow,1,L"商品名称2");
	m_list.SetItemText(nRow,2,L"颜色2");
	m_list.SetItemText(nRow,3,L"尺码2");
	m_list.SetItemText(nRow,4,L"数量2");
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CRFI_CHECK_DLG::InitList()
{
	static bool bFirst = true;
	if (bFirst)
	{
		bFirst=FALSE;

		CHeaderCtrl *pHeader = NULL; 
		pHeader = m_list.GetHeaderCtrl(); 
		if(pHeader) 
		{   
			TRACE("header item count:%d/n", pHeader->GetItemCount()); 
			int iColumn=pHeader->GetItemCount(); 
			for (int i=0; i<iColumn; i++) 
			{ 
				HDITEM hdItem; 
				BOOL bResult = FALSE; 
				bResult=pHeader->GetItem(i, &hdItem); //直接在OnInitDialog中调用,程序会挂掉。
				hdItem.fmt |= HDF_OWNERDRAW; 
				bResult=pHeader->SetItem(i, &hdItem); 
			} 
			//pHeader->Invalidate();
		}
	}
}


缩放

void CTestListCtrlDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);

	CRect rectClient;
	GetClientRect(&rectClient);

	{
		int left = 0;
		int top = 39;
		int columnWidth = 52;

		int widthProductName = (rectClient.Width()-columnWidth*4)<128?128:(rectClient.Width()-columnWidth*4);

		CRect rect(left,top,left+rectClient.Width(),rectClient.Height()-64);
		GetDlgItem(IDC_LIST2)->MoveWindow(&rect);

		m_list.SetColumnWidth(0,columnWidth);
		m_list.SetColumnWidth(1,widthProductName);
		m_list.SetColumnWidth(2,columnWidth);
		m_list.SetColumnWidth(3,columnWidth);
		m_list.SetColumnWidth(4,columnWidth);
	}
}


依赖文件

C8637ListCtrl.h

#pragma once
#include "C8637HeaderCtrl.h"

// C8637ListCtrl

class C8637ListCtrl : public CListCtrl
{
	DECLARE_DYNAMIC(C8637ListCtrl)

public:
	C8637ListCtrl();
	virtual ~C8637ListCtrl();

	C8637HeaderCtrl m_headerCtrl;
protected:
	DECLARE_MESSAGE_MAP()
	virtual void PreSubclassWindow();
public:
	CFont* m_font;

	void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
	void SetFontSelf(int nHeight, LPCTSTR lpszFacename);
	afx_msg void OnNcPaint();
	afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct);
	virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);
};



C8637ListCtrl.cpp

// C8637ListCtrl.cpp : implementation file
//

#include "stdafx.h"
#include "C8637ListCtrl.h"

/*
[1]《如何重绘CListCtrl的表头》
http://qiusuoge.com/9200.html
[2]《CListCtrl的Report风格自绘》
http://jingyan.baidu.com/article/5bbb5a1b38af1113eaa17910.html
[3]《CListCtrl插入多列(REPORT样式)》
http://blog.sina.com.cn/s/blog_6392417a0100gxmj.html
*/

// C8637ListCtrl

IMPLEMENT_DYNAMIC(C8637ListCtrl, CListCtrl)

C8637ListCtrl::C8637ListCtrl()
{
	m_font = nullptr;
}

C8637ListCtrl::~C8637ListCtrl()
{
	if (m_font != nullptr)
	{
		delete m_font;
		m_font = nullptr;
	}
}


BEGIN_MESSAGE_MAP(C8637ListCtrl, CListCtrl)
	ON_WM_NCPAINT()
	ON_WM_MEASUREITEM_REFLECT()
END_MESSAGE_MAP()



// C8637ListCtrl message handlers




void C8637ListCtrl::PreSubclassWindow()
{
	//use our custom CHeaderCtrl as long as there 
	//is a headerctrl object to subclass 
	if(GetHeaderCtrl()) 
	{   
		m_headerCtrl.SubclassWindow(GetHeaderCtrl()->m_hWnd); 
	}

	CRect rcwin;  
	GetWindowRect(rcwin);  

	WINDOWPOS wp;  
	wp.hwnd=GetSafeHwnd();  
	wp.cx=rcwin.Width();  
	wp.cy=rcwin.Height();  
	wp.flags=SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER;  
	SendMessage(WM_WINDOWPOSCHANGED,0,(LPARAM)&wp);  

	CListCtrl::PreSubclassWindow();
}


void C8637ListCtrl::OnNcPaint()
{
	// TODO: Add your message handler code here
	// Do not call CListCtrl::OnNcPaint() for painting messages
}

void C8637ListCtrl::MeasureItem( LPMEASUREITEMSTRUCT lpMeasureItemStruct )
{
	lpMeasureItemStruct->itemHeight = 28;
}

void C8637ListCtrl::SetFontSelf( int nHeight, LPCTSTR lpszFacename )
{
	//先删除原有字体   
	if(m_font != NULL)  
		delete m_font;  
	m_font = new CFont;  
	//创建字体   
	m_font->CreateFont(  
		nHeight,                   // nHeight   
		0,                         // nWidth   
		0,                         // nEscapement   
		0,                         // nOrientation   
		FW_NORMAL,                 // nWeight   
		FALSE,                     // bItalic   
		FALSE,                     // bUnderline   
		0,                         // cStrikeOut   
		ANSI_CHARSET,              // nCharSet   
		OUT_DEFAULT_PRECIS,        // nOutPrecision   
		CLIP_DEFAULT_PRECIS,       // nClipPrecision   
		DEFAULT_QUALITY,           // nQuality   
		DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily   
		lpszFacename);             // lpszFacename   

	//设置字体	
	SetFont(m_font, TRUE);  
}


void C8637ListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	ASSERT(lpDrawItemStruct->CtlType == ODT_LISTVIEW);  
	CDC dc;   
	dc.Attach(lpDrawItemStruct->hDC);  
	ASSERT(NULL != dc.GetSafeHdc());  
	// Save these value to restore them when done drawing.  
	COLORREF crOldTextColor = dc.GetTextColor();  
	COLORREF crOldBkColor = dc.GetBkColor();  

	// If this item is selected, set the background color   
	// and the text color to appropriate values. Also, erase  
	// rect by filling it with the background color.  
	if ((lpDrawItemStruct->itemAction | ODA_SELECT) &&  
		(lpDrawItemStruct->itemState & ODS_SELECTED))  
	{  
		dc.SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));  
		dc.SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));  
		dc.FillSolidRect(&lpDrawItemStruct->rcItem,   
			::GetSysColor(COLOR_HIGHLIGHT));  
	}  
	else  
	{  
		if(lpDrawItemStruct->itemID%2)  
			dc.FillSolidRect(&lpDrawItemStruct->rcItem, RGB(255,255,250));  
		else  
			dc.FillSolidRect(&lpDrawItemStruct->rcItem, RGB(255,255,255));  
	}  

	// If this item has the focus, draw a red frame around the  
	// item's rect.  
	if ((lpDrawItemStruct->itemAction | ODA_FOCUS) &&  
		(lpDrawItemStruct->itemState & ODS_FOCUS))  
	{  
		CBrush br(RGB(0, 0, 128));  
		dc.FrameRect(&lpDrawItemStruct->rcItem, &br);  
	}  

	// Draw the text.  
	CString strText(_T(""));  
	CRect rcItem;  

	for(int i=0; i<GetHeaderCtrl()->GetItemCount(); i++)  
	{  
		strText = GetItemText(lpDrawItemStruct->itemID, i);  
		GetSubItemRect(lpDrawItemStruct->itemID, i, LVIR_LABEL, rcItem);  
		rcItem.left += 5;  
		if (i<2)
		{
			dc.DrawText(  
				strText,  
				strText.GetLength(),  
				&rcItem,  
				DT_LEFT|DT_SINGLELINE|DT_VCENTER);  
		}
		else
		{
			dc.DrawText(  
				strText,  
				strText.GetLength(),  
				&rcItem,  
				DT_CENTER|DT_SINGLELINE|DT_VCENTER);  
		}

	}  

	// Reset the background color and the text color back to their  
	// original values.  
	dc.SetTextColor(crOldTextColor);  
	dc.SetBkColor(crOldBkColor);  

	dc.Detach();  
}


C8637HeaderCtrl.h

#pragma once


// C8637HeaderCtrl

class C8637HeaderCtrl : public CHeaderCtrl
{
	DECLARE_DYNAMIC(C8637HeaderCtrl)

public:
	C8637HeaderCtrl();
	virtual ~C8637HeaderCtrl();

protected:
	DECLARE_MESSAGE_MAP()
public:
	LRESULT OnLayout( WPARAM wParam, LPARAM lParam);
	virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);
};



C8637HeaderCtrl.cpp

// C8637HeaderCtrl.cpp : implementation file
//

#include "stdafx.h"
#include "C8637HeaderCtrl.h"


// C8637HeaderCtrl

IMPLEMENT_DYNAMIC(C8637HeaderCtrl, CHeaderCtrl)

	C8637HeaderCtrl::C8637HeaderCtrl()
{

}

C8637HeaderCtrl::~C8637HeaderCtrl()
{
}


BEGIN_MESSAGE_MAP(C8637HeaderCtrl, CHeaderCtrl)
	ON_MESSAGE(HDM_LAYOUT, OnLayout)
END_MESSAGE_MAP()



// C8637HeaderCtrl message handlers




void C8637HeaderCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	ASSERT(lpDrawItemStruct-> CtlType   ==   ODT_HEADER);       
	HDITEM       hdi;       
	TCHAR       lpBuffer[256];       
	hdi.mask   =   HDI_TEXT;       
	hdi.pszText   =   lpBuffer;       
	hdi.cchTextMax   =   256;   
	GetItem(lpDrawItemStruct-> itemID,&hdi);     
	CDC*       pDC;
	CPen       pen, *pOldPen;
	pDC   =   CDC::FromHandle(lpDrawItemStruct-> hDC);           
	pDC-> SetTextColor(RGB(0,0,0));     
	pDC-> SetBkColor(RGB(235,239,245)); 
	CBrush       brush;       
	brush.CreateSolidBrush(RGB(235,239,245));
	CRect       rect   =   lpDrawItemStruct-> rcItem;   
	//THIS   FONT   IS   ONLY   FOR   DRAWING   AS   LONG   AS   WE   DON'T   DO   A   SetFont(...)       
	CBrush       *pOldBrush=pDC-> SelectObject(&brush);       
	rect.top-=0,rect.right+=1;
	pDC-> FillRect(&rect,&brush);	
	pen.CreatePen(PS_SOLID, 1, RGB(220,220,220));
	pOldPen = pDC->SelectObject(&pen);
	pDC->Rectangle(&rect);//Draw border
	pDC->SelectObject(pOldPen);
	pDC-> SelectObject(pOldBrush);       
	pDC-> SelectObject(GetStockObject(DEFAULT_GUI_FONT));

	//DRAW   THE   TEXT 

	CFont font;
	font.CreatePointFont(116,L"黑体",pDC);
	CFont *pFont = pDC->SelectObject(&font);
	lpDrawItemStruct-> rcItem.top   +=   8; 
	::DrawText(lpDrawItemStruct->hDC,lpBuffer, wcslen(lpBuffer),   &lpDrawItemStruct->rcItem,DT_VCENTER|DT_CENTER);
	pDC->SelectObject(pFont);
	//pDC-> SelectStockObject(SYSTEM_FONT);
}

LRESULT C8637HeaderCtrl::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 = 32;
	pwpos->cy = nHeight; 
	prc->top = nHeight; 
	return lResult; 
}


你可能感兴趣的:(自定义MFC ClistCtrl控件的示例代码)