Partilhar via


Sequência de inicialização de subtipos de projeto

O ambiente constrói um projeto chamando a implementação de fábrica do projeto base de CreateProject. A construção de um subtipo de projeto começa quando o ambiente determina que a lista GUID do tipo de projeto para a extensão de um arquivo de projeto não está vazia. A extensão do arquivo de projeto e o GUID do projeto especificam se o projeto é um tipo de projeto Visual Basic ou Visual C#. Por exemplo, a extensão .vbproj e {F184B08F-C81C-45F6-A57F-5ABD9991F28F} identificam um projeto do Visual Basic.

Inicialização do ambiente de subtipos de projeto

O procedimento a seguir detalha a sequência de inicialização de um sistema de projeto agregado por vários subtipos de projeto.

  1. O ambiente chama o projeto base de , e enquanto o projeto analisa seu arquivo de projeto, ele descobre que a lista de GUIDs CreateProjectdo tipo de projeto agregado não nullé . O projeto descontinua diretamente a criação de seu projeto.

  2. O projeto chama QueryService o SVsCreateAggregateProject serviço para criar um subtipo de projeto usando a implementação do CreateAggregateProject método pelo ambiente. Dentro desse método, o ambiente faz chamadas de função recursivas para suas implementações de , e InitializeForOuter métodos enquanto ele está andando a lista de GUIDs de tipo de projeto, SetInnerProject começando com o subtipo de PreCreateForOuterprojeto mais externo.

    O seguinte detalha as etapas de inicialização.

    1. A implementação do ambiente do CreateAggregateProject método chama o HrCreateInnerProj método com a seguinte declaração de função:

      <CodeContentPlaceHolder>0

      Quando essa função é chamada pela primeira vez, ou seja, para o subtipo de projeto mais externo, os parâmetros pOuter e são passados como null e pOwner a função define o subtipo IUnknown de projeto mais externo como pOuter.

    2. Em seguida, o ambiente chama HrCreateInnerProj a função com o segundo tipo de projeto GUID na lista. Esse GUID corresponde ao segundo subtipo de projeto interno que entra em direção ao projeto base na sequência de agregação.

    3. O pOuter agora está apontando para o IUnknown subtipo de projeto mais externo e HrCreateInnerProj chama sua implementação de seguido por uma chamada para sua implementação de PreCreateForOuter SetInnerProject. No PreCreateForOuter método, você passa o controle IUnknown do subtipo de projeto mais externo, pOuter. O projeto próprio (subtipo de projeto interno) precisa criar seu objeto de projeto agregado aqui. Na implementação do método, você passa um ponteiro para o IUnknown do SetInnerProject projeto interno que está sendo agregado. Esses dois métodos criam o objeto de agregação e suas implementações precisam seguir regras de agregação COM para garantir que um subtipo de projeto não acabe mantendo uma contagem de referência para si mesmo.

    4. HrCreateInnerProj chama sua implementação de PreCreateForOuter. Nesse método, o subtipo de projeto faz seu trabalho de inicialização. Você pode, por exemplo, registrar eventos de solução no InitializeForOuter.

    5. HrCreateInnerProj é chamado recursivamente até que o último GUID (o projeto base) na lista seja alcançado. Para cada uma dessas chamadas, as etapas, c a d, são repetidas. pOuter aponta para o subtipo IUnknown de projeto mais externo para cada nível de agregação.

Exemplo

O exemplo a seguir detalha o processo programático em uma representação aproximada do CreateAggregateProject método à medida que ele é implementado pelo ambiente. O código é apenas um exemplo; ele não se destina a ser compilado, e toda a verificação de erros foi removida para maior clareza.

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