我有一个列表视图控件(这里是ListView),我用这样的代码填充它: var Item: TListItem; Column: TListColumn;begin ListView.ViewStyle := vsReport; Column := ListView.Columns.Add; Column.Width := 200; Column.Alignment:= taCen
var Item: TListItem; Column: TListColumn; begin ListView.ViewStyle := vsReport; Column := ListView.Columns.Add; Column.Width := 200; Column.Alignment:= taCenter; Column.Caption:= 'Column 1'; Column:= ListView.Columns.Add; Column.Width := 200; Column.Alignment := taCenter; Column.Caption := 'Column 2'; Item := ListView.Items.Add; Item.Caption := 'Item 1'; Item.SubItems.Add('Subitem 1'); end;
问题是当我在我的应用程序中使用VCL样式时,文本不在列表视图标题中居中:
如何使标题标题在VCL样式的应用程序中居中?
负责绘制列标题的样式挂钩从不检查列的文本对齐,并始终以左对齐方式绘制文本,显然是疏忽.首先创建Vcl.ComCtrls.TListViewStyleHook的后代和祖先的类助手,以便我们可以访问我们需要的私有变量.
TListViewStyleHookHelper = class helper for TListViewStyleHook function getFHeaderHandle: HWnd; end; TListViewStyleHookEx = class(Vcl.ComCtrls.TListViewStyleHook) strict protected procedure DrawHeaderSection(Canvas: TCanvas; R: TRect; Index: Integer; const Text: string; IsPressed, IsBackground: Boolean); override; end;
修复方法:
uses Winapi.Commctrl; function TListViewStyleHookHelper.getFHeaderHandle: HWnd; begin Result := Self.FHeaderHandle; end; procedure TListViewStyleHookEx.DrawHeaderSection(Canvas: TCanvas; R: TRect; Index: Integer; const Text: string; IsPressed, IsBackground: Boolean); var Item: THDItem; ImageList: HIMAGELIST; DrawState: TThemedHeader; IconWidth, IconHeight: Integer; Details: TThemedElementDetails; LListView: TListView; DT_Align: Integer; begin FillChar(Item, SizeOf(Item), 0); Item.mask := HDI_FORMAT; Header_GetItem(getFHeaderHandle, Index, Item); if IsBackground then DrawState := thHeaderItemNormal else if IsPressed then DrawState := thHeaderItemPressed else DrawState := thHeaderItemNormal; Details := StyleServices.GetElementDetails(DrawState); StyleServices.DrawElement(Canvas.Handle, Details, R); ImageList := SendMessage(getFHeaderHandle, HDM_GETIMAGELIST, 0, 0); Item.mask := HDI_FORMAT or HDI_IMAGE; InflateRect(R, -2, -2); IconWidth := 0; if (ImageList <> 0) and Header_GetItem(getFHeaderHandle, Index, Item) then begin if Item.fmt and HDF_IMAGE = HDF_IMAGE then begin ImageList_Draw(ImageList, Item.iImage, Canvas.Handle, R.Left, R.Top, ILD_TRANSPARENT); ImageList_GetIconSize(ImageList, IconWidth, IconHeight); Inc(R.Left, IconWidth + 5); end; end; if IconWidth = 0 then Inc(R.Left, 2); DT_Align := 0; if Control is TListView then begin LListView := TListView(Control); if (Index > -1) and (Index < LListView.Columns.Count) then case LListView.Columns[Index].Alignment of taLeftJustify: DT_Align := 0; taRightJustify: DT_Align := 2; taCenter: DT_Align := 1; end; end; DrawControlText(Canvas, Details, Text, R, DT_VCENTER or DT_Align or DT_SINGLELINE or DT_END_ELLIPSIS); end;
最后我们必须为TListView控件注册我们的扩展样式钩子:
Initialization TCustomStyleEngine.RegisterStyleHook(TListView, TListViewStyleHookEx); Finalization TCustomStyleEngine.UnRegisterStyleHook(TListView, TListViewStyleHookEx);