Partilhar via


Obter informações sobre o conteúdo de uma pasta

A seção Obtendo a ID de uma pasta discutiu duas abordagens para obter o ponteiro de um objeto de namespace para uma lista de identificadores de item (PIDL). Uma pergunta óbvia é: uma vez que você tem um PIDL, o que você pode fazer com ele? Uma pergunta relacionada é: E se nenhuma das abordagens funcionar ou for adequada para a sua aplicação? A resposta a ambas as perguntas requer uma análise mais detalhada de como o namespace é implementado. A chave é a interface IShellFolder.

Usando a interface IShellFolder

No início desta documentação, as pastas de namespace eram chamadas de objetos. Embora, nessa altura, o termo tenha sido utilizado num sentido vago, na verdade também é verdade em sentido estrito. Cada pasta de namespace é representada por um objeto COM (Component Object Model). Cada objeto de pasta expõe um número de interfaces que podem ser usadas para uma ampla variedade de tarefas. Algumas interfaces que são opcionais podem não ser expostas por todas as pastas. No entanto, todas as pastas devem expor a interface fundamental, IShellFolder.

A primeira etapa no uso de um objeto pasta é recuperar um ponteiro para a sua interface IShellFolder . Além de fornecer acesso a outras interfaces do objeto, IShellFolder expõe um grupo de métodos que lidam com várias tarefas comuns, várias das quais são discutidas nesta seção.

Para recuperar um ponteiro para a interfaceIShellFolder de um objeto de namespace, deverás primeiro chamar SHGetDesktopFolder. Esta função retorna um ponteiro para a interface IShellFolder da raiz do namespace, a área de trabalho. Assim que tiver a interface IShellFolder da área de trabalho, existem várias maneiras de avançar.

Se você já tiver o PIDL da pasta em que está interessado — por exemplo, chamando SHGetFolderLocation —, você pode recuperar sua interfaceIShellFolderchamando o método IShellFolder::BindToObject da área de trabalho. Se você tiver o caminho de um objeto de sistema de arquivos, você deve primeiro obter seu PIDL chamando o método IShellFolder::P arseDisplayName da área de trabalho e, em seguida, chamar IShellFolder::BindToObject. Se nenhuma dessas abordagens for aplicável, você poderá usar outros métodos IShellFolder para navegar no namespace. Para obter mais informações, consulte Navegando no namespace.

Enumerando o conteúdo de uma pasta

A primeira coisa que você geralmente quer fazer com uma pasta é descobrir o que ela contém. Você deve primeiro chamar o método IShellFolder::EnumObjects da pasta . A pasta criará um objeto de enumeração OLE padrão e retornará sua interfaceIEnumIDList. Essa interface expõe quatro métodos padrão —Clone, Next, Resete Skip— que podem ser usados para enumerar o conteúdo da pasta.

O procedimento básico para enumerar o conteúdo de uma pasta é:

  1. Chame as pastas método IShellFolder::EnumObjects para recuperar um ponteiro para a interfaceIEnumIDListde um objeto de enumeração.
  2. Passe um PIDL não alocado para IEnumIDList::Next. Next cuida da alocação do PIDL, mas o aplicativo deve desalocá-lo quando não for mais necessário. Quando Next retornar, o PIDL conterá apenas o ID do item do objeto e os caracteres NULL de terminação. Em outras palavras, é um PIDL de nível único, relativo à pasta, não um PIDL totalmente qualificado.
  3. Repita o passo 2 até que Próximo retorne S_FALSE, indicando que todos os itens foram enumerados.
  4. Chame IEnumIDList::Release para liberar o objeto de enumeração.

Observação

É importante acompanhar se está a trabalhar com um PIDL completo ou relativo. Algumas funções e métodos aceitarão qualquer um deles, mas outros aceitarão apenas um ou outro.

 

Os três métodosIEnumIDList restantes (Reset, Skipe Clone) são úteis se você precisar fazer enumerações repetidas da pasta. Eles permitem que você redefina a enumeração, ignore um ou mais objetos e faça uma cópia do objeto de enumeração para preservar seu estado.

Determinando nomes de exibição e outras propriedades

Depois de enumerar todos os PIDLs contidos por uma pasta, você pode descobrir que tipo de objetos eles representam. O IShellFolder interface fornece uma série de métodos úteis, dois dos quais são discutidos aqui. Outros métodos de IShellFolder e outras interfaces de pasta Shell são discutidos mais tarde.

