一直使用这个方法进行视图的动态创建,从没遇到过问题。今天需要从一继承自CView的视图类创建。结果遇到失败!!!
这里的pViewClass就是你想创建的视图类用法如下:
CChildFrame* pChildFrame = (CChildFrame*)CreateNewView(IDR_MAINFRAME,RUNTIME_CLASS(CChildFrame),
RUNTIME_CLASS(CView),pDocument);
这里只要我使用RUNTIME_CLASS(CView)就失败,或者自己从CView继承的类也是失败,如果换做其他的比如CListView或者子类,都没有问题。唯独CView遇到问题,我很纳闷,跟踪无果,再说其他CListView最终也是继承自CView的啊。大家帮忙看看,谢谢了。CMDIChildWndEx* CMainFrame::CreateNewView(UINT nIDResource, CRuntimeClass *pFrameClass, CRuntimeClass *pViewClass, CDocument *pDoc)
{
CMDIChildWndEx* pFrame=(CMDIChildWndEx*)pFrameClass->CreateObject();
ASSERT_KINDOF(CMDIChildWndEx, pFrame); CCreateContext context;
context.m_pCurrentDoc=pDoc; // use existing document
context.m_pCurrentFrame=NULL; //pFrame;// new child frame to be upon
context.m_pNewViewClass=pViewClass; // RUNTIME_CLASS(CMyHtmlView);// new view to be created
context.m_pNewDocTemplate=pDoc->GetDocTemplate(); //pTemplate;// use existing document template
context.m_pLastView=NULL; // no if (!pFrame->LoadFrame(nIDResource,WS_OVERLAPPEDWINDOW|FWS_ADDTOTITLE,/*AfxGetMainWnd()*/this,&context))
{
TRACE(L"Warning: Couldn't load frame window!\n");
AfxMessageBox(_T("Warning: Couldn't load frame window!\n"));
return NULL;
} pFrame->InitialUpdateFrame(pDoc,TRUE);
//just delagate to implementation in CFrameWnd
//pTemplate->InitialUpdateFrame(pHtmlChild,pDoc,TRUE); //it worked!
return pFrame;
}
这里的pViewClass就是你想创建的视图类用法如下:
CChildFrame* pChildFrame = (CChildFrame*)CreateNewView(IDR_MAINFRAME,RUNTIME_CLASS(CChildFrame),
RUNTIME_CLASS(CView),pDocument);
这里只要我使用RUNTIME_CLASS(CView)就失败,或者自己从CView继承的类也是失败,如果换做其他的比如CListView或者子类,都没有问题。唯独CView遇到问题,我很纳闷,跟踪无果,再说其他CListView最终也是继承自CView的啊。大家帮忙看看,谢谢了。CMDIChildWndEx* CMainFrame::CreateNewView(UINT nIDResource, CRuntimeClass *pFrameClass, CRuntimeClass *pViewClass, CDocument *pDoc)
{
CMDIChildWndEx* pFrame=(CMDIChildWndEx*)pFrameClass->CreateObject();
ASSERT_KINDOF(CMDIChildWndEx, pFrame); CCreateContext context;
context.m_pCurrentDoc=pDoc; // use existing document
context.m_pCurrentFrame=NULL; //pFrame;// new child frame to be upon
context.m_pNewViewClass=pViewClass; // RUNTIME_CLASS(CMyHtmlView);// new view to be created
context.m_pNewDocTemplate=pDoc->GetDocTemplate(); //pTemplate;// use existing document template
context.m_pLastView=NULL; // no if (!pFrame->LoadFrame(nIDResource,WS_OVERLAPPEDWINDOW|FWS_ADDTOTITLE,/*AfxGetMainWnd()*/this,&context))
{
TRACE(L"Warning: Couldn't load frame window!\n");
AfxMessageBox(_T("Warning: Couldn't load frame window!\n"));
return NULL;
} pFrame->InitialUpdateFrame(pDoc,TRUE);
//just delagate to implementation in CFrameWnd
//pTemplate->InitialUpdateFrame(pHtmlChild,pDoc,TRUE); //it worked!
return pFrame;
}
or DECLARE_SERIAL: CView.
Error: Trying to create object which is not DECLARE_DYNCREATE
or DECLARE_SERIAL: CView.这不有个错误提示吗
CListView 就支持动态创建
afxcview.hclass CListView : public CCtrlView
{
DECLARE_DYNCREATE(CListView)CView 就不支持
afxwin.hclass CView : public CWnd
{
DECLARE_DYNAMIC(CView)
cc.m_pCurrentDoc = NULL;
cc.m_pCurrentFrame = this;
cc.m_pLastView = NULL;
cc.m_pNewDocTemplate = NULL;
cc.m_pNewViewClass = RUNTIME_CLASS(CMyVView); CView *m_pviewLogin = (CView*)this->CreateView(&cc);
if(m_pviewLogin == NULL)
{
TRACE("CreateView failed!\n");
return -1;
}
m_pviewLogin->ModifyStyleEx(WS_EX_CLIENTEDGE,NULL);
class CMyVView : public CView
{
DECLARE_DYNCREATE(CMyVView)protected:
CMyVView(); // 动态创建所使用的受保护的构造函数
virtual ~CMyVView();public:
virtual void OnDraw(CDC* pDC); // 重写以绘制该视图
#ifdef _DEBUG
virtual void AssertValid() const;
#ifndef _WIN32_WCE
virtual void Dump(CDumpContext& dc) const;
#endif
#endifprotected:
DECLARE_MESSAGE_MAP()
};
不知道你是怎么做的,反正我随便继承个CView,如此创建就成功了
我产品的工程好像有问题,一定是我别的地方有问题。看来麻烦大了当初为了研究我的这个CreateNewView()方法,深入的研读了MFC SRC代码,追踪了MFC VIEW/DOC的机制。当时确信这个方法应该是没有问题的了,今天突然懵了MDI工程,针对同一个文档的多视图创建,比如一个CView、CListView、CChartView,大家都是如何实现同一个数据源的多视图展示?有否别的方法分享?谢谢。
CMyView里面又引用了该视图视图使用的框架类头文件,导致无法预知的引用错误,可能如此。
正在修改测试。MFC的文档视图架构实在太复杂,MFC的封装也很是难于理解。我当初花费了3个月的时间研读MFC SRC关于DOC/VIEW部分的实现框架,基本上还比较清楚,也很佩服MFC的源代码的优雅。
我是用vs2008做的mfc程序,将模板定义修改为:
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_MAINFRAME,
RUNTIME_CLASS(CVAppExeDoc),
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
RUNTIME_CLASS(CVAppExeView));
进行了屏蔽系统自身菜单,加载自定义菜单,做了不少工作,后面也成功了。
动态创建是通过一个命令调用一个dll,这个dll再发消息到mainframe进行创建,
创建代码如下:
CChildFrame* pFrame = new CChildFrame;
CCreateContext Context;
CVAppExeDoc* pMsgsManagerDoc = (CVAppExeDoc*)(RUNTIME_CLASS(CVAppExeDoc)->CreateObject());
Context.m_pCurrentDoc = pMsgsManagerDoc ;
Context.m_pLastView = NULL;
Context.m_pNewDocTemplate = NULL;
Context.m_pCurrentFrame = this;
POSITION pos = theApp.m_pDocManager->GetFirstDocTemplatePosition();
Context.m_pNewDocTemplate = theApp.m_pDocManager->GetNextDocTemplate(pos);
Context.m_pNewViewClass = RUNTIME_CLASS(CVAppExeView); pFrame->LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | WS_CAPTION | FWS_ADDTOTITLE, this, &Context ); CVAppExeView* pView = (CVAppExeView*)(Context.m_pLastView);
ASSERT(pView);然后就在ASSERT(pView);出现断言,
有朋友可以帮忙看下吗?