改变TListView的表格头部颜色
列表头实际上是一个SysHeader32控件,如果想改变它的颜色,唯一的办法就是自己画!那如何自己画呢?
1、首先,那个SysHeader32的每一个Item都必须具有HDF_OWNERDRAW属性。
2、当Item具有HDF_OWNERDRAW时,Windows在画它们之前将向SysHeader32的Owner(也就是TListView)发送WM_DRAWITEM消息,因此必须截获TListView的窗口过程检测消息WM_DRAWITEM然后自己画。
大概步骤如下:
1、定义变量和方法
TWndMethod OldLVWndProc;

void __fastcall NewLVWndProc(TMessage& Message);
2、在FormCreate中安装新的窗口过程
OldLVWndProc=LV1->WindowProc;
LV1->WindowProc=NewLVWndProc;

//设置属性
SetupColumnToOwnerDraw();

//-------------------------------------------
void __fastcall SetupColumnToOwnerDraw()
{
HWND HeaderHandle;
HD_ITEM hdi;

HeaderHandle = GetDlgItem(ListView1->Handle, 0);

for(int i=0;i < ListView1->Columns->Count; i++)
{
hdi.mask = HDI_TEXT | HDI_FORMAT | HDI_WIDTH;
hdi.fmt = HDF_LEFT | HDF_OWNERDRAW | HDF_STRING;
hdi.cxy = ListView1->Columns->Items[i]->Width;
hdi.cchTextMax = ListView1->Columns->Items[i]->Caption.Length();
hdi.pszText = ListView1->Columns->Items[i]->Caption.c_str();

Header_SetItem(HeaderHandle, i, &hdi);
}
}
3、编写代码:
void __fastcall TForm1::NewLVWndProc(TMessage& Message)
{
if(Message.Msg == WM_DRAWITEM)
{
DRAWITEMSTRUCT* dis;
TRect Rect;
TCanvas* FCanvas;
int LVOffset = 0;
AnsiString ColCaption;

///////////
dis = (DRAWITEMSTRUCT*)Message.LParam;

FCanvas = new TCanvas();
FCanvas->Handle = dis->hDC;
Rect = (TRect)dis->rcItem;

FCanvas->Brush->Color = ListView1->Color;
FCanvas->FillRect(Rect);

//Draw LV first
if(ListView1->SmallLVs != NULL && ListView1->Columns->Items[dis->itemID]->LVIndex != -1)
{
LVOffset = 16 + 12;
ListView1->SmallLVs->Draw(FCanvas,
Rect.Left + 6,
Rect.Top + 1,
ListView1->Columns->Items[dis->itemID]->LVIndex,
true);
}

// 采用和TListView相同的字体颜色
FCanvas->Font->Assign(ListView1->Font);
FCanvas->Font->Color = ListView1->Font->Color;
FCanvas->Brush->Style = bsClear;

ColCaption = ListView1->Columns->Items[dis->itemID]->DisplayName;

DrawTextEx(FCanvas->Handle,Str.c_str(),
ColCaption.Length(),
&TRect(Rect.Left + 5 + LVOffset,Rect.Top + 1,Rect.Right,Rect.Bottom),
DT_END_ELLIPSIS,NULL);

delete FCanvas;

Message.Result = 1;
return;
}
//把其它消息发送到原来的处理函数
OldLVWndProc(Message);
}
上面代码好像已经成功了,确切地说是只完成了一半,因为只要你改变了列的大小,它马上就恢复了原来的样子了。所以还有一步操作要做:
void __fastcall TForm1::NewLVWndProc(TMessage& Message)
{
if(Message.Msg == WM_DRAWITEM)
{
}
else if(Message.Msg == WM_PAINT)
{
if(this->ViewStyle == vsReport)
{
//先进行正常画
OldLVWndProc(Message);
//每一次画完之后都必须重新设置属性
SetupColumnToOwnerDraw(i);
//再画
OldLVWndProc(Message);
return;
}
}
//把其它消息发送到原来的处理函数
OldLVWndProc(Message);
}
1、首先,那个SysHeader32的每一个Item都必须具有HDF_OWNERDRAW属性。
2、当Item具有HDF_OWNERDRAW时,Windows在画它们之前将向SysHeader32的Owner(也就是TListView)发送WM_DRAWITEM消息,因此必须截获TListView的窗口过程检测消息WM_DRAWITEM然后自己画。
大概步骤如下:
1、定义变量和方法



2、在FormCreate中安装新的窗口过程

























3、编写代码:



















































上面代码好像已经成功了,确切地说是只完成了一半,因为只要你改变了列的大小,它马上就恢复了原来的样子了。所以还有一步操作要做:





















【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了