Поделиться через


Инициализация последовательности подтипов проекта

Среда создает проект путем вызова базовой реализации фабрики проектов CreateProject. Создание подтипа проекта начинается, когда среда определяет, что список GUID типа проекта для расширения файла проекта не пуст. Расширение файла проекта и GUID проекта указывают, является ли проект типом проекта Visual Basic или Visual C#. Например, расширение Vbproj и {F184B08F-C81C-45F6-A57F-5ABD99991F28F} определите проект Visual Basic.

Инициализация подтипов проекта среды

Следующая процедура содержит сведения о последовательности инициализации для системы проекта, агрегированной несколькими подтипами проекта.

  1. Среда вызывает базовый проект CreateProject, и пока проект анализирует файл проекта, он обнаруживает, что список идентификаторов GUID типа агрегатного проекта не nullявляется. Проект прекращает непосредственное создание проекта.

  2. Проект вызывает QueryService SVsCreateAggregateProject службу для создания подтипа CreateAggregateProject проекта с помощью реализации метода среды. В этом методе среда выполняет рекурсивные вызовы PreCreateForOuterфункций для реализаций и InitializeForOuter методов, пока он идет по списку ИДЕНТИФИКАТОРов типов проекта, SetInnerProject начиная с самого внешнего подтипа проекта.

    Ниже описаны шаги инициализации.

    1. Реализация метода среды CreateAggregateProject вызывает HrCreateInnerProj метод со следующим объявлением функции:

      <CodeContentPlaceHolder>0

      Когда эта функция вызывается в первый раз, то есть для самого внешнего подтипа проекта, параметры pOuter и передаются как null и pOwner функция задает самый внешний подтип IUnknown pOuterпроекта.

    2. Затем функция вызова HrCreateInnerProj среды со вторым идентификатором GUID типа проекта в списке. Этот GUID соответствует второму внутреннему подтипу проекта, который выполняется в направлении базового проекта в последовательности агрегирования.

    3. Теперь указывает pOuter на внешний подтип проекта и HrCreateInnerProj вызывает реализациюPreCreateForOuter, за которой следует вызов вашей реализацииSetInnerProjectIUnknown. В PreCreateForOuter методе вы передаете управление IUnknown самым внешним подтипом проекта. pOuter Собственный проект (внутренний подтип проекта) должен создать здесь свой агрегатный объект проекта. SetInnerProject В реализации метода вы передаете указатель на IUnknown внутренний проект, который агрегируется. Эти два метода создают объект агрегирования, и реализации должны следовать правилам статистической обработки COM, чтобы убедиться, что подтип проекта не содержит к себе счетчик ссылок.

    4. HrCreateInnerProj вызывает реализацию PreCreateForOuter. В этом методе подтип проекта выполняет свою инициализацию. Например, можно регистрировать события решения в InitializeForOuter.

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