ListBoxでアイコン表示するには?


study  2005-07-30 00:46:08  No: 16722

はじめまして。よろしくお願い致します。

現在、下記プログラムでListBoxに、ある階層以下のフォルダ・テキストを表示しています。
ここで、Listboxに表示される各項目の左端にアイコンを表示するにはどうしたらよいのでしょう?
現在のプログラムでは、一覧に表示されたフォルダを選択してボタンを押すと、そのフォルダ内を表示するようになっています。
各項目のアイコン取得方法がわからず、Listbox.Items.AddObject(text,ico)と出来るのかもわからないです。
引き続き調べていますが、何かヒントがありましたら宜しくお願い致します。

以下ソースです。

type
  TFrmTempl = class(TForm)
    Subjects: TListBox;
    Btn1: TBtn;
    MsgBox: TEzcMsgBox;
    procedure Btn1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    TmpFile: TStringList;
    FSubject: string;
    FBody: TStrings;
    bodyFlg: boolean;
    res: boolean;
    strPass: string;
  end;
var
  FrmTempl: TFrmTempl;

procedure TFrmTempl.FormCreate(Sender: TObject);
var
  FInf: TSearchRec;
  F: TextFile;
  S: string;
begin
  TmpFile := TStringList.Create;
  FBody := TStringList.Create;

  if FindFirst('C:\aaa\bbb\*.*',faDirectory,FInf)=0 then begin
     try
        repeat
           if (FInf.Attr in [faDirectory]) and (FInf.Name <> '.') and (FInf.Name <> '..') then
           begin
              Subjects.Items.Add(FInf.Name);
              TmpFile.Add('C:\aaa\bbb\'+FInf.Name);
           end;
        Until (FindNext(FInf) <> 0);
     finally
        FindClose(FInf);
     end{try};
  end;

  if FindFirst('C:\aaa\bbb\*.txt',faAnyFile-faVolumeID,FInf)=0 then begin
     try
        repeat
           if (FInf.Name <> '.') and (FInf.Name <> '..') then
           begin
              Subjects.Items.Add(FInf.Name);
              TmpFile.Add('C:\aaa\bbb\'+FInf.Name);
           end;
        Until (FindNext(FInf) <> 0);
     finally
        FindClose(FInf);
     end{try};
  end;
  strPass := 'C:\aaa\bbb\';
end;

procedure TFrmTempl.Btn1Click(Sender: TObject);
var
  mt: TStringList;
  F: TextFile;
  S: string;
  FInf: TSearchRec;
begin
  if Subjects.ItemIndex < 0 then
     exit;

  if bodyFlg then
     if FileExists(strPass+Subjects.Items.Strings[Subjects.ItemIndex]) then
    if MsgBox.Execute('Exception',mdYesNo) = mbNO then
       Exit;

  //フォルダを選択した場合展開する
  if FileExists(strPass+Subjects.Items.Strings[Subjects.ItemIndex]) = false then
  begin
     //カレントディレクトリ移動
     strPass := strPass + Subjects.Items.Strings[Subjects.ItemIndex] + '\';

     //初期化
     Subjects.Clear;
     TmpFile.Clear;

     //一覧表示
     if FindFirst(strPass+'*.*',faDirectory,FInf)=0 then begin
        try
           repeat
              if (FInf.Attr in [faDirectory]) and (FInf.Name <> '.') and (FInf.Name <> '..') then
              begin
                 Subjects.Items.Add(FInf.Name);
                 TmpFile.Add(strPass+FInf.Name);
              end;
           Until (FindNext(FInf) <> 0);
        finally
           FindClose(FInf);
        end{try};
     end;

     if FindFirst(strPass+'*.txt',faAnyFile-faVolumeID,FInf)=0 then begin
        try
           repeat
              if (FInf.Name <> '.') and (FInf.Name <> '..') then
              begin
                 Subjects.Items.Add(FInf.Name);
                 TmpFile.Add(strPass+FInf.Name);
              end;
           Until (FindNext(FInf) <> 0);
        finally
           FindClose(FInf);
        end{try};
     end;
     
     exit;
  end;
{
  AssignFile(F,'C:\aaa\bbb\'+FInf.Name);
  Reset(F);
  try
     if not Eof(F) then
     begin
        Readln(F, S);
        Subjects.items.Add(S);
        TmpFile.Add('C:\aaa\bbb\'+FInf.Name);
     end;
  finally
        CloseFile(F);
  end;
}
  mt := TStringList.Create;
  mt.LoadFromFile(TmpFile[Subjects.ItemIndex]);

  if mt.Count>1 then
    begin
      mt.Delete(0);
      while mt.Count>0 do
        begin
          if trim(mt[0])='' then
            mt.Delete(0)
          else
             break;
        end;
    end;
  FSubject := Subjects.Items[Subjects.ItemIndex];
  FBody.Assign(mt);
  mt.free;
  Close;
  res := true;
end;


シモ  2005-07-30 01:39:34  No: 16723

ちょっとだけ考えてみました。
やり方の流れとしては、表示するフォルダ、ファイルのアイコンを取得
して、ListBox1のCanvasにDrawすれば出来ると思います。
もちろんRectも取得する必要が出てくると思います。

下のソースは、FormにTbuttonとTListBox、TImageを設置して
TButtonのClickイベントに書いてあります。
この方法の応用で目的達成出来ませんか?

procedure TForm1.Button1Click(Sender: TObject);
var
  S:String;
begin
  s :=ExtractFilePath(Application.ExeName);
  S := InputBox('ファイル','',S); //←アイコンを取得するファイル名
  Image1.Picture.Icon.Handle := ExtractIcon( HInstance, PChar(S), 0); //アイコン取得
  ListBox1.Canvas.Draw(1,1,Image1.Picture.Graphic);//ListBoxに表示
end;


moro  2005-07-30 08:59:40  No: 16724

ListBoxは使わないで、ListView(レポート形式でShowColumnHeadersがFalse)にしては?見た目はListBoxとほとんど一緒です。
TListItemのImageIndexを設定すれば、左側に小さなアイコンが表示されます。

余談ですが、リストボックスにはLB_DIRを送るとファイル一覧が表示されます。貧相ですが。


ListBox⇒ListView⇒She  2005-08-01 02:39:59  No: 16725

>Listbox.Items.AddObject(text,ico)と出来るのかもわからないです
この ico が TIconならば、それは出来ない。
どうしても ListBoxでアイコン表示したいのなら、そのDATAは別の TListなどに入れておく必要あり。
今回の場合はグラフィックDATAなので TImageListに格納するのが適当。

ListBox.Items.AddObject(text, TObject(ImageList1.AddIcon(icon)));

ListBoxのObjectには ImageListに追加したアイコンのindexを入れる。
ListBox1DrawItemイベントで ListBoxにアイコン描画する際には、そのindexを使って ImageList1.GetIcon関数でアイコンDATAを取り出し、オーナードローを行う。


deldel  2005-08-02 20:48:14  No: 16726

ShFileControlsというコンポーネントがアイコンを表示しています。
TCustomListBoxから派生しています。参考になるかと思います。

http://www.delphianworld.com/
で、ShFileControls を検索してみてください。


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

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






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