之前我发了一篇文章《对话框中嵌入多视图的一种方法》, 不适用于是主对话框的情况,看如下语句,
CFrameWnd *pFrame = (CFrameWnd*)this;
类类型的强制转型是非常不安全的,转型之后pFrame指针指向的却是你应用程序类对象CXXXXApp,那么如果再调用GetActiveView(), SetActiveView()就会出错。
所以必须为对话框加入GetActiveView和SerActiveView两个成员函数,具体实现如下:
对话框头文件中加入如下声明:
CView* GetActiveView() const;
CView* m_pViewActive;
void SetActiveView(CView* pViewNew, BOOL bNotify = TRUE);
GetActiveView函数很简单,如下定义:
CView* CXXXXDlg::GetActiveView() const
{
ASSERT(m_pViewActive == NULL ||
m_pViewActive->IsKindOf(RUNTIME_CLASS(CView)));
return m_pViewActive;
}
SetActiveView函数如下定义:
void CXXXXDlg::SetActiveView(CView *pViewNew, BOOL bNotify)
{
CView* pViewOld = m_pViewActive;
if (pViewNew == pViewOld)
return; // do not re-activate if SetActiveView called more than once
m_pViewActive = NULL; // no active for the following processing
// deactivate the old one
if (pViewOld != NULL)
pViewOld->SendMessage(WM_ACTIVATE, WA_INACTIVE, 0);
m_pViewActive = pViewNew;
// activate
if (pViewNew != NULL && bNotify)
pViewNew->SendMessage(WM_ACTIVATE, WA_ACTIVE, 0);
}
SetActiveView函数中采用SendMessage的方法来activate视图,因为OnActivateView在CView中是protected成员,不能在对话框中的成员函数中调用。最后的实现方法与《对话框中嵌入多视图的一种方法》相似,直接调用GetActiveView和SetActiveView即可,而不需要再类型转换。