Implementación de las interfaces básicas de objetos de carpeta
El procedimiento para implementar una extensión de espacio de nombres es similar al de cualquier otro objeto del Modelo de Objetos Componentes (COM) en proceso. Todas las extensiones deben ser compatibles con tres interfaces principales que proporcionan al Windows Explorer la información básica necesaria para mostrar las carpetas de la extensión en la vista de árbol. Sin embargo, para hacer un uso completo de las capacidades del Explorador de Windows, su extensión también debe exponer una o más interfaces opcionales que soporten características más sofisticadas, como menús de acceso directo o arrastrar y soltar, y proporcionar una vista de carpetas.
Este documento trata sobre cómo implementar las interfaces primarias y opcionales a las que el Explorador de Windows llama para obtener información sobre el contenido de su extensión. Para saber cómo implementar una vista de carpetas y cómo personalizar el Explorador de Windows, consulte Implementación de una vista de carpetas.
- Implantación básica y registro
- Gestión de los PIDL
- Implementación de las interfaces primarias
- Implementación de las interfaces opcionales
- Trabajar con la implementación predeterminada de la vista de carpetas de Shell
Implantación básica y registro
Como servidor COM en proceso, su DLL debe exponer varias funciones e interfaces estándar:
Estas funciones e interfaces se implementan del mismo modo que la mayoría de los demás objetos COM. Para más información, consulte la documentación de COM.
Registro de una extensión
Como con todos los objetos COM, debe crear un identificador de clase (CLSID) GUID para su extensión. Registre el objeto creando una subclave de HKEY_CLASSES_ROOT\CLSID con el nombre del CLSID de su extensión. La DLL debe registrarse como servidor en proceso y debe especificar el modelo de subprocesamiento del apartamento. Puede personalizar el comportamiento de la carpeta raíz de una extensión añadiendo diversas subclaves y valores a la clave CLSID de la extensión.
Varios de estos valores sólo se aplican a las extensiones con puntos de unión virtuales. Estos valores no se aplican a las extensiones cuyos puntos de unión son carpetas del sistema de archivos. Para más información, consulte Especificación de la ubicación de una extensión de espacio de nombres. Para modificar el comportamiento de una extensión con un punto de unión virtual, añada uno o varios de los siguientes valores a la clave CLSID de la extensión:
- WantsFORPARSING. El nombre de análisis sintáctico de una extensión con un punto de unión virtual tendrá normalmente la forma ::{GUID}. Las extensiones de este tipo suelen contener elementos virtuales. Sin embargo, algunas extensiones, como Mis Documentos, corresponden en realidad a carpetas del sistema de archivos, aunque tengan puntos de unión virtuales. Si su extensión representa objetos del sistema de ficheros de esta forma, puede establecer el valor WantsFORPARSING. A continuación, el Explorador de Windows solicitará el nombre de análisis de la carpeta raíz llamando al objeto de carpeta IShellFolder::GetDisplayNameOf método con uFlags establecer para SHGDN_FORPARSING y pidl se establece en un único puntero vacío a una lista de identificadores de elementos (PIDL). Un PIDL vacío sólo contiene un terminador. El método debería devolver la carpeta raíz de ::{GUID} nombre de análisis sintáctico.
- HideFolderVerbs. Los verbos registrados en HKEY_CLASSES_ROOT\Carpeta normalmente están asociadas a todas las extensiones. Aparecen en el menú contextual de la extensión y pueden invocarse mediante ShellExecute. Para evitar que cualquiera de estos verbos se asocie a su extensión, establezca el valor HideFolderVerbs.
- HideAsDelete. Si un usuario intenta eliminar su extensión, el Explorador de Windows la ocultará.
- HideAsDeletePerUser. Este valor tiene el mismo efecto que HideAsDelete pero por usuario. La extensión está oculta sólo para aquellos usuarios que han intentado eliminarla. La extensión es visible para todos los demás usuarios.
- QueryForOverlay. Establezca este valor para indicar que el icono de la carpeta raíz puede tener un icono superpuesto. El objeto carpeta debe admitir la función IShellIconOverlay interfaz. Antes de que el Windows Explorer muestre el icono de la carpeta raíz, solicitará un icono superpuesto llamando a uno de los dos botones IShellIconOverlay métodos con pidlItem en un PIDL vacío.
El resto de valores y subclaves se aplican a todas las extensiones:
- Para especificar el nombre de visualización de la carpeta del punto de unión de la extensión, establezca el valor predeterminado de la subclave CLSID de la extensión en una cadena adecuada.
- Cuando el cursor pasa por encima de una carpeta, suele aparecer un infotip que describe su contenido. Para proporcionar un infotip para la carpeta raíz de su extensión, cree un InfoTip REG_SZ para la clave CLSID de la extensión, y establecerla en una cadena apropiada.
- Para especificar un icono personalizado para la carpeta raíz de su extensión, cree una subclave de la subclave CLSID de la extensión denominada DefaultIcon. Establezca el valor por defecto de DefaultIcon to a REG_SZ valor que contiene el nombre del archivo que contiene el icono, seguido de una coma, seguido de un signo menos, seguido del índice del icono en ese archivo.
- Por defecto, el menú contextual de la carpeta raíz de su extensión contendrá los elementos definidos en HKEY_CLASSES_ROOT\Folder. El Delete, Rename, and Propiedades elementos si ha configurado los indicadores SFGAO_XXX adecuados. Puede añadir otros elementos al menú contextual de la carpeta raíz, o sustituir los elementos existentes, del mismo modo que lo haría para un menú contextual de tipo de archivo. Crear un Shell bajo la clave CLSID de la extensión, y defina los comandos como se explica en Ampliación de los menús contextuales.
- Si necesita una forma más flexible de manejar el menú contextual de la carpeta raíz, puede implementar una función gestor del menú contextual. Para registrar el controlador del menú contextual, cree un archivo ShellEx bajo la clave CLSID de la extensión. Registre el CLSID del manejador como lo haría para un manejador convencional Creación de manejadores de extensiones de shell.
- Para añadir una página a la hoja de propiedades Propiedades de la carpeta raíz, dé a la carpeta el valor SFGAO_HASPROPSHEET atributo e implementar un atributo manejador de hojas de propiedades. Para registrar el controlador de la hoja de propiedades, cree un archivo ShellEx bajo la clave CLSID de la extensión. Registre el CLSID del manejador como lo haría para un manejador convencional Creación de manejadores de extensiones de shell.
- Para especificar los atributos de la carpeta raíz, añada un atributo ShellFolder a la subclave CLSID de la extensión. Cree un valor de Atributos y ajústelo a la combinación adecuada de SFGAO_XXX banderas.
La siguiente tabla enumera algunos atributos de uso común para las carpetas raíz.
Marca | Value | Descripción |
---|---|---|
SFGAO_FOLDER | 0x20000000 | La carpeta raíz de la extensión contiene uno o más elementos. |
SFGAO_HASSUBFOLDER | 0x80000000 | La carpeta raíz de la extensión contiene uno o más sub-carpetas. El Explorador de Windows colocará un signo más ( + ) junto al icono de la carpeta. |
SFGAO_CANDELETE | 0x00000020 | La carpeta raíz de la extensión pueden ser eliminados por el usuario. El menú contextual de la carpeta tendrá un icono Borrar elemento. Este indicador debe fijarse para los puntos de unión que se sitúan bajo uno de los carpetas virtuales. |
SFGAO_CANRENAME | 0x00000010 | La carpeta raíz de la extensión pueden ser renombrados por el usuario. El menú contextual de la carpeta tendrá un icono Renombrar elemento. |
SFGAO_HASPROPSHEET | 0x00000040 | La carpeta raíz de la extensión tiene un Propiedades hoja de propiedades. El menú contextual de la carpeta tendrá un icono Propiedades elemento. Para proporcionar la hoja de propiedades, debe implementar una función manejador de hojas de propiedades. Registre el manejador bajo la clave CLSID de la extensión, como se ha comentado anteriormente. |
El siguiente ejemplo muestra la entrada de registro CLSID para una extensión cuyo nombre para mostrar es MiExtensión. La extensión tiene un icono personalizado que está contenido en la DLL de la extensión con un índice de 1. El SFGAO_FOLDER, SFGAO_HASSUBFOLDER, y SFGAO_CANDELETE atributos están establecidos.
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
Gestión de los PIDL
Cada elemento del espacio de nombres Shell debe tener un único PIDL. El Windows Explorer asigna un PIDL a su carpeta raíz y pasa el valor a su extensión durante la inicialización. Su extensión es entonces responsable de asignar un PIDL correctamente construido a cada uno de sus objetos y proporcionar esos PIDLs al Explorador de Windows a petición. Cuando el Shell utiliza un PIDL para identificar uno de los objetos de su extensión, su extensión debe ser capaz de interpretar el PIDL e identificar el objeto en particular. Su extensión también debe asignar un nombre para mostrar y un nombre de análisis sintáctico para cada objeto. Dado que prácticamente todas las interfaces de carpetas utilizan PIDL, las extensiones suelen implementar una única gestor PIDL para manejar todas esas tareas.
El término PIDL es la abreviatura de ITEMIDLIST o un puntero a dicha estructura, dependiendo del contexto. Según lo declarado, un ITEMIDLIST estructura tiene un único miembro, un SHITEMID estructura. Un objeto de ITEMIDLIST es en realidad una matriz empaquetada de dos o más SHITEMID estructuras. El orden de estas estructuras define una ruta a través del espacio de nombres, de la misma manera que c:\MiDirectorio\MiArchivo define una ruta a través del sistema de archivos. Normalmente, el PIDL de un objeto consistirá en una serie de SHITEMID que corresponden a las carpetas que definen la ruta del espacio de nombres, seguidas de las estructuras SHITEMID estructura, seguida de un terminador.
El terminador es un SHITEMID estructura con el cb miembro establece NULO. El terminador es necesario porque el número de SHITEMID en el PIDL de un objeto depende de la ubicación del objeto en el espacio de nombres de Shell y del punto de inicio de la ruta. Además, el tamaño de los distintos SHITEMID estructuras pueden variar. Cuando recibe un PIDL, no tiene forma sencilla de determinar su tamaño o incluso el número total de SHITEMID estructuras. En su lugar, debe «recorrer» la matriz empaquetada, estructura por estructura, hasta llegar al terminador.
Para crear un PIDL, su aplicación necesita:
- Crear un SHITEMID estructura para cada uno de sus objetos.
- Reúna los datos pertinentes SHITEMID estructuras en un PIDL.
Creación de una estructura SHITEMID
Un objeto de SHITEMID identifica unívocamente el objeto dentro de su carpeta. De hecho, un tipo de PIDL utilizado por muchas de las IShellFolder métodos consiste únicamente en el del objeto SHITEMID estructura seguida de un terminador. La definición de un SHITEMID estructura es:
typedef struct _SHITEMID {
USHORT cb;
BYTE abID[1];
} SHITEMID, * LPSHITEMID;
El abID es el identificador del objeto. Debido a que la longitud de abID no está definido y puede variar, el cb miembro se establece al dimensionamiento de SHITEMID estructura, en bytes.
Porque ni la longitud ni el contenido de abID está estandarizado, puede utilizar cualquier esquema que desee para asignar abID valor a sus objetos. El único requisito es que no puede haber dos objetos en la misma carpeta con valores idénticos. Sin embargo, por razones de rendimiento, su SHITEMID estructura debería ser DWORD-alineado. En otras palabras, usted debería construir sus abID valores tales como cb es un múltiplo integral de 4.
Typicamente, abID apunta a una estructura definida por la extensión. Además del ID del objeto, esta estructura se utiliza a menudo para contener información relacionada, como el tipo o los atributos del objeto. De este modo, los objetos de carpeta de su extensión pueden extraer rápidamente la información del PIDL en lugar de tener que consultarla.
Nota:
Uno de los aspectos más importantes del diseño de una estructura de datos para un PIDL es hacer que la estructura sea persistente y transportable. En el contexto de los PIDL, el significado de estos términos es:
- Persistente. El sistema suele colocar los PIDL en varios tipos de almacenamiento a largo plazo, como los archivos de acceso directo. A continuación, puede recuperar estos PIDL del almacenamiento más tarde, posiblemente después de que el sistema se haya reiniciado. Un PIDL que se ha recuperado del almacenamiento debe seguir siendo válido y significativo para su extensión. Este requisito significa, por ejemplo, que no debe utilizar punteros o manejadores en su estructura PIDL. Los PIDL que contengan este tipo de datos normalmente carecerán de sentido cuando el sistema los recupere posteriormente de su almacenamiento.
- Transportable. Un PIDL debe seguir teniendo sentido cuando se transporta de un ordenador a otro. Por ejemplo, una PIDL puede escribirse en un archivo de acceso directo, copiarse en un disquete y transportarse a otro ordenador. Ese PIDL debería seguir siendo significativo para su extensión que se ejecuta en el segundo ordenador. Por ejemplo, para garantizar que sus PIDL sean transportables, utilice explícitamente caracteres ANSI o Unicode. Evitar tipos de datos tales como TCHAR o LPTSTR. Si utiliza esos tipos de datos, un PIDL creado en un ordenador que ejecute una versión Unicode de su extensión no podrá ser leído por una versión ANSI de esa extensión que se ejecute en un ordenador diferente.
La siguiente declaración muestra un ejemplo sencillo de una estructura de datos.
typedef struct tagMYPIDLDATA {
USHORT cb;
DWORD dwType;
WCHAR wszDisplayName[40];
} MYPIDLDATA, *LPMYPIDLDATA;
El cb miembro se establece por el dimensionamiento de la MYPIDLDATA estructura. Este miembro hace MYPIDLDATA un válido SHITEMID estructura por y para sí mismo. El resto de los miembros son equivalentes al abID miembro de un SHITEMID estructuran y guardan datos privados. El dwType es un valor definido por la extensión que indica el tipo de objeto. Para este ejemplo, dwType se establece VERDAD para carpetas FALSO de todas formas. Este miembro permite, por ejemplo, determinar rápidamente si el objeto es una carpeta o no. El wszDisplayName contiene el nombre para mostrar del objeto. Como no se puede asignar el mismo nombre de visualización a dos objetos diferentes de la misma carpeta, el nombre de visualización también sirve como ID del objeto. En este ejemplo, wszDisplayName se establecen 40 carácteres para garantizar que el SHITEMID estructura estará DWORD-alineada. Para limitar el tamaño de sus PIDL, puede utilizar una matriz de caracteres de longitud variable y ajustar el valor de cb en consecuencia. Rellene la cadena de visualización con suficientes caracteres '\0' para mantener la estructura de DWORD alineación. Otros miembros que puede ser útil incluir en la estructura son el tamaño del objeto, los atributos o el nombre de análisis.
Construir un PIDL
Una vez que haya definido SHITEMID para sus objetos, puede utilizarlas para construir un PIDL. Los PIDL pueden construirse para diversos fines, pero la mayoría de las tareas utilizan uno de los dos tipos de PIDL. El más sencillo, un PIDL de un solo nivel, identifica el objeto en relación con su carpeta padre. Este tipo de PIDL es utilizado por muchas de las IShellFolder métodos. Un PIDL de un solo nivel contiene el objeto SHITEMID seguida de un terminador. Un PIDL completamente cualificado define una ruta a través de la jerarquía de espacios de nombres desde el escritorio hasta el objeto. Este tipo de PIDL comienza en el escritorio y contiene un SHITEMID para cada carpeta de la ruta, seguida del objeto y el terminador. Un PIDL completamente cualificado identifica de forma única el objeto dentro de todo el espacio de nombres de Shell.
La forma más sencilla de construir un PIDL es trabajar directamente con el archivo ITEMIDLIST estructura en sí misma. Crear un ITEMIDLIST estructura, pero asigne memoria suficiente para contener todos los SHITEMID estructuras. La dirección de esta estructura apuntará a la inicial SHITEMID estructura. Defina valores para los miembros de esta estructura inicial y, a continuación, añada tantos valores adicionales SHITEMID estructuras como quiera, en el orden apropiado. El siguiente procedimiento describe cómo crear un PIDL de un solo nivel. Contiene dos SHITEMID estructuras—a MYPIDLDATA estructura seguida de un terminador:
- Use el CoTaskMemAlloc función para asignar memoria a la PIDL. Asigne memoria suficiente para sus datos privados más un USHORT (dos bytes) para el terminador. Transfiere el resultado a LPMYPIDLDATA.
- Establecer el miembro cb del primer MYPIDLDATA estructura al dimensionamiento de esa estructura. Por ejemplo, usted debería cb dimensionar el (MYPIDLDATA). Si desea utilizar una estructura de longitud variable, tendrá que calcular el valor de cb.
- Asignar valores apropiados a los miembros de datos privados.
- Calcular la dirección del siguiente SHITEMID estructura. Convierte la dirección de la estructura actual MYPIDLDATA a LPBYTE, y añade ese valor al valor de cb determinado en paso 3.
- En este caso, el siguiente SHITEMID estructura es el terminador. Establecer la estructura del cb miembro a cero.
Para PIDL más largos, asigne memoria suficiente y repita los pasos 3-5 para cada PIDL adicional SHITEMID estructura.
La siguiente función de ejemplo toma el tipo y el nombre para mostrar de un objeto y devuelve el PIDL de un solo nivel del objeto. La función asume que el nombre mostrado, incluyendo su terminación null no supere el número de carácteres declarados para el carácter MYPIDLDATA estructura. Si esa suposición resulta ser errónea, el StringCbCopyW función truncará el nombre mostrado. El g_pMalloc variable es un IMalloc creado en otro lugar y almacenado en una variable 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;
Un PIDL plenamente cualificado debe tener SHITEMID estructruras para cada objeto, desde el escritorio hasta su objeto. Su extensión recibe un PIDL completamente cualificado para su carpeta raíz cuando el Shell llama a IPersistFolder::Initialize. Para construir un PIDL completamente cualificado para un objeto, tome el PIDL que el Shell ha asignado a su carpeta raíz, y añada el carácter SHITEMID estructuras necesarias para pasar de la carpeta raíz al objeto.
Interpretar PIDLs
Cuando el Shell o una aplicación llama a una de las interfaces de su extensión para solicitar información sobre un objeto, normalmente identificará el objeto mediante un PIDL. Algunos métodos, tales como IShellFolder::GetUIObjectOf, use trata de PIDL relativos a la carpeta principal y fáciles de interpretar. Sin embargo, es probable que su extensión también reciba PIDL totalmente cualificados. A continuación, su gestor PIDL debe determinar a cuál de sus objetos se refiere ese PIDL.
Lo que complica la tarea de asociar un objeto a un PIDL completamente cualificado es que uno o más de los parámetros iniciales SHITEMID estructuras en el PIDL pueden pertenecer a objetos que se encuentran fuera de su extensión en el espacio de nombres de Shell. No tiene forma de interpretar el significado de la abID miembro de esas estructuras. Lo que debe hacer su extensión es «recorrer» la lista de SHITEMID estructuras, hasta llegar a la estructura correspondiente a la carpeta raíz. A partir de entonces, sabrá interpretar la información del SHITEMID estructuras.
Para recorrer el PIDL, tome la primera cb y añadirlo a la dirección de la PIDL para avanzar el puntero hasta el inicio de la siguiente SHITEMID estructura. Entonces apuntará a la estructura cb miembro, que puede utilizar para avanzar el puntero hasta el inicio del siguiente elemento SHITEMID estructura, etc. Cada vez que avance el puntero, examine el SHITEMID para determinar si ha llegado a la raíz del espacio de nombres de su extensión.
Implementación de las interfaces primarias
Como ocurre con todos los objetos COM, la implementación de una extensión es en gran medida una cuestión de implementación de una colección de interfaces. Esta sección trata de las tres interfaces principales que deben ser implementadas por todas las extensiones. Se utilizan para la inicialización y para proporcionar al Explorador de Windows información básica sobre el contenido de la extensión. Estas interfaces más un vista de carpeta, son todo lo que se necesita para una ampliación funcional. Sim embargo, para explotar todas las características de Windows Exporer, la mayoría de las extensiones también implementan una o más de las interfaces opcionales.
IPersistFolder Interface
El IPersistFolder interfaz se llama para iniciar un nuevo objeto de carpeta. El IPersistFolder método asigna un PIDL completo al nuevo objeto. Guarde este PIDL para su uso posterior. Por ejemplo, un objeto carpeta debe utilizar este PIDL para construir PIDLs completamente cualificados para los hijos del objeto. El creador del objeto carpeta también puede llamar a IPersist::GetClassID para solicitar el CLSID del objeto.
Normalmente, un objeto carpeta se crea e inicializa mediante el método IShellFolder::BindToObject método. Sin embargo, cuando un usuario navega por su extensión, el Explorador de Windows crea e inicializa el objeto carpeta raíz de la extensión. El PIDL que el objeto carpeta raíz recibe a través de IPersistFolder::Initialize contiene la ruta desde el escritorio a la carpeta raíz que necesitará para construir PIDLs completamente cualificados para su extensión.
IShellFolder Interface
El Shell trata una extensión como una colección ordenada jerárquicamente de objetos de carpeta. El IShellFolder interfaz es lo principal de todas las implementaciones de extensiones. Representa un objeto carpeta y proporciona al Explorador de Windows gran parte de la información necesaria para mostrar el contenido de la carpeta.
IShellFolder suele ser el solo interfaz de carpetas que no sea IPersistFolder que se expone directamente por un objeto carpeta. Aunque el Explorador de Windows utiliza una serie de interfaces obligatorias y opcionales para obtener información sobre el contenido de la carpeta, obtiene punteros a esas interfaces a través de IShellFolder.
El Explorador de Windows obtiene el CLSID de la carpeta raíz de su extensión de varias maneras. Para información, consulte Especificación de la ubicación de una extensión de espacio de nombres o Visualización de una vista autónoma de una extensión de espacio de nombres. Windows Explorer a continuación, utiliza ese CLSID para crear e inicializar una instancia de la carpeta raíz y la consulta de un IShellFolder interfaz. Su extensión crea un objeto carpeta para representar la carpeta raíz y devuelve el objeto IShellFolder interfaz. Gran parte del resto de la interacción entre su extensión y el Explorador de Windows tiene lugar a través de IShellFolder. Windows Explorer llama IShellFolder a:
- Solicita un objeto que pueda enumerar el contenido de la carpeta raíz.
- Obtener diversos tipos de información sobre el contenido de la carpeta raíz.
- Solicitar un objeto que exponga una de las interfaces opcionales. A continuación, esas interfaces pueden consultarse para obtener información adicional, como iconos o menús de acceso directo.
- Solicita un objeto carpeta que representa una subcarpeta de la carpeta raíz.
Cuando un usuario abre una sub-carpeta de la carpeta raíz, Windows Explorer llama IShellFolder::BindToObject. Su extensión crea e inicializa un nuevo objeto carpeta para representar la subcarpeta y devuelve su objeto IShellFolder interfaz. A continuación, Windows Exporer llama a esta interfaz para obtener diversos tipos de información, y así sucesivamente hasta que el usuario decide navegar por otra parte del espacio de nombres Shell o cerrar el Explorador de Windows.
En el resto de esta sección se analizan brevemente los aspectos más importantes IShellFolder métodos y cómo aplicarlos.
EnumObjects
Antes de mostrar el contenido de una carpeta en la vista en árbol, Windows Explorer debe determinar primero qué contiene la carpeta llamando a la función IShellFolder::EnumObjects método. Este método crea un objeto de enumeración OLE estándar que expone un objeto IEnumIDList y devuelve el puntero de dicha interfaz. The IEnumIDList permite al Explorador de Windows obtener los PIDL de todos los objetos que contiene la carpeta. A continuación, estos PIDL se utilizan para obtener información sobre los objetos que contiene la carpeta. Para más información, consulte IEnumIDList Interface.
Nota:
El IEnumIDList::Next método solo debe devolver PIDLs que sean relativos a la carpeta padre. El PIDL debe contener solo el objeto SHITEMID estructura, seguida de un terminador.
CreateViewObject
Antes de que se muestre el contenido de una carpeta, el Explorador de Windows llama a este método para solicitar un puntero a una carpeta IShellView interfaz. Esta interfaz es utilizada por el Explorador de Windows para gestionar la vista de carpetas. Crea un objeto de vista de carpeta y devuelve su IShellView interfaz.
El IShellFolder::CreateViewObject método para solicitar una de las interfaces opcionales, como por ejemplo IContextMenu, para la carpeta en sí mismo. La implementación de este método debe crear un objeto que exponga la interfaz solicitada y devuelva el puntero a la interfaz. Si el Windows Explorer necesita una interfaz opcional para uno de los objetos que contiene la carpeta, llamará a IShellFolder::GetUIObjectOf.
GetUIObjectOf
Mientras que la información básica sobre el contenido de una carpeta está disponible a través de la función IShellFolder método su extensión también puede proporcionar al Windows Explorer varios tipos de información adicional. Por ejemplo, puede especificar iconos para el contenido de una carpeta o para el menú contextual de un objeto. Windows Explorer llama el IShellFolder::GetUIObjectOf método para intentar recuperar información adicional sobre un objeto contenido en una carpeta. El Explorador de Windows especifica para qué objeto desea la información y el IID de la interfaz correspondiente. A continuación, el objeto carpeta crea un objeto que expone la interfaz solicitada y devuelve el puntero de la interfaz.
Si su extensión permite a los usuarios transferir objetos con arrastrar y soltar o con el portapapeles, el Explorador de Windows llamará a IShellFolder::GetUIObjectOf para solicitar un IDataObject or IDropTarget interfaz. Para más información, consulte Transferencia de objetos de Shell con arrastrar y soltar y el portapapeles.
Windows Explorer llama IShellFolder::CreateViewObject cuando quiere el mismo tipo de información sobre la propia carpeta.
BindToObject
Windows Explorer llama al IShellFolder::BindToObject método cuando un usuario intenta abrir una de las subcarpetas de su extensión. Si riid is set to IID_IShellFolder, debe crear e inicializar un objeto carpeta que represente la subcarpeta y devolver el objeto IShellFolder interfaz.
Nota:
Actualmente, el Windows Explorar solo llama a este método para solicitar un IShellView interfaz. Sin embargo, no dé por sentado que siempre será así. Siempre debe comprobar el valor de riid antes de proceder.
GetDisplayNameOf
Windows Explorer llama al IShellFolder::GetDisplayNameOf método para convertir el PIDL de uno de los objetos de la carpeta en un nombre. Ese PIDL debe ser relativo a la carpeta padre del objeto. En otras palabras, debe contener un único no-NULO SHITEMID estructura. Porque hay más de una forma posible de nombrar objetos, Windows Explorer especifica el tipo de nombre estableciendo uno o varios SHGDNF banderas en el uFlags parámetro. Uno de dos valores, SHGDN_NORMAL o SHGDN_INFOLDER, se establerá para especificar si el nombre debe ser relativo a la carpeta o relativo al escritorio. Uno de los otros tres valores, SHGDN_FOREDITING, SHGDN_FORADDRESSBAR, or SHGDN_FORPARSING, para especificar para qué se utilizará el nombre.
Debe devolver el nombre en forma de STRRET estructura. Si SHGDN_FOREDITING, SHGDN_FORADDRESSBAR, and SHGDN_FORPARSING no están definidos, devuelve el nombre para mostrar del objeto. Si el SHGDN_FORPARSING está activada, Windows Explorer está solicitando un nombre de análisis. Los nombres de análisis se pasan a IShellFolder::ParseDisplayName para obtener el PIDL de un objeto, aunque se encuentre uno o varios niveles por debajo de la carpeta actual en la jerarquía de espacios de nombres. Por ejemplo, el nombre de análisis de un objeto del sistema de archivos es su ruta. Puede pasar la ruta completa de cualquier objeto del sistema de archivos a la función de escritorio IShellFolder::ParseDisplayName método, y devolverá el PIDL completo del objeto.
Aunque los nombres analizados son cadenas de texto, no tienen que incluir necesariamente el nombre para mostrar. Debe asignar nombres de análisis en función de lo que funcione de forma más eficiente cuando IShellFolder::ParseDisplayName se llama. Por ejemplo, muchas de las carpetas virtuales de Shell no forman parte del sistema de archivos y no tienen una ruta completa. En su lugar, a cada carpeta se le asigna un GUID y el nombre analizado adopta la forma ::{GUID}. Independientemente del esquema que utilice, debe ser capaz de "ida y vuelta" de forma fiable. Por ejemplo, si quien llama pasa un nombre de análisis a IShellFolder::ParseDisplayName para recuperar el PIDL de un objeto, y luego pasa ese PIDL a IShellFolder::GetDisplayNameOf con el SHGDN_FORPARSING la persona que llama debe recuperar el nombre de análisis original.
GetAttributesOf
Windows Explorer llama el IShellFolder::GetAttributesOf método para determinar los atributos de uno o varios elementos contenidos por un objeto carpeta. El valor de cidl gives the number of items in the query, and aPidl apunta a una lista de sus PIDLs.
Dado que la comprobación de algunos atributos puede llevar mucho tiempo, el Explorador de Windows suele restringir la consulta a un subconjunto de los indicadores disponibles estableciendo sus valores en rfgInOut. Su método debe comprobar solo aquellos atributos cuyas banderas estén definidas en rfgInOut. Deje activadas las banderas válidas y borre el resto. Si se incluye más de un elemento en la consulta, establezca solo los indicadores que se apliquen a todos los elementos.
Nota:
Los atributos deben estar correctamente configurados para que un elemento se muestre correctamente. Por ejemplo, si un elemento es una carpeta que contiene subcarpetas, debe definir la SFGAO_HASSUBFOLDER bandera. De otra forma, Windows Explorer no mostrará un + junto al icono del elemento en la vista de árbol.
ParseDisplayName
El IShellFolder::ParseDisplayName es, en cierto sentido, un reflejo de IShellFolder::GetDisplayNameOf. El uso más común de este método es convertir el nombre de análisis de un objeto en el PIDL asociado. El nombre de análisis puede referirse a cualquier objeto que se encuentre por debajo de la carpeta en la jerarquía del espacio de nombres. El PIDL devuelto es relativo al objeto carpeta que expone el método y normalmente no está completamente cualificado. En otras palabras, aunque el PIDL puede contener varios SHITEMID estructuras, la primera será la del propio objeto o la primera subcarpeta de la ruta desde la carpeta al objeto. La persona que llama tendrá que añadir este PIDL al PIDL completo de la carpeta para obtener un PIDL completo para el objeto.
IShellFolder::ParseDisplayName también se puede llamar para solicitar los atributos de un objeto. Dado que determinar todos los atributos aplicables puede llevar mucho tiempo, la persona que llama establecerá solo aquellos SFGAO_XXX banderas que representan la información que interesa a la persona que llama. Debe determinar cuáles de esos atributos son verdaderos para el objeto y borrar las banderas restantes.
IEnumIDList Interface
Cuando el Explorador de Windows necesita enumerar los objetos que contiene una carpeta, llama a IShellFolder::EnumObjects. El objeto carpeta debe crear un objeto de enumeración que exponga los parámetros IEnumIDList y vuelve el puntero de dicha interfaz. Windows Explorer usará de forma típica IEnumIDList para enumerar los PIDL de todos los objetos que contiene la carpeta.
IEnumIDList es una interfaz de enumeración OLE estándar y se implementa de la forma habitual. Recuerde, sin embargo, que los PIDLs que devuelva deben ser relativos a la carpeta y contener solo el objeto SHITEMID estructura y y un terminador.
Implementación de las interfaces opcionales
Hay una serie de interfaces Shell opcionales que pueden soportar los objetos de carpeta de su extensión. Muchos de ellos, como IExtractIcon, le permiten personalizar varios aspectos de la forma en que el usuario ve su extensión. Otros, como IDataObject, permitir que su extensión admita funciones como arrastrar y soltar.
Ninguna de las interfaces opcionales está expuesta directamente por un objeto carpeta. En su lugar, el Explorador de Windows llama a uno de los dos IShellView método para solicitar una interfaz:
- Windows Explorer llama por un objeto de una carpeta IShellFolder::GetUIObjectOf para solicitar una interfaz para uno de los objetos contenidos por la carpeta.
- Windows Explorer llama por un objeto de una carpeta IShellFolder::CreateViewObject para solicitar una interfaz para uno de los objetos contenidos por la carpeta en sí mismo.
Para proporcionar la información, el objeto carpeta crea un objeto que expone la interfaz solicitada y devuelve el puntero de la interfaz. Windows Explorer luego llama a esa interfaz para recuperar la información necesaria. Esta sección trata de las interfaces opcionales más utilizadas.
IExtractIcon
Windows Explorer pide un IExtractIcon interfaz antes de mostrar el contenido de una carpeta. La interfaz permite a su extensión especificar iconos personalizados para los objetos que contiene la carpeta. De lo contrario, se utilizarán los iconos estándar de archivos y carpetas. Para proporcionar un icono personalizado, cree un objeto de extracción de iconos que exponga IExtractIcon y devuelve un puntero a esa interfaz. Para más información, consulte el IExtractIcon documentación de referencia o Creación de manejadores de iconos.
IContextMenu
Cuando un usuario hace clic con el botón derecho en un objeto, Windows Explorer pide un IContextMenu interfaz antes de mostrar el contenido de una carpeta. Para proporcionar menús de acceso directo a sus objetos, cree un objeto manejador de menús y devuelva su objeto IContextMenu interfaz.
Los procedimientos para crear un objeto manejador de menú son muy similares a los utilizados para crear una extensión Shell manejadora de menú. Para información, consulte Creación de controladores de menú contextual o el IContextMenu, IContextMenu2, or IContextMenu3 referencia.
IQueryInfo
Windows Explorer llama la IQueryInfo interfaz para recuperar una cadena de texto infotip.
IDataObject and IDropTarget
Cuando sus objetos son mostrados por el Explorador de Windows, un objeto de carpeta no tiene forma directa de saber cuando un usuario está intentando cortar, copiar o arrastrar un objeto. En su lugar, uando un usuario hace clic con el botón derecho en un objeto, Windows Explorer pide un IDataObject interfaz antes de mostrar el contenido de una carpeta. Para permitir la transferencia del objeto, cree un objeto de datos y devuelva un puntero a su IDataObject interfaz.
Del mismo modo, un usuario podría intentar soltar un objeto de datos en una representación del Explorador de Windows de uno de sus objetos, como un icono o una ruta de la barra de direcciones. En su lugar, uando un usuario entonces hace clic con el botón derecho en un objeto, Windows Explorer pide un IDropTarget interfaz antes de mostrar el contenido de una carpeta. Para poder soltar el objeto de datos, cree un objeto que exponga una IDropTarget y devuelve el puntero de la interfaz.
El manejo de la transferencia de datos es uno de los aspectos más complicados de escribir extensiones de espacios de nombres. Para una discusión más detallada, consulte Transferencia de objetos de Shell con arrastrar y soltar y el portapapeles.
Trabajar con la implementación predeterminada de la vista de carpetas de Shell
Las fuentes de datos que utilizan el objeto de vista predeterminado de la carpeta Shell (DefView) deben implementar estas interfaces:
Opcionalmente, también pueden implementar IPersistFolder3.