Share via


Séquence d’initialisation des sous-types de projets

L’environnement construit un projet en appelant l’implémentation de la fabrique de projet de base de CreateProject. La construction d’un sous-type de projet démarre lorsque l’environnement détermine que la liste GUID du type de projet pour l’extension d’un fichier projet n’est pas vide. L’extension de fichier projet et le GUID du projet spécifient si le projet est un type de projet Visual Basic ou Visual C#. Par exemple, l’extension .vbproj et {F184B08F-C81C-45F6-A57F-5ABD9991F28F} identifient un projet Visual Basic.

Initialisation de l’environnement des sous-types de projet

La procédure suivante détaille la séquence d’initialisation d’un système de projet agrégé par plusieurs sous-types de projet.

  1. L’environnement appelle le projet de CreateProjectbase et, tandis que le projet analyse son fichier projet, il découvre que la liste des GUID de type de projet d’agrégation n’est pas null. Le projet cesse de créer directement son projet.

  2. Le projet appelle QueryService le SVsCreateAggregateProject service pour créer un sous-type de projet à l’aide de l’implémentation de l’environnement de la CreateAggregateProject méthode. Dans cette méthode, l’environnement effectue des appels de fonction récursifs à vos implémentations PreCreateForOuteret SetInnerProjectInitializeForOuter méthodes tout en parcourant la liste des GUID de type de projet, en commençant par le sous-type de projet le plus externe.

    Les étapes d’initialisation suivantes sont détaillées.

    1. L’implémentation de l’environnement de la CreateAggregateProject méthode appelle la HrCreateInnerProj méthode avec la déclaration de fonction suivante :

      <CodeContentPlaceHolder>0

      Lorsque cette fonction est appelée pour la première fois, c’est-à-dire pour le sous-type de projet le plus externe, les paramètres pOuter et pOwner sont passés en tant que null et la fonction définit le sous-type IUnknown de projet le plus externe sur pOuter.

    2. Ensuite, l’environnement appelle HrCreateInnerProj la fonction avec le deuxième GUID de type de projet dans la liste. Ce GUID correspond au deuxième sous-type de projet interne pas à pas vers le projet de base dans la séquence d’agrégation.

    3. Il pOuter pointe maintenant vers le IUnknown sous-type de projet le plus externe et HrCreateInnerProj appelle votre implémentation suivie PreCreateForOuter d’un appel à votre implémentation de SetInnerProject. Dans PreCreateForOuter la méthode, vous passez le contrôle IUnknown du sous-type de projet le plus externe. pOuter Le projet détenu (sous-type de projet interne) doit créer ici son objet projet agrégé. Dans l’implémentation de la SetInnerProject méthode, vous passez un pointeur vers le IUnknown projet interne en cours d’agrégation. Ces deux méthodes créent l’objet d’agrégation et vos implémentations doivent suivre les règles d’agrégation COM pour s’assurer qu’un sous-type de projet ne finit pas par contenir un nombre de références lui-même.

    4. HrCreateInnerProj appelle votre implémentation de PreCreateForOuter. Dans cette méthode, le sous-type de projet effectue son travail d’initialisation. Vous pouvez, par exemple, inscrire des événements de solution dans InitializeForOuter.

    5. HrCreateInnerProj est appelé de manière récursive jusqu’à ce que le dernier GUID (le projet de base) dans la liste soit atteint. Pour chacun de ces appels, les étapes, c à d, sont répétées. pOuter pointe vers le sous-type IUnknown de projet le plus externe pour chaque niveau d’agrégation.

Exemple

L’exemple suivant détaille le processus programmatique dans une représentation approximative de la CreateAggregateProject méthode, car elle est implémentée par l’environnement. Le code n’est qu’un exemple ; il n’est pas destiné à être compilé, et toute erreur case activée a été supprimée pour plus de clarté.

HRESULT CreateAggregateProject
(
    LPCOLESTR lpstrGuids,
    LPCOLESTR pszFilename,
    LPCOLESTR pszLocation,
    LPCOLESTR pszName,
    VSCREATEPROJFLAGS grfCreateFlags,
    REFIID iidProject,
    void **ppvProject)
{
    HRESULT hr = NOERROR;
    CComPtr<IUnknown> srpunkProj;
    CComPtr<IVsAggregatableProject> srpAggProject;
    CComBSTR bstrGuids = lpstrGuids;
    BOOL fCanceled = FALSE;
    *ppvProject = NULL;

    HrCreateInnerProj(
         bstrGuids, NULL, NULL, pszFilename, pszLocation,
         pszName, grfCreateFlags, &srpunkProj, &fCanceled);
    srpunkProj->QueryInterface(
        IID_IVsAggregatableProject, (void **)&srpAggProject));
    srpAggProject->OnAggregationComplete();
    srpunkProj->QueryInterface(iidProject, ppvProject);
}

HRESULT HrCreateInnerProj
(
    WCHAR *pwszGuids,
    IUnknown *pOuter,
    IVsAggregatableProject *pOwner,
    LPCOLESTR pszFilename,
    LPCOLESTR pszLocation,
    LPCOLESTR pszName,
    VSCREATEPROJFLAGS grfCreateFlags,
    IUnknown **ppInner,
    BOOL *pfCanceled
)
{
    HRESULT hr = NOERROR;
    CComPtr<IUnknown> srpInner;
    CComPtr<IVsAggregatableProject> srpAggInner;
    CComPtr<IVsProjectFactory> srpProjectFactory;
    CComPtr<IVsAggregatableProjectFactory> srpAggPF;
    GUID guid = GUID_NULL;
    WCHAR *pwszNextGuids = wcschr(pwszGuids, L';');
    WCHAR wszText[_MAX_PATH+150] = L"";

    if (pwszNextGuids)
    {
        *pwszNextGuids++ = 0;
    }

    CLSIDFromString(pwszGuids, &guid);
    GetProjectTypeMgr()->HrGetProjectFactoryOfGuid(
        guid, &srpProjectFactory);
    srpProjectFactory->QueryInterface(
        IID_IVsAggregatableProjectFactory,
        (void **)&srpAggPF);
    srpAggPF->PreCreateForOuter(pOuter, &srpInner);
    srpInner->QueryInterface(
        IID_IVsAggregatableProject, (void **)&srpAggInner);

    if (pOwner)
    {
        IfFailGo(pOwner->SetInnerProject(srpInner));
    }

    if (pwszNextGuids)
    {
        CComPtr<IUnknown> srpNextInner;
        HrCreateInnerProj(
            pwszNextGuids, pOuter ? pOuter : srpInner,
            srpAggInner, pszFilename, pszLocation, pszName,
            grfCreateFlags, &srpNextInner, pfCanceled);
    }

    return srpAggInner->InitializeForOuter(
        pszFilename, pszLocation, pszName, grfCreateFlags,
        IID_IUnknown, (void **)ppInner, pfCanceled);
}