Инициализация последовательности подтипов проекта
Среда создает проект путем вызова базовой реализации фабрики проектов CreateProject. Создание подтипа проекта начинается, когда среда определяет, что список GUID типа проекта для расширения файла проекта не пуст. Расширение файла проекта и GUID проекта указывают, является ли проект типом проекта Visual Basic или Visual C#. Например, расширение Vbproj и {F184B08F-C81C-45F6-A57F-5ABD99991F28F} определите проект Visual Basic.
Инициализация подтипов проекта среды
Следующая процедура содержит сведения о последовательности инициализации для системы проекта, агрегированной несколькими подтипами проекта.
Среда вызывает базовый проект CreateProject, и пока проект анализирует файл проекта, он обнаруживает, что список идентификаторов GUID типа агрегатного проекта не
null
является. Проект прекращает непосредственное создание проекта.Проект вызывает
QueryService
SVsCreateAggregateProject службу для создания подтипа CreateAggregateProject проекта с помощью реализации метода среды. В этом методе среда выполняет рекурсивные вызовы PreCreateForOuterфункций для реализаций и InitializeForOuter методов, пока он идет по списку ИДЕНТИФИКАТОРов типов проекта, SetInnerProject начиная с самого внешнего подтипа проекта.Ниже описаны шаги инициализации.
Реализация метода среды CreateAggregateProject вызывает
HrCreateInnerProj
метод со следующим объявлением функции:<CodeContentPlaceHolder>0
Когда эта функция вызывается в первый раз, то есть для самого внешнего подтипа проекта, параметры
pOuter
и передаются какnull
иpOwner
функция задает самый внешний подтипIUnknown
pOuter
проекта.Затем функция вызова
HrCreateInnerProj
среды со вторым идентификатором GUID типа проекта в списке. Этот GUID соответствует второму внутреннему подтипу проекта, который выполняется в направлении базового проекта в последовательности агрегирования.Теперь указывает
pOuter
на внешний подтип проекта иHrCreateInnerProj
вызывает реализациюPreCreateForOuter, за которой следует вызов вашей реализацииSetInnerProjectIUnknown
. В PreCreateForOuter методе вы передаете управлениеIUnknown
самым внешним подтипом проекта.pOuter
Собственный проект (внутренний подтип проекта) должен создать здесь свой агрегатный объект проекта. SetInnerProject В реализации метода вы передаете указатель наIUnknown
внутренний проект, который агрегируется. Эти два метода создают объект агрегирования, и реализации должны следовать правилам статистической обработки COM, чтобы убедиться, что подтип проекта не содержит к себе счетчик ссылок.HrCreateInnerProj
вызывает реализацию PreCreateForOuter. В этом методе подтип проекта выполняет свою инициализацию. Например, можно регистрировать события решения в InitializeForOuter.HrCreateInnerProj
вызывается рекурсивно до достижения последнего GUID (базового проекта) в списке. Для каждого из этих вызовов повторяются шаги c через d.pOuter
указывает на самый внешний подтипIUnknown
проекта для каждого уровня агрегирования.
Пример
В следующем примере описывается программный процесс в приблизительном представлении CreateAggregateProject метода, реализованного средой. Код является просто примером; Он не предназначен для компиляции, и все ошибки, проверка, были удалены для ясности.
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);
}