我以前在MFC应用程序中使用CSplitterWnd
,使用它的CreateView
函数。一切都工作正常,但现在我想将一个参数传递给我的视图的构造函数,所以我不能使用MFC动态对象创建(DECLARE_DYNCREATE
和IMPLEMENT_DYNCREATE
),因为它们需要一个空构造函数。
在互联网上搜索了一下后,我找到了一个看起来像这样的例子:
m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CMyView), CSize(0,0), pContext);
m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CMyView), CSize(0,0), pContext);
m_pView0=(CMyView *)m_wndSplitter.GetPane(0,0);
m_pView1=(CMyView *)m_wndSplitter.GetPane(0,1);
这可能是一种解决方法(即:在CMyView
中创建一个新功能,让我指定我想要的东西),但这很难看并且容易出错。任何人都知道我是否还有其他办法可以做到这一点?
编辑:在ee回答后添加更多详细信息:
你的权利,初始化方法可以工作,但这迫使我记得调用初始化方法,但就像你指出我可能不会多次创建这些视图,所以应该没问题。我可能想要的另一件事是自己管理视图的生命周期,所以再次使用CreateView是不可能的。
由于
答案 0 :(得分:1)
当你说它会变得丑陋且容易出错时,你的意思是你的视图创作会在很多地方多次发生吗?如果是这样,那么我会部分同意你的看法。
但是,如果您只有两个案例,其中您在应用启动时创建视图,那么“丑陋”和“容易出错”归结为另外两行:
m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CMyView), CSize(0,0), pContext);
m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CMyView), CSize(0,0), pContext);
m_pView0=(CMyView *)m_wndSplitter.GetPane(0,0);
m_pView1=(CMyView *)m_wndSplitter.GetPane(0,1);
//additional stuff
m_pView0->Initialize(v1, v2, v3);
m_pView1->Initialize(v4, v5, v6);
这对我来说似乎并不那么糟糕。也许您正试图避免某种特定情况?
答案 1 :(得分:0)
我认为没有办法将视图指针交给拆分器窗口。相反,您需要从CWplitterWnd
派生一个类并覆盖CreateView
虚拟方法。
默认方法与pClass->CreateObject()
类似,但您的版本可以根据需要创建对象。但是,您将需要处理该方法处理的任何其他详细信息,因为您将无法调用默认实现。
答案 2 :(得分:0)
我没有尝试过,但我认为这样的事情应该有效:
CMyView *pView = new CMyView( PARAM );
splitter.CreateView( 0,
0,
pView->GetRuntimeClass(),
size,
0);
显然你仍然需要在你的视图中使用DECLARE_DYNCREATE(CMyView),你需要提供一个默认的构造函数,但是你可以使用参数化的构造函数。
答案 3 :(得分:0)
在检查了Javier De Pedro的答案之后我虽然可以覆盖创建功能所以我做了(半伪代码):
class ObjGetter
{
static CObject* obj;
public:
ObjGetter(CObject* obj_){obj = obj_;}
static CObject* __stdcall getObj() { return obj; }
};
CObject* ObjGetter::obj = NULL;
BOOL CMyFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
//...
myView = new CMyView(NULL);
CRuntimeClass rt(*myView->GetRuntimeClass());
ObjGetter objGetter(myView);
rt.m_pfnCreateObject = &ObjGetter::getObj;
m_wndSplitter.CreateView(0,0, &rt, CSize(0,0), pContext);
}
现在这项工作但是有一个问题,它会在关闭时破坏我的课程,我说我可能想要自己跟踪内存,所以我在CMyView中重载PostNcDestroy什么也不做,而不是调用delete这个:
CMyView::PostNcDestroy(){}
现在它应该防止它被删除但现在它在退出时崩溃所以我覆盖CMyFrame :: OnClose如下:
void CMyFrame::OnClose()
{
m_wndSplitter.DeleteView(0, 0);
delete myView; myView = NULL; //seems to be needed to be deleted before
//CFrameWnd::OnClose or it crash
CFrameWnd::OnClose();
}
现在理论上我应该能够将myView指针保留在其他地方,只要我在文档退出之前删除它。
感谢您的帮助。