概述
在开发有关数据库的软件时,经常是需要制造三级窗体的,而三级窗体的构建是跟数据库中的某张表是有关系的,弄多了之后就觉得每次都拖控件好麻烦,特别是当字段较多时,所以决定将这一步骤省略,直接自动生成,这样工作量就没那么大了,因为是自动生成的,因此怎么弄都很难符合人的审美观念,所以还需要自己后续做一下工作,即只需要摆放好控件的位置即可完成。基本界面如下:
前期工作
为了自动生成代码,首先要分析xe2里面的dfm窗体文件格式,同时生成代码时的cpp/h/dfm三个文件的关联等,不过前者更在重要,后者很简单的。
dfm文件格式是这样的
object FrmParent: TFrmParent Left = 0 Top = 0 BorderStyle = bsSingle Caption = ''#35780#20215#20934#21017#29238#31383#21475 object cxPageControl1: TcxPageControl Left = 0 Top = 0 Width = 691 end end
每个控件都是以object或inherited开始的,end为结束标识符,若控件内还有别的控件,则在object……end里包含,很简单的,其实就是一棵树,一棵N叉树,因此为了通用性,在程序里将其内容读出,在内存里构造出同样的一棵树。唔。。。数据结构课程的内容用上了,也不算是白学了,还是有点用的。
详细设计
数据结构定下来了,那么具体的算法也定下来了,就是每一个控件作为一个节点添加到这棵树上,然后再将其写入文件中。总体思想就是这么简单。(其实本来就很简单。。)接下来就是再将控件名读入头文件,并修改一些地方就可以在xe2里面编译成功了。
细节问题,如Caption = ''#35780#20215#20934#21017#29238#31383#21475 ,当dfm文件是中文时,就会变成刚才那段数字,这串数字是怎么解释的呢,百度一下这串数字后发现,其实是unicode的汉字内码,只需要将其转换就行啦,像#29238转为十六进制Ox7236,目前unicode采用的是UCS-2格式,就是两个字节代表一个汉字,也有UCS-4格式,四个字节,不过汉字才六七万个,去掉生僻字,采用UCS-2就行了,两个字节就是2的16次方,可以代表65536个汉字,所以#29238即代表“父”字。
如为了扩展性,总不能把控件类型写死在程序里面吧?假如发现有一套控件很好用,换了一套控件怎么办?重新改?开玩笑,真改就笨死了。因此留一个接口,等需要添加新的控件时再加载进去,做法就是使用配置文件记录下控件的基本信息,就是读取dfm文件,通过简单的拼装后写入xml配置文件内,那就换多少套控件都不怕了。配置文件xml格式如下,每添加一个控件信息就添加一个节点。
<?xml version="1.0" encoding="GB2312"?> <Root> <TcxTextEdit Name="cxTextEdit1">
<Left>10</Left>
<Top>10</Top>
<Style.BorderColor>clWindowFrame</Style.BorderColor>
<Style.BorderStyle>ebs3D</Style.BorderStyle>
<Style.HotTrack>False</Style.HotTrack>
<TabOrder>0</TabOrder>
<Text>''</Text>
<Width>121</Width>
</TcxTextEdit> </Root>
如数据库内应该有一张字段表,包含着表名,字段名,字段中文名。这样才能将读入程序写入dfm文件内。
如生成的窗体里必须有TdxLayoutControl控件(在DevExpress控件包内),因为它可以帮你自动对控件的位置进行布局,虽然是很简单的,但是这是必须使用的。
主要的难点在于dfm文件,内存里的多叉树,xml文件,以多叉树为中转点,互相转换。
最终成果
自动生成的界面如图: