松鼠的博客

导航

改变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 2008-11-24 21:40  Xproer-松鼠  阅读(962)  评论(1)    收藏  举报