[WinAPI] 파일 아이콘 가져오기 – 1. Shell_GetImageLists, SHGetFileInfo

이번 글에서는 파일 아이콘을 가져오는 작업을 해보겠습니다.

아이콘을 가져오는건 여러 가지 방법이 있지만 윈도우에서 기본적으로 제공하는 파일 아이콘들, 예를들어 텍스트 파일, 엑셀 파일, 파워포인트 파일 등, 이런 것들을 API를 사용해서 가져오는 방법에 대해 알아보겠습니다.

Shell_GetImageListsSHGetFileInfo 함수를 사용하여 아이콘을 가져올 것이고, 최종적으로 아래와 같이 탐색기 화면을 만들어 보겠습니다.

참고로 파일 탐색기는 MFC Shell Tree, List Control로 만들면 금방 만듭니다.

Shell_GetImageLists함수부터 알아보겠습니다. 해당 함수는 시스템 이미지 목록을 검색합니다.

// 성공시 TRUE, 실패시 FALSE
BOOL Shell_GetImageLists(
	HIMAGELIST *phiml, // 32x32 시스템 이미지 목록
	HIMAGELIST *phimlSmall // 16x16 시스템 이미지 목록
);

멤버 변수에 아래와 같이 CImageList 변수를 선언합니다.

CImageList m_ImageListSmall; // 아이콘 표시용 - Small
CImageList m_ImageListLarge; // 아이콘 표시용 - Large

그리고 아래와 같이 아이콘을 가져옵니다.

// 아이콘 가져오기
HIMAGELIST hSystemImgListSmall, hSystemImgListLarge;
BOOL bRes = Shell_GetImageLists( &hSystemImgListLarge, &hSystemImgListSmall );
if (bRes != TRUE)
	return;

m_ImageListSmall.Attach( hSystemImgListSmall );
m_ImageListLarge.Attach( hSystemImgListLarge );	

주의사항으로는, 해당 이미지 리스트는 글로벌 시스템 이미지 목록이므로 Destroy를 시키면 안된다는 겁니다.
프로그램이 종료될 땐 CImageList를 Detach 시켜줘야합니다.

m_ImageListSmall.Detach();
m_ImageListLarge.Detach();

이렇게 이미지 리스트를 받아오면, 어느 위치에 어떤 이미지가 있는지 알 수가 없습니다.
이 경우 SHGetFileInfo 함수를 사용하여 파일 시스템에서의 정보를 얻어옵니다.

// 성공시 0 아님, 실패시 0
DWORD_PTR SHGetFileInfoA(
	LPCSTR      pszPath, // 경로 및 파일 이름
	DWORD       dwFileAttributes, // 파일 속성 플래그
	SHFILEINFOA *psfi, // 파일 정보 반환
	UINT        cbFileInfo, // SHFILEINFOA 크기
	UINT        uFlags // 검색 할 파일 정보 지정 플래그
);

사용 방법은 아래와 같습니다.

SHGetFileInfo( _T("C:\\Program Files\\Test.txt"), 0, &sfi, sizeof(SHFILEINFO), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES); // 절대 경로로 검색
SHGetFileInfo( _T(".ppt"), 0, &sfi, sizeof(SHFILEINFO), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES); // 확장자로 검색
SHGetFileInfo( _T("Does not matter"), FILE_ATTRIBUTE_DIRECTORY, &sfi, sizeof(SHFILEINFO), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES); // 디렉토리 인 경우

SHFILEINFO::iIcon 혹은 SHFILEINFO::hIcon을 사용하면 됩니다.

주의할점은 SHGetFileInfo 사용 하기전에 COM객체를 초기화 해야 한다는 것입니다.

예시로 아래와 같이 사용하시면 됩니다.

HRESULT hr = CoInitialize(NULL);
// ...

SHGetFileInfo( _T(".ppt"), 0, &sfi, sizeof(SHFILEINFO), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES); // 확장자로 검색

// ...
CoUninitialize();

다음 글에서는 위 코드들로 리스트 컨트롤에 아이콘을 표시해보도록 하겠습니다.