TListViewで、HideSelectionをFalseに指定することにより、
TListView以外にフォーカスさせたときに、選択していた項目の
色が変わり、見分けることができるのですが、少し色が薄いため
もっと濃い色に変更したいのですが方法がわかりません。
どなたかご教授していただけないでしょうか?
当方の環境はフリーのTurbo Delphi
TListViewは
ViewStyle := vsReport
MultiSelect := True
RowSelect := True
等の設定で行っております。
>もっと濃い色に変更したいのですが方法がわかりません。
ビジュアル系のコンポーネントには,多くの場合,CustomDrawといった名前のイベントが
用意されています.これらのイベントを利用すれば,WorkArea(ヘッダ部分を除いたデータ
の表示部分)のカスタマイズできます.
ただし,たいていの場合,自分で描画コード(領域の塗りつぶしやテキストの描画)を書く
必要があります.
Turbo Delphiは分かりませんが,Delphi7の場合は,以下のイベントがあります.
OnAdvancedCustomDraw
OnAdvancedCustomDrawItem
OnAdvancedCustomDrawSubItem
OnCustomDraw,OnCustomDrawItemというのもありますが,これらは,XPスタイルが
無効になってしまうようです.
(この2つはViewStyleがvsReportの時のみ有効なイベント)
上の3つのどれかを使用するのがいいでしょう.
結構面倒かも知れません.ネットで調べながらということになるでしょう.多分.
がんばってください.
Mr.XRAY様、ご回答ありがとうございます。
(HPもよく参考にさせていただいております。)
OnAdvancedCustomDrawItemのイベント等で、
Canvas.Brush.Colorなどを変更することで実現できそうな感じです。
(とは言っても、なかなか難しくて試行錯誤しながらやってみたいと思います。)
ありがとうございました。
ちょっとやってみました.
少しばかり苦労しました.どこが?... う〜ん.
とりあえずは動作しているようです.参考までに.
Windows XP + Delphi7 Proで動作確認しています.
CommCtrlをusesしてください.
procedure TForm1.ListView1AdvancedCustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
var DefaultDraw: Boolean);
var
AIndex : Integer;
ARect : TRect;
dwFormat : DWORD;
i : Integer;
StrItem : String;
begin
if not (ListView1.Focused) then begin
if Item.Selected then begin
AIndex := Item.Index;
//行のRect領域を取得.以下でも可
//ListView_GetItemRect(ListView1.Handle,AIndex,ARect,LVIR_BOUNDS);
ARect := Item.DisplayRect(drBounds);
OffsetRect(ARect,3,0);
//その領域を塗り潰す
ListView1.Canvas.Brush.Color := clLime;
ListView1.Canvas.FillRect(ARect);
//文字(データ)の描画
SetBkMode(ListView1.Canvas.Handle,TRANSPARENT);
dwFormat := DT_SINGLELINE or DT_VCENTER;
for i:=0 to ListView1.Columns.Count-1 do begin
case ListView1.Column[i].Alignment of
taRightJustify: dwFormat := dwFormat or DT_RIGHT;
taCenter : dwFormat := dwFormat or DT_CENTER;
else
dwFormat := dwFormat or DT_LEFT;
end;
//Rectの調整は適当に
if i=0 then begin
//Caption描画
ARect := Item.DisplayRect(drLabel);
ARect := Rect(ARect.Left+3,ARect.Top,ARect.Right,ARect.Bottom);
StrItem := Item.Caption;
DrawText(ListView1.Canvas.Handle,PChar(StrItem),-1,ARect,dwFormat);
end else begin
//SubItemの描画
ListView_GetSubItemRect(ListView1.Handle,AIndex,i,LVIR_LABEL,@ARect);
ARect := Rect(ARect.Left+6,ARect.Top,ARect.Right,ARect.Bottom);
StrItem := Item.SubItems[i-1];
DrawText(ListView1.Canvas.Handle,PChar(StrItem),-1,ARect,dwFormat);
end;
end;
//本来の描画は実行しない
DefaultDraw := False;
end;
end;;
end;
Listviewにフォーカスが戻ったときに,選択領域の色が少し残ってしまうようです.
描画領域を工夫する必要がありそうです.
Mr.XRAY様、サンプルまでありがとうございます。
このサンプルで私の環境では、意図どおり完璧に描画できました。
(選択領域の色が残ることも無いようです。)
当初、私は単純にItem.Selectedの行だけ描画を変えようと思ったのですが、
デフォルトの描画で上書きされてしまうのですね。
このため、このサンプルのように、デフォルト描画を実行せず、
全て処理を書かなければならないのですね。
ありがとうございました。
>全て処理を書かなければならないのですね。
実は小生もこれで悩んだんです.OnCustomDrawの場合はそうしなければいけない
んですが,以前,Advancedでは,Brushの設定だけで(Stateが描画前)指定色で描画されていたんです.
FocusedとかSelectedなどの条件があると,全て描画する必要があるようです.
ツイート | ![]() |