DB에 파일명이 저장된 정보를 읽어와서 리스트뷰에 뿌릴려고 합니다.
리스트뷰에 해당 파일의 아이콘을 시스템에서 읽어와서 파일 아이콘을 나타낼수 있도록 했는데.. 처음에는 정상적으로 동작을 하는데.. 계속해서 많은 자료를 읽어와서 리스트뷰에 뿌려주면 그림과 같은 에러 메세지가 나타납니다.
SHFileInfo를 이용해서 아이콘 정보를 가져오는데.. 리소스가 부족하나는 메세지로 보아서 단순히 화면에 뿌려진 리스트 뷰의 아이템을 삭제한다고 아이콘이 포함된 객체가 해제되는것이 아니고 또다른 곳에서 메모리를 사용하고 있다고 결론을 내렸습니다. 혹시 SHFileInfo를 사용할때 따로 할당된 메모리를 해제해야 하는지요?
아래 코드에서 해제가 안된 메모리가 있는지 한번 봐주세요.. 부탁드립니다.
제가 작성한 코드는
// DB에서 파일명을 읽어와서 리스트 뷰에 뿌린다..
procedure TFrmMain.ViewFileList(AFoldID: String);
var
Query : TZQuery;
AItem : TListItem;
SaveCursor : TCursor;
begin
Query := TZQuery.Create(Self);
Query.Connection := DM.ZConnection;
SaveCursor := Screen.Cursor;
try
Screen.Cursor := crHourglass;
with Query do
begin
//리스트 뷰의 아이템을 전부 삭제
SendMessage(lvFile.Handle, LVM_DELETEALLITEMS, 0, 0);
SQL.Clear;
SQL.Add(' SELECT FL_ID, FL_NM FROM FILE WHERE FD_ID = :FDID ');
ParamByName('FDID').AsString := AFoldID;
Open;
if not IsEmpty then
while not EOF do
begin
AItem := lvFile.Items.Add;
AItem.Caption := FieldByName('FL_NM').AsString;
AItem.SubItems.Add(IntToStr(FieldByName('FL_ID').AsInteger));
//아이콘을 얻어온다..
AItem.ImageIndex := GetShellImage(PChar(FieldByName('FL_NM').AsString),
lvFile.ViewStyle = vsIcon);
Next;
end;
end;
finally
Screen.Cursor := SaveCursor;
Query.Free;
end;
end;
//해당파일의 시스템 이미지를 얻는다..
function TFrmMain.GetShellImage(FileName: PChar; Large: Boolean): Integer;
var
FileInfo : TSHFileInfo;
Flags : Integer;
begin
FillChar(FileInfo, SizeOf(FileInfo), #0);
Flags := SHGFI_USEFILEATTRIBUTES or SHGFI_ICON or ILD_TRANSPARENT ;
if Large then Flags := Flags or SHGFI_LARGEICON
else Flags := Flags or SHGFI_SMALLICON;
SHGetFileInfo(PChar(FileName),
0,
FileInfo,
SizeOf(FileInfo),
Flags);
Result := FileInfo.iIcon;
end;
//폼이 나타날때.. 리스트뷰로 시스템 아이콘을 얻서서...붇인다..
procedure TFrmMain.MainFormShow(Sender: TObject);
var
SHFileInfo : TSHFileInfo;
ImageListHandle : THandle;
begin
ImageListHandle := SHGetFileInfo('C:\',
0,
SHFileInfo,
SizeOf(SHFileInfo),
SHGFI_SYSICONINDEX or SHGFI_SMALLICON);
SendMessage(lvFile.Handle, LVM_SETIMAGELIST, LVSIL_SMALL, ImageListHandle);
ImageListHandle := SHGetFileInfo('C:\',
0,
SHFileInfo,
SizeOf(SHFileInfo),
SHGFI_SYSICONINDEX or SHGFI_LARGEICON);
SendMessage(lvFile.Handle, LVM_SETIMAGELIST, LVSIL_NORMAL, ImageListHandle);
end;
==> 안녕하세요 BaSTaD 입니다..
아래 부분을 보니까 인덱스를 가져오는게 아니라 아이콘 핸들을 가져오시네요-_-;;
일케 해보세요... SHGFI_SMALLICON or SHGFI_LARGEICON 하면 아이콘 핸들입니다...
function GetIconIndex(AFileName: String): Integer;
var
SHInfo: TSHFileInfo;
begin
SHGetFileInfo(
PChar(AFileName),
FILE_ATTRIBUTE_NORMAL,
SHInfo,
SizeOf(TSHFileInfo),
SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX
);
Result := SHInfo.iIcon;
end;
그럼 성겅하시길..
by KDDG 만수 ㅔ 이