Q&A

  • 폴더 아이콘을 가지고 오는 방법
트리뷰와 리스트뷰를 이용해서 탐색기 비슷한걸 구현하고 있습니다.

다만 존재하는 파일이나 폴더를 가지고 오는게 아니라 스트링을 받아서

그 구조에 따라 트리와 리스트를 구현하는 방법입니다.

문제는 파일 아이콘의 경우 이곳에서 검색해서 찾은 윈도우 FileInfo API를 이용해

가지고 오는 방법으로 해결했으나 폴더 아이콘을 가지고 올 길이 막막하다는데 있습니다.

중간에 이미지 리스트를 바꿔치기 해서 폴더만 처리하고 다시 바꿔 놓을까 하는 생각도 했었는데

리스트 뷰의 smallImages 속성은 중간에 바꿔치기하는게 안되더군요...
안되는건지 제가 못하는건지...

어쨌든 폴더 아이콘을 가지고 와서 뿌려주는 방법이 궁금합니다.

아래는 제가 찾아낸 소스입니다. 여기서 '아이콘'으로 검색해서 찾았구요.

아래부분에 DirShellInfo 를 이용해서 폴더 아이콘을 가지고 오는 부분이 있습니다.

파일 아이콘을 가져 올 때랑은 다른 방식이더군요.

그런데 여기서 사용하는 DirShellInfo가 뭘 의미하는지 모르겠습니다.

다른 곳에서 선언된 놈을 가져다 사용하는거 같은데 이 소스 안에는 그 부분이 없더군요

윈도우 API는 도움말에도 없어 더욱 난감하네요.

방법을 아시는 분은 답변을 해주세요 T_T


---------------------------------------------------------------------
ShGetFileInfo API를 이용하면 됩니다.

// Get System Image List
procedure TfrmRemoteExplorer.GetSystemImageList;
var
  SysImageList :uint;      // temporary handle for System ImageLists
  ShFileInfo :TShFileInfo; // Shell File Info structure
begin
  lvFileList.LargeImages := TImageList.Create(self);
  SysImageList := ShGetFileInfo('',0,ShFileInfo,SizeOf(ShFileInfo),
                                shgfi_SysIconIndex or shgfi_LargeIcon);
  if SysImageList <> 0 then
  begin
    lvFileList.LargeImages.Handle := SysImageList;
    lvFileList.LargeImages.ShareImages := true; // Avoid freeing of System Image List !
  end;
  lvFileList.SmallImages := TImageList.Create(self);
  SysImageList := ShGetFileInfo('',0,ShFileInfo,SizeOf(ShFileInfo),shgfi_SysIconIndex or shgfi_SmallIcon);
  if SysImageList <> 0 then
  begin
    lvFileList.SmallImages.Handle := SysImageList;
    lvFileList.SmallImages.ShareImages := true; // Avoid freeing of System Image List !
  end;
end;

function GetImageIndex(Filename: String): Integer;
var
  Fileinfo: TSHFileInfo;
begin
  if SHGetFileInfo(PChar(FileName), 0, Fileinfo, sizeof(TSHFileInfo),
     SHGFI_ICON or SHGFI_SYSICONINDEX or SHGFI_USEFILEATTRIBUTES) <> 0 then
  begin
     Result := Fileinfo.IIcon;
  end else Result := 0;
end;

procedure TfrmRemoteExplorer.DisplayFileList;
var
  List, CommaList: TStringList;
  I, DirCnt, FileCnt: Integer;
  Item: TListItem;
  f: Single;
begin
  List:= TStringList.Create;
  CommaList:= TStringList.Create;
  List.Text:= FFileList;
  DirCnt:= 0;
  FileCnt:= 0;
  lvFileList.Items.Clear;
  lvFileList.Items.BeginUpdate;
  for I:= 0 to List.Count - 1 do
  begin
    CommaList.CommaText:= List[I];
    Item:= lvFileList.Items.Add;
    if CommaList.Count < 4 then
    begin
       Item.Caption:= CommaList.Text;
       Continue;
    end;
    Item.Caption:= CommaList[0];
    f:= StrToFloat(CommaList[1]);
    Item.SubItems.Add(FormatFloat('#,0', f));
    Item.SubItems.Add(CommaList[2]);
    Item.SubItems.Add(CommaList[3]);
    if CommaList[3] = 'dir' then
    begin
      Item.ImageIndex:= DirShellInfo.iIcon;          <------- 바로 이부분~!!!!
      ~~~~~~~~~~~~~~~~~~~~~~~

      Inc(DirCnt);
    end
    else
    begin
      Item.ImageIndex:= GetImageIndex(Item.Caption);
      Inc(FileCnt);
    end;
  end;
  StatusBar1.SimpleText:= Format('[디렉토리 : %d개] / [파일 : %d개]', [DirCnt, FileCnt]);
  lvFileList.Items.EndUpdate;
  lvFileList.CustomSort(@CustomSortProc,2);
  List.Free;
  CommaList.Free;
end;


1  COMMENTS
  • Profile
    최용일 2003.04.22 19:41
    안녕하세요. 최용일입니다.

    GetImageIndex란 함수에서 SHGFI_USEFILEATTRIBUTES옵션을 빼고 존재하는 폴더 아무거나하나 넣어주시면 구하실 수 있습니다.

    SHGFI_OPENICON옵션을 추가해주면 펼쳐진 폴더도 구하실 수 있구요...

    ^^ 항상 즐코하세요...