폴더의 내용에 대한 정보 가져오기

폴더 ID 가져오기 섹션에서는 PIDL(항목 식별자 목록)에 대한 네임스페이스 개체의 포인터를 가져오는 두 가지 방법을 설명했습니다. 한 가지 분명한 질문은 PIDL이 있으면 어떻게 할 수 있습니까? 관련 질문은 다음과 같습니다. 두 방법 모두 작동하지 않거나 애플리케이션에 적합한 경우 어떻게 해야 할까요? 두 질문에 대한 답변은 네임스페이스가 구현되는 방법을 자세히 살펴보는 것이 필요합니다. 키는 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, ResetSkip을 노출합니다.

폴더의 내용을 열거하기 위한 기본 절차는 다음과 같습니다.

  1. IShellFolder::EnumObjects 메서드 폴더를 호출하여 열거형 개체의 IEnumIDList 인터페이스에 대한 포인터를 검색합니다.
  2. 할당되지 않은 PIDL을 IEnumIDList::Next전달합니다. 다음으로 PIDL 할당을 처리하지만 애플리케이션은 더 이상 필요하지 않은 경우 할당을 취소해야 합니다. Next가 반환되면 PIDL에는 개체의 항목 ID와 종료되는 NULL 문자만 포함됩니다. 즉, 정규화된 PIDL이 아닌 폴더를 기준으로 하는 단일 수준 PIDL입니다.
  3. Next가 S_FALSE 반환하여 모든 항목이 열거되었음을 나타낼 때까지 2단계를 반복합니다.
  4. IEnumIDList::Release를 호출하여 열거형 개체를 해제합니다.

참고 항목

전체 또는 상대 PIDL로 작업하는지 여부를 추적하는 것이 중요합니다. 일부 함수와 메서드는 둘 중 하나를 수락하지만 다른 함수는 하나만 사용하거나 다른 함수를 사용합니다.

 

폴더의 반복 열거를 수행해야 하는 경우 3개의 IEnumIDList 메서드(다시 설정, 건너뛰기 복제)를 다시 기본 것이 유용합니다. 열거형을 다시 설정하거나 하나 이상의 개체를 건너뛰고 열거형 개체의 복사본을 만들어 상태를 유지할 수 있습니다.

표시 이름 및 기타 속성 확인

폴더에 포함된 모든 PIDL을 열거한 후에는 어떤 종류의 개체를 나타내는지 확인할 수 있습니다. IShellFolder 인터페이스는 여러 가지 유용한 메서드를 제공하며, 그 중 두 가지는 여기에서 설명합니다. 다른 IShellFolder 메서드 및 기타 셸 폴더 인터페이스는 나중에 설명합니다.

가장 유용한 속성 중 하나는 개체의 표시 이름입니다. 개체의 표시 이름을 검색하려면 해당 PIDL을 IShellFolder::GetDisplayNameOf에 전달합니다. 개체는 네임스페이스의 부모 폴더 아래에 위치할 수 있지만 해당 PIDL은 폴더를 기준으로 해야 합니다.

IShellFolder::GetDisplayNameOf는 STRRET 구조의 일부로 표시 이름을 반환합니다. STRRET 구조에서 표시 이름을 추출하는 것은 다소 까다로울 수 있으므로 Shell은 작업을 수행하는 두 가지 함수인 StrRetToStrStrRetToBuf를 제공합니다. 두 함수 모두 STRRET 구조를 사용하고 표시 이름을 일반 문자열로 반환합니다. 문자열이 할당되는 방식만 다릅니다.

표시 이름 외에도 개체에는 폴더인지 또는 이동할 수 있는지 여부와 같은 여러 특성이 있을 수 있습니다. IShellFolder::GetAttributesOf에 해당 PIDL을 전달하여 개체의 특성을 검색할 수 있습니다. 특성의 전체 목록은 매우 크므로 자세한 내용은 참조를 참조해야 합니다. GetAttributesOf전달하는 PIDL은 단일 수준이어야 합니다. 특히 IShellFolder::GetAttributesOf는 IEnumIDList::Next에서 반환된 PIDL을 수락합니다. PIDL 배열을 전달할 수 있으며 GetAttributesOf 는 배열의 모든 개체에 공통된 특성을 반환합니다.

개체의 정규화된 경로 또는 PIDL 이 있는 경우 SHGetFileInfo 는 여러 용도로 충분한 개체에 대한 정보를 검색하는 간단한 방법을 제공합니다. SHGetFileInfo 는 정규화된 경로 또는 PIDL을 사용하고 다음을 포함하여 개체에 대한 다양한 정보를 반환합니다.

  • 개체의 표시 이름
  • 개체의 특성
  • 개체의 아이콘에 대한 핸들
  • 시스템 이미지 목록에 대한 핸들
  • 개체 아이콘이 포함된 파일의 경로입니다.

하위 폴더의 IShellFolder 인터페이스에 대한 포인터 가져오기

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을 해제해서는 안 됩니다.