Freigeben über


Initialisierungssequenz von Projektuntertypen

Die Umgebung erstellt ein Projekt durch Aufrufen der Basisprojekt-Factoryimplementierung von CreateProject. Die Erstellung eines Projektuntertyps beginnt, wenn die Umgebung bestimmt, dass die GUID-Liste des Projekttyps für die Erweiterung einer Projektdatei nicht leer ist. Die Projektdateierweiterung und projekt-GUID geben an, ob es sich bei dem Projekt um einen Visual Basic- oder Visual C#-Projekttyp handelt. Beispielsweise identifizieren die .vbproj-Erweiterung und {F184B08F-C81C-45F6-A57F-5ABD9991F28F} ein Visual Basic-Projekt.

Initialisierung von Projektuntertypen in der Umgebung

Im folgenden Verfahren wird die Initialisierungssequenz für ein Projektsystem beschrieben, das von mehreren Projektuntertypen aggregiert wird.

  1. Die Umgebung ruft die Basisprojekts CreateProjectauf, und während das Projekt seine Projektdatei analysiert, erkennt es, dass die Aggregat-Projekttyp-GUIDs-Liste nicht nullist. Das Projekt bricht die direkte Erstellung des Projekts ab.

  2. Das Projekt ruft QueryService den Dienst auf SVsCreateAggregateProject , um einen Projektuntertyp mithilfe der Implementierung der CreateAggregateProject Methode zu erstellen. Innerhalb dieser Methode führt die Umgebung rekursive Funktionsaufrufe an Ihre Implementierungen PreCreateForOuterSetInnerProject und InitializeForOuter Methoden durch, während die Liste der Projekttyp-GUIDs durchlaufen wird, beginnend mit dem äußersten Projektuntertyp.

    Im Folgenden werden die Initialisierungsschritte beschrieben.

    1. Die Implementierung der Methode ruft die CreateAggregateProjectHrCreateInnerProj Methode mit der folgenden Funktionsdeklaration auf:

      <CodeContentPlaceHolder>0

      Wenn diese Funktion zum ersten Mal aufgerufen wird, d. h. für den äußersten Projektuntertyp, werden die Parameter pOuter übergeben und pOwner als null übergeben, und die Funktion legt den äußersten Projektuntertyp IUnknown auf pOuter.

    2. Als Nächstes ruft die Umgebung die Funktion mit der GUID des zweiten Projekttyps in der Liste auf HrCreateInnerProj . Diese GUID entspricht dem zweiten inneren Projektuntertyp, der in Richtung des Basisprojekts in der Aggregationssequenz ausgeführt wird.

    3. Dies pOuter verweist nun auf den IUnknown Untertyp des äußersten Projekts und HrCreateInnerProj ruft Die Implementierung von PreCreateForOuter gefolgt von einem Aufruf der Implementierung von SetInnerProject. In PreCreateForOuter der Methode übergeben Sie die Steuerung IUnknown des äußersten Projektuntertyps, pOuter. Das im Besitz befindliche Projekt (innerer Projektuntertyp) muss hier sein aggregiertes Projektobjekt erstellen. In der SetInnerProject Methodenimplementierung übergeben Sie einen Zeiger auf das IUnknown innere Projekt, das aggregiert wird. Diese beiden Methoden erstellen das Aggregationsobjekt, und Ihre Implementierungen müssen COM-Aggregationsregeln befolgen, um sicherzustellen, dass ein Projektuntertyp keine Referenzanzahl für sich selbst enthält.

    4. HrCreateInnerProj ruft Ihre Implementierung von PreCreateForOuter. Bei dieser Methode funktioniert der Projektuntertyp mit der Initialisierung. Sie können z. B. Lösungsereignisse in InitializeForOuter.

    5. HrCreateInnerProj wird rekursiv aufgerufen, bis die letzte GUID (das Basisprojekt) in der Liste erreicht ist. Für jeden dieser Aufrufe werden die Schritte c bis d wiederholt. pOuter verweist auf den äußersten Projektuntertyp IUnknown für jede Aggregationsebene.

Beispiel

Im folgenden Beispiel wird der programmgesteuerte Prozess in einer ungefähren Darstellung der CreateAggregateProject Methode beschrieben, wie sie von der Umgebung implementiert wird. Der Code ist nur ein Beispiel; sie soll nicht kompiliert werden, und alle Fehlerüberprüfungen wurden aus Gründen der Übersichtlichkeit entfernt.

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);
}