Partilhar via


Implementando as interfaces básicas de objetos de pasta

O procedimento para implementar uma extensão de namespace é semelhante ao de qualquer outro objeto COM (Component Object Model) em processo. Todas as extensões devem suportar três interfaces primárias que fornecem ao Windows Explorer as informações básicas necessárias para exibir as pastas da extensão no modo de exibição em árvore. No entanto, para fazer pleno uso dos recursos do Windows Explorer, sua extensão também deve expor uma ou mais interfaces opcionais que suportam recursos mais sofisticados, como menus de atalho ou arrastar e soltar, e fornecer uma exibição de pasta.

Este documento discute como implementar as interfaces primárias e opcionais que o Windows Explorer chama para obter informações sobre o conteúdo da sua extensão. Para obter uma discussão sobre como implementar um modo de exibição de pasta e como personalizar o Windows Explorer, consulte Implementando um modo de exibição de pasta.

Implementação Básica e Registo

Como um servidor COM em processo, sua DLL deve expor várias funções e interfaces padrão:

Essas funções e interfaces são implementadas da mesma forma que para a maioria dos outros objetos COM. Para obter detalhes, consulte a documentação do COM.

Registrando uma extensão

Como em todos os objetos COM, você deve criar um GUID de identificador de classe (CLSID) para sua extensão. Registe o objeto criando uma subchave em HKEY_CLASSES_ROOT\CLSID, nomeando-a com o CLSID da sua extensão. A DLL deve ser registrada como um servidor em processo e deve especificar o modelo de threading de apartamento. Você pode personalizar o comportamento da pasta raiz de uma extensão adicionando uma variedade de subchaves e valores à chave CLSID da extensão.

Vários desses valores se aplicam apenas a extensões com pontos de junção virtuais. Esses valores não se aplicam a extensões cujos pontos de junção são pastas do sistema de arquivos. Para obter mais discussões, consulte Especificando o local de uma extensão de namespace. Para modificar o comportamento de uma extensão com um ponto de junção virtual, adicione um ou mais dos seguintes valores à chave CLSID da extensão:

  • QueremosFORPARSING. O nome de análise para uma extensão com um ponto de junção virtual normalmente terá a forma ::{GUID}. Extensões desse tipo normalmente contêm itens virtuais. No entanto, algumas extensões, como Meus Documentos, na verdade correspondem a pastas do sistema de arquivos, mesmo que tenham pontos de junção virtuais. Se sua extensão representa objetos do sistema de arquivos dessa maneira, você pode definir o valor WantsFORPARSING. O Windows Explorer solicitará o nome de análise de sua pasta raiz chamando o método IShellFolder::GetDisplayNameOf do objeto de pasta com uFlags definido como SHGDN_FORPARSING e pidl definido como um único ponteiro vazio para uma lista de identificadores de item (PIDL). Um PIDL vazio contém apenas um terminador. O seu método deve então retornar o nome de análise GUID da pasta raiz ::{}.
  • HideFolderVerbs. Os verbos registrados em HKEY_CLASSES_ROOT\pasta normalmente estão associados a todas as extensões. Eles aparecem no menu de atalho da extensão e podem ser invocados por ShellExecute. Para evitar que qualquer um desses verbos seja associado à sua extensão, defina o valor HideFolderVerbs.
  • HideAsDelete. Se um utilizador tentar eliminar a extensão, o Explorador do Windows ocultará a extensão.
  • HideAsDeletePerUser. Esse valor tem o mesmo efeito que HideAsDelete, mas por usuário. A extensão está oculta apenas para os usuários que tentaram excluí-la. A extensão é visível para todos os outros usuários.
  • QueryForOverlay. Defina esse valor para indicar que o ícone da pasta raiz pode ter uma sobreposição de ícone. O objeto de pasta deve suportar o IShellIconOverlay interface. Antes que o Windows Explorer exiba o ícone da pasta raiz, ele solicitará um ícone de sobreposição chamando um dos dois métodos de IShellIconOverlay com pidlItem definido como um PIDL vazio.

