zoukankan      html  css  js  c++  java
  • 一个测试程序迭代的故事02

    第四个需求 更好的显示测试项

    最后写的那一段测试代码在哪里运行?这要记住放在那个主菜单项下,然后点击这个主菜单才能看到。最好能直接显示出来最后那个菜单项。

    这个需求MainMenu就无法做到了,因为没有地方记录那个是最后插入的菜单项。

    ActionList可以记录最后插入的Action,让菜单项关联Action,应该就可以显示最后插入的菜单项。获得最后的Action,找到与之关联的菜单项都不难,但怎么才能显示这个菜单项?

    看看MainMenu的帮助,没有成员方法可以显示子菜单。但运行程序的时候,鼠标点击一下主菜单,会显示子菜单。追踪一下这段代码,应该有所发现。

    很遗憾,TMenu很多行为是Windows控制的,没能找到显示子菜单的代码。上网搜了搜,大富翁论坛的离线数据中也搜了搜,果然也没有发现什么可行方法。

    不过既然是Windows控制的,也许可以通过发送消息触发显示子菜单的代码。打开Spy++,看一下鼠标点击菜单时的消息,就是一个左键点击的消息。这个消息要带鼠标的坐标,也就是说要知道菜单项的位置信息。想想就觉得麻烦,还是知难而退,另辟蹊径吧。

    有的软件有功能树,用来显示全部功能,用TreeView结合ActionList也许可以满足需求。TreeView不能在设计时与Action关联,需要在运行时遍历ActionList,把每个Action加入到TreeView中,Category作为一级节点,Action作为二级节点,Caption作为节点的Text,指针作为节点的Data。然后在Click事件中把Data转成Action执行。

    现在测试代码的步骤变为:打开测试工程,打开相关窗体,打开ActionList编辑器,新建一个Action,双击Action,在Execute事件中添加代码,然后编译运行程序,点击TreeView节点,观看代码的作用。

    需求解决了!

    索性走的更远一些。1、类似ActionList转TreeView,MainMenu也根据ActionList在运行时自动建立。2、测试窗体显示的时候遍历TreeView,找到最后Action对应的节点,突出显示出来,让测试工作更简化。3、节点样式都一样,看着不方便,根据节点的Index显示过渡色。4、给TreeView增加一个排序功能,方便人工检索。

    完美!?

    这里还可以总结出一些解决疑问方法:1、看帮助。2、看组件的源代码。3、上网或者在离线数据中搜索解决方案。4、参考类似软件。

     

    第五个需求 代码复用

    按照最新的方案改好了一个窗体,再改另一个窗体时又出现了新问题:显示测试项的那些代码是每个窗体都需要,复制到每个窗体中肯定不是好方法。初学Delphi的时候有过惨痛的教训,同样的代码用一次复制一次,占用空间不说,以后要改进代码的时候,工作量那叫大!

    公共函数!

    把相同的代码做成公共函数,放在公共的单元中,在每个窗体中引用这个单元,调用公共函数。是一种解决方法,但不够好,调用公共函数的代码也是重复的,添加MainMenu和TreeView的工作同样是重复的。

    类继承!

    把重复使用的代码和组件提取到一个父窗体中,其他实际写测试代码的子窗体都从父窗体继承。窗体也是类,只不过附加了资源文件,也可以使用继承机制。

    创建子窗体时节省了大量工作,只需从父窗体继承,上面的组件就放置好了,父窗体的成员方法也可以直接调用。优化或者添加公共功能时只需修改父窗体。编译后的程序尺寸也减少了。真是好处多多!

    有一点需要注意,父窗体的imageList中不要放图片,否则子窗体会复制一份图片资源,让子窗体的体积变大。看来继承机制不是那么彻底。解决方法也简单,运行时加载图片就好。

    只是,以前创建的窗体不易改造,走捷径就要修改dfm文件。

    重复输入代码,重复放置组件,重复设置属性,只要是重复的工作都应该仔细考虑效率问题。重复输入代码,可以考虑公共函数和类继承。重复放置组件可以考虑窗体继承和DataModule、Frame。重复设置属性可以考虑存储到ini文件和注册表。整个程序的复用可以考虑动态链接库、COM+等。代码复用不仅可以一次做功多处使用,还方便日后升级和替换

    还不够?!

    这里有一点需要注意:父窗体不用实例化,更不要放在第一个实例化,否则父窗体会成为主窗体。

     

    第六个需求 窗体之间导航

    窗体不止一个时,就要考虑窗体之间如何导航。一般程序开始只显示主窗体,需要显示其他的窗体时,再通过一个Action显示该窗体。

    在采用继承方式前,每个窗体都要增加显示其他窗体的Action。采用了继承方式后,可以在父窗体中统一添加Action,新增一个窗体就新增一个Action,这样每个子窗体之间都可以相互导航。

    工作量不大,可以满足需求。但实际测试过程中,多数情况下需要多次修改代码、编译、测试。每次都先显示主窗体,再打开子窗体,再测试代码,然后再关闭子窗体,再关闭主窗体,才完成一次测试,测试步骤有点繁琐!

    当然可以在测试代码后,在IDE中用Ctrl+F2重置程序,但这样会忽略之后的异常,也无法保存窗体信息,还节省不了多少工作。不好!

    在每次编译前,在工程选项中把要测试的窗体放在第一位,运行的时候就直接显示该窗体。这实际就是把这个窗体变成主窗体,也有点繁琐,不好,但指明了方向!

    每次运行时,直接显示最后修改的窗体,效率最高。这就是目标!

    看了看MainForm的帮助,Application对象创建的第一个窗体就是主窗体。根据窗体文件的保存时间,时间最靠后的就是最后修改的窗体,第一个创建这个窗体就能完成任务。但所有窗体创建前是无法遍历的,显然行不通。

    主窗体不能改,但是可以不自动显示,而显示其他窗体。Screen对象中保存着所有自动创建的窗体,遍历所有窗体,通过运行时信息(RTTI)获得窗体文件名,找到最后修改的窗体,显示。完成!

    等等,高兴早了。关闭窗体的时候无法关闭程序!

    再看看MainForm的帮助,关闭主窗体才能结束程序。而现在主窗体并没有显示,无法关闭。所以要在关闭其他窗体的时候,再显示主窗体,然后关闭主窗体。

    当然,代码只要写到父窗体中就可以。

    完成!

    在写遍历所有窗体代码时,联想到也可以通过遍历窗体自动创建显示窗体的Action,这样又省了些工作。删除一个窗体或增加一个窗体,都不用增加工作量。

    完美!

  • 相关阅读:
    linux创建www用户组和用户
    php+nginx改为socket
    laravel重写
    centos7精简版(minimal)killall: command not found
    php+nginx 整合
    php编译安装
    Nginx的编译安装
    sql 中常见的控制流语句
    sqlserver 中常见的函数 数学函数
    sqlserver 中常见的函数字符串函数
  • 原文地址:https://www.cnblogs.com/unjiang/p/13074223.html
Copyright © 2011-2022 走看看