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.
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.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.
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
epOwner
vengono passati comenull
e la funzione imposta il sottotipoIUnknown
di progetto più esterno supOuter
.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.ora
pOuter
punta alIUnknown
sottotipo del progetto più esterno eHrCreateInnerProj
chiama l'implementazione di PreCreateForOuter seguita da una chiamata all'implementazione di SetInnerProject. Nel PreCreateForOuter metodo si passa il controlloIUnknown
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'oggettoIUnknown
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.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.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 sottotipoIUnknown
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);
}