Os valores e subchaves restantes aplicam-se a todas as extensões:

  • Para especificar o nome de exibição da pasta de ponto de junção da extensão, defina o valor padrão da subchave CLSID da extensão como uma cadeia de caracteres apropriada.
  • Quando o cursor passa sobre uma pasta, normalmente é exibida uma dica de informação que descreve o conteúdo da pasta. Para fornecer uma dica de informações para a pasta raiz da extensão, crie uma dica de informações REG_SZ valor para a chave CLSID da extensão e defina-a como uma cadeia de caracteres apropriada.
  • Para especificar um ícone personalizado para a pasta raiz da extensão, crie uma subchave da subchave CLSID da extensão chamada DefaultIcon. Defina o valor padrão de DefaultIcon como um valor REG_SZ contendo o nome do arquivo que contém o ícone, seguido por uma vírgula, seguido por um sinal de subtração, seguido pelo índice do ícone nesse arquivo.
  • Por padrão, o menu de atalho da pasta raiz da extensão conterá os itens definidos em HKEY_CLASSES_ROOT\Folder. Os itens Excluir, Renomeare Propriedades serão adicionados se você tiver definido os sinalizadores de SFGAO_XXX apropriados. Você pode adicionar outros itens ao menu de atalho da pasta raiz ou substituir itens existentes, da mesma forma que faria para um tipo de arquivo . Crie uma subchave Shell sob a chave CLSID da extensão e defina os comandos conforme discutido em Estendendo menus de atalho.
  • Se você precisar de uma maneira mais flexível de lidar com o menu de atalho da pasta raiz, poderá implementar um manipulador de menu de atalho . Para registrar o manipulador de menu de atalho, crie uma chave ShellEx sob a chave CLSID da extensão. Registre o CLSID do manipulador como faria para um convencional Criando manipuladores de extensão de shell.
  • Para adicionar uma página à folha de propriedades da pasta raiz, dê à pasta o atributo SFGAO_HASPROPSHEET e implemente um manipulador de folha de propriedades . Para registar o manipulador de folha de propriedades, crie uma chave de ShellEx sob a chave CLSID da extensão. Registre o CLSID do manipulador como faria para um convencional Criando manipuladores de extensão de shell.
  • Para especificar os atributos da pasta raiz, adicione uma subchave ShellFolder à subchave CLSID da extensão. Crie um valor de Atributos e configure-o com a combinação apropriada dos sinalizadores SFGAO_XXX.

A tabela a seguir lista alguns atributos comumente usados para pastas raiz.

Bandeira Valor Descrição
SFGAO_FOLDER 0x20000000 A pasta raiz da extensão contém um ou mais itens.
SFGAO_HASSUBFOLDER 0x80000000 A pasta raiz da extensão contém uma ou mais subpastas. O Windows Explorer colocará um sinal de adição ( + ) ao lado do ícone da pasta.
SFGAO_CANDELETE 0x00000020 A pasta raiz da extensão pode ser excluída pelo usuário. O menu de atalho da pasta terá um item Eliminar. Esse sinalizador deve ser definido para pontos de junção colocados sob uma das pastas virtuais.
SFGAO_CANRENAME 0x00000010 A pasta raiz da extensão pode ser renomeada pelo usuário. O menu de atalho da pasta terá um item Renomear.
SFGAO_HASPROPSHEET 0x00000040 A pasta raiz da extensão tem uma Propriedades ficha de propriedades. O menu de atalho da pasta terá um item Propriedades. Para fornecer a folha de propriedades, você deve implementar um manipulador de folha de propriedades . Registre o manipulador sob a chave CLSID da extensão, conforme discutido anteriormente.

 

O exemplo a seguir mostra a entrada do registo CLSID para uma extensão com o nome de exibição MyExtension. A extensão tem um ícone personalizado que está contido na DLL da extensão com um índice de 1. Os atributos SFGAO_FOLDER, SFGAO_HASSUBFOLDERe SFGAO_CANDELETE são definidos.

HKEY_CLASSES_ROOT
   CLSID
      {Extension CLSID}
         (Default) = MyExtension
         InfoTip = Some appropriate text
      DefaultIcon
         (Default) = c:\MyDir\MyExtension.dll,-1
      InProcServer32
         (Default) = c:\MyDir\MyExtension.dll
         ThreadingModel = Apartment
      ShellFolder
         Attributes = 0xA00000020

Manipulação de PIDLs

Cada item no namespace Shell deve ter um PIDL exclusivo. O Windows Explorer atribui um PIDL à sua pasta raiz e passa o valor para sua extensão durante a inicialização. Sua extensão é então responsável por atribuir um PIDL construído corretamente a cada um de seus objetos e fornecer esses PIDLs ao Windows Explorer mediante solicitação. Quando o Shell usa um PIDL para identificar um dos objetos da sua extensão, sua extensão deve ser capaz de interpretar o PIDL e identificar o objeto específico. Sua extensão também deve atribuir um nome de exibição e um nome de análise a cada objeto. Como os PIDLs são usados por praticamente todas as interfaces de pastas, as extensões geralmente implementam um único gestor de PIDL para gerir todas estas tarefas.

