Implémentation des interfaces d’objet de dossier de base

La procédure d’implémentation d’une extension d’espace de noms est similaire à celle de tout autre objet COM (Component Object Model) in-process. Toutes les extensions doivent prendre en charge trois interfaces principales qui fournissent à Windows Explorer les informations de base nécessaires pour afficher les dossiers de l’extension dans l’arborescence. Toutefois, pour tirer pleinement profit des fonctionnalités de Windows Explorer, votre extension doit également exposer une ou plusieurs interfaces facultatives qui prennent en charge des fonctionnalités plus sophistiquées, telles que les menus contextuels ou le glisser-déplacer, et fournir un affichage des dossiers.

Ce document explique comment implémenter les interfaces primaires et facultatives que Windows Explorer appelle pour obtenir des informations sur le contenu de votre extension. Pour plus d’informations sur l’implémentation d’un affichage de dossiers et la personnalisation de Windows Explorer, consultez Implémentation d’un affichage dossier.

Implémentation et inscription de base

En tant que serveur COM in-process, votre DLL doit exposer plusieurs fonctions et interfaces standard :

Ces fonctions et interfaces sont implémentées de la même manière que pour la plupart des autres objets COM. Pour plus d’informations, consultez la documentation COM.

Inscription d’une extension

Comme pour tous les objets COM, vous devez créer un GUID d’identificateur de classe (CLSID) pour votre extension. Inscrivez l’objet en créant une sous-clé de HKEY_CLASSES_ROOT\CLSID nommé pour le CLSID de votre extension. La DLL doit être inscrite en tant que serveur in-process et doit spécifier le modèle de thread d’appartement. Vous pouvez personnaliser le comportement du dossier racine d’une extension en ajoutant diverses sous-clés et valeurs à la clé CLSID de l’extension.

Plusieurs de ces valeurs s’appliquent uniquement aux extensions avec des points de jonction virtuels. Ces valeurs ne s’appliquent pas aux extensions dont les points de jonction sont des dossiers de système de fichiers. Pour plus d’informations, consultez Spécification de l’emplacement d’une extension d’espace de noms. Pour modifier le comportement d’une extension avec un point de jonction virtuel, ajoutez une ou plusieurs des valeurs suivantes à la clé CLSID de l’extension :

  • WantsFORPARSING. Le nom d’analyse d’une extension avec un point de jonction virtuel a normalement la forme ::{GUID}. Les extensions de ce type contiennent normalement des éléments virtuels. Toutefois, certaines extensions, telles que Mes documents, correspondent en fait à des dossiers de système de fichiers, même s’ils ont des points de jonction virtuels. Si votre extension représente ainsi des objets de système de fichiers, vous pouvez définir la valeur WantsFORPARSING. Windows Explorer demande ensuite le nom d’analyse de votre dossier racine en appelant la méthode IShellFolder::GetDisplayNameOf de l’objet de dossier avec uFlags défini sur SHGDN_FORPARSING et pidl défini sur un pointeur vide unique vers une liste d’identificateur d’élément (PIDL). Un CODE PIDL vide contient uniquement un point de terminaison. Votre méthode doit ensuite retourner le nom d’analyse ::{GUID} du dossier racine.
  • HideFolderVerbs. Les verbes inscrits sous HKEY_CLASSES_ROOT\Dossier sont normalement associés à toutes les extensions. Ils apparaissent dans le menu contextuel de l’extension et peuvent être appelés par ShellExecute. Pour empêcher l’un de ces verbes d’être associé à votre extension, définissez la valeur HideFolderVerbs.
  • HideAsDelete. Si un utilisateur tente de supprimer votre extension, Windows Explorer la masquera à la place.
  • HideAsDeletePerUser. Cette valeur a le même effet que HideAsDelete, mais par utilisateur. L’extension est masquée uniquement pour les utilisateurs qui ont tenté de la supprimer. L’extension est visible par tous les autres utilisateurs.
  • QueryForOverlay. Définissez cette valeur pour indiquer que l’icône du dossier racine peut avoir une superposition d’icônes. L’objet folder doit prendre en charge l’interface IShellIconOverlay . Avant que Windows Explorer affiche l’icône du dossier racine, il demande une icône de superposition en appelant l’une des deux méthodes IShellIconOverlay avec pidlItem défini sur un PIDL vide.

