当前位置:网站首页>MFC中如何重绘CListCtrl的表头
MFC中如何重绘CListCtrl的表头
2022-07-01 18:43:00 【mary288267】
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);
}
边栏推荐
- AppGallery Connect场景化开发实战—图片存储分享
- 从零开始学 MySQL —数据库和数据表操作
- Cdga | if you are engaged in the communication industry, you should get a data management certificate
- Database foundation: select basic query statement
- Solution of intelligent supply chain management platform in aquatic industry: support the digitalization of enterprise supply chain and improve enterprise management efficiency
- 水产行业智能供应链管理平台解决方案:支撑企业供应链数字化,提升企业管理效益
- Lake Shore 连续流动低温恒温器传输线
- 华为联机对战服务玩家掉线重连案例总结
- PriorityQueue的用法和底层实现原理
- Gameframework eating guide
猜你喜欢

Cdga | if you are engaged in the communication industry, you should get a data management certificate

2. Create your own NFT collections and publish a Web3 application to show them start and run your local environment

M91快速霍尔测量仪—在更短的时间内进行更好的测量
![[quick application] there are many words in the text component. How to solve the problem that the div style next to it will be stretched](/img/5c/b0030fd5fbc07eb94013f2699c2a04.png)
[quick application] there are many words in the text component. How to solve the problem that the div style next to it will be stretched

ACM mm 2022 video understanding challenge video classification track champion autox team technology sharing

Today, with the popularity of micro services, how does service mesh exist?

The market value evaporated by 74billion yuan, and the big man turned and entered the prefabricated vegetables

3. "Create your own NFT collections and publish a Web3 application to show them" cast NFT locally

Manufacturing SRM management system supplier all-round closed-loop management, to achieve procurement sourcing and process efficient collaboration

Lake Shore—OptiMag 超导磁体系统 — OM 系列
随机推荐
云服务器ECS夏日省钱秘籍,这次@老用户快来领走
Once the SQL is optimized, the database query speed is increased by 60 times
华为游戏初始化init失败,返回错误码907135000
Love business in Little Red Book
Lefse analysis
【AGC】如何解决事件分析数据本地和AGC面板中显示不一致的问题?
Docker deploy mysql8.0
[quick application] win7 system cannot run and debug projects using Huawei ide
MATLAB中subplot函数的使用
Database foundation: select basic query statement
Three ways for redis to realize current limiting
寶,運維100+服務器很頭疼怎麼辦?用行雲管家!
Is PMP cancelled??
AppGallery Connect场景化开发实战—图片存储分享
Yyds dry inventory ravendb start client API (III)
案例分享:QinQ基本组网配置
Go语言高级
Lumiprobe 活性染料丨吲哚菁绿说明书
Netease games, radical going to sea
JS find the next adjacent element of the number in the array