Q&A

  • 시스템에서 아이콘을 가져와 listview에 보여줄 때..
탐색기 비슷한걸 만들고 있는 중입니다.

예전에 찾아서 이용하던 방식으로 파일 이름으로 인덱스를 가져와

각각의 이름에 맞는 아이콘을 리스브 뷰에 보여주고 있습니다.

(mpg는 윈미아이콘, mp3는 윈엠프 아이콘, txt는 메모장아이콘
처럼 각각 pc에 설정된 것에 맞는 아이콘들...)

그러다가 제가 만든 아이콘을 추가해야할 일이 생겼습니다.

상위 폴더로 이동하는 아이콘 하고 그 비슷한거 를 추가해야 했습니다.

그래서 기존에 listview의 smallImages에 그대로 연결해 쓰던

SysImageList를 따로 만든 임의의 imagelist(test2ImageList )에 복사 해넣고
(addimage로 이미지 하나하나를 넣어줬습니다.)

제가 필요한 새로운 아이콘 두개를 임시 imagelist(tmpImageList)에 넣어놓고

test2ImageList.AddImage(tmpImageList,0);

로 추가 시켜줬습니다.

그러고 실행을 해서 사용했는데...

사용하다보면 갑자기 제 pc의 아이콘들이 전부 사라져버립니다..

탐색기를 실행해보면 죄다 아이콘이 안보이고...

제가 SysImageList를 건드렸나 싶어 소스를 아무리 디비봐도

여기선 그림을 얻어와 임시 imagelist에 넣어줬을 뿐 직접 이걸로

작업한 부분은 없더군요...

도대체 뭐가 잘못된건지... T_T

한번 제 소스를 살펴보시고 잘못된게 있으면 꼭 지적해주세요.. 부탁드립니다.



procedure TBizListView.GetSystemImageList(TargetListView: TListView);
var
  SysImageList :uint;      // temporary handle for System ImageLists
  ShFileInfo :TShFileInfo; // Shell File Info structure
  testImageList, test2ImageList: TImageList;
  i, j: integer;
begin
  testImageList := TImageList.Create(self);


  TargetListView.LargeImages := TImageList.Create(self);
  SysImageList := ShGetFileInfo('',0,ShFileInfo,SizeOf(ShFileInfo), shgfi_SysIconIndex or shgfi_LargeIcon);
  if SysImageList <> 0 then
  begin
    TargetListView.LargeImages.Handle := SysImageList;
    TargetListView.LargeImages.ShareImages := true; // Avoid freeing of System Image List !
  end;
  TargetListView.SmallImages := TImageList.Create(self);
  SysImageList := ShGetFileInfo('',0,ShFileInfo,SizeOf(ShFileInfo),shgfi_SysIconIndex or shgfi_SmallIcon);
  if SysImageList <> 0 then
  begin
    //**********여기서부터가 sysimagelist에서 이미지를 가져와
    // test2ImageList에 이미지들을 넣어주는 부분..

    testImageList.Handle := SysImageList;
    test2ImageList := TImageList.Create(self);
    for i := 0 to testImageList.Count - 1 do
    begin
      j := test2ImageList.AddImage(testImageList,i);
    end;

    //**********임의로 추가하고 싶은 아이콘 두개를 tmpImageList에
    //저장했다가  test2ImageList에 넣어주는 부분입니다.
   // imgParentFolderIndex ,  imgtestFolderIndex 는 전역변수입니다.

    imgParentFolderIndex := test2ImageList.AddImage(tmpImageList,0);
    imgtestFolderIndex := test2ImageList.AddImage(tmpImageList,1);

    TargetListView.SmallImages.Handle := test2ImageList.Handle;
    TargetListView.SmallImages.ShareImages := true;
     // Avoid freeing of System Image List !
  end;
end;



function TBizListView.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;
3  COMMENTS
  • Profile
    최용일 2004.04.17 02:05
    안녕하세요. 최용일입니다.

    시스템 이미지 리스트는 함부로 해제하면 안됩니다.

    TImageList.ShareImages속성을 True로 해서 사용하세요.

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

  • Profile
    고가람 2004.04.17 03:23
    항상 질문해서 답변만 받아가고...

    정말 너무 죄송하네요...

    언제나 감사하게 생각하고 있습니다..

    제가 소스를 수정하면서 sysImageList를 ShareImages := true하는 부분이

    빠져버렸던 거군요.. T_T

    1. 제가 작업한 로직이 큰 문제는 없는건가요?

    2. sysimageList의 shareImages를 true로 하지 않았다면
       매번 free가 됐어야 하는데.. free가 안되고 잘 되다가 가끔씩 해제가 됐던건
       무엇때문인가요?

    3. sysimageList는 listview 컨테이너에 포함된 놈이 아닌데도...
       제 프로그램에서 해제할 수 있는건가요? 변수로 선언해서 핸들을
       가져오면서 그게 가능해진건지... 대강은 이해가 가는데 명확히
       정리가 안되네요...

    질문도 횡설수설이네요.. 죄송합니다.. T_T

    procedure TBizListView.GetSystemImageList(TargetListView: TListView);
  • Profile
    최용일 2004.04.17 03:54
    안녕하세요. 최용일입니다.

    1.글쎄요... 대강봐서 ...
    testImageList는 객체를 생성하지 않으셨네요...

    2. 저도 정확한 이유는 잘 모릅니다.
    3. 핸들만 알면 해제는 가능합니다.

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