Les valeurs et sous-clés restantes s’appliquent à toutes les extensions :

  • Pour spécifier le nom d’affichage du dossier du point de jonction de l’extension, définissez la valeur par défaut de la sous-clé CLSID de l’extension sur une chaîne appropriée.
  • Lorsque le curseur pointe sur un dossier, une info-bulle s’affiche généralement qui décrit le contenu du dossier. Pour fournir une info-bulle pour le dossier racine de votre extension, créez une REG_SZ valeur InfoTip pour la clé CLSID de l’extension et définissez-la sur une chaîne appropriée.
  • Pour spécifier une icône personnalisée pour le dossier racine de votre extension, créez une sous-clé de la sous-clé CLSID de l’extension nommée DefaultIcon. Définissez la valeur par défaut de DefaultIcon sur une valeur REG_SZ contenant le nom du fichier contenant l’icône, suivie d’une virgule, suivie d’un signe moins, suivie de l’index de l’icône dans ce fichier.
  • Par défaut, le menu contextuel du dossier racine de votre extension contient les éléments définis sous HKEY_CLASSES_ROOT\Folder. Les éléments Supprimer, Renommer et Propriétés sont ajoutés si vous avez défini les indicateurs de SFGAO_XXX appropriés. Vous pouvez ajouter d’autres éléments au menu contextuel du dossier racine ou remplacer des éléments existants, comme vous le feriez pour un type de fichier. Créez une sous-clé Shell sous la clé CLSID de l’extension et définissez des commandes comme décrit dans Extension des menus contextuels.
  • Si vous avez besoin d’une méthode plus flexible pour gérer le menu contextuel du dossier racine, vous pouvez implémenter un gestionnaire de menus contextuels. Pour inscrire le gestionnaire de menus contextuels, créez une clé ShellEx sous la clé CLSID de l’extension. Inscrivez le CLSID du gestionnaire comme vous le feriez pour un gestionnaire de gestionnaires de création d’extensions shell conventionnels.
  • Pour ajouter une page à la feuille de propriétés du dossier racine, attribuez au dossier l’attribut SFGAO_HASPROPSHEET et implémentez un gestionnaire de feuille de propriétés. Pour inscrire le gestionnaire de feuilles de propriétés, créez une clé ShellEx sous la clé CLSID de l’extension. Inscrivez le CLSID du gestionnaire comme vous le feriez pour un gestionnaire de gestionnaires de création d’extensions shell conventionnels.
  • Pour spécifier les attributs du dossier racine, ajoutez une sous-clé ShellFolder à la sous-clé CLSID de l’extension. Créez une valeur Attributes et définissez-la sur la combinaison appropriée d’indicateurs SFGAO_XXX .

Le tableau suivant répertorie certains attributs couramment utilisés pour les dossiers racines.

Indicateur Valeur Description
SFGAO_FOLDER 0x20000000 Le dossier racine de l’extension contient un ou plusieurs éléments.
SFGAO_HASSUBFOLDER 0x80000000 Le dossier racine de l’extension contient un ou plusieurs sous-dossiers. Windows Explorer place un signe plus ( + ) en regard de l’icône de dossier.
SFGAO_CANDELETE 0x00000020 Le dossier racine de l’extension peut être supprimé par l’utilisateur. Le menu contextuel du dossier comportera un élément Supprimer . Cet indicateur doit être défini pour les points de jonction placés sous l’un des dossiers virtuels.
SFGAO_CANRENAME 0x00000010 Le dossier racine de l’extension peut être renommé par l’utilisateur. Le menu contextuel du dossier contient un élément Renommer .
SFGAO_HASPROPSHEET 0x00000040 Le dossier racine de l’extension comporte une feuille de propriétés Propriétés . Le menu contextuel du dossier contient un élément Propriétés . Pour fournir la feuille de propriétés, vous devez implémenter un gestionnaire de feuille de propriétés. Inscrivez le gestionnaire sous la clé CLSID de l’extension, comme indiqué précédemment.

 

L’exemple suivant montre l’entrée de Registre CLSID pour une extension avec le nom complet MyExtension. L’extension a une icône personnalisée contenue dans la DLL de l’extension avec un index de 1. Les attributs SFGAO_FOLDER, SFGAO_HASSUBFOLDER et SFGAO_CANDELETE sont définis.

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

Gestion des PIDL

Chaque élément de l’espace de noms Shell doit avoir un PIDL unique. Windows Explorer affecte un PIDL à votre dossier racine et transmet la valeur à votre extension lors de l’initialisation. Votre extension est ensuite chargée d’affecter un PIDL correctement construit à chacun de ses objets et de fournir ces PIDLs à Windows Explorer sur demande. Lorsque l’interpréteur de commandes utilise un PIDL pour identifier l’un des objets de votre extension, votre extension doit être en mesure d’interpréter le PIDL et d’identifier l’objet particulier. Votre extension doit également affecter un nom d’affichage et un nom d’analyse à chaque objet. Étant donné que les FICHIERS PIDL sont utilisés par pratiquement toutes les interfaces de dossier, les extensions implémentent généralement un seul gestionnaire PIDL pour gérer toutes ces tâches.

