Delen via


Initialisatievolgorde van projectsubtypen

De omgeving stelt een project samen door gebruik te maken van de basisprojectfabrieksimplementatie van CreateProject. De bouw van een projectsubtype begint wanneer de omgeving bepaalt dat de GUID-lijst van het projecttype voor de extensie van een projectbestand niet leeg is. De bestandsextensie van het project en de project-GUID geven aan of het project een Visual Basic- of Visual C#-projecttype is. De extensie .vbproj en {F184B08F-C81C-45F6-A57F-5ABD9991F28F} identificeren bijvoorbeeld een Visual Basic-project.

Initialisatie van projecsitamtypen binnen een omgeving

In de volgende procedure wordt de initialisatievolgorde beschreven voor een projectsysteem dat wordt geaggregeerd door meerdere projectsubtypen.

  1. In de omgeving wordt het basisproject CreateProject aangeroepen en terwijl het project zijn projectbestand parseert, wordt gedetecteerd dat de lijst met GUID's van het geaggregeerde projecttype niet null is. Het project stopt rechtstreeks met het maken van het project.

  2. Het project roept QueryServiceSVsCreateAggregateProject service aan om een projectsubtype te maken met behulp van de implementatie van de methode van de CreateAggregateProject omgeving. Binnen deze methode maakt de omgeving recursieve functie-aanroepen naar uw implementaties vanPreCreateForOuterSetInnerProject, en InitializeForOuter methoden terwijl deze de lijst met projecttype-GUID's doorloopt, te beginnen met het buitenste projectsubtype.

    Hieronder worden de initialisatiestappen beschreven.

    1. De implementatie van de methode in de CreateAggregateProject omgeving roept de HrCreateInnerProj methode aan met de volgende functiedeclaratie:

      <CodeContentPlaceHolder>0

      Wanneer deze functie voor het eerst wordt aangeroepen, dat wil gezegd, voor het buitenste projectsubtype, worden de parameters pOuter en pOwner doorgegeven als null en de functie stelt het buitenste projectsubtype IUnknown in op pOuter.

    2. Vervolgens roept de omgeving de HrCreateInnerProj functie aan met de tweede projecttype-GUID in de lijst. Deze GUID komt overeen met het tweede subtype van het binnenste project dat in de aggregatiereeks naar het basisproject stapt.

    3. Het pOuter verwijst nu naar het IUnknown buitenste projectsubtype en HrCreateInnerProj roept uw implementatie aan van PreCreateForOuter gevolgd door een aanroep naar uw implementatie van SetInnerProject. In de PreCreateForOuter-methode geeft u het controle-element IUnknown van het buitenste projectsubtype pOuter op. Het eigen project (inner project-subtype) moet hier zijn geaggregeerde projectobject maken. In de SetInnerProject methode-implementatie geeft u een aanwijzer door naar het IUnknown binnenste project dat wordt samengevoegd. Met deze twee methoden wordt het aggregatieobject gemaakt en moeten uw implementaties COM-aggregatieregels volgen om ervoor te zorgen dat een projectsubtype geen verwijzingsaantal voor zichzelf bevat.

    4. HrCreateInnerProj roept uw implementatie van PreCreateForOuter aan. In deze methode voert het subtype van het project zijn initialisatiewerk uit. U kunt bijvoorbeeld oplossingsevenementen registreren in InitializeForOuter.

    5. HrCreateInnerProj wordt recursief aangeroepen totdat de laatste GUID (het basisproject) in de lijst is bereikt. Voor elk van deze aanroepen worden de stappen, c tot en met d, herhaald. pOuter verwijst naar het buitenste projectsubtype IUnknown voor elk aggregatieniveau.

Voorbeeld

In het volgende voorbeeld wordt het programmatische proces in een benaderende weergave van de CreateAggregateProject-methode beschreven, zoals deze door de omgeving wordt geïmplementeerd. De code is slechts een voorbeeld; het is niet bedoeld om te worden gecompileerd en alle foutcontrole is voor de duidelijkheid verwijderd.

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