Développement avec Windows Explorer

Windows Explorer est une application puissante de navigation et de gestion des ressources. Les Explorer Windows sont accessibles en tant qu’ensemble intégré via Explorer.exe ou l’interface IExplorerBrowser. Les Explorer Windows (Explorer.exe) peuvent être générés en tant que processus distinct à l’aide de ShellExecuteEx ou d’une fonction similaire.

Les fenêtres d’explorateur ouvertes peuvent être découvertes et programmées à l’aide d’IShellWindows (CLSID_ShellWindows), et de nouvelles instances de Windows Explorer peuvent être créées à l’aide d’IWebBrowser2 (CLSID_ShellBrowserWindow).

L’exemple de code suivant montre comment le modèle d’automatisation Windows Explorer peut être utilisé pour créer et découvrir des fenêtres d’explorateur en cours d’exécution.

#define _WIN32_WINNT 0x0600
#define _WIN32_IE 0x0700
#define _UNICODE

#include <windows.h>
#include <shobjidl.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <strsafe.h>
#include <propvarutil.h>
 
#pragma comment(lib, "shlwapi.lib")
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "propsys.lib")
 
// Use the Shell Windows object to find all of the explorer and IExplorer 
// windows and close them.
 
void CloseExplorerWindows()
{
    IShellWindows* psw;
    
    if (SUCCEEDED(CoCreateInstance(CLSID_ShellWindows, 
                                   NULL,  
                                   CLSCTX_LOCAL_SERVER, 
                                   IID_PPV_ARGS(&psw))))
    {
        VARIANT v = { VT_I4 };
        if (SUCCEEDED(psw->get_Count(&v.lVal)))
        {
            // Walk backward to make sure that the windows that close
            // do not cause the array to be reordered.
            while (--v.lVal >= 0)
            {
                IDispatch *pdisp;
                
                if (S_OK == psw->Item(v, &pdisp))
                {
                    IWebBrowser2 *pwb;
                    if (SUCCEEDED(pdisp->QueryInterface(IID_PPV_ARGS(&pwb))))
                    {
                        pwb->Quit();
                        pwb->Release();
                    }
                    pdisp->Release();
                }
            }
        }
        psw->Release();
    }
}
 
// Convert an IShellItem or IDataObject into a VARIANT that holds an IDList
// suitable for use with IWebBrowser2::Navigate2.
 
HRESULT InitVariantFromObject(IUnknown *punk, VARIANT *pvar)
{
    VariantInit(pvar);
 
    PIDLIST_ABSOLUTE pidl;
    HRESULT hr = SHGetIDListFromObject(punk, &pidl);
    if (SUCCEEDED(hr))
    {
        hr = InitVariantFromBuffer(pidl, ILGetSize(pidl), pvar);
        CoTaskMemFree(pidl);
    }
    return hr;
}
 
HRESULT ParseItemAsVariant(PCWSTR pszItem, IBindCtx *pbc, VARIANT *pvar)
{
    VariantInit(pvar);
 
    IShellItem *psi;
    HRESULT hr = SHCreateItemFromParsingName(pszItem, NULL, IID_PPV_ARGS(&psi));
    if (SUCCEEDED(hr))
    {
        hr = InitVariantFromObject(psi, pvar);
        psi->Release();
    }
    return hr;
}

HRESULT GetKnownFolderAsVariant(REFKNOWNFOLDERID kfid, VARIANT *pvar)
{
    VariantInit(pvar);
 
    PIDLIST_ABSOLUTE pidl;
    HRESULT hr = SHGetKnownFolderIDList(kfid, 0, NULL, &pidl);
    if (SUCCEEDED(hr))
    {
        hr = InitVariantFromBuffer(pidl, ILGetSize(pidl), pvar);
        CoTaskMemFree(pidl);
    }
    return hr;
}

