Obtendo a ID de uma pasta

Antes de usar um objeto de namespace, você precisa de uma maneira de identificá-lo. Isso significa obter seu ponteiro para uma PIDL (lista de identificadores de item) ou, no caso de objetos do sistema de arquivos, seu caminho. Esta seção discute duas das maneiras mais simples de obter IDs de objeto.

Para uma abordagem mais poderosa que funcionará com qualquer pasta, use a interface IShellFolder . Consulte Obter informações sobre o conteúdo de uma pasta para obter mais detalhes.

A caixa de diálogo OpenFiles

Para permitir que o usuário navegue pelo namespace e selecione uma pasta, seu aplicativo pode usar a interface IFileDialog . Chamar essa interface com o sinalizador FOS_PICKFOLDERS inicia a caixa de diálogo comum Abrir Arquivos no modo "selecionar pastas".

Para o Windows Vista e posteriores, essa é a maneira recomendada de escolher pastas.

A caixa de diálogo SHBrowseForFolder

Para permitir que o usuário navegue pelo namespace e selecione uma pasta, seu aplicativo pode simplesmente invocar SHBrowseForFolder. Chamar essa função inicia uma caixa de diálogo com uma interface do usuário que funciona um pouco como as caixas de diálogo comuns Abrir ou Salvar Como .

Quando o usuário seleciona uma pasta, SHBrowseForFolder retorna o PIDL totalmente qualificado da pasta e seu nome de exibição. Se a pasta estiver no sistema de arquivos, o aplicativo poderá converter o PIDL em um caminho chamando SHGetPathFromIDList. O aplicativo também pode restringir o intervalo de pastas que o usuário pode selecionar especificando uma pasta raiz. Somente as pastas abaixo dessa raiz no namespace serão exibidas. A ilustração a seguir mostra a caixa de diálogo SHBrowseForFolder , com a pasta raiz definida como Arquivos de Programas.

captura de tela da caixa de diálogo Procurar pasta

Um exemplo simples de como usar SHBrowseForFolder é fornecido posteriormente.

Pastas Especiais e CSIDLs

Várias pastas comumente usadas são designadas como especiais pelo sistema. Essas pastas têm uma finalidade bem definida e a maioria delas está presente em todos os sistemas. Mesmo que eles não estejam presentes inicialmente, seus nomes e locais ainda serão definidos, para que possam ser adicionados posteriormente. A coleção de pastas especiais inclui todas as pastas virtuais padrão do sistema, como Impressoras, Meus Documentos e Bairro de Rede. Ele também inclui várias pastas padrão do sistema de arquivos, como Arquivos de Programas e Sistema.

Embora as pastas sejam um componente padrão de todos os sistemas, seus nomes e locais no namespace podem variar. Por exemplo, o diretório System é C:\Winnt\System32 em alguns sistemas e C:\Windows\System32 em outros. No passado, as variáveis de ambiente forneceram uma maneira de determinar o nome e o local de uma pasta especial em qualquer sistema específico. O Shell agora fornece uma maneira mais robusta e flexível de identificar pastas especiais, CSIDLs. Geralmente, você deve usá-las em vez de variáveis de ambiente.

As CSIDLs fornecem uma maneira uniforme de identificar e localizar pastas especiais, independentemente de seu nome ou local em um sistema específico. Ao contrário das variáveis de ambiente, as CSIDLs podem ser usadas com pastas virtuais, bem como pastas do sistema de arquivos. Cada pasta especial tem um CSIDL exclusivo atribuído a ela. Por exemplo, a pasta do sistema de arquivos Arquivos de Programas tem um CSIDL de CSIDL_PROGRAM_FILES e a pasta virtual Network Neighborhood tem um CSIDL de CSIDL_NETWORK.

Um CSIDL é usado em conjunto com uma das várias funções do Shell para recuperar o PIDL de uma pasta especial ou o caminho de uma pasta especial do sistema de arquivos. Se a pasta não existir em um sistema, seu aplicativo poderá forçá-la a ser criada combinando seu CSIDL com CSIDL_FLAG_CREATE. O CSIDL pode ser passado para as seguintes funções:

Observe que essas duas funções foram introduzidas com a versão 5.0 do Shell e substituem as funções SHGetSpecialFolderLocation e SHGetSpecialFolderPath .

Um exemplo simples de como usar CSIDLs e SHBrowseForFolder

A função de exemplo a seguir, PidlBrowse, ilustra como usar CSIDLs para recuperar o PIDL de uma pasta e usar SHBrowseForFolder para que o usuário selecione uma pasta. Ele retorna o PIDL e o nome de exibição da pasta selecionada.

LPITEMIDLIST PidlBrowse(HWND hwnd, int nCSIDL, LPSTR pszDisplayName)
{
    LPITEMIDLIST pidlRoot = NULL;
    LPITEMIDLIST pidlSelected = NULL;
    BROWSEINFO bi = {0};

    if(nCSIDL)
    {
        SHGetFolderLocation(hwnd, nCSIDL, NULL, NULL, &pidlRoot);
    }

    else
    {
        pidlRoot = NULL;
    }

    bi.hwndOwner = hwnd;
    bi.pidlRoot = pidlRoot;
    bi.pszDisplayName = pszDisplayName;
    bi.lpszTitle = "Choose a folder";
    bi.ulFlags = 0;
    bi.lpfn = NULL;
    bi.lParam = 0;

    pidlSelected = SHBrowseForFolder(&bi);

    if(pidlRoot)
    {
        CoTaskMemFree(pidlRoot);
    }

    return pidlSelected;
}

O aplicativo de chamada passa um identificador de janela, que é necessário para SHBrowseForFolder. O parâmetro nCSIDL é um CSIDL opcional usado para especificar uma pasta raiz. Somente pastas abaixo da pasta raiz na hierarquia serão exibidas. A ilustração mostrada anteriormente foi gerada chamando essa função com nCSIDL definido como CSIDL_PROGRAM_FILES. O aplicativo de chamada também passa um buffer de cadeia de caracteres, pszDisplayName, para manter o nome de exibição da pasta selecionada quando PidlBrowse retornar. É responsabilidade do aplicativo de chamada liberar a IDList retornada por SHBrowseForFolder usando CoTaskMemFree.