Le terme PIDL est l’abréviation d’une structure ITEMIDLIST ou d’un pointeur vers une telle structure, selon le contexte. Comme déclaré, une structure ITEMIDLIST a un seul membre, une structure SHITEMID . La structure ITEMIDLIST d’un objet est en fait un tableau empaqueté de deux structures SHITEMID ou plus. L’ordre de ces structures définit un chemin d’accès via l’espace de noms, de la même façon que c:\MyDirectory\MyFile définit un chemin via le système de fichiers. En règle générale, le PIDL d’un objet se compose d’une série de structures SHITEMID qui correspondent aux dossiers qui définissent le chemin d’accès de l’espace de noms, suivis de la structure SHITEMID de l’objet, suivi d’un terminateur.

Le terminateur est une structure SHITEMID , avec le membre cb défini sur NULL. Le terminateur est nécessaire, car le nombre de structures SHITEMID dans le PIDL d’un objet dépend de l’emplacement de l’objet dans l’espace de noms Shell et du point de départ du chemin. En outre, la taille des différentes structures SHITEMID peut varier. Lorsque vous recevez un PIDL, vous n’avez aucun moyen simple de déterminer sa taille ou même le nombre total de structures SHITEMID . Au lieu de cela, vous devez « parcourir » le tableau empaqueté, structure par structure, jusqu’à ce que vous atteigniez le terminateur.

Pour créer un PIDL, votre application doit :

  1. Créez une structure SHITEMID pour chacun de ses objets.
  2. Assemblez les structures SHITEMID pertinentes dans un PIDL.

Création d’une structure SHITEMID

La structure SHITEMID d’un objet identifie de manière unique l’objet dans son dossier. En fait, un type de PIDL utilisé par de nombreuses méthodes IShellFolder se compose uniquement de la structure SHITEMID de l’objet, suivie d’un terminateur. La définition d’une structure SHITEMID est la suivante :

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

Le membre abID est l’identificateur de l’objet. Étant donné que la longueur d’abID n’est pas définie et peut varier, le membre cb est défini sur la taille de la structure SHITEMID , en octets.

Étant donné que ni la longueur ni le contenu d’abID ne sont standardisés, vous pouvez utiliser n’importe quel schéma pour affecter des valeurs abID à vos objets. La seule exigence est que vous ne pouvez pas avoir deux objets dans le même dossier avec des valeurs identiques. Toutefois, pour des raisons de performances, votre structure SHITEMID doit être alignée sur DWORD. En d’autres termes, vous devez construire vos valeurs abID de telle sorte que cb soit un multiple intégral de 4.

En règle générale, abID pointe vers une structure définie par l’extension. En plus de l’ID de l’objet, cette structure est souvent utilisée pour contenir diverses informations connexes, telles que le type ou les attributs de l’objet. Les objets de dossier de votre extension peuvent ensuite extraire rapidement les informations du PIDL au lieu d’avoir à les interroger.

Notes

L’un des aspects les plus importants de la conception d’une structure de données pour un PIDL est de rendre la structure persistante et transportable. Dans le contexte des PIDL, la signification de ces termes est :

  • Persistant. Le système place fréquemment des fichiers PIDL dans différents types de stockage à long terme, tels que les fichiers de raccourcis. Il peut ensuite récupérer ces PIDLs à partir du stockage ultérieurement, éventuellement après le redémarrage du système. Un PIDL qui a été récupéré à partir du stockage doit toujours être valide et significatif pour votre extension. Cette exigence signifie, par instance, que vous ne devez pas utiliser de pointeurs ou de handles dans votre structure PIDL. Les fichiers PIDL contenant ce type de données n’auront normalement aucun sens lorsque le système les récupérera ultérieurement à partir du stockage.
  • Transportable. Un PIDL doit rester significatif lorsqu’il est transporté d’un ordinateur à un autre. Par exemple, un fichier PIDL peut être écrit dans un fichier de raccourcis, copié sur une disquette et transporté vers un autre ordinateur. Ce PIDL doit toujours être significatif pour votre extension exécutée sur le deuxième ordinateur. Pour instance, pour vous assurer que vos PIDL sont transportables, utilisez explicitement des caractères ANSI ou Unicode. Évitez les types de données tels que TCHAR ou LPTSTR. Si vous utilisez ces types de données, un PIDL créé sur un ordinateur exécutant une version Unicode de votre extension ne sera pas lisible par une version ANSI de cette extension exécutée sur un autre ordinateur.

 

La déclaration suivante montre un exemple simple de structure de données.

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

Le membre cb est défini sur la taille de la structure MYPIDLDATA . Ce membre fait de MYPIDLDATA une structure SHITEMID valide, en soi. Les autres membres sont équivalents au membre abID d’une structure SHITEMID et contiennent des données privées. Le membre dwType est une valeur définie par l’extension qui indique le type d’objet. Pour cet exemple, dwType est défini sur TRUE pour les dossiers et FALSE dans le cas contraire. Ce membre vous permet, par instance, de déterminer rapidement si l’objet est un dossier ou non. Le membre wszDisplayName contient le nom d’affichage de l’objet. Étant donné que vous ne devez pas affecter le même nom d’affichage à deux objets différents dans le même dossier, le nom complet sert également d’ID d’objet. Dans cet exemple, wszDisplayName est défini sur 40 caractères pour garantir que la structure SHITEMID sera alignée sur DWORD. Pour limiter la taille de vos PIDL, vous pouvez utiliser un tableau de caractères de longueur variable et ajuster la valeur de cb en conséquence. Placez la chaîne d’affichage avec suffisamment de caractères « \0 » pour maintenir l’alignement DWORD de la structure. D’autres membres qui peuvent être utiles à placer dans la structure incluent la taille, les attributs ou le nom d’analyse de l’objet.

Construction d’un PIDL

Une fois que vous avez défini des structures SHITEMID pour vos objets, vous pouvez les utiliser pour construire un PIDL. Les PIDL peuvent être construits à diverses fins, mais la plupart des tâches utilisent l’un des deux types de PIDL. Le piDL le plus simple, un seul niveau, identifie l’objet par rapport à son dossier parent. Ce type de PIDL est utilisé par de nombreuses méthodes IShellFolder . Un CODE PIDL de niveau unique contient la structure SHITEMID de l’objet, suivie d’un terminateur. Un PIDL complet définit un chemin d’accès à travers la hiérarchie d’espace de noms du bureau vers l’objet . Ce type de PIDL commence sur le bureau et contient une structure SHITEMID pour chaque dossier dans le chemin d’accès, suivie de l’objet et de la marque de fin. Un PIDL complet identifie de manière unique l’objet dans l’espace de noms Shell entier.

La façon la plus simple de construire un PIDL consiste à travailler directement avec la structure ITEMIDLIST elle-même. Créez une structure ITEMIDLIST , mais allouez suffisamment de mémoire pour contenir toutes les structures SHITEMID . L’adresse de cette structure pointe vers la structure SHITEMID initiale. Définissez des valeurs pour les membres de cette structure initiale, puis ajoutez autant de structures SHITEMID supplémentaires que nécessaire, dans l’ordre approprié. La procédure suivante explique comment créer un fichier PIDL à un seul niveau. Il contient deux structures SHITEMID : une structure MYPIDLDATA suivie d’un terminateur :

  1. Utilisez la fonction CoTaskMemAlloc pour allouer de la mémoire pour le PIDL. Allouez suffisamment de mémoire pour vos données privées, ainsi qu’un USHORT (deux octets) pour le terminateur. Castez le résultat en LPMYPIDLDATA.
  2. Définissez le membre cb de la première structure MYPIDLDATA sur la taille de cette structure. Pour cet exemple, vous devez définir cb sur sizeof(MYPIDLDATA). Si vous souhaitez utiliser une structure de longueur variable, vous devez calculer la valeur de cb.
  3. Affectez les valeurs appropriées aux membres de données privés.
  4. Calculez l’adresse de la structure SHITEMID suivante. Castez l’adresse de la structure MYPIDLDATA actuelle en LPBYTE et ajoutez cette valeur à la valeur de cb déterminée à l’étape 3.
  5. Dans ce cas, la structure SHITEMID suivante est le terminateur. Définissez le membre cb de la structure sur zéro.

Pour les FICHIERS PIDL plus longs, allouez suffisamment de mémoire et répétez les étapes 3 à 5 pour chaque structure SHITEMID supplémentaire.

L’exemple de fonction suivant prend le type et le nom d’affichage d’un objet et retourne le code PIDL de l’objet à un seul niveau. La fonction suppose que le nom d’affichage, y compris son caractère null de fin, ne dépasse pas le nombre de caractères déclarés pour la structure MYPIDLDATA . Si cette hypothèse s’avère erronée, la fonction StringCbCopyW tronquera le nom d’affichage. La variable g_pMalloc est un pointeur IMalloc créé ailleurs et stocké dans une variable globale.

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;

Un PIDL complet doit avoir des structures SHITEMID pour chaque objet, du bureau à votre objet. Votre extension reçoit un PIDL complet pour votre dossier racine lorsque l’interpréteur de commandes appelle IPersistFolder::Initialize. Pour construire un PIDL complet pour un objet, prenez le PIDL que l’interpréteur de commandes a attribué à votre dossier racine, puis ajoutez les structures SHITEMID nécessaires pour vous emmener du dossier racine à l’objet.

Interprétation des LISTES DE CONTRÔLE DL

Lorsque l’interpréteur de commandes ou une application appelle l’une des interfaces de votre extension pour demander des informations sur un objet, elle identifie généralement l’objet par un PIDL. Certaines méthodes, telles que IShellFolder::GetUIObjectOf, utilisent des PIDL qui sont relatifs au dossier parent et sont simples à interpréter. Toutefois, votre extension recevra probablement également des PIDL complets. Votre gestionnaire PIDL doit ensuite déterminer les objets auxquels PIDL fait référence.

Ce qui complique la tâche d’associer un objet à un PIDL complet, c’est qu’une ou plusieurs des structures SHITEMID initiales dans le PIDL peuvent appartenir à des objets qui se trouvent en dehors de votre extension dans l’espace de noms Shell. Vous n’avez aucun moyen d’interpréter la signification du membre abID de ces structures. Ce que votre extension doit faire est de « parcourir » la liste des structures SHITEMID , jusqu’à ce que vous atteignez la structure qui correspond à votre dossier racine. À partir de là, vous saurez comment interpréter les informations dans les structures SHITEMID .

Pour parcourir le PIDL, prenez la première valeur cb et ajoutez-la à l’adresse du PIDL pour avancer le pointeur vers le début de la structure SHITEMID suivante. Il pointe ensuite vers le membre cb de cette structure, que vous pouvez utiliser pour avancer le pointeur vers le début de la structure SHITEMID suivante, et ainsi de suite. Chaque fois que vous avancez le pointeur, examinez la structure SHITEMID pour déterminer si vous avez atteint la racine de l’espace de noms de votre extension.

Implémentation des interfaces principales

Comme pour tous les objets COM, l’implémentation d’une extension consiste en grande partie à implémenter une collection d’interfaces. Cette section décrit les trois interfaces principales qui doivent être implémentées par toutes les extensions. Ils sont utilisés pour l’initialisation et pour fournir aux Explorer Windows des informations de base sur le contenu de l’extension. Ces interfaces, ainsi qu’une vue de dossier, sont tout ce qui est requis pour une extension fonctionnelle. Toutefois, pour exploiter pleinement les fonctionnalités de Windows Explorer, la plupart des extensions implémentent également une ou plusieurs interfaces facultatives.

IPersistFolder, interface

L’interface IPersistFolder est appelée pour initialiser un nouvel objet de dossier. La méthode IPersistFolder::Initialize affecte un PIDL complet au nouvel objet. Stockez ce PIDL pour une utilisation ultérieure. Par instance, un objet dossier doit utiliser ce PIDL pour construire des PIDL complets pour les enfants de l’objet. Le créateur de l’objet folder peut également appeler IPersist::GetClassID pour demander le CLSID de l’objet.

En règle générale, un objet de dossier est créé et initialisé par la méthode IShellFolder::BindToObject de son dossier parent. Toutefois, lorsqu’un utilisateur accède à votre extension, Windows Explorer crée et initialise l’objet de dossier racine de l’extension. Le PIDL que l’objet de dossier racine reçoit via IPersistFolder::Initialize contient le chemin d’accès du bureau au dossier racine dont vous aurez besoin pour construire des FICHIERS PIDL complets pour votre extension.

IShellFolder, interface

L’interpréteur de commandes traite une extension comme une collection hiérarchique d’objets de dossier. L’interface IShellFolder est le cœur de toute implémentation d’extension. Il représente un objet de dossier et fournit à Windows Explorer une grande partie des informations nécessaires pour afficher le contenu du dossier.

IShellFolder est généralement la seule interface de dossier autre que IPersistFolder qui est directement exposée par un objet de dossier. Bien que Windows Explorer utilise une variété d’interfaces obligatoires et facultatives pour obtenir des informations sur le contenu du dossier, il obtient des pointeurs vers ces interfaces via IShellFolder.

