但是这样做会出错C:\Documents and Settings\Administrator\桌面\fz20031\MainFrm.cpp(103) : error C2248: 'Create' : cannot access protected member declared in class 'CFormView' c:\program files\microsoft visual studio\vc98\mfc\include\afxext.h(756) : see declaration of 'Create'
CViewClients* m_wndViewClients = (CViewClients*)pRC->CreateObject();
m_wndViewClients->Create(NULL,NULL,AFX_WS_DEFAULT_VIEW, CRect(0,0,0,0), this, AFX_IDW_PANE_FIRST, NULL);
c:\program files\microsoft visual studio\vc98\mfc\include\afxext.h(756) : see declaration of 'Create'
把派生于CFormView的CViewClients类的protected构造函数改为public即可。
CViewClients* m_wndViewClients = (CViewClients*)pRC->CreateObject(); 句改成: CViewClients* m_wndViewClients = new CViewClients;
构造函数还是 public 。 试一试。
改为:
CView* m_wndViewClients = new CViewClients; 再Create必定成功。 通过父类指针的虚调用机制,即可正确调用到该protected member。 你要理解实际发生的事情:
CViewClients public CFormView public CView public CWnd
CWnd 的 Create是public virtual function,所以这里m_wndViewClients->Create(...)
是调用的是public的CWnd::Create(...),但由于该函数是
virtual function,于是进行运行时对象判别,发现是一个派生类CFormView对象,于是调
用CFormView::Create(...),如果你在CViewClients中重载该
virtual function,它同样调用CViewClients::Create(...),即使它是protected。 多查查MSDN。看一下MFC的源文件。
我昨天已经这样改了,运行成功,但是出现了一个更奇怪的事情。当显示先建的那个视图(现在基类为CView)时,视图中什么也没有,我已经在DRAW函数中添加了一些代码,但是没有显示。
1.view Create时显式调用OnInitialUpdate()没有。
2.view 显示时有没有设定失效区Invalidate() ,InvalidateRect
3.view 的坐标映射方式。
//这是在APP中动态创建一个CView的视图.开始的视图基于CFormView.
CView *pActiveView=((CFrameWnd *)m_pMainWnd)->GetActiveView();
m_pOldView=pActiveView;
m_pNewView=(CView *)new CDialogRecordShow;
CDocument* pCurrentDoc=((CFrameWnd *)m_pMainWnd)->GetActiveDocument();
CCreateContext newContext;
newContext.m_pNewViewClass=NULL;
newContext.m_pNewDocTemplate=NULL;
newContext.m_pLastView=NULL;
newContext.m_pCurrentFrame=NULL;
newContext.m_pCurrentDoc=pCurrentDoc; UINT viewID=AFX_IDW_PANE_FIRST+1;
CRect rect(0,0,0,0);
m_pNewView->Create(NULL,"AnyWindowName",WS_CHILD,rect,m_pMainWnd,viewID,&newContext);
m_pNewView->SendMessage(WM_INITIALUPDATE,0,0);
//视图切换函数
CView * CFz2003App::SwitchView()
{
CView * pActiveView=((CFrameWnd *)m_pMainWnd)->GetActiveView();
CView * pNewView =NULL;
if(pActiveView==m_pOldView)
pNewView=m_pNewView;
else
pNewView=m_pOldView;
UINT temp=::GetWindowLong(pActiveView->m_hWnd,GWL_ID);
::SetWindowLong(pActiveView->m_hWnd,GWL_ID,::GetWindowLong(pNewView->m_hWnd,GWL_ID));
::SetWindowLong(pActiveView->m_hWnd,GWL_ID,temp);
pActiveView->ShowWindow(SW_HIDE);
pNewView->ShowWindow(SW_SHOW);
//m_pNewView->OnInitialUpdate();
((CFrameWnd *)m_pMainWnd)->SetActiveView(pNewView);
((CFrameWnd *)m_pMainWnd)->RecalcLayout();
pNewView->Invalidate();
//((CFrameWnd *)m_pMainWnd)->UpdateWindow();
return pActiveView;}
void CFz2003App::OnShow()
{
SwitchView();
// TODO: Add your command handler code here
}
pNewView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);