该环境通过调用 CreateProject的基本项目工厂实现构造项目。 项目子类型的构造开始,当环境确定项类型 GUID 为项目文件的扩展列表不为空。 项目文件扩展名和项目 GUID 指定项目是否 Visual Basic 或 Visual C# 项类型。 例如, .vbproj 扩展名和 {F184B08F- C81 C-45F6-A57F-5ABD9991F28F} 标识一个 Visual Basic 项目。
项目子类型的环境的初始化
以下过程详细说明了多个项目子类型聚合的项目系统的初始化顺序。
该环境调用基项目的 CreateProject,,所以,当该项分析其项目文件时它发现复合项目类型 GUID 列表不是 null。 该项目停止直接创建它的项。
使用 CreateAggregateProject 方法的环境的实现,该项对 SVsCreateAggregateProject 服务的 QueryService 创建项目子类型。 在环境进行递归函数的方法中调用 PreCreateForOuter、 M:Microsoft.VisualStudio.Shell.Interop.IVsAggregatableProject.SetInnerProject(System.Object) 和 InitializeForOuter 方法的实现,当它来浏览项类型 GUID 列表时,从最外面的项目子类型开始。
下面详细介绍初始化步骤。
CreateAggregateProject 方法环境的实现调用具有以下特点声明的 HrCreateInnerProj方法:
HRESULT HrCreateInnerProj ( WCHAR *pwszGuids, IUnknown *pOuter, IVsAggregatableProject *pOwner, LPCOLESTR pszFilename, LPCOLESTR pszLocation, LPCOLESTR pszName, VSCREATEPROJFLAGS grfCreateFlags, IUnknown **ppInner, BOOL *pfCancelled )
虽然此功能最外面的项目子类型时第一次调用,也就是说,参数, pOuter 和 pOwner 通过,当 null 和函数用于设置最外面的项目子类型 IUnknown 到 pOuter。
接下来该环境调用与第二个项目类型的 GUID 的 HrCreateInnerProj 功能在列表中。 此 GUID 对应于遍历从拖向摘要序列的基项目的第二个内部项的子类型。
pOuter 现在指向最外面的项目子类型的 IUnknown ,并且, HrCreateInnerProj 调用 PreCreateForOuter 的实现中调用遵循为 SetInnerProject的实现。 在 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);
}
请参见
参考
Microsoft.VisualStudio.Shell.Flavor