Condividi tramite


Sequenza di inizializzazione dei sottotipi di progetto

L'ambiente costruisce un progetto chiamando l'implementazione della factory di progetto di base di CreateProject. La costruzione di un sottotipo di progetto inizia quando l'ambiente determina che l'elenco GUID del tipo di progetto per l'estensione di un file di progetto non è vuoto. L'estensione del file di progetto e il GUID del progetto specificano se il progetto è un tipo di progetto Visual Basic o Visual C#. Ad esempio, l'estensione vbproj e {F184B08F-C81C-45F6-A57F-5ABD9991F28F} identificano un progetto Visual Basic.

Inizializzazione dell'ambiente dei sottotipi di progetto

La procedura seguente illustra in dettaglio la sequenza di inizializzazione per un sistema di progetto aggregato da più sottotipi di progetto.

  1. L'ambiente chiama il progetto di CreateProjectbase e, mentre il progetto analizza il file di progetto, rileva che l'elenco DI GUID del tipo di progetto aggregato non nullè . Il progetto non viene più creato direttamente.

  2. Il progetto chiama QueryService il SVsCreateAggregateProject servizio per creare un sottotipo di progetto usando l'implementazione dell'ambiente del CreateAggregateProject metodo . All'interno di questo metodo l'ambiente esegue chiamate di funzione ricorsive alle implementazioni di PreCreateForOuterSetInnerProject e InitializeForOuter i metodi mentre si trova nell'elenco dei GUID del tipo di progetto, a partire dal sottotipo di progetto più esterno.

    Di seguito vengono descritti in dettaglio i passaggi di inizializzazione.

    1. L'implementazione dell'ambiente del CreateAggregateProject metodo chiama il HrCreateInnerProj metodo con la dichiarazione di funzione seguente:

      <CodeContentPlaceHolder>0

      Quando questa funzione viene chiamata per la prima volta, ovvero per il sottotipo di progetto più esterno, i parametri pOuter e pOwner vengono passati come null e la funzione imposta il sottotipo IUnknown di progetto più esterno su pOuter.

    2. Successivamente, l'ambiente chiama HrCreateInnerProj la funzione con il secondo GUID del tipo di progetto nell'elenco. Questo GUID corrisponde al secondo sottotipo di progetto interno che esegue l'istruzione verso il progetto di base nella sequenza di aggregazione.

    3. ora pOuter punta al IUnknown sottotipo del progetto più esterno e HrCreateInnerProj chiama l'implementazione di PreCreateForOuter seguita da una chiamata all'implementazione di SetInnerProject. Nel PreCreateForOuter metodo si passa il controllo IUnknown del sottotipo di progetto più esterno, pOuter. Il progetto di proprietà (sottotipo di progetto interno) deve creare qui il relativo oggetto progetto aggregato. Nell'implementazione del SetInnerProject metodo si passa un puntatore all'oggetto IUnknown del progetto interno che viene aggregato. Questi due metodi creano l'oggetto di aggregazione e le implementazioni devono seguire le regole di aggregazione COM per assicurarsi che un sottotipo di progetto non finirà per contenere un conteggio dei riferimenti a se stesso.

    4. HrCreateInnerProj chiama l'implementazione di PreCreateForOuter. In questo metodo, il sottotipo di progetto esegue il lavoro di inizializzazione. È ad esempio possibile registrare gli eventi della soluzione in InitializeForOuter.

    5. HrCreateInnerProj viene chiamato in modo ricorsivo finché non viene raggiunto l'ultimo GUID (progetto di base) nell'elenco. Per ognuna di queste chiamate, i passaggi, da c a d, vengono ripetuti. pOuter punta al sottotipo IUnknown di progetto più esterno per ogni livello di aggregazione.

Esempio

Nell'esempio seguente viene descritto in dettaglio il processo programmatico in una rappresentazione approssimativa del CreateAggregateProject metodo come implementato dall'ambiente. Il codice è solo un esempio; non è progettato per essere compilato e tutto il controllo degli errori è stato rimosso per maggiore chiarezza.

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