專案子類型的初始化順序
環境藉由呼叫 CreateProject 的基底專案 Factory 實作來建構專案。 當環境判斷專案檔案副檔名的專案類型 GUID 清單不是空白時,開始建構專案子類型。 專案檔案副檔名和專案 GUID 指定專案是 Visual Basic 或 Visual C# 專案類型。 例如:.vbproj 副檔名和 {F184B08F-C81C-45F6-A57F-5ABD9991F28F} 識別 Visual Basic 專案。
環境的專案子類型初始化
下列程序詳細說明由多個專案子類型彙總的專案系統初始化順序。
環境呼叫基底專案的 CreateProject,而專案剖析其專案檔案時,它發現彙總專案類型 GUID 清單不是
null
。 專案不再直接建立其專案。專案呼叫 SVsCreateAggregateProject 服務上的
QueryService
,以使用環境的 CreateAggregateProject 方法實作來建立專案子類型。 在這個方法中,環境從最外層的專案子類型開始逐步執行專案類型 GUID 清單,同時對 PreCreateForOuter、SetInnerProject 和 InitializeForOuter 方法的實作進行遞迴函式呼叫。下面詳細介紹初始化步驟。
環境的 CreateAggregateProject 方法實作使用下列函式宣告呼叫
HrCreateInnerProj
方法:<CodeContentPlaceHolder>0
第一次呼叫此函式時,也就是對於最外層的專案子類型,參數
pOuter
和pOwner
會作為null
傳入,而且函式將最外層的專案子類型IUnknown
設定為pOuter
。接下來,環境使用清單中的第二個專案類型 GUID 來呼叫
HrCreateInnerProj
函式。 此 GUID 對應於彙總順序中逐步進入基底專案的第二個內部專案子類型。pOuter
現在指向最外層專案子類型的IUnknown
,HrCreateInnerProj
呼叫 PreCreateForOuter 的實作,然後呼叫 SetInnerProject 的實作。 在 PreCreateForOuter 方法中,您傳入最外層專案子類型pOuter
的控制IUnknown
。 擁有的專案 (內部專案子類型) 必須在這裡建立其彙總專案物件。 在 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);
}