Uma das propriedades mais úteis é o nome de exibição do objeto. Para recuperar o nome para exibição de um objeto, passe seu PIDL para IShellFolder::GetDisplayNameOf. Embora o objeto possa estar localizado em qualquer lugar abaixo da pasta pai no namespace, seu PIDL deve ser relativo à pasta.

IShellFolder::GetDisplayNameOf retorna o nome para exibição como parte de uma estrutura STRRET. Como extrair o nome de exibição de uma estrutura de STRRET pode ser um pouco complicado, o Shell fornece duas funções que fazem o trabalho para você, StrRetToStr e StrRetToBuf. Ambas as funções usam uma estrutura STRRET e retornam o nome de exibição como uma cadeia de caracteres normal. Eles diferem apenas em como a cadeia de caracteres é alocada.

Além de seu nome para exibição, um objeto pode ter vários atributos, como se é uma pasta ou se pode ser movido. Você pode recuperar os atributos de um objeto passando seu PIDL para IShellFolder::GetAttributesOf. A lista completa de atributos é bastante grande, por isso deve consultar a referência para obter mais detalhes. Observe que o PIDL que você passa para GetAttributesOf deve ser de nível único. Em particular, IShellFolder::GetAttributesOf aceitará os PIDLs retornados por IEnumIDList::Next. Você pode passar uma matriz de PIDLs e GetAttributesOf retornará os atributos que todos os objetos na matriz têm em comum.

Se você tiver um caminho totalmente qualificado ou PIDL de um objeto, SHGetFileInfo fornece uma maneira simples de recuperar informações sobre um objeto que são suficientes para muitas finalidades. SHGetFileInfo usa um caminho totalmente qualificado ou PIDL e retorna uma variedade de informações sobre o objeto, incluindo:

  • Nome de exibição do objeto
  • Atributos do objeto
  • Mecanismos para os ícones do objeto
  • Um identificador para a lista de imagens do sistema
  • O caminho do arquivo que contém o ícone do objeto

Obtendo um ponteiro para a interface IShellFolder de uma subpasta

Você pode determinar se sua pasta contém subpastas chamando IShellFolder::GetAttributesOf e verificando se o sinalizador SFGAO_FOLDER está definido. Se um objeto for uma pasta, você pode vincular a ele, o que fornece um ponteiro para sua interface IShellFolder.

Para vincular a uma subpasta, chame o método IShellFolder::BindToObject da pasta pai. Esse método obtém o PIDL da subpasta e retorna um ponteiro para sua interface IShellFolder. Depois de ter esse ponteiro, você pode usar os métodos IShellFolder para enumerar o conteúdo das subpastas, determinar suas propriedades e assim por diante.

Determinando a pasta-mãe de um objeto

Se você tiver o PIDL de um objeto, talvez precise de um identificador para uma das interfaces expostas por sua pasta pai. Por exemplo, se pretenderes determinar o nome de exibição associado a um PIDL utilizando IShellFolder::GetDisplayNameOf, deverás primeiro recuperar a interface IShellFolder do objeto pai. É possível fazer isso com as técnicas discutidas nas seções anteriores. No entanto, uma abordagem muito mais simples é usar a função Shell, SHBindToParent. Esta função usa o PIDL totalmente qualificado de um objeto e retorna um ponteiro de interface especificado na pasta pai. Opcionalmente, ele também retorna o PIDL de nível único do item para uso em métodos como IShellFolder::GetAttributesOf.

A aplicação de consola de exemplo apresentada a seguir recupera o PIDL da pasta especial do sistema e devolve o seu nome de exibição.

#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;
}

A aplicação primeiro usa SHGetFolderLocation para recuperar o PIDL da pasta System. Em seguida, ele chama SHBindToParent, que retorna um ponteiro para a interface deIShellFolderda pasta pai e o PIDL da pasta System em relação ao pai. Em seguida, usa o método IShellFolder::GetDisplayNameOf da pasta pai para recuperar o nome de exibição da pasta Sistema. Como GetDisplayNameOf retorna uma estrutura deSTRRET, StrRetToBuf é usada para converter o nome para exibição em uma cadeia de caracteres normal. Depois de exibir o nome de apresentação, os ponteiros da interface são libertados e o PIDL do sistema é liberado. Tome nota de que você não deve liberar o PIDL relativo retornado por SHBindToParent.