来源: http://www.codeproject.com/KB/splitter/st_splitterwnd.aspx
下载源文件: http://www.codeproject.com/KB/splitter/st_splitterwnd/st_splitterwnd_src.zip
下载Demo: http://www.codeproject.com/KB/splitter/st_splitterwnd/st_splitterwnd_demo.zip
你是否曾经尝试正确的分割Windows窗口,然后加上一个转换视图的方法,更妙的是,你是否还让单独的分隔条铺满整个窗口?然后你还想着让这样的结果在你下次启动程序仍然存在呢?老实讲,我就这样做过,当每次我不得不在旧代码中修改,于是错误和时间频繁出现。
于是,我想静下心来好好的想一个解决方法—能解决所有问题的方法,那就是写一个可复用的基类。当然,我从本网站和其它网站找到了很多有用的资料。其中,ShowColumn和HideColumn方法借鉴了Oleg Galkin发布在www.codeguru.com上的一篇文章,此外,借助于Caroline Englebienne,Adrian Roman和Dongik Shin的文章我写出了支持视图转换的方法。
现在,我将再一次分享这些经验。只要你喜欢,你完全可以将这些应用在自己的工程中,但是如果不做照搬过来,我可不能保证不会出现错误甚至崩溃。
本文说介绍的分割窗口基类的方法十分简单,但仍有一些事情需要考虑,否则你会得到CsplitterWnd类中的诸多断言之一。
本文说介绍的基类只适用于静态的窗口切割,并且每次只能切割一个窗口,水平或者垂直。一旦窗口切割完毕,接着还可以在此基础上重复切割,就像上图所示。我将第一个窗口分割成两个面板,左右各一个。接着,我又将左面板分割成上下面板。下面板又被水平地分割位左右面板。
为了实现这样的功能,首先需要将源文件中的ST_splitterwnd.h和ST_splitterwnd.cpp加到工程中。
接着针对每个要被分割的窗口在CmainFrame中添加相应的ST_splitterWnd成员:
在函数CmainFrame::OnCreateClient中,创造第一个ST_SplitterWnd的对象:
其中Create函数定义如下:
注:如果想要进一步的在分割窗口中进行下次分割,必须将pView1和pView2参数中其中一个或两个设为NULL。如果没有这样做,将会出现断言错误。
View1和view2是用来将视图类传递到SplitterWnd,就像正常使用CsplitterWnd类一样,也必须使用RUNTIME_CLASS宏进行传递。如:
使用AddSubDivision方法实现进一步的分割:
上面的例子将从水平方向上分割左面板并且在顶面板上填充一个视图,底部的视图通过赋值NULL实现进一步的分割。AddSubDivision函数定义如下:
// false for a horizontal split
该函数的用法基本上和Create相同。第一个参数(nSide)用于描述将要添加的分割面板的位置,定义了四个静态常量(LEFT_SIDE, RIGHT_SIDE, TOP_SIDE和BOTTOM_SIDE)。最后一个参数将决定是垂直分割(true)还是水平分割(false)。AddSubDivison函数返回一个ST_SplitterWnd类型的指针,该指针指向的对象还可以被分割下去:
false);
本文说介绍的基类中还有一个特征是在一个面板中进行视图类的转换。为了达到这样的目的,可以使用AddView函数。
注:当使用AddView函数时,视图要加入的面板不能包含视图,换句话说,面板必须初始化为NULL,就像再一次分割一样。
函数AddView定义如下:
基本上就是上面所说这些工作了。还有三个较为重要的函数:SetInitialStatus,SwitchToView和ToggleSide。
SetInitialStatus用于从注册表中记录一些设置参数,如尺寸,面板位置。
SwitchToView用于同一面板中多个视图的通讯。
ToggleSide隐藏和显示一个面板。
姓名:Daniel Zuppinger
简历:1983年来开始从事专业的IT开发。早期的一些工程使用Cobol,接着是Pascal,Modula1,C,Visual C++1.0和C++。1986年以后从事咨询工作,1990年以来在瑞士Infobrain工作。目前的研究领域为GSM应用项目管理和软件开发(TAP3)。已婚,有两个女儿。
喜好:Paragliding, OL
职位:CTO
居住地:瑞士