2002-10-31
想静下心来写点程序真是困难。这不,为了软件的安装问题,我又被紧急派到北京。匆匆茫茫到了北京一看,原来又是项目组的老问题:项目负责人(一位60多岁的老先生)又扔下管理协调工作,自己玩自己的技术;一帮刚毕业的未经过任何培训的学生不知道自己应该干些什么。唉,我真是服了,从去年4月份一直到现在居然没有一点改进。忙完北京的工作,我一刻没有停留的杀回老家,继续我的Looking。
回到家后,我面对的第一个问题是3D图形组件的动态挂接问题。说白一点,就像Delphi的Component如何被组织管理并动态放置在控件面板上。这个问题又分为两个小问题:
a)组件的注册、加载、内部数据结构的组织。
b)图形化界面的布局。
我想先解决第二个问题,这可能是因为我对于进入核心编码还没有作好心理准备,或者是因为我的状态还没有“热”起来。但是,实现一个什么样的布局,我还没有一个概念。说实在的,我不太清楚别人是怎么写程序的。对于我来说,写程序或者具体的技术是相对简单的。但一个概念的建立却是一个痛苦的过程。在这里我所说的概念是一种非常宽泛的东西,但它是我的一切工作的起点。其实,编写每个项目的过程,就是一个寻找某种概念的过程。
我下载并安装了一个3DMax,主要是看看它的界面风格。最后我决定实现一个类似Delphi的控件面板,精确的说是类似JDeveloper那样的控件面板。但,这时候问题就来了,而且要比我想像的复杂的多。标准的MFC的Dock布局好像很难实现类似Delphi那样的布局。我在网上寻找了很多MFC扩展风格库,但好像没有能实现这种布局的。可能是我没有找到,可能是我找到了没有看到。当然了,这都不重要了,它已经激起了我对它的兴趣。在以前我写过的很多程序里,我都用到了Dock窗体,但我对Dock的实现机制并不了解。一段时间里,我甚至认为Dock是由Windows系统新增加的一种新风格。现在是应该解决这个问题的时候了。
我仔细研究了一下MFC和VCL对Dock实现的源代码后,我的心凉了半截。MFC在实现Dock功能的核心类CDockBar,是一种以“行”为组织方式的布局方式。它用一个动态数组来管理自己的所有子Dock窗体。如果数组中的某个元素是NULL,就产生了一个Break,也就是分行。其结果如下面的图片。而Delphi在Dock的问题上几乎没有什么布局的概念。Delphi的控件面板的布局风格是由一个叫TCustomControlBar的控件完成的。TCustomControlBar也是以“行”作为基本布局组织方式的,但它提供了一个行合并的概念,同时它也提供了更多的布局动态调整方式。
因此要在MFC中实现TCustomControlBar那样的Dock风格,就必须修改CDockBar的数据结构。但是MFC好像并不想别人修改它的界面风格。CDockBar::DockControlBar和CDockBar::RemoveControlBar等这些重要的函数,都不是虚函数。这就意味着,如果要修改CDockBar,就必须修改与其相关的CDockContext、CFrameWnd、CMiniDockFrameWnd和从CControlBar继承下来的所有ToolBar、MenuBar、ControlBar。另一个问题是,众所周知MFC和VCL是根本不同的两种风格的应用程序框架。要把VCL的东西放到MFC中,是非常困难的。
在建立了基本概念后,唯一的问题就是“作”还是“不作”。让我产生这种犹豫的原因有两个,首先是开发成本问题,其次是MFC版本升级问题。最让我犹豫的是第二个问题。最后我还是选择了作,至少它能让我对MFC框架有更深的了解。剩下的问题就是分析TCustomControlBar的算法。TCustomControlBar中有3个关键函数AlignControls、UpdateItems和DockControl。我想,TCustomControlBar的作者一定是疯了,这3个函数有800多行,AlignControls就有400多行。我实在找不出他这样写程序的理由,唯一的理由可能是,他根本就不想让别人看懂。还是那句话,蚂蚁啃骨头的精神。
在这里我想说一句项目外的话题,程序员如何看待代码阅读的问题。看别人的代码可能是大多数程序员都不愿意作的事情,原因可能只有一个,太耗神。但这又是必须作的一件事情。不看看别人的东西,又怎能知道自己的东西的好与坏?大约在3年前,我一直认为自己是一个C语言好手。后来我失业了,闲极难忍的我忽发奇想,想看看编译器是如何实现的。于是我去分析GNU C编译器的源代码。为了方便看懂GNU C的文档(呵呵,我的E文不好,离开Windows下的词霸就完蛋了),我又去分析TexInfo的源代码,并写了一个把TexInfo文件转换成Windows Help文件的程序。虽然后来我在GNU C的RTL语言中迷失了方向,并最后放弃,但我对C的观念却从此完全改变了。看别人的代码是一个很好的学习过程,是击破自己的固步自封的好手段。从那以后,当有人说我的C语言如何如何时,我都保持沉默,并对赞美者的无知而悲哀。
在家里写程序真有一种“山中无岁月”的感觉,饿了就吃,困了就睡,吃饱睡足就干活。记不清有多少天了,从日期推断,可能有一周了。最后的封装工作终于完成了。其最终结果如下图所示。它基本上实现了TCustomControlBar的所有布局调整风格。