IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> MFC中如何重绘CListCtrl的表头 -> 正文阅读

[C++知识库]MFC中如何重绘CListCtrl的表头

MFC中的CListCtrl实际上是由两个控件组成,一个是表头控件,一个是列表控件。有些时候,我们需要重绘表头,使其满足特定的场景要求。
本文介绍了CListCtrl表头的重绘方法,自定义表头效果如下。
在这里插入图片描述

一、从CHeaderCtrl派生出自定义表头类CCustomHeader

MFC中表示表头控件的类是CHeaderCtrl,我们从它派生一个新类CCustomHeader 。
头文件为:

class CCustomHeader : public CHeaderCtrl
{
	DECLARE_DYNAMIC(CCustomHeader)

public:
	CCustomHeader();
	virtual ~CCustomHeader();
	//设置表头单元格的对齐方式,参见DrawText函数中文字对齐格式
	void SetTextAlign(UINT uFormat = DT_CENTER | DT_SINGLELINE | DT_VCENTER);

protected:
	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
	DECLARE_MESSAGE_MAP()

private:
	UINT m_nTextAlignFormat;	//表头文字对齐方式
};

实现文件

// CCustomHeader.cpp: 实现文件
//

#include "pch.h"
#include "TestCustomHeader.h"
#include "CCustomHeader.h"


// CCustomHeader

IMPLEMENT_DYNAMIC(CCustomHeader, CHeaderCtrl)

CCustomHeader::CCustomHeader()
	:m_nTextAlignFormat(DT_CENTER | DT_SINGLELINE | DT_VCENTER)
{}

CCustomHeader::~CCustomHeader()
{}

void CCustomHeader::SetTextAlign(UINT uFormat)
{
	m_nTextAlignFormat = uFormat;
}

BEGIN_MESSAGE_MAP(CCustomHeader, CHeaderCtrl)
END_MESSAGE_MAP()

void CCustomHeader::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;
	pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
	HGDIOBJ hOldFont = pDC->SelectObject(GetStockObject(DEFAULT_GUI_FONT));
	
	// 绘制按钮边框
	::DrawFrameControl(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem, DFC_BUTTON, DFCS_BUTTONPUSH);

	//绘制文本
	::DrawText(lpDrawItemStruct->hDC, lpBuffer, _tcslen(lpBuffer),
		&lpDrawItemStruct->rcItem, m_nTextAlignFormat);

	pDC->SelectObject(hOldFont);
}

请注意,在实现文件中,我们重写了DrawItem虚函数;因此当表头控件是自绘样式时,每次绘制都会调用DrawItem函数,在该函数中我们获取表头控件的DC,然后即可进行绘制。
另请注意在DrawItem中使用的如下函数:

BOOL GetItem( int nPos, HDITEM* pHeaderItem ) const;
说明:该函数可以获取表头控件每一项的信息(Retrieves information about a header control item.)

利用该函数,我们获取了表头中每一项的标题内容。

二、使用自定义表头类CCustomHeader

新建一个基于对话框的程序,在对话框类的头文件中增加:

	CListCtrl m_wndLstMain;		//表示列表控件本身
	CCustomHeader m_wndHeader;	//表示列表控件的表头控件

在OnInitDialog函数中增加:

BOOL CTestDlg::OnInitDialog()
{
	//.... 省略
	
	// TODO: 在此添加额外的初始化代码
	CRect rect;
	m_wndLstMain.GetClientRect(rect);
	m_wndLstMain.InsertColumn(0, _T("姓名"), LVCFMT_LEFT, rect.Width() / 3);
	m_wndLstMain.InsertColumn(1, _T("班级"), LVCFMT_LEFT, rect.Width() / 3);
	m_wndLstMain.InsertColumn(2, _T("学号"), LVCFMT_LEFT, rect.Width() / 3);

	m_wndLstMain.InsertItem(0, _T("张三"));
	m_wndLstMain.SetItemText(0, 1, _T("一班"));
	m_wndLstMain.SetItemText(0, 2, _T("001"));

	m_wndLstMain.InsertItem(1, _T("李四"));
	m_wndLstMain.SetItemText(1, 1, _T("一班"));
	m_wndLstMain.SetItemText(1, 2, _T("002"));

	m_wndLstMain.InsertItem(2, _T("王五"));
	m_wndLstMain.SetItemText(2, 1, _T("一班"));
	m_wndLstMain.SetItemText(2, 2, _T("003"));

	m_wndLstMain.SetExtendedStyle(LVS_EX_GRIDLINES);
	
	//子类化列表控件的表头
	CHeaderCtrl* pHeader = m_wndLstMain.GetHeaderCtrl();
	if(pHeader)
		m_wndHeader.SubclassWindow(pHeader->GetSafeHwnd());
	HDITEM hdItem;
	hdItem.mask = HDI_FORMAT;
	for (int i = 0; i < m_wndHeader.GetItemCount(); i++)
	{
		m_wndHeader.GetItem(i, &hdItem);
		hdItem.fmt |= HDF_OWNERDRAW;	//增加自绘样式
		m_wndHeader.SetItem(i, &hdItem);
	}
	
	//.... 省略
}

注意在上述函数中,我们首先初始化了CListCtrl对象,创建了多个列及多个子项,然后利用GetHeaderCtrl()函数找到了CListCtrl对象的表头控件,最后调用SubclassWindow子类化表头控件并将其绑定到m_wndHeader(这是我们重写的表头控件类对象)。
但是,仅仅如此还并未结束,我们需要将表头的每一项都改为自绘样式,这样,表头重绘时才会调用DrawItem函数,具体代码为:

	HDITEM hdItem;
	hdItem.mask = HDI_FORMAT;
	for (int i = 0; i < m_wndHeader.GetItemCount(); i++)
	{
		m_wndHeader.GetItem(i, &hdItem);
		hdItem.fmt |= HDF_OWNERDRAW;	//增加自绘样式
		m_wndHeader.SetItem(i, &hdItem);
	}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-03 10:32:27  更:2022-07-03 10:34:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 16:29:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码