HRESULT GetShellItemFromCommandLine(REFIID riid, void **ppv)
{
    *ppv = NULL;
    HRESULT hr = E_FAIL;

    int cArgs;
    PWSTR *ppszCmd = CommandLineToArgvW(GetCommandLineW(), &cArgs);
    if (ppszCmd && cArgs > 1)
    {
        WCHAR szSpec[MAX_PATH];
        StringCchCopyW(szSpec, ARRAYSIZE(szSpec), ppszCmd[1]);
        PathUnquoteSpacesW(szSpec);

        hr = szSpec[0] ? S_OK : E_FAIL;   // Protect against empty data
        if (SUCCEEDED(hr))
        {
            hr = SHCreateItemFromParsingName(szSpec, NULL, riid, ppv);
            if (FAILED(hr))
            {
                WCHAR szFolder[MAX_PATH];
                GetCurrentDirectoryW(ARRAYSIZE(szFolder), szFolder);

                hr = PathAppendW(szFolder, szSpec) ? S_OK : E_FAIL;
                if (SUCCEEDED(hr))
                {
                    hr = SHCreateItemFromParsingName(szFolder, NULL, riid, ppv);
                }
            }
        }
    }
    return hr;
}

HRESULT GetShellItemFromCommandLineAsVariant(VARIANT *pvar)
{
    VariantInit(pvar);

    IShellItem *psi;
    HRESULT hr = GetShellItemFromCommandLine(IID_PPV_ARGS(&psi));
    if (SUCCEEDED(hr))
    {
        hr = InitVariantFromObject(psi, pvar);
        psi->Release();
    }
    return hr;
}

void OpenWindow()
{
    IWebBrowser2 *pwb;
    HRESULT hr = CoCreateInstance(CLSID_ShellBrowserWindow, 
                                  NULL,
                                  CLSCTX_LOCAL_SERVER, 
                                  IID_PPV_ARGS(&pwb));
    if (SUCCEEDED(hr))
    {
        CoAllowSetForegroundWindow(pwb, 0);

        pwb->put_Left(100);
        pwb->put_Top(100);
        pwb->put_Height(600);
        pwb->put_Width(800);
 
        VARIANT varTarget = {0};
        hr = GetShellItemFromCommandLineAsVariant(&varTarget);
        if (FAILED(hr))
        {
            hr = GetKnownFolderAsVariant(FOLDERID_UsersFiles, &varTarget);
        }

        if (SUCCEEDED(hr))
        {
            VARIANT vEmpty = {0};
            hr = pwb->Navigate2(&varTarget, &vEmpty, &vEmpty, &vEmpty, &vEmpty);
            if (SUCCEEDED(hr))
            {
                pwb->put_Visible(VARIANT_TRUE);
            }
            VariantClear(&varTarget);
        }
        pwb->Release();
    }
}

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED |  COINIT_DISABLE_OLE1DDE);
    if (SUCCEEDED(hr))
    {
        CloseExplorerWindows();

        OpenWindow();

        CoUninitialize();
    }
    return 0;
}

La zone cliente Windows Explorer peut être hébergée à l’aide de l’interface IExplorerBrowser. Le client Windows Explorer et les contrôles d’arborescence d’espaces de noms sont des composants standard de Windows Vista et versions ultérieures. Les développeurs peuvent réutiliser les interfaces en tant que composants de génération. L’une des utilisations courantes de ces contrôles consiste à créer des explorateurs personnalisés adaptés au domaine problématique.

Les contrôles dans Windows Explorer sont classés dans les catégories fonctionnelles suivantes :

Les contrôles de navigation aident les utilisateurs à déterminer le contexte et à naviguer dans l’espace de domaine logique associé, appelé espace de page. Par exemple, l’espace de page pour Windows Explorer est l’espace de noms Shell. Les espaces de page sont composés de zéro ou plus de pages.

Le tableau suivant répertorie et décrit les contrôles de navigation disponibles dans Windows Explorer dans les systèmes d’exploitation Windows Vista et ultérieurs.

