Delphi中TListView自定义列标题颜色:如何填充标题栏空白区域
Delphi TListView 列标题右侧空白区域上色解决方案
问题核心:自定义TMyListView实现列标题上色后,最后一列右侧至ListView右边界的标题栏空白区域未被填充对应颜色,可通过处理Header控件的自定义绘制消息,在绘制阶段补填空白区域。
具体实现代码
type TMyListView = class(TListView) private FHeaderBrush: TBrush; procedure WMNotify(var Message: TWMNotify); message WM_NOTIFY; protected procedure CreateParams(var Params: TCreateParams); override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; end; constructor TMyListView.Create(AOwner: TComponent); begin inherited; FHeaderBrush := TBrush.Create; FHeaderBrush.Color := clSkyBlue; // 替换为你的自定义标题颜色 end; destructor TMyListView.Destroy; begin FHeaderBrush.Free; inherited; end; procedure TMyListView.CreateParams(var Params: TCreateParams); begin inherited; // 启用自定义绘制通知 Params.Style := Params.Style or LVS_OWNERDRAWFIXED; end; procedure TMyListView.WMNotify(var Message: TWMNotify); var pNMHDR: PNMHDR; pNMCustomDraw: PNMCustomDraw; HeaderRect: TRect; ColumnCount: Integer; LastColumnRight: Integer; begin inherited; pNMHDR := Message.NMHdr; // 仅处理Header控件的自定义绘制消息 if (pNMHDR^.code = NM_CUSTOMDRAW) and (pNMHDR^.hwndFrom = HeaderHandle) then begin pNMCustomDraw := PNMCustomDraw(pNMHDR); case pNMCustomDraw^.dwDrawStage of CDDS_PREPAINT: Message.Result := CDRF_NOTIFYITEMDRAW; // 通知绘制每个列项 CDDS_ITEMPREPAINT: begin // 绘制单个列标题背景 SetDCBrushColor(pNMCustomDraw^.hdc, ColorToRGB(FHeaderBrush.Color)); FillRect(pNMCustomDraw^.hdc, pNMCustomDraw^.rc, FHeaderBrush.Handle); // 绘制列标题文字(可自定义文字颜色、对齐方式) SetTextColor(pNMCustomDraw^.hdc, clBlack); SetBkMode(pNMCustomDraw^.hdc, TRANSPARENT); DrawText(pNMCustomDraw^.hdc, PChar(Columns[pNMCustomDraw^.dwItemSpec].Caption), -1, pNMCustomDraw^.rc, DT_SINGLELINE or DT_VCENTER or DT_LEFT or DT_END_ELLIPSIS); Message.Result := CDRF_SKIPDEFAULT; // 跳过默认绘制 end; CDDS_POSTPAINT: begin // 填充最后一列右侧的空白区域 GetClientRect(HeaderHandle, HeaderRect); ColumnCount := Columns.Count; if ColumnCount > 0 then begin LastColumnRight := 0; // 计算所有列的总宽度(应对列宽调整场景) for var I := 0 to ColumnCount - 1 do Inc(LastColumnRight, Columns[I].Width); HeaderRect.Left := LastColumnRight; if HeaderRect.Left < HeaderRect.Right then begin SetDCBrushColor(pNMCustomDraw^.hdc, ColorToRGB(FHeaderBrush.Color)); FillRect(pNMCustomDraw^.hdc, HeaderRect, FHeaderBrush.Handle); end; end else begin // 无列时填充整个Header区域 SetDCBrushColor(pNMCustomDraw^.hdc, ColorToRGB(FHeaderBrush.Color)); FillRect(pNMCustomDraw^.hdc, HeaderRect, FHeaderBrush.Handle); end; end; end; end; end;
关键说明
- Header控件消息拦截:通过
WM_NOTIFY消息捕获Header控件的NM_CUSTOMDRAW事件,分阶段处理绘制逻辑。 - 空白区域计算:在
CDDS_POSTPAINT阶段,计算所有列的总宽度,对比Header控件的客户区右边界,确定空白区域范围后填充颜色。 - 自适应列宽变化:每次绘制时重新计算列总宽度,确保列宽调整后空白区域仍能正确填充。
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