O termo PIDL é uma abreviação de uma estruturaITEMIDLIST ou um ponteiro para tal estrutura, dependendo do contexto. Como declarado, uma estrutura ITEMIDLIST tem um único membro, uma estrutura SHITEMID. A estrutura ITEMIDLIST de um objeto é, na verdade, uma matriz compactada de duas ou mais estruturas SHITEMID. A ordem dessas estruturas define um caminho através do namespace, da mesma forma que c:\MyDirectory\MyFile define um caminho através do sistema de arquivos. Tipicamente, o PIDL de um objeto consistirá numa série de estruturas SHITEMID que correspondem às pastas que definem o caminho do namespace, seguidas pela estrutura SHITEMID do objeto, seguida por um terminador.

O terminador é uma estrutura SHITEMID, com o membro cb definido como NULL. O terminador é necessário porque o número de estruturas de SHITEMID no PIDL de um objeto depende da localização do objeto no espaço de nomes do Shell e do ponto inicial do caminho. Além disso, o tamanho das várias estruturas SHITEMID pode variar. Quando recebe um PIDL, não tem uma maneira simples de determinar o seu tamanho ou mesmo o número total de estruturas SHITEMID de e. Em vez disso, deve-se "percorrer" a matriz compactada, estrutura por estrutura, até chegar ao terminador.

Para criar um PIDL, seu aplicativo precisa:

  1. Crie uma estrutura SHITEMID de para cada um dos seus objetos.
  2. Monte as estruturas relevantes de SHITEMID num PIDL.

Criando uma estrutura SHITEMID

A estrutura SHITEMID de um objeto identifica exclusivamente o objeto dentro da sua pasta. Na verdade, um tipo de PIDL usado por muitos dos métodos IShellFolder consiste apenas na estrutura de SHITEMID do objeto, seguida por um terminador. A definição de uma estrutura SHITEMID é:

typedef struct _SHITEMID { 
    USHORT cb; 
    BYTE   abID[1]; 
} SHITEMID, * LPSHITEMID;

O membro abID é o identificador do objeto. Como o comprimento de abID não está definido e pode variar, o membro cb é definido para ser o tamanho da estrutura SHITEMID, em bytes.

Como nem o comprimento nem o conteúdo de abID são padronizados, você pode usar qualquer esquema que deseje atribuir valores abID aos seus objetos. O único requisito é que você não pode ter dois objetos na mesma pasta com valores idênticos. No entanto, por motivos de desempenho, a sua estrutura SHITEMID deve estar alinhada com DWORD. Em outras palavras, deve construir os seus valores de abID de forma que cb seja um múltiplo inteiro de 4.

Normalmente, abID aponta para uma estrutura definida por uma extensão. Além da ID do objeto, essa estrutura é frequentemente usada para armazenar uma variedade de informações relacionadas, como o tipo ou os atributos do objeto. Os objetos de pasta da sua extensão podem então extrair rapidamente as informações do PIDL em vez de ter que consultá-las.

Observação

Um dos aspetos mais importantes do projeto de uma estrutura de dados para um PIDL é tornar a estrutura persistente e transportável. No contexto das PIDLs, o significado destes termos é:

  • Persistível. O sistema frequentemente coloca PIDLs em vários tipos de armazenamento de longo prazo, como arquivos de atalho. Ele pode então recuperar esses PIDLs do armazenamento mais tarde, possivelmente depois que o sistema tiver sido reinicializado. Um PIDL que foi recuperado do armazenamento ainda deve ser válido e significativo para sua extensão. Este requisito significa, por exemplo, que você não deve usar ponteiros ou alças em sua estrutura PIDL. PIDLs contendo esse tipo de dados normalmente não terão sentido quando o sistema mais tarde os recuperar do armazenamento.
  • Transportável. Um PIDL deve permanecer significativo quando transportado de um computador para outro. Por exemplo, um PIDL pode ser gravado em um arquivo de atalho, copiado para um disquete e transportado para outro computador. Esse PIDL ainda deve ser significativo para sua extensão em execução no segundo computador. Por exemplo, para garantir que seus PIDLs sejam transportáveis, use caracteres ANSI ou Unicode explicitamente. Evite tipos de dados como TCHAR ou LPTSTR. Se você usar esses tipos de dados, um PIDL criado em um computador que executa uma versão Unicode da sua extensão não será legível por uma versão ANSI dessa extensão em execução em um computador diferente.

 

A declaração a seguir mostra um exemplo simples de uma estrutura de dados.

typedef struct tagMYPIDLDATA {
  USHORT cb;
  DWORD dwType;
  WCHAR wszDisplayName[40];
} MYPIDLDATA, *LPMYPIDLDATA;

