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.
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.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.
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 comonull
epOwner
a função define o subtipoIUnknown
de projeto mais externo comopOuter
.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.O
pOuter
agora está apontando para oIUnknown
subtipo de projeto mais externo eHrCreateInnerProj
chama sua implementação de seguido por uma chamada para sua implementação de PreCreateForOuter SetInnerProject. No PreCreateForOuter método, você passa o controleIUnknown
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 oIUnknown
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.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.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 subtipoIUnknown
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);
}