Windows Explorer obtient le CLSID du dossier racine de votre extension de différentes manières. Pour plus d’informations, consultez Spécification de l’emplacement d’une extension d’espace de noms ou Affichage d’une vue Self-Contained d’une extension d’espace de noms. Windows Explorer utilise ensuite ce CLSID pour créer et initialiser un instance du dossier racine et une requête pour une interface IShellFolder. Votre extension crée un objet dossier pour représenter le dossier racine et retourne l’interface IShellFolder de l’objet. La majeure partie de l’interaction entre votre extension et Windows Explorer s’effectue ensuite via IShellFolder. Windows Explorer appelle IShellFolder pour :

  • Demandez un objet qui peut énumérer le contenu du dossier racine.
  • Obtenez différents types d’informations sur le contenu du dossier racine.
  • Demandez un objet qui expose l’une des interfaces facultatives. Ces interfaces peuvent ensuite être interrogées pour obtenir des informations supplémentaires, telles que des icônes ou des menus contextuels.
  • Demandez un objet de dossier qui représente un sous-dossier du dossier racine.

Lorsqu’un utilisateur ouvre un sous-dossier du dossier racine, Windows Explorer appelle IShellFolder::BindToObject. Votre extension crée et initialise un nouvel objet de dossier pour représenter le sous-dossier et retourne son interface IShellFolder . Windows Explorer appelle ensuite cette interface pour différents types d’informations, et ainsi de suite jusqu’à ce que l’utilisateur décide de naviguer ailleurs dans l’espace de noms Shell ou de fermer Windows Explorer.

Le reste de cette section décrit brièvement les méthodes IShellFolder les plus importantes et la façon de les implémenter.

EnumObjects

Avant d’afficher le contenu d’un dossier dans l’arborescence, les Explorer Windows doivent d’abord déterminer ce que contient le dossier en appelant la méthode IShellFolder::EnumObjects. Cette méthode crée un objet d’énumération OLE standard qui expose une interface IEnumIDList et retourne ce pointeur d’interface. L’interface IEnumIDList permet aux Explorer Windows d’obtenir les codes PIN de tous les objets contenus dans le dossier. Ces FICHIERS PIDL sont ensuite utilisés pour obtenir des informations sur les objets contenus dans le dossier. Pour plus d’informations, consultez Interface IEnumIDList.

Notes

La méthode IEnumIDList::Next ne doit retourner que les FICHIERS PIDL relatifs au dossier parent. Le CODE PIDL doit contenir uniquement la structure SHITEMID de l’objet, suivie d’une terminaison.

 

CreateViewObject

Avant que le contenu d’un dossier ne soit affiché, Windows Explorer appelle cette méthode pour demander un pointeur vers une interface IShellView. Cette interface est utilisée par les Explorer Windows pour gérer l’affichage des dossiers. Créez un objet d’affichage de dossier et retournez son interface IShellView .

La méthode IShellFolder::CreateViewObject est également appelée pour demander l’une des interfaces facultatives, telles que IContextMenu, pour le dossier lui-même. Votre implémentation de cette méthode doit créer un objet qui expose l’interface demandée et retourne le pointeur d’interface. Si Windows Explorer a besoin d’une interface facultative pour l’un des objets contenus dans le dossier, il appelle IShellFolder::GetUIObjectOf.

GetUIObjectOf

Bien que des informations de base sur le contenu d’un dossier soient disponibles via les méthodes IShellFolder, votre extension peut également fournir à Windows Explorer différents types d’informations supplémentaires. Par instance, vous pouvez spécifier des icônes pour le contenu d’un dossier ou le menu contextuel d’un objet. Windows Explorer appelle la méthode IShellFolder::GetUIObjectOf pour tenter de récupérer des informations supplémentaires sur un objet contenu dans un dossier. Windows Explorer spécifie l’objet pour lequel il souhaite obtenir les informations et l’IID de l’interface appropriée. L’objet folder crée ensuite un objet qui expose l’interface demandée et retourne le pointeur d’interface.

Si votre extension permet aux utilisateurs de transférer des objets avec le glisser-déplacer ou le Presse-papiers, Windows Explorer appelle IShellFolder::GetUIObjectOf pour demander une interface IDataObject ou IDropTarget. Pour plus d’informations, consultez Transfert d’objets shell avec glisser-déplacer et le Presse-papiers.

Windows Explorer appelle IShellFolder::CreateViewObject lorsqu’il souhaite obtenir le même type d’informations sur le dossier lui-même.

BindToObject

Windows Explorer appelle la méthode IShellFolder::BindToObject lorsqu’un utilisateur tente d’ouvrir l’un des sous-dossiers de votre extension. Si riid a la valeur IID_IShellFolder, vous devez créer et initialiser un objet dossier qui représente le sous-dossier et renvoyer l’interface IShellFolder de l’objet.

Notes

Actuellement, Windows Explorer appelle cette méthode uniquement pour demander une interface IShellFolder. Toutefois, ne partez pas du principe que ce sera toujours le cas. Vous devez toujours case activée la valeur de riid avant de continuer.

 

