4

TListView で ownerdraw を使用する場合、リストビューの font.style が [] に設定されていても、カスタム描画されたサブアイテムに続くすべてのサブアイテムについて、サブアイテムはデフォルトですべて BOLD フォント スタイルになります。

私が見つけた回避策は、CustomDrawSubItem イベントで設定されたスタイルを強制することです。

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

([] を使用した単純な呼び出しは、デフォルトのスタイルが [] 以外に設定されていない限り機能しません。これは、SetStyle 呼び出しがスタイルが変更されたと見なさないためです)

ただし、これは余分な処理時間を伴う厄介な修正です。より良い解決策はありますか?

デモ プロジェクト: http://www.mediafire.com/?v8bsdpvpfqy47vn

4

2 に答える 2

4

VCLコントロールに問題があるようだというjachguateのコメントに同意します。の可能性のある設計上の問題TCustomListView.CNNotify。しかし、そこでの論理に従うのは簡単ではありません。

1つの解決策は、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 に答える
4

あなたが説明した正確な状況に遭遇したことはありませんが、同様の問題に遭遇しました。サブアイテムごとにを変更TListViewするOnAdvancedCustomDrawSubItemイベントが割り当てられたオーナー描画を使用すると、1 つのサブアイテムの を変更した後、それらの を変更しても、後続のサブアイテムが間違った設定で描画されることがわかりました。私の回避策は、イベント ハンドラーの最後でイベント ハンドラーを手動で呼び出すことです。これは Windowsに報告するよう合図し、すべてが正しく描画されます。オーナー描画中にイベントが正しく接続されていないかのように、フォントの変更が検出されず、Windows に正しく報告されません。Canvas.FontSender.Canvas.FontSender.Canvas.FontSender.Canvas.Font.OnChangeOnAdvancedCustomDrawSubItemTListViewCDRF_NEWFONTSender.Canvas.Font.OnChangeTListView

于 2012-11-21T18:13:48.190 に答える