用VC做软件的都知道,其实在做实际的项目的时候我们很少使用文档和视图结构的,一般对话框居多,但是要是在对话框上加上菜单和状态栏效果不是很好,比如对话框窗体大小发生变化时候,你必须去动态改变菜单和状态栏以适应对话框窗体的变化 。而窗体单文档或者多文档框架机构就为我们提供了一个很好的这样的界面。我想完全可以利用的。话题好像远了,我们直接开始无文档视图结构的拆分窗体吧。
先给个最终运行效果。
左边框架的view里面是一个treectrl 右边view里面是一个listctrl。
我记录下我的实现步骤。
开始我想在建立程序的时候选择的是单文档 无文档/视图结构支持。发现向导生成的类里面有个CChildView,我看了下这个CChildView是继承自CWnd,于是我又建立一个“视图”继承自CWnd心想:然后用CSplitterWnd拆分下,然后降这两个视图加进去不就OK了?动手!
第一步:在CMainFrame类中加入成员变量:
CSplitterWnd m_wndSplitter;
第二步:
重写OnCreateClient,代码如下:
...{
m_wndSplitter.CreateStatic(this,1,2);
m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CChildView), CSize(180, 100), pContext);
m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(C2View), CSize(100, 100), pContext);
//return CFrameWnd::OnCreateClient(lpcs, pContext);
return true;
}
其中C2View是继承CWnd的一个类(这个和向导生成的CChildView一样),当然记得要把相关的头文件包含进去,比如我这里要在MainFrm.h里面加入我刚才新建类的头文件 1View.h. 有个值得注意的地方是return CFrameWnd::OnCreateClient(lpcs, pContext);这个地方是向导生成的,一定要改成return true 不然程序出错,我搞了好久在网上查了很多才看到的
编译发现如下错误:
error C2039: 'classCChildView' : is not a member of 'CChildView'
error C2039: 'classC2View' : is not a member of 'CChildView'
我以前在有文档视图类里面按照这样的方法去拆分的窗体都是成功的,但是那个视图类不是继承CWnd的。那里我用的视图都是继承自CView的。我想:莫非拆分窗体只能加入来自CView的视图? 动手,于是新建了两个视图类C1View 和C3View继承自CView,将上述代码改为
...{
m_wndSplitter.CreateStatic(this,1,2);
m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(C1View), CSize(180, 100), pContext);
m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(C3View), CSize(100, 100), pContext);
//return CFrameWnd::OnCreateClient(lpcs, pContext);
return true;
}
哈哈!编译顺利通过!
结果也出来了!,但是,别高兴的太早,结果如下图所示:
注意到什么了么??原来拆分的框架将工具栏和状态栏的位置都占领了(我建立的程序是有初始化现实工具栏和状态栏的)研究了很久不知道怎么才能解决这个问题,我想应该能搞定,哪个高人要是搞定了一定要告诉我下啊。
既然这个不行干吗要在一颗树上吊死呢?想起文档视图结构拆分的时候菜单和状态栏可以正常现实的
好的,建立一个单文档程序 选中文档视图结构支持(不要着急,我却是是没有文档视图结构支持的拆分窗体,往下看)
找到你应用程序类的 initinstance里面下面一段代码:
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CWMServerManagerDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CWMServerManagerView));
AddDocTemplate(pDocTemplate);
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// The one and only window has been initialized, so show and update it.
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
这里就是程序初始化的时候加入文档视图和框架的关联的,好的!删!换成下面的代码:
m_pMainWnd = pFrame;
// create and load the frame with its resources
pFrame->LoadFrame(IDR_MAINFRAME,
WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL,
NULL);
// The one and only window has been initialized, so show and update it.
pFrame->ShowWindow(SW_SHOW);
pFrame->UpdateWindow();
现在你知道做什么了么?
对了,就是把向导生成的 *doc.h *doc.cpp *View.h *view.cpp文件都删掉*根据你的程序名字不一样。
现在我们在来按照上面的方法新建两个类继承自CView,加入拆分视图,ok 成功!
没有骗你哦,确实没有文档、视图结构支持,代码简洁多了!很遗憾的是CSDN上没有提供文件上传的功能,不然可以把实例放上去了,有要实例的可以联系我MSN:fancylea@163.com
最后顺便说下,之后你可以在各自的view里面创建你要的控件了,在view的OnInitialUpdate()里面调用你想要的控件的create方法就ok了 注意,程序在初始化的时候OnInitialUpdate()被调用两次的,所以你最好要建立一个变量标识下,比如我在相应的view类里面加上 成员 int m_nflag;创建成员先检测m_nflag是否等于1就是
...{
//创建控件的代码;
m_nflag = 1;//创建以后m_nflag = 1,避免再次创建空间;
}
当然了,如果视图随窗口尺寸变化你想同时更新控件的大小和分布 可以在view里面的 OnDraw()里面改变
比如:
CRect nowRect;
GetClientRect(&nowRect);//获得view大小
//比如我想让我的list ctrl布满整个view
m_pmyListctrl->MoveWindow(nowRect,TRUE);
好啦,就到这里,手大字好酸……
本来还想加上没有文档视图的MFC MDI程序的,下次有时间在写啦。(这个在vb里面实现好方便的)