Sekwencja inicjowania podtypów projektów
Środowisko konstruuje projekt przez wywołanie podstawowej implementacji CreateProjectfabryki projektu . Konstrukcja podtypu projektu rozpoczyna się, gdy środowisko określa, że lista identyfikatorów GUID typu projektu dla rozszerzenia pliku projektu nie jest pusta. Rozszerzenie pliku projektu i identyfikator GUID projektu określają, czy projekt jest typem projektu Visual Basic, czy Visual C#. Na przykład rozszerzenie vbproj i {F184B08F-C81C-45F6-A57F-5ABD99991F28F} identyfikują projekt języka Visual Basic.
Inicjowanie podtypów projektu w środowisku
Poniższa procedura zawiera szczegóły sekwencji inicjowania systemu projektu zagregowanego przez wiele podtypów projektu.
Środowisko wywołuje element projektu CreateProjectpodstawowego , a projekt analizuje jego plik projektu, odnajduje, że lista identyfikatorów GUID typu projektu agregacji nie
null
jest . Projekt kończy bezpośrednie tworzenie projektu.Projekt wywołuje usługę
QueryService
SVsCreateAggregateProject w celu utworzenia podtypu projektu przy użyciu implementacji CreateAggregateProject środowiska metody . W ramach tej metody środowisko wykonuje cykliczne wywołania funkcji do implementacji PreCreateForOuterSetInnerProject metod i InitializeForOuter podczas przechodzenia przez listę identyfikatorów GUID typu projektu, począwszy od najbardziej zewnętrznego podtypu projektu.Poniżej przedstawiono szczegółowe instrukcje inicjowania.
Implementacja CreateAggregateProject środowiska metody wywołuje metodę
HrCreateInnerProj
za pomocą następującej deklaracji funkcji:<CodeContentPlaceHolder>0
Gdy ta funkcja jest wywoływana po raz pierwszy, oznacza to, że w przypadku najbardziej zewnętrznego podtypu projektu parametry
pOuter
ipOwner
są przekazywane jakonull
, a funkcja ustawia najbardziej zewnętrzny podtypIUnknown
projektu napOuter
wartość .Następnie środowisko wywołuje
HrCreateInnerProj
funkcję z drugim identyfikatorem GUID typu projektu na liście. Ten identyfikator GUID odpowiada drugiemu podtypowi projektu wewnętrznego krok po kroku w kierunku projektu podstawowego w sekwencji agregacji.Element
pOuter
wskazujeIUnknown
teraz na podtyp najbardziej zewnętrznego projektu iHrCreateInnerProj
wywołuje implementację PreCreateForOuter , po której następuje wywołanie implementacji SetInnerProjectelementu . W PreCreateForOuter metodzie przekazujesz kontrolęIUnknown
najbardziej zewnętrznego podtypu projektu,pOuter
. Należący do niego projekt (podtyp projektu wewnętrznego) musi utworzyć tutaj zagregowany obiekt projektu. W implementacji SetInnerProject metody przekazujesz wskaźnik doIUnknown
projektu wewnętrznego, który jest agregowany. Te dwie metody tworzą obiekt agregacji, a implementacje muszą być zgodne z regułami agregacji COM, aby upewnić się, że podtyp projektu nie zawiera liczby odwołań do siebie.HrCreateInnerProj
wywołuje implementację .PreCreateForOuter W tej metodzie podtyp projektu wykonuje swoją pracę inicjaliza. Możesz na przykład zarejestrować zdarzenia rozwiązania w programie InitializeForOuter.HrCreateInnerProj
jest wywoływana rekursywnie do momentu osiągnięcia ostatniego identyfikatora GUID (projektu podstawowego) na liście. Dla każdego z tych wywołań kroki, c przez d, są powtarzane.pOuter
wskazuje najbardziej zewnętrzny podtypIUnknown
projektu dla każdego poziomu agregacji.
Przykład
W poniższym przykładzie szczegółowo przedstawiono proces programowy w przybliżonej reprezentacji CreateAggregateProject metody, która jest implementowana przez środowisko. Kod jest tylko przykładem; nie jest przeznaczony do skompilowania, a wszystkie sprawdzanie błędów zostało usunięte w celu zapewnienia przejrzystości.
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);
}