GetDisplayNameOf

Windows Explorer appelle la méthode IShellFolder::GetDisplayNameOf pour convertir le PIDL de l’un des objets du dossier en nom. Ce PIDL doit être relatif au dossier parent de l’objet. En d’autres termes, il doit contenir une seule structure SHITEMID non NULL. Étant donné qu’il existe plusieurs façons possibles de nommer des objets, Windows Explorer spécifie le type de nom en définissant un ou plusieurs indicateurs SHGDNF dans le paramètre uFlags. L’une des deux valeurs, SHGDN_NORMAL ou SHGDN_INFOLDER, sera définie pour spécifier si le nom doit être relatif au dossier ou relatif au bureau. L’une des trois autres valeurs, SHGDN_FOREDITING, SHGDN_FORADDRESSBAR ou SHGDN_FORPARSING, peut être définie pour spécifier le nom utilisé.

Vous devez retourner le nom sous la forme d’une structure STRRET . Si SHGDN_FOREDITING, SHGDN_FORADDRESSBAR et SHGDN_FORPARSING ne sont pas définis, retournez le nom d’affichage de l’objet. Si l’indicateur SHGDN_FORPARSING est défini, Windows Explorer demande un nom d’analyse. Les noms d’analyse sont passés à IShellFolder::P arseDisplayName pour obtenir le PIDL d’un objet, même s’il peut se trouver à un ou plusieurs niveaux sous le dossier actif dans la hiérarchie d’espaces de noms. Par exemple, le nom d’analyse d’un objet de système de fichiers est son chemin d’accès. Vous pouvez passer le chemin d’accès complet de n’importe quel objet du système de fichiers à la méthode IShellFolder::P arseDisplayName du bureau, qui retourne le PIDL complet de l’objet.

Bien que les noms d’analyse soient des chaînes de texte, ils n’ont pas nécessairement besoin d’inclure le nom d’affichage. Vous devez attribuer des noms d’analyse en fonction de ce qui fonctionnera le plus efficacement lorsque IShellFolder::P arseDisplayName est appelé. Par instance, la plupart des dossiers virtuels de l’interpréteur de commandes ne font pas partie du système de fichiers et n’ont pas de chemin d’accès complet. Au lieu de cela, un GUID est attribué à chaque dossier et le nom de l’analyse prend la forme ::{GUID}. Quel que soit le schéma que vous utilisez, il doit être en mesure d’effectuer un « aller-retour » fiable. Par instance, si un appelant transmet un nom d’analyse à IShellFolder::P arseDisplayName pour récupérer le PIDL d’un objet, puis passe ce PIDL à IShellFolder::GetDisplayNameOf avec l’indicateur SHGDN_FORPARSING défini, l’appelant doit récupérer le nom d’analyse d’origine.

GetAttributesOf

Windows Explorer appelle la méthode IShellFolder::GetAttributesOf pour déterminer les attributs d’un ou plusieurs éléments contenus par un objet de dossier. La valeur cidl donne le nombre d’éléments dans la requête, et aPidl pointe vers une liste de leurs PIDL.

Étant donné que le test de certains attributs peut prendre du temps, Windows Explorer limite généralement la requête à un sous-ensemble des indicateurs disponibles en définissant leurs valeurs dans rfgInOut. Votre méthode doit tester uniquement les attributs dont les indicateurs sont définis dans rfgInOut. Laissez les indicateurs valides définis et effacez le reste. Si plusieurs éléments sont inclus dans la requête, définissez uniquement les indicateurs qui s’appliquent à tous les éléments.

Notes

Les attributs doivent être correctement définis pour qu’un élément soit correctement affiché. Par instance, si un élément est un dossier qui contient des sous-dossiers, vous devez définir l’indicateur SFGAO_HASSUBFOLDER. Sinon, windows Explorer n’affiche pas de + en regard de l’icône de l’élément dans l’arborescence.

 

ParseDisplayName

La méthode IShellFolder::P arseDisplayName est en quelque sorte une image miroir de IShellFolder::GetDisplayNameOf. L’utilisation la plus courante de cette méthode consiste à convertir le nom d’analyse d’un objet en PIDL associé. Le nom de l’analyse peut faire référence à n’importe quel objet qui se trouve sous le dossier dans la hiérarchie de l’espace de noms. Le PIDL retourné est relatif à l’objet folder qui expose la méthode et n’est généralement pas entièrement qualifié. En d’autres termes, bien que le PIDL puisse contenir plusieurs structures SHITEMID , la première sera celle de l’objet lui-même ou le premier sous-dossier dans le chemin d’accès du dossier à l’objet. L’appelant doit ajouter ce PIDL au PIDL complet du dossier pour obtenir un PIDL complet pour l’objet.

