환경은 기본 프로젝트 팩터리 구현을 호출하여 프로젝트를 생성합니다 CreateProject. 프로젝트 하위 형식의 생성은 환경이 프로젝트 파일의 확장 프로그램에 대한 프로젝트 형식 GUID 목록이 비어 있지 않다고 판단할 때 시작됩니다. 프로젝트 파일 확장명과 프로젝트 GUID는 프로젝트가 Visual Basic 또는 Visual C# 프로젝트 형식인지 여부를 지정합니다. 예를 들어 .vbproj 확장 및 {F184B08F-C81C-45F6-A57F-5ABD9991F28F}은 Visual Basic 프로젝트를 식별합니다.
환경의 프로젝트 하위 형식 초기화
다음 절차에서는 여러 프로젝트 하위 형식으로 집계된 프로젝트 시스템의 초기화 시퀀스를 자세히 설명합니다.
환경은 기본 프로젝트를 CreateProject호출하고 프로젝트가 프로젝트 파일을 구문 분석하는 동안 집계 프로젝트 형식 GUID 목록이 아니라
null는 것을 발견합니다. 프로젝트는 직접 프로젝트 만들기를 중단합니다.이 프로젝트는 서비스를 호출
QueryServiceSVsCreateAggregateProject 하여 환경의 메서드 구현을 사용하여 프로젝트 하위 형식을 만듭니다 CreateAggregateProject . 이 메서드 내에서 환경은 가장 바깥쪽 프로젝트 하위 형식부터 시작하여 프로젝트 형식 GUID 목록을 탐색하는 동안 사용자 구현 PreCreateForOuterSetInnerProject 및 InitializeForOuter 메서드에 대한 재귀 함수 호출을 수행합니다.다음은 초기화 단계에 대해 자세히 설명합니다.
환경의 메서드 구현은 CreateAggregateProject 다음 함수 선언을 사용하여
HrCreateInnerProj메서드를 호출합니다.<CodeContentPlaceHolder>0
이 함수가 처음으로 호출되는 경우, 즉 가장 바깥쪽 프로젝트 하위 형식의 경우 매개 변수
pOuter가pOwner전달null되고 함수는 가장 바깥쪽 프로젝트 하위 형식IUnknown을 로pOuter설정합니다.그런 다음, 환경에서 목록에서 두 번째 프로젝트 형식 GUID를 사용하여 함수를 호출
HrCreateInnerProj합니다. 이 GUID는 집계 시퀀스에서 기본 프로젝트를 향해 스테핑하는 두 번째 내부 프로젝트 하위 형식에 해당합니다.pOuter이제 가장 바깥쪽 프로젝트 하위 형식을 가리키IUnknown고HrCreateInnerProj구현을 호출한 다음 구현을 호출 PreCreateForOuterSetInnerProject합니다. 메서드에서 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);
}