4

如果您将 ownerdraw 与 TListView 一起使用,则子项默认情况下都是 BOLD 字体样式,即使 listview font.style 设置为 [],对于自定义绘制后的所有子项也是如此。

我发现的一种解决方法是强制在 CustomDrawSubItem 事件中设置样式:

ListView2.Canvas.Font.Style := [fsItalic];
ListView2.Canvas.Font.Style := [];

(除非默认样式设置为 [] 以外的其他内容,否则带有 [] 的简单调用将不起作用,因为 SetStyle 调用不认为样式已更改)

然而,这是一个丑陋的修复,需要额外的处理时间。有更好的解决方案吗?

演示项目:http ://www.mediafire.com/?v8bsdpvpfqy47vn

4

2 回答 2

4

我没有遇到你描述的确切情况,但我遇到了类似的问题。当我使用所有者绘制TListViewOnAdvancedCustomDrawSubItem事件并分配一个事件来更改Canvas.Font每个子项时,我发现在我更改了Sender.Canvas.Font一个子项之后,即使我更改了后续子项的设置,后续子项也会使用错误的设置进行绘制Sender.Canvas.FontSender.Canvas.Font.OnChange我的解决方法是在事件处理程序结束时手动调用事件处理OnAdvancedCustomDrawSubItem程序。这表明向 WindowsTListView报告CDRF_NEWFONT,然后一切都被正确绘制。就好像Sender.Canvas.Font.OnChange事件TListView在所有者绘制时未正确连接,因此它不会检测到字体更改,因此不会正确地向 Windows 报告。

于 2012-11-21T18:13:48.190 回答
4

我同意 jachguate 的评论,即 VCL 控件似乎存在问题;一个可能的设计问题TCustomListView.CNNotify。但要遵循那里的逻辑并不容易。

一种解决方案是在 DefaultDraw 为 true 时强制更改控件的画布,以便 VCL 在自定义绘图通知返回之前再次创建并选择控件的字体到传递的 DC。例子:

procedure TForm1.LVCustomDrawSubItem(Sender: TCustomListView; Item: TListItem;
  SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean);
Var R: TRect;
    bmp: TBitmap;
    x: Integer;
begin
  DefaultDraw := True;

  if SubItem = 1 then begin
    DefaultDraw := False;
    ...
      ...       
      Sender.Canvas.Draw(R.Left - 2, R.Top, Bmp);
      Bmp.Free;
    end;
  end;

  if DefaultDraw then
    Sender.Canvas.Brush.Color := ColorToRGB(clWindow);     // <--
end;


如果可能的话,我更喜欢的方法是避免使用控件的画布。您可以为您的情况使用临时 DC,这也避免了问题评论中提到的黑色背景问题。

uses
  commctrl;

  ...

procedure TForm1.LVCustomDrawSubItem(Sender: TCustomListView; Item: TListItem;
  SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean);
Var R: TRect;
    bmp: TBitmap;
    x: Integer;
    DC: HDC;
begin
  DefaultDraw := True;

  if SubItem = 1 then begin
    DefaultDraw := False;
    ...
      ...

      DC := GetDC(Sender.Handle);
      ImageList_Draw(TypeImages.Handle, 0, DC, R.Left - 2, R.Top, ILD_NORMAL);
      ReleaseDC(Sender.Handle, DC);

      Bmp.Free;
    end;
  end;
end;
于 2012-11-21T18:17:24.190 回答