ListViewのColumns[0].Alignmentがうまく働かない


まこと  2008-10-23 06:28:27  No: 32326

ListView(ViewStyleはvsReport)で、左端のColumnsのAlignmentをtaRightJustify
に設定し、右寄せしようとしたのですが、うまくいきません。
(他のColumnsは右寄せできたのですが、左端だけうまくいかないのです。)

どのようにすれば右寄せできるのでしょうか?他に何かプロパティをいじるなど
すればよいのでしょうか?よろしくお願いします。


monaa  2008-10-24 02:49:40  No: 32327

未確認で個人的な意見ですが、仕様じゃないですかね?
一番左のカラムはEditやIconの配置がデフォルトで可能になってますから
右寄せ機能は実装されていないのだと思います。


ttt  2008-10-24 04:16:12  No: 32328

一応、MSDNでListView_SetColumn→LVCOLUMNとたどっていくとさらりと一文書いてあったりします。例えばこのあたり。
http://msdn.microsoft.com/en-us/library/bb774743(VS.85).aspx
> The alignment of the leftmost column is always left-justified; it cannot be changed.
(少し古いドキュメントだともっとあっさりした表現になっています)

というわけで、どうしても右寄せにしたかったらオーナードローにするしかなさそうですね。


まこと  2008-10-24 05:25:30  No: 32329

お2人とも、書き込みどうもありがとうございます。
> The alignment of the leftmost column is always left-justified; it cannot be changed.

この動作は仕様なのですね。

オーナードローはListBoxで簡単なものをやったことがある
のですが、ListViewはCaption部分とSubItems部分が分かれ
ていたりして、まだよく分かっていない部分があります。

多分基本は一緒だと思うので、これから挑戦してみたいと
思います。


まこと  2008-11-08 05:52:55  No: 32330

この件で、OwnerDrawで解決すべく、以下のように記述しました。
ですが、ここでいくつか問題が出ました。原因についてご指摘いただける
と幸いです。
  なお、前提条件として、ListViewのスタイルはvsReportで、Font
を9ポイントのMSゴシックにしています。

(1)発生した問題
  ・選択行のみ、フォントの色をclHighlightTextにしたかったが、
    変更できない。
  ・選択行のみ、フォントが9ポイントのMSゴシックになっていない。
    (見た感じでは11ポイントくらいのMSPゴシックになっている様子。)
  ・ヘッダー部分をダブルクリックして、Columnの幅を変更したとき、
    再描画がされず、表示が変になる。(特にこれに一番苦慮しています。)

(2)実際に記述したコード(DrawItemイベントの内容)

procedure TMTEMain.ListView1DrawItem(Sender: TCustomListView;
  Item: TListItem; Rect: TRect; State: TOwnerDrawState);
var
  R0, R1, R2, R3, R4: TRect;
  H: HDC;
  Str: String;
begin
  R0 := Item.DisplayRect(drBounds); // 行全体

  R1 := R0; // R1 は Colmuns[0]の位置
  R1.Right := R1.Left + ListView1.Column[0].Width;
  R2 := R0; // R2 は Colmuns[1]の位置
  R2.Left := R1.Right;
  R2.Right := R2.Left + ListView1.Column[1].Width;
  R3 := R0; // R3 は Colmuns[2]の位置
  R3.Left := R2.Right;
  R3.Right := R3.Left + ListView1.Column[2].Width;

  H := ListView1.Canvas.Handle;
  if Item.Selected then begin
    ListView1.Canvas.Font.Color := clHighlightText;
    ListView1.Canvas.Brush.Color := clHighlight;
  end else begin
    ListView1.Canvas.Font.Color := clWindowText;
    ListView1.Canvas.Brush.Color := clWindow;
  end;

  ListView1.Canvas.FillRect(R0);

  DrawText(H, PChar(Item.Caption), Length(Item.Caption), R1, DT_RIGHT or DT_VCENTER or DT_END_ELLIPSIS);
  DrawText(H, PChar(Item.SubItems[0]), Length(Item.SubItems[0]), R2, DT_RIGHT or DT_VCENTER or DT_END_ELLIPSIS);
  DrawText(H, PChar(Item.SubItems[1]), Length(Item.SubItems[1]), R3, DT_RIGHT or DT_VCENTER or DT_END_ELLIPSIS);
  if Item.Selected then DrawFocusRect(H, R0); // 点線の描画
end;


まこと  2008-11-08 06:22:51  No: 32331

自己レスです。
  先ほど、頭を切り替えて改めて検索をしたところ、

  if Item.Selected then begin
    SetTextColor(H, ColorToRGB(clHighlightText));

などと記述すれば、フォントの色を変更できることが分かりました。

  理屈がまだよく分かっていないのですが、これを入れたらフォント
の大きさも9ポイントのMSゴシックになったようです。


ttt  2008-11-08 06:31:46  No: 32332

・Item.Selectedではなくて、State引数のodSelectedを見るようにしたらどうでしょうか?

・Canvasにコントロールと同じフォントが割り当てられているとは限らないので
ListView.Canvas.Font := ListView.Font のように明示的に設定する必要があります。

・ListViewをサブクラス化してHDN_ENDTRACKメッセージを捕まえるという方法があったと思います。
単にOnMouseUpで再描画をかけるとかでもいけるかもしれませんが。


ttt  2008-11-08 06:35:57  No: 32333

と書き込んでいる間に新しい情報が……

つまり、
(1) CanvasのHandleを取得してHに格納
(2) Canvasのプロパティを変更
(3) Hを使って描画
という順番でやっているので、(2)の変更が反映されていないということのようですね。
(1)と(2)の順番を入れ替えるか、そもそもHandleを使わずCanvasのメソッドで描画すれば良いはずです。


まこと  2008-11-10 04:32:07  No: 32334

書き込みどうもありがとうございます。
  単純に H := 〜  のところを後ろにもってきただけで、文字の表
示についてはうまく動作しました m(__)m

  ですが、HDN_ENDTRACKを捕らえて処理をする、というものだけは
まだ成功していません。とりあえずもう少し試行錯誤してみたいと
思います。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加