O membro cb é ajustado ao tamanho da estrutura MYPIDLDATA. Este membro faz de MYPIDLDATA uma estrutura SHITEMID válida por si só . O resto dos membros é equivalente ao membro abID de uma estrutura SHITEMID e mantêm dados privados. O membro dwType é um valor definido por extensão que indica o tipo de objeto. Neste exemplo, dwType é definido como TRUE para pastas e FALSE caso contrário. Esse membro permite, por exemplo, determinar rapidamente se o objeto é uma pasta ou não. O membro wszDisplayName contém o nome de exibição do objeto. Como você não atribuiria o mesmo nome para exibição a dois objetos diferentes na mesma pasta, o nome para exibição também serve como ID do objeto. Neste exemplo, wszDisplayName é definido como 40 caracteres para garantir que a estrutura SHITEMID será DWORD-alinhada. Para limitar o tamanho de seus PIDLs, você pode usar uma matriz de caracteres de comprimento variável e ajustar o valor de cb de acordo. Preencha a cadeia de caracteres de exibição com caracteres '\0' suficientes para manter o alinhamento de DWORD da estrutura. Outros membros que podem ser úteis para colocar na estrutura incluem o tamanho, os atributos ou o nome de análise do objeto.

Construindo um PIDL

Depois de definir estruturas SHITEMID para seus objetos, você pode usá-las para construir um PIDL. Os PIDLs podem ser construídos para uma variedade de propósitos, mas a maioria das tarefas usa um dos dois tipos de PIDL. O PIDL mais simples, de nível único, identifica o objeto em relação à sua pasta pai. Este tipo de PIDL é usado por muitos dos IShellFolder métodos. Um PIDL de nível único contém a estrutura de SHITEMID do objeto, seguida por um terminador. Um PIDL totalmente qualificado define um caminho através da hierarquia de namespace da área de trabalho para o objeto. Esse tipo de PIDL começa na área de trabalho e contém uma estrutura de SHITEMID para cada pasta no caminho, seguida pelo objeto e pelo terminador. Um PIDL totalmente qualificado identifica exclusivamente o objeto dentro de todo o namespace do Shell.

A maneira mais simples de construir um PIDL é trabalhar diretamente com a estrutura ITEMIDLIST propriamente dita. Crie uma estrutura ITEMIDLIST, mas aloque memória suficiente para armazenar todas as estruturas SHITEMID. O endereço desta estrutura apontará para a estrutura inicial SHITEMID. Defina valores para os membros dessa estrutura inicial e, em seguida, acrescente quantas estruturas de SHITEMID adicionais forem necessárias, na ordem apropriada. O procedimento a seguir descreve como criar um PIDL de nível único. Contém duas estruturas SHITEMID — uma estrutura MYPIDLDATA seguida por um terminador:

  1. Use a função CoTaskMemAlloc para alocar memória para o PIDL. Aloque memória suficiente para os seus dados privados, além de um USHORT (dois bytes) para o terminador. Converta o resultado em LPMYPIDLDATA.
  2. Configure o membro cb da primeira estrutura de MYPIDLDATA com o tamanho dessa estrutura. Para este exemplo, você definiria cb como sizeof(MYPIDLDATA). Se você quiser usar uma estrutura de comprimento variável, você terá que calcular o valor de cb.
  3. Atribua valores apropriados aos membros de dados privados.
  4. Calcule o endereço da próxima SHITEMID estrutura. Converta o endereço da estrutura MYPIDLDATA atual para LPBYTE e adicione esse valor ao valor de cb determinado na etapa 3.
  5. Neste caso, a próxima estrutura SHITEMID é o terminador. Defina o membro cb da estrutura como zero.

Para PIDLs mais longos, aloque memória suficiente e repita as etapas 3 a 5 para cada estrutura SHITEMID adicional.

A função de exemplo a seguir usa o tipo e o nome de exibição de um objeto e retorna o PIDL de nível único do objeto. A função assume que o nome de exibição, incluindo seu de terminação nulo caractere, não excede o número de caracteres declarados para a estrutura MYPIDLDATA. Se essa suposição se revelar errada, a função StringCbCopyW truncará o nome de exibição. A variável g_pMalloc é um ponteiro IMalloc criado noutro local e armazenado numa variável global.

