Sdílet prostřednictvím


Inicializační sekvence podtypů projektů

Prostředí vytváří projekt voláním základní implementace objektu CreateProjectpro vytváření projektů . Konstrukce podtypu projektu začíná, když prostředí určí, že seznam GUID typu projektu pro příponu souboru projektu není prázdný. Přípona souboru projektu a identifikátor GUID projektu určují, zda je projekt typu projektu jazyka Visual Basic nebo Visual C#. Například rozšíření .vbproj a {F184B08F-C81C-45F6-A57F-5ABD9991F28F} identifikují projekt jazyka Visual Basic.

Inicializace podtypů projektu v prostředí

Následující postup podrobně popisuje inicializační sekvenci systému projektu agregovaného více podtypy projektu.

  1. Prostředí volá základní projekt CreateProjecta zatímco projekt parsuje jeho soubor projektu zjistí, že seznam GUID agregovaného typu projektu není null. Projekt přestane přímo vytvářet svůj projekt.

  2. Projekt volá QueryService službu k SVsCreateAggregateProject vytvoření podtypu projektu pomocí implementace CreateAggregateProject prostředí metody. V rámci této metody prostředí provádí rekurzivní funkce volání vašich implementací PreCreateForOuterSetInnerProject a InitializeForOuter metod, zatímco prochází seznam identifikátorů GUID typu projektu, počínaje vnějším podtypem projektu.

    Následující podrobnosti podrobně popisuje kroky inicializace.

    1. Implementace metody prostředí CreateAggregateProject volá metodu HrCreateInnerProj s následující deklarací funkce:

      <CodeContentPlaceHolder>0

      Pokud se tato funkce volá poprvé, tj. pro vnější podtyp projektu, parametry pOuter a pOwner jsou předány jako null a funkce nastaví vnější podtyp IUnknown projektu na pOuter.

    2. Dále funkce volání HrCreateInnerProj prostředí s druhým identifikátorem GUID typu projektu v seznamu. Tento identifikátor GUID odpovídá druhému podtypu vnitřního projektu krokování směrem k základnímu projektu v agregační sekvenci.

    3. Nyní pOuter ukazuje na IUnknown podtyp vnějšího projektu a HrCreateInnerProj volá vaši implementaci PreCreateForOuter SetInnerProject, po které následuje volání implementace . V PreCreateForOuter metodě předáváte řízení IUnknown vnějšího podtypu projektu , pOuter. Vlastní projekt (podtyp vnitřního projektu) musí zde vytvořit svůj agregovaný objekt projektu. V implementaci SetInnerProject metody předáte ukazatel na IUnknown vnitřní projekt, který je agregován. Tyto dvě metody vytvoří objekt agregace a vaše implementace musí dodržovat pravidla agregace modelu COM, aby se zajistilo, že podtyp projektu nebude držet počet odkazů na sebe sama.

    4. HrCreateInnerProj volá vaši implementaci PreCreateForOuter. V této metodě podtyp projektu funguje inicializace. Můžete například registrovat události řešení v InitializeForOuter.

    5. HrCreateInnerProj se nazývá rekurzivně, dokud se nedosáhne posledního identifikátoru GUID (základního projektu) v seznamu. U každého z těchto volání se opakují kroky c až d. pOuter odkazuje na podtyp IUnknown vnějšího projektu pro každou úroveň agregace.

Příklad

Následující příklad podrobně popisuje programový proces v přibližné reprezentaci CreateAggregateProject metody, protože je implementováno prostředím. Kód je jen příkladem; není určena ke kompilaci a veškerá kontrola chyb byla odstraněna z důvodu srozumitelnosti.

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