폴더의 내용에 대한 정보 가져오기
폴더 ID 가져오기 섹션에서는 PIDL(항목 식별자 목록)에 대한 네임스페이스 개체의 포인터를 가져오는 두 가지 방법을 설명했습니다. 한 가지 분명한 질문은 PIDL이 있으면 어떻게 할 수 있습니까? 관련 질문은 다음과 같습니다. 두 방법 모두 작동하지 않거나 애플리케이션에 적합한 경우 어떻게 해야 할까요? 두 질문에 대한 답변은 네임스페이스가 구현되는 방법을 자세히 살펴보는 것이 필요합니다. 키는 IShellFolder 인터페이스입니다.
- IShellFolder 인터페이스 사용
- 폴더의 내용 열거
- 표시 이름 및 기타 속성 확인
- 하위 폴더의 IShellFolder 인터페이스에 대한 포인터 가져오기
- 개체의 부모 폴더 확인
이 설명서의 앞부분에서 네임스페이스 폴더를 개체라고 했습니다. 비록, 그 시점에서, 용어는 느슨한 의미에서 사용 되었다, 그것은 실제로 뿐만 아니라 엄격한 의미에서 사실. 모든 네임스페이스 폴더는 COM(Component Object Model) 개체로 표시됩니다. 각 폴더 개체는 다양한 작업에 사용할 수 있는 여러 인터페이스를 노출합니다. 선택 사항인 일부 인터페이스는 일부 폴더에서 노출되지 않을 수 있습니다. 그러나 모든 폴더는 기본 인터페이스 인 IShellFolder를 노출해야 합니다.
폴더 개체를 사용하는 첫 번째 단계는 해당 IShellFolder 인터페이스에 대한 포인터를 검색하는 것입니다. IShellFolder는 개체의 다른 인터페이스에 대한 액세스를 제공하는 것 외에도 이 섹션에서 설명하는 몇 가지 일반적인 작업을 처리하는 메서드 그룹을 노출합니다.
네임스페이스 개체의 IShellFolder 인터페이스에 대한 포인터를 검색하려면 먼저 SHGetDesktopFolder를 호출해야 합니다. 이 함수는 네임스페이스 루트 데스크톱의 IShellFolder 인터페이스에 대한 포인터를 반환합니다. 데스크톱의 IShellFolder 인터페이스가 있으면 다양한 방법으로 진행할 수 있습니다.
예를 들어 SHGetFolderLocation을 호출하여 관심 있는 폴더의 PIDL이 이미 있는 경우 데스크톱의 IShellFolder::BindToObject 메서드를 호출하여 해당 IShellFolder 인터페이스를 검색할 수 있습니다. 파일 시스템 개체의 경로가 있는 경우 먼저 데스크톱의 IShellFolder::P arseDisplayName 메서드를 호출한 다음 IShellFolder::BindToObject를 호출하여 해당 PIDL을 가져와야 합니다. 이러한 방법 중 어느 것도 적용되지 않는 경우 다른 IShellFolder 메서드를 사용하여 네임스페이스를 탐색할 수 있습니다. 자세한 내용은 네임스페이스 탐색을 참조하세요.
일반적으로 폴더로 수행하려는 첫 번째 작업은 폴더에 포함된 내용을 확인하는 것입니다. 먼저 폴더의 IShellFolder::EnumObjects 메서드를 호출해야 합니다. 이 폴더는 표준 OLE 열거형 개체를 만들고 해당 IEnumIDList 인터페이스를 반환합니다. 이 인터페이스는 폴더의 내용을 열거하는 데 사용할 수 있는 네 가지 표준 메서드인 Clone, Next, Reset 및 Skip을 노출합니다.
폴더의 내용을 열거하기 위한 기본 절차는 다음과 같습니다.
- IShellFolder::EnumObjects 메서드 폴더를 호출하여 열거형 개체의 IEnumIDList 인터페이스에 대한 포인터를 검색합니다.
- 할당되지 않은 PIDL을 IEnumIDList::Next에 전달합니다. 다음으로 PIDL 할당을 처리하지만 애플리케이션은 더 이상 필요하지 않은 경우 할당을 취소해야 합니다. Next가 반환되면 PIDL에는 개체의 항목 ID와 종료되는 NULL 문자만 포함됩니다. 즉, 정규화된 PIDL이 아닌 폴더를 기준으로 하는 단일 수준 PIDL입니다.
- Next가 S_FALSE 반환하여 모든 항목이 열거되었음을 나타낼 때까지 2단계를 반복합니다.
- IEnumIDList::Release를 호출하여 열거형 개체를 해제합니다.
참고
전체 또는 상대 PIDL로 작업하는지 여부를 추적하는 것이 중요합니다. 일부 함수와 메서드는 둘 중 하나를 수락하지만 다른 함수는 하나만 사용하거나 다른 함수를 사용합니다.
폴더의 반복 열거를 수행해야 하는 경우 3개의 IEnumIDList 메서드(다시 설정, 건너뛰기 및 복제)를 다시 기본 것이 유용합니다. 열거형을 다시 설정하거나 하나 이상의 개체를 건너뛰고 열거형 개체의 복사본을 만들어 상태를 유지할 수 있습니다.
폴더에 포함된 모든 PIDL을 열거한 후에는 어떤 종류의 개체를 나타내는지 확인할 수 있습니다. IShellFolder 인터페이스는 여러 가지 유용한 메서드를 제공하며, 그 중 두 가지는 여기에서 설명합니다. 다른 IShellFolder 메서드 및 기타 셸 폴더 인터페이스는 나중에 설명합니다.
가장 유용한 속성 중 하나는 개체의 표시 이름입니다. 개체의 표시 이름을 검색하려면 해당 PIDL을 IShellFolder::GetDisplayNameOf에 전달합니다. 개체는 네임스페이스의 부모 폴더 아래에 위치할 수 있지만 해당 PIDL은 폴더를 기준으로 해야 합니다.
IShellFolder::GetDisplayNameOf는 STRRET 구조의 일부로 표시 이름을 반환합니다. STRRET 구조에서 표시 이름을 추출하는 것은 다소 까다로울 수 있으므로 Shell은 작업을 수행하는 두 가지 함수인 StrRetToStr 및 StrRetToBuf를 제공합니다. 두 함수 모두 STRRET 구조를 사용하고 표시 이름을 일반 문자열로 반환합니다. 문자열이 할당되는 방식만 다릅니다.
표시 이름 외에도 개체에는 폴더인지 또는 이동할 수 있는지 여부와 같은 여러 특성이 있을 수 있습니다. IShellFolder::GetAttributesOf에 해당 PIDL을 전달하여 개체의 특성을 검색할 수 있습니다. 특성의 전체 목록은 매우 크므로 자세한 내용은 참조를 참조해야 합니다. GetAttributesOf에 전달하는 PIDL은 단일 수준이어야 합니다. 특히 IShellFolder::GetAttributesOf는 IEnumIDList::Next에서 반환된 PIDL을 수락합니다. PIDL 배열을 전달할 수 있으며 GetAttributesOf 는 배열의 모든 개체에 공통된 특성을 반환합니다.
개체의 정규화된 경로 또는 PIDL 이 있는 경우 SHGetFileInfo 는 여러 용도로 충분한 개체에 대한 정보를 검색하는 간단한 방법을 제공합니다. SHGetFileInfo 는 정규화된 경로 또는 PIDL을 사용하고 다음을 포함하여 개체에 대한 다양한 정보를 반환합니다.
- 개체의 표시 이름
- 개체의 특성
- 개체의 아이콘에 대한 핸들
- 시스템 이미지 목록에 대한 핸들
- 개체 아이콘이 포함된 파일의 경로입니다.
IShellFolder::GetAttributesOf를 호출하고 검사 SFGAO_FOLDER 플래그가 설정되어 있는지 확인하여 폴더에 하위 폴더가 있는지 여부를 확인할 수 있습니다. 개체가 폴더인 경우 IShellFolder 인터페이스에 대한 포인터를 제공하는 폴더에 바인딩할 수 있습니다.
하위 폴더에 바인딩하려면 부모 폴더의 IShellFolder::BindToObject 메서드를 호출합니다. 이 메서드는 하위 폴더의 PIDL을 사용하고 해당 IShellFolder 인터페이스에 대한 포인터를 반환합니다. 이 포인터가 있으면 IShellFolder 메서드를 사용하여 하위 폴더 콘텐츠를 열거하고 해당 속성을 확인하는 등의 작업을 수행할 수 있습니다.
개체의 PIDL이 있는 경우 부모 폴더에서 노출하는 인터페이스 중 하나에 대한 핸들이 필요할 수 있습니다. 예를 들어 IShellFolder::GetDisplayNameOf를 사용하여 PIDL과 연결된 표시 이름을 확인하려면 먼저 개체 부모의 IShellFolder 인터페이스를 검색해야 합니다. 이전 섹션에서 설명한 기술로 이 작업을 수행할 수 있습니다. 그러나 훨씬 더 간단한 방법은 Shell 함수인 SHBindToParent를 사용하는 것입니다. 이 함수는 개체의 정규화된 PIDL을 사용하고 부모 폴더에 지정된 인터페이스 포인터를 반환합니다. 필요에 따라 IShellFolder::GetAttributesOf와 같은 메서드에서 사용할 항목의 단일 수준 PIDL도 반환합니다.
다음 샘플 콘솔 애플리케이션은 시스템 특수 폴더의 PIDL을 검색하고 표시 이름을 반환합니다.
#include <shlobj.h>
#include <shlwapi.h>
#include <iostream.h>
#include <objbase.h>
int main()
{
IShellFolder *psfParent = NULL;
LPITEMIDLIST pidlSystem = NULL;
LPCITEMIDLIST pidlRelative = NULL;
STRRET strDispName;
TCHAR szDisplayName[MAX_PATH];
HRESULT hr;
hr = SHGetFolderLocation(NULL, CSIDL_SYSTEM, NULL, NULL, &pidlSystem);
hr = SHBindToParent(pidlSystem, IID_IShellFolder, (void **) &psfParent, &pidlRelative);
if(SUCCEEDED(hr))
{
hr = psfParent->GetDisplayNameOf(pidlRelative, SHGDN_NORMAL, &strDispName);
hr = StrRetToBuf(&strDispName, pidlSystem, szDisplayName, sizeof(szDisplayName));
cout << "SHGDN_NORMAL - " <<szDisplayName << '\n';
}
psfParent->Release();
CoTaskMemFree(pidlSystem);
return 0;
}
애플리케이션은 먼저 SHGetFolderLocation을 사용하여 시스템 폴더의 PIDL을 검색합니다. 그런 다음, 부모 폴더의 IShellFolder 인터페이스에 대한 포인터와 부모에 상대적인 시스템 폴더의 PIDL을 반환하는 SHBindToParent를 호출합니다. 그런 다음 부모 폴더의 IShellFolder::GetDisplayNameOf 메서드를 사용하여 시스템 폴더의 표시 이름을 검색합니다. GetDisplayNameOf는 STRRET 구조를 반환하므로 StrRetToBuf는 표시 이름을 일반 문자열로 변환하는 데 사용됩니다. 표시 이름을 표시하면 인터페이스 포인터가 해제되고 시스템 PIDL이 해제됩니다. SHBindToParent에서 반환된 상대 PIDL을 해제해서는 안 됩니다.