Contrôle de navigation Description
Barre d’adresse (contrôle De navigation) Affiche l’adresse de la page active dans l’espace de page. Vous pouvez cliquer sur les boutons de navigation pour accéder à n’importe quel ancêtre dans l’espace de page. Les utilisateurs peuvent également taper des URL et des chemins d’accès pour naviguer.
Arborescence des dossiers Fournit une nouvelle version d’un contrôle d’arborescence, optimisé pour les grands espaces de page.
Voyage Active la navigation relative via des boutons de style web tels que Précédent et Précédent.
Titre Affiche le nom et le contexte actuels de l’explorateur.
Espace de page Affiche la branche active de l’espace de page. Les pages peuvent être triées selon différents critères. Les utilisateurs peuvent cliquer sur une page pour y accéder.

 

Contrôles de commande

Les contrôles de commande publient les fonctionnalités du Explorer Windows aux utilisateurs. Ces contrôles effectuent des actions générales ou spécifiques à un ou plusieurs éléments sélectionnés.

Contrôle de commande Description
Barre d'outils Affiche les boutons des commandes couramment utilisées (nouvelle version d’une barre d’outils de commandes). Les options de personnalisation incluent des boutons déroulants, des boutons fractionnés, du texte descriptif facultatif et une zone de dépassement de capacité.
Bannière Apparaît sous la forme d’un seul contrôle personnalisé facultatif au centre de la barre d’outils. Il représente la commande principale pour le contexte actuel.
Barre de menus Présente les commandes via les menus.
Menu contextuel Répertorie un sous-ensemble de commandes disponibles contextuellement pertinents qui s’affichent à la suite d’un clic droit sur un élément.

 

Contrôles de propriété et d’aperçu

Les contrôles de propriété et d’aperçu sont utilisés pour afficher un aperçu des éléments, ainsi que pour afficher et modifier les propriétés des éléments.

Control Description
PRÉVERSION Affiche un aperçu de l’élément sélectionné, tel qu’une miniature ou une icône dynamique.
Propriétés Affiche les propriétés de l’élément sélectionné. Pour plusieurs sélections, il affiche un résumé des propriétés du groupe d’éléments sélectionné. Pour une sélection null, il affiche un résumé des propriétés de la page active (contenu de la vue de liste).

 

Contrôles de filtrage et d’affichage

Les contrôles de filtrage et d’affichage sont utilisés pour manipuler l’ensemble d’éléments dans la vue de liste et pour modifier la présentation des éléments dans la vue de liste.

Control Description
Filtrer Filtre ou organise les éléments dans une vue de liste en fonction des propriétés répertoriées sous forme de colonnes. Le fait de cliquer sur une colonne est trié par cette propriété.
Roue de mot Filtre dynamiquement et incrémentiellement les éléments affichés dans une vue de liste en fonction d’une chaîne de texte d’entrée.
Affichage Permet à l’utilisateur de modifier le mode d’affichage d’un contrôle listview. Un curseur peut être utilisé pour déterminer la taille de l’icône.

 

Contrôle Listview

Le contrôle listview est utilisé pour afficher un ensemble d’éléments dans l’un des quatre modes d’affichage : détails, vignettes, icônes ou panorama. Le contrôle listview permet également à l’utilisateur de sélectionner et d’activer un ou plusieurs éléments.

Attention

Bien que certains de ces contrôles aient des noms et/ou des fonctionnalités similaires aux contrôles Windows Presentation Foundation standard (WPF) trouvés dans l’espace de noms System.Windows.Controls, il s’agit de classes distinctes.

 

Ces contrôles distincts fonctionnent en grande partie ensemble par le biais d’événements générés soit par l’interaction utilisateur, soit par les contrôles eux-mêmes. Le tableau suivant présente les trois catégories d’événements principales.

Catégorie d'événements Exemple
Navigation Passer d’une page à l’autre.
Sélection Modification de la sélection actuelle dans la vue de liste.
Afficher la modification Modification de l’ordre de présentation ou du mode d’affichage dans la vue de liste.