LPITEMIDLIST CreatePIDL(DWORD dwType, LPCWSTR pwszDisplayName)
{
    LPMYPIDLDATA   pidlOut;
    USHORT         uSize;

    pidlOut = NULL;

    //Calculate the size of the MYPIDLDATA structure.
    uSize = sizeof(MYPIDLDATA);

    // Allocate enough memory for the PIDL to hold a MYPIDLDATA structure 
    // plus the terminator
    pidlOut = (LPMYPIDLDATA)m_pMalloc->Alloc(uSize + sizeof(USHORT));

    if(pidlOut)
    {
       //Assign values to the members of the MYPIDLDATA structure
       //that is the PIDL's first SHITEMID structure
       pidlOut->cb = uSize;
       pidlOut->dwType = dwType;
       hr = StringCbCopyW(pidlOut->wszDisplayName, 
                          sizeof(pidlOut->wszDisplayName), pwszDisplayName);
       
       // TODO: Add error handling here to verify the HRESULT returned 
       // by StringCbCopyW.

       //Advance the pointer to the start of the next SHITEMID structure.
       pidlOut = (LPMYPIDLDATA)((LPBYTE)pidlOut + pidlOut->cb);

       //Create the terminating null character by setting cb to 0.
       pidlOut->cb = 0;
    }

    return pidlOut;

Um PIDL totalmente qualificado deve ter estruturas SHITEMID para cada objeto, da área de trabalho ao seu objeto. Sua extensão recebe um PIDL totalmente qualificado para sua pasta raiz quando o Shell chama IPersistFolder::Initialize. Para construir um PIDL totalmente qualificado para um objeto, pegue o PIDL que o Shell atribuiu à sua pasta raiz e anexe as estruturas SHITEMID necessárias para levá-lo da pasta raiz ao objeto.

Interpretação de PIDLs

Quando o Shell ou um aplicativo chama uma das interfaces da extensão para solicitar informações sobre um objeto, ele geralmente identifica o objeto por um PIDL. Alguns métodos, como IShellFolder::GetUIObjectOf, usam PIDLs que são relativos à pasta pai e são simples de interpretar. No entanto, sua extensão provavelmente também receberá PIDLs totalmente qualificados. Seu gerenciador PIDL deve então determinar a qual dos seus objetos o PIDL está se referindo.

O que complica a tarefa de associar um objeto a um PIDL totalmente qualificado é que uma ou mais das estruturas iniciais SHITEMID no PIDL podem pertencer a objetos que estão fora da sua extensão no namespace Shell. Não tens forma de interpretar o significado do membro abID dessas estruturas. O que a sua extensão deve fazer é percorrer a lista de estruturas SHITEMID, até chegar à estrutura que corresponde à sua pasta raiz. A partir daí, saberá como interpretar as informações nas estruturas SHITEMID.

Para percorrer o PIDL, obtenha o primeiro valor cb e adicione-o ao endereço do PIDL para avançar o ponteiro até o início da estrutura SHITEMID seguinte. Em seguida, ele estará apontando para o membro cb dessa estrutura, que você pode usar para avançar o ponteiro para o início da próxima estrutura de SHITEMID e assim por diante. Sempre que avançar o ponteiro, examine a estrutura SHITEMID para determinar se atingiu a raiz do namespace da sua extensão.

Implementando as interfaces primárias

Como acontece com todos os objetos COM, a implementação de uma extensão é em grande parte uma questão de implementar uma coleção de interfaces. Esta seção discute as três interfaces primárias que devem ser implementadas por todas as extensões. Eles são usados para inicialização e para fornecer o Windows Explorer com informações básicas sobre o conteúdo da extensão. Essas interfaces, juntamente com uma visualização de pasta , são tudo o que se precisa para uma extensão funcional. No entanto, para explorar plenamente os recursos do Windows Explorer, a maioria das extensões também implementa uma ou mais das interfaces opcionais.

IPersistFolder Interface

O interface IPersistFolder é chamado para inicializar um novo objeto de pasta. O método IPersistFolder::Initialize atribui um PIDL totalmente qualificado ao novo objeto. Armazene este PIDL para uso posterior. Por exemplo, um objeto de pasta deve usar esse PIDL para construir PIDLs totalmente qualificados para os filhos do objeto. O criador do objeto de pasta também pode chamar IPersist::GetClassID para solicitar o CLSID do objeto.

Normalmente, um objeto de pasta é criado e inicializado pelo método IShellFolder::BindToObject de sua pasta pai. No entanto, quando um usuário navega para sua extensão, o Windows Explorer cria e inicializa o objeto de pasta raiz da extensão. O PIDL que o objeto de pasta raiz recebe através IPersistFolder::Initialize contém o caminho da área de trabalho para a pasta raiz que você precisará para construir PIDLs totalmente qualificados para sua extensão.

IShellFolder Interface

O Shell trata uma extensão como uma coleção ordenada hierarquicamente de objetos de pasta. A interface IShellFolder é o núcleo de qualquer implementação de extensão. Ele representa um objeto de pasta e fornece ao Windows Explorer muitas das informações necessárias para exibir o conteúdo da pasta.

IShellFolder é tipicamente a única interface de pasta, além de IPersistFolder, que é diretamente exposta por um objeto de pasta. Enquanto o Windows Explorer usa uma variedade de interfaces necessárias e opcionais para obter informações sobre o conteúdo da pasta, ele obtém ponteiros para essas interfaces através IShellFolder.

O Windows Explorer obtém o CLSID da pasta raiz da extensão de várias maneiras. Para mais detalhes, consulte Especificação do local de uma extensão de namespace ou Visualização de uma vista Self-Contained de uma extensão de namespace. Em seguida, o Windows Explorer usa esse CLSID para criar e inicializar uma instância da pasta raiz e consultar uma interface IShellFolder. Sua extensão cria um objeto de pasta para representar a pasta raiz e retorna a interface IShellFolder do objeto. Grande parte do restante da interação entre sua extensão e o Windows Explorer ocorre por meio IShellFolder. O Windows Explorer chama IShellFolder para:

  • Solicite um objeto que possa enumerar o conteúdo da pasta raiz.
  • Obtenha vários tipos de informações sobre o conteúdo da pasta raiz.
  • Solicite um objeto que exponha uma das interfaces opcionais. Essas interfaces podem então ser consultadas para obter informações adicionais, como ícones ou menus de atalho.
  • Solicite um objeto de pasta que represente uma subpasta da pasta raiz.

Quando um usuário abre uma subpasta da pasta raiz, o Windows Explorer chama IShellFolder::BindToObject. A sua extensão cria e inicializa um novo objeto de pasta para representar a subpasta e retorna a sua interface IShellFolder . Em seguida, o Windows Explorer chama essa interface para vários tipos de informações e assim por diante até que o usuário decida navegar em outro lugar no namespace do Shell ou fechar o Windows Explorer.

O restante desta seção discute brevemente os métodos mais importantes IShellFolder e como implementá-los.

EnumObjects

Antes de exibir o conteúdo de uma pasta no modo de exibição de árvore, o Windows Explorer deve primeiro determinar o que a pasta contém chamando o método IShellFolder::EnumObjects. Esse método cria um objeto de enumeração OLE padrão que expõe um IEnumIDList interface e retorna esse ponteiro de interface. A interface IEnumIDList permite que o Windows Explorer obtenha os PIDLs de todos os objetos contidos na pasta. Esses PIDLs são usados para obter informações sobre os objetos contidos pela pasta. Para mais detalhes, veja IEnumIDList Interface.

Observação

O método IEnumIDList::Next só deve retornar PIDLs que são relativos à pasta pai. O PIDL deve conter apenas a estrutura SHITEMID composta por do objeto, seguida por um terminador.

 

CreateViewObject

Antes que o conteúdo de uma pasta seja exibido, o Windows Explorer chama este método para solicitar um ponteiro para a interface IShellView. Esta interface é utilizada pelo Explorador do Windows para gerir a vista de pastas. Crie um objeto para a exibição de pasta e retorne a interface IShellView do .

O método IShellFolder::CreateViewObject também é chamado para solicitar uma das interfaces opcionais, como IContextMenu, para a própria pasta. Sua implementação desse método deve criar um objeto que expõe a interface solicitada e retorna o ponteiro da interface. Se o Windows Explorer precisar de uma interface opcional para um dos objetos contidos pela pasta, ele chamará IShellFolder::GetUIObjectOf.

GetUIObjectOf

Embora informações básicas sobre o conteúdo de uma pasta estejam disponíveis através dos métodos IShellFolder, sua extensão também pode fornecer ao Windows Explorer vários tipos de informações adicionais. Por exemplo, você pode especificar ícones para o conteúdo de uma pasta ou o menu de atalho de um objeto. O Windows Explorer chama o IShellFolder::GetUIObjectOf método para tentar recuperar informações adicionais sobre um objeto contido por uma pasta. O Windows Explorer especifica para qual objeto ele deseja as informações e o IID da interface relevante. Em seguida, o objeto folder cria um objeto que expõe a interface solicitada e retorna o ponteiro da interface.

Se a sua extensão permitir que os utilizadores transfiram objetos com o recurso de arrastar e soltar ou a área de transferência, o Windows Explorer chamará IShellFolder::GetUIObjectOf para solicitar uma interface IDataObject ou IDropTarget. Para obter detalhes, consulte Transferindo objetos do shell com arrastar e soltar e a área de transferência.

O Windows Explorer chama IShellFolder::CreateViewObject quando deseja o mesmo tipo de informação sobre a própria pasta.

BindToObject

O Windows Explorer chama o IShellFolder::BindToObject método quando um usuário tenta abrir uma das subpastas da sua extensão. Se riid estiver definido como IID_IShellFolder, você deverá criar e inicializar um objeto de pasta que represente a subpasta e retornar a interfaceIShellFolderdo objeto.

Observação

No momento, o Windows Explorer chama esse método apenas para solicitar um IShellFolder interface. No entanto, não parta do princípio de que será sempre esse o caso. Você deve sempre verificar o valor de riid antes de prosseguir.

 

GetDisplayNameOf

O Windows Explorer chama o IShellFolder::GetDisplayNameOf método para converter o PIDL de um dos objetos da pasta em um nome. Esse PIDL deve ser relativo à pasta pai do objeto. Em outras palavras, ele deve conter uma única estrutura de nãoNULLSHITEMID. Como há mais de uma maneira possível de nomear objetos, o Windows Explorer especifica o tipo de nome definindo um ou mais sinalizadores deSHGDNFno parâmetro uFlags. Um dos dois valores, SHGDN_NORMAL ou SHGDN_INFOLDER, será definido para especificar se o nome deve ser relativo à pasta ou relativo à área de trabalho. Um dos outros três valores, SHGDN_FOREDITING, SHGDN_FORADDRESSBARou SHGDN_FORPARSING, pode ser definido para especificar para que o nome será usado.

Você deve retornar o nome na forma de uma estrutura STRRET. Se SHGDN_FOREDITING, SHGDN_FORADDRESSBARe SHGDN_FORPARSING não estiverem definidos, retorne o nome para exibição do objeto. Se o sinalizador SHGDN_FORPARSING estiver definido, o Windows Explorer está solicitando um nome de interpretação. Os nomes de análise são passados para a IShellFolder::ParseDisplayName para obter o PIDL de um objeto, mesmo que ele possa estar localizado um ou mais níveis abaixo da pasta atual na hierarquia de namespace. Por exemplo, o nome de análise de um objeto de sistema de arquivos é seu caminho. Você pode passar o caminho totalmente qualificado de qualquer objeto no sistema de arquivos para o método IShellFolder::P arseDisplayName da área de trabalho e ele retornará o VIDL totalmente qualificado do objeto.

Embora os nomes analisados sejam cadeias de texto, eles não precisam necessariamente incluir os nomes exibidos. Você deve atribuir nomes para análise com base no que funcionará com mais eficiência quando IShellFolder::ParseDisplayName for chamado. Por exemplo, muitas das pastas virtuais do Shell não fazem parte do sistema de arquivos e não têm um caminho totalmente qualificado. Em vez disso, cada pasta recebe um GUID e o nome de análise assume a forma ::{GUID}. Independentemente do esquema que se usar, ele deve ser capaz de "ciclo completo" de forma confiável. Por exemplo, se um chamador passar um nome de análise para IShellFolder::ParseDisplayName para recuperar o PIDL de um objeto e, em seguida, passar esse PIDL para IShellFolder::GetDisplayNameOf com o sinalizador SHGDN_FORPARSING ativado, o chamador poderá recuperar o nome de análise original.

ObterAtributosDe

O Windows Explorer chama o IShellFolder::GetAttributesOf método para determinar os atributos de um ou mais itens contidos por um objeto de pasta. O valor de cidl fornece o número de itens na consulta e aPidl aponta para uma lista de seus PIDLs.

Como o teste de alguns atributos pode ser demorado, o Windows Explorer normalmente restringe a consulta a um subconjunto dos sinalizadores disponíveis definindo seus valores em rfgInOut. Seu método deve testar apenas os atributos cujos sinalizadores estão definidos em rfgInOut. Deixe os sinalizadores válidos definidos e limpe o restante. Se mais de um item for incluído na consulta, defina apenas os sinalizadores que se aplicam a todos os itens.

Observação

Os atributos devem ser definidos corretamente para que um item seja exibido corretamente. Por exemplo, se um item for uma pasta que contém subpastas, você deverá definir o sinalizador SFGAO_HASSUBFOLDER. Caso contrário, o Windows Explorer não exibirá um + ao lado do ícone do item no modo de exibição em árvore.

 

ParseDisplayName

O método IShellFolder::ParseDisplayName é, em certo sentido, uma imagem espelhada de IShellFolder::GetDisplayNameOf. O uso mais comum desse método é converter o nome de análise de um objeto no PIDL associado. O nome de análise pode se referir a qualquer objeto que esteja abaixo da pasta na hierarquia de namespace. O PIDL retornado é relativo ao objeto de pasta que expõe o método e geralmente não é totalmente qualificado. Em outras palavras, embora o PIDL possa conter várias estruturas SHITEMID, a primeira será a do próprio objeto ou a primeira subpasta no caminho da pasta para o objeto. O chamador terá que acrescentar esse PIDL ao PIDL totalmente qualificado da pasta para obter um PIDL totalmente qualificado para o objeto.

IShellFolder::ParseDisplayName também pode ser chamado para solicitar atributos de um objeto. Como a determinação de todos os atributos aplicáveis pode ser demorada, o chamador definirá apenas os sinalizadores SFGAO_XXX que representam informações nas quais o chamador está interessado. Você deve determinar quais desses atributos são verdadeiros para o objeto e limpar os sinalizadores restantes.

IEnumIDList Interface

Quando o Windows Explorer precisa enumerar os objetos contidos por uma pasta, ele chama IShellFolder::EnumObjects. O objeto pasta deve criar um objeto de enumeração que exponha a interface IEnumIDList e retornar esse ponteiro de interface. O Windows Explorer normalmente usará IEnumIDList para enumerar os PIDLs de todos os objetos contidos pela pasta.

IEnumIDList é uma interface de enumeração OLE padrão e é implementada da maneira usual. Lembre-se, no entanto, de que os PIDLs que você retorna devem ser relativos à pasta e conter apenas a estrutura deSHITEMIDdo objeto e um terminador.

Implementando as interfaces opcionais

Há várias interfaces opcionais do Shell que os objetos de pasta da extensão podem suportar. Muitos deles, como IExtractIcon, permitem que você personalize vários aspetos da maneira como o usuário vê sua extensão. Outros, como IDataObject, permitem que sua extensão ofereça suporte a recursos como arrastar e soltar.

Nenhuma das interfaces opcionais é exposta diretamente por um objeto de pasta. Em vez disso, o Windows Explorer chama um dos dois métodos IShellFolder para solicitar uma interface:

  • O Windows Explorer chama a função IShellFolder::GetUIObjectOf de um objeto da pasta para solicitar uma interface para um dos objetos que ela contém.
  • O Windows Explorer chama o IShellFolder::CreateViewObject de um objeto de pasta para solicitar uma interface para a própria pasta.

Para fornecer as informações, o objeto folder cria um objeto que expõe a interface solicitada e retorna o ponteiro da interface. Em seguida, o Windows Explorer chama essa interface para recuperar as informações necessárias. Esta seção discute as interfaces opcionais mais comumente usadas.

IExtractIcon

O Windows Explorer solicita uma IExtractIcon interface antes de exibir o conteúdo de uma pasta. A interface permite que sua extensão especifique ícones personalizados para os objetos contidos pela pasta. Caso contrário, os ícones de arquivo e pasta padrão serão usados. Para fornecer um ícone personalizado, crie um objeto de extração de ícone que exponha IExtractIcon e retorne um ponteiro para essa interface. Para obter mais discussões, consulte a documentação de referência do IExtractIcon ou Criando manipuladores de ícones.

IContextMenu

Quando um usuário clica com o botão direito do mouse em um objeto, o Windows Explorer solicita um IContextMenu interface. Para fornecer menus de atalho para seus objetos, crie um objeto de manipulador de menu e retorne seu IContextMenu interface.

Os procedimentos para criar um objeto de manipulador de menu são muito semelhantes aos usados para criar uma extensão Shell do manipulador de menu. Para obter detalhes, consulte Criando manipuladores de menu de contexto ou o IContextMenu, IContextMenu2ou IContextMenu3 referência.

IQueryInfo

O Windows Explorer chama o IQueryInfo interface para recuperar uma cadeia de texto de dica de informação.

IDataObject e IDropTarget

Quando seus objetos são exibidos pelo Windows Explorer, um objeto de pasta não tem nenhuma maneira direta de saber quando um usuário está tentando cortar, copiar ou arrastar um objeto. Em vez disso, o Windows Explorer solicita um IDataObject interface. Para permitir que o objeto seja transferido, crie um objeto de dados e retorne um ponteiro para seu IDataObject interface.

Da mesma forma, um usuário pode tentar soltar um objeto de dados em uma representação do Windows Explorer de um de seus objetos, como um ícone ou caminho da barra de endereço. Em seguida, o Windows Explorer solicita um IDropTarget interface. Para permitir que o objeto de dados seja descartado, crie um objeto que exponha um IDropTarget interface e retorne o ponteiro da interface.

Lidar com a transferência de dados é um dos aspetos mais complicados de escrever extensões de namespace. Para obter uma discussão detalhada, consulte Transferindo objetos do shell com arrastar e soltar e a área de transferência.

Trabalhando com a implementação padrão da visualização de pastas do shell

As fontes de dados que usam o objeto de exibição de pasta padrão do Shell (DefView) devem implementar estas interfaces:

Opcionalmente, eles também podem implementar IPersistFolder3.