松鼠的博客

导航

统计

改变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);   
}
 
复制代码

posted on   Xproer-松鼠  阅读(951)  评论(1编辑  收藏  举报

编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示