TListViewのHideSelectionの色について

解決


  2008-06-18 23:20:18  No: 31023

TListViewで、HideSelectionをFalseに指定することにより、
TListView以外にフォーカスさせたときに、選択していた項目の
色が変わり、見分けることができるのですが、少し色が薄いため
もっと濃い色に変更したいのですが方法がわかりません。
どなたかご教授していただけないでしょうか?

当方の環境はフリーのTurbo Delphi
TListViewは
 ViewStyle := vsReport
 MultiSelect := True
 RowSelect := True
等の設定で行っております。


Mr.XRAY  2008-06-20 15:47:56  No: 31024

>もっと濃い色に変更したいのですが方法がわかりません。

ビジュアル系のコンポーネントには,多くの場合,CustomDrawといった名前のイベントが
用意されています.これらのイベントを利用すれば,WorkArea(ヘッダ部分を除いたデータ
の表示部分)のカスタマイズできます.
ただし,たいていの場合,自分で描画コード(領域の塗りつぶしやテキストの描画)を書く
必要があります.

Turbo Delphiは分かりませんが,Delphi7の場合は,以下のイベントがあります.

OnAdvancedCustomDraw
OnAdvancedCustomDrawItem
OnAdvancedCustomDrawSubItem

OnCustomDraw,OnCustomDrawItemというのもありますが,これらは,XPスタイルが
無効になってしまうようです.
(この2つはViewStyleがvsReportの時のみ有効なイベント)
上の3つのどれかを使用するのがいいでしょう.

結構面倒かも知れません.ネットで調べながらということになるでしょう.多分.
がんばってください.


  2008-06-21 07:06:25  No: 31025

Mr.XRAY様、ご回答ありがとうございます。
(HPもよく参考にさせていただいております。)

OnAdvancedCustomDrawItemのイベント等で、
Canvas.Brush.Colorなどを変更することで実現できそうな感じです。

(とは言っても、なかなか難しくて試行錯誤しながらやってみたいと思います。)
ありがとうございました。


Mr.XRAY  2008-06-22 00:24:34  No: 31026

ちょっとやってみました.
少しばかり苦労しました.どこが?... う〜ん.
とりあえずは動作しているようです.参考までに.
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;


Mr.XRAY  2008-06-22 00:40:42  No: 31027

Listviewにフォーカスが戻ったときに,選択領域の色が少し残ってしまうようです.
描画領域を工夫する必要がありそうです.


  2008-06-22 06:13:38  No: 31028

Mr.XRAY様、サンプルまでありがとうございます。

このサンプルで私の環境では、意図どおり完璧に描画できました。
(選択領域の色が残ることも無いようです。)

当初、私は単純にItem.Selectedの行だけ描画を変えようと思ったのですが、
デフォルトの描画で上書きされてしまうのですね。
このため、このサンプルのように、デフォルト描画を実行せず、
全て処理を書かなければならないのですね。

ありがとうございました。


Mr.XRAY  2008-06-22 07:01:58  No: 31029

>全て処理を書かなければならないのですね。

実は小生もこれで悩んだんです.OnCustomDrawの場合はそうしなければいけない
んですが,以前,Advancedでは,Brushの設定だけで(Stateが描画前)指定色で描画されていたんです.

FocusedとかSelectedなどの条件があると,全て描画する必要があるようです.


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

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






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