IShellFolder::P arseDisplayName peut également être appelé pour demander les attributs d’un objet. Étant donné que la détermination de tous les attributs applicables peut prendre du temps, l’appelant définit uniquement les indicateurs SFGAO_XXX qui représentent les informations qui intéressent l’appelant. Vous devez déterminer lequel de ces attributs est vrai pour l’objet et effacer les indicateurs restants.

IEnumIDList, interface

Lorsque Windows Explorer doit énumérer les objets contenus dans un dossier, il appelle IShellFolder::EnumObjects. L’objet folder doit créer un objet d’énumération qui expose l’interface IEnumIDList et retourner ce pointeur d’interface. Les Explorer Windows utilisent généralement IEnumIDList pour énumérer les LISTES DE PROPRIÉTÉ PERSONNELLE de tous les objets contenus dans le dossier.

IEnumIDList est une interface d’énumération OLE standard qui est implémentée de la manière habituelle. N’oubliez pas, toutefois, que les codes PIDL que vous retournez doivent être relatifs au dossier et contenir uniquement la structure SHITEMID de l’objet et un point de terminaison.

Implémentation des interfaces facultatives

Il existe un certain nombre d’interfaces Shell facultatives que les objets de dossier de votre extension peuvent prendre en charge. La plupart d’entre eux, comme IExtractIcon, vous permettent de personnaliser différents aspects de la façon dont l’utilisateur perçoit votre extension. D’autres, comme IDataObject, autorisent votre extension à prendre en charge des fonctionnalités telles que le glisser-déplacer.

Aucune des interfaces facultatives n’est exposée directement par un objet de dossier. Au lieu de cela, Windows Explorer appelle l’une des deux méthodes IShellFolder pour demander une interface :

Pour fournir les informations, l’objet dossier crée un objet qui expose l’interface demandée et retourne le pointeur d’interface. Windows Explorer appelle ensuite cette interface pour récupérer les informations nécessaires. Cette section décrit les interfaces facultatives les plus couramment utilisées.

IExtractIcon

Windows Explorer demande une interface IExtractIcon avant d’afficher le contenu d’un dossier. L’interface permet à votre extension de spécifier des icônes personnalisées pour les objets contenus dans le dossier. Dans le cas contraire, les icônes de fichier et de dossier standard seront utilisées. Pour fournir une icône personnalisée, créez un objet d’extraction d’icône qui expose IExtractIcon et retournez un pointeur vers cette interface. Pour plus d’informations, consultez la documentation de référence IExtractIcon ou Création de gestionnaires d’icônes.

IContextMenu

Lorsqu’un utilisateur clique avec le bouton droit sur un objet, Windows Explorer demande une interface IContextMenu. Pour fournir des menus contextuels pour vos objets, créez un objet gestionnaire de menus et retournez son interface IContextMenu .

Les procédures de création d’un objet gestionnaire de menus sont très similaires à celles utilisées pour créer une extension Shell de gestionnaire de menus. Pour plus d’informations, consultez Création de gestionnaires de menus contextuels ou référence IContextMenu, IContextMenu2 ou IContextMenu3 .

IQueryInfo

Windows Explorer appelle l’interface IQueryInfo pour récupérer une chaîne de texte d’info-bulle.

IDataObject et IDropTarget

Lorsque vos objets sont affichés par Windows Explorer, un objet de dossier n’a pas de moyen direct de savoir quand un utilisateur tente de couper, copier ou faire glisser un objet. Au lieu de cela, Windows Explorer demande une interface IDataObject. Pour autoriser le transfert de l’objet, créez un objet de données et retournez un pointeur vers son interface IDataObject .

De même, un utilisateur peut tenter de supprimer un objet de données sur une représentation windows Explorer d’un de vos objets, comme une icône ou un chemin d’accès de barre d’adresse. Windows Explorer demande ensuite une interface IDropTarget. Pour autoriser la suppression de l’objet de données, créez un objet qui expose une interface IDropTarget et retournez le pointeur d’interface.

La gestion du transfert de données est l’un des aspects les plus délicats de l’écriture d’extensions d’espace de noms. Pour une discussion détaillée, consultez Transfert d’objets shell avec glisser-déplacer et le Presse-papiers.

Utilisation de l’implémentation de l’affichage de dossiers shell par défaut

Les sources de données qui utilisent l’objet d’affichage de dossiers Shell par défaut (DefView) doivent implémenter les interfaces suivantes :

Éventuellement, ils peuvent également implémenter IPersistFolder3.