用组件开发一致的界面.DOC

上传人:国*** 文档编号:772582 上传时间:2018-10-31 格式:DOC 页数:32 大小:258.50KB
下载 相关 举报
用组件开发一致的界面.DOC_第1页
第1页 / 共32页
用组件开发一致的界面.DOC_第2页
第2页 / 共32页
用组件开发一致的界面.DOC_第3页
第3页 / 共32页
用组件开发一致的界面.DOC_第4页
第4页 / 共32页
用组件开发一致的界面.DOC_第5页
第5页 / 共32页
点击查看更多>>
资源描述

1、第 11 章 用组件开发一致的界面什么能算是好的界面,标准是非常主观的。许多商业应用程序都跟随着 WinTel 标准:灰色的按钮和控件,白色的背景。对商务程序来说,这可能是个不错的主意,因为通过多年的熟悉使得这个界面在某种程度上较为舒服,但这是个好的界面吗?Alan Cooper 是Visual Basic 之父,他建议“通过坚持使他们(Microsoft 和 Apple)各自独立的开发者群体遵守既定的方针,他们偷偷摸摸地阻止了来自应用者群体的革新。”Cooper,212 Cooper 认为, “我并不鼓吹忽略界面风格方面的指导,从而导致界面出现混乱。我仅仅认为应该像参议员看待说客那样来看待对

2、界面风格的指导,而绝不能像司机服从于交警那样。立法者知道说客想要削减某项经费,但说客并非来自于持有客观态度的第三方。”Cooper,212在所有的条件下都是最好的界面可能并不存在,即使在一定的条件下,界面的设计仍然是高度主观的。如果你能开发出像图 11.1 所示的新 RealPlayer 那样的界面,而且符合你的目的,那就很好了。如果你不擅长创建独一无二或非常有趣的图形用户界面,而且并没有雇佣图形设计者的预算,那么可能会开发出与 WinTel 风格类似的应用程序。对于商业目的而言,也许较为熟悉的风格可以避免使用方面的障碍。图 11.1 RealPlayer 8 使用了一些漂亮的图形按钮,并进行

3、了视觉人类工程学方面的尝试。还可以选用卡通标志和斑马条纹等外表只有一个问题不是主观的,它也是本章的主题,那就是界面应该是一致、连贯、完全的。不一致、不连贯、不完全,不考虑界面的风格对用户来说是不可容忍的。第 11 章示范了一些技术,可用于简化开发并确保一致性,包括如何使用定制组件、组件模板和窗体第 11 章 用组件开发一致的界面 265继承,以提供一致、连贯而完全的应用程序。266 Delphi 6 应用开发指南11.1 定 制 组 件创建定制组件很有趣,而且定制组件也很有用。首先,显而易见的理由是可以重用已有的对象,并封装新的或增强的特性;其次,它可以提供一致的效用。无须绘制组件时保证相同的

4、尺寸、风格、字体、颜色或措辞,可以对组件进行定制以确保这些目标。11.1.1 定制组件的三个 C定制组件的三个 C 是一致性、连贯性和完备性。一致性意味着组件在你的应用程序和其他地方的行为是一致的。一致性(Consistency)组件每次都表现出相同的行为和初始状态,才能提供一致性。对组件的行为或状态进行一次编程,则所有的组件实例都具有一致的外观和行为。一致性并不追求数量,注意到这一点是很重要的。定制组件无须进行大量的修改,即可提供一致性。即使组件只是重载了缺省的大小或形状,创建一个定制组件也可确保一致性。有两个直接的方法可以做到这一点。您可以子类化所有的需要微小修改的组件然后再安装;或者快速

5、地创建组件模板,这更容易一些(参考 11.2 节“创建组件模板”)。连贯性(Coherency)一致性是连贯的一个方面。如果对象不具有一致性,也会缺少连贯性。连贯性是对控制流和操作的逻辑性的度量,它要求语义上相似的操作具有一致的行为。定制控件和组件模板可用于提供更为连贯的行为流程。没有一致性和连贯性,应用程序不可能是完全的。完备性(Completeness)不一致、不完全的应用程序看起来是不合逻辑且不正确的,这样必定是不完备的。如果应用程序不被用户群体所接受,也不能说是完备的。完备性度量了应用程序是否执行了所要求的任务、结果是否正确、应用程序是否具有合理的容错级别。如果程序给出正确却不合时宜的

6、回答,也是不完备的。而迅速的提供错误的结果,仍然是错误的。如果程序的行为毫无规律、不一致、或不合逻辑,那么该程序是失败的。即使程序有相应的用户群体,仍然可能失败,因为用户群体可以拒绝使用该程序,或恶意共谋使用该程序提供错误的或不合适宜的结果。为什么组件帮助你走向胜利组件是对象。每个对象都属于某个类。这意味着有一组代码需要测试、调试和扩展。如果一个类已经是完美的,那么每个实例都不会出错。这样如果类满足了 3C 标准,那么类的每个实例都会满足该标准。第 11 章 用组件开发一致的界面 267注意:“大而复杂的软件系统需要设计师,以便开发者能够朝着共同的目标前进。”Jacobsen,Booch,an

7、d Rumbaugh 62。设计师是这样的人,他形成解决方案的概念并向程序员说清设计意图。即便开始 时的进度比通常慢,也要把事情做正确,这将会节省大量金 钱和思考的时间,防止在最后才发现出轨。没有经验、缺乏技术的管理者可能认为编写组件接近于消磨时间,但这是面向对象的程序设计。以非面向对象的方法去使用面向对象工具是一个错误。使用 Delphi 编写结构化程序可以很快地到达 beta 版,这在短期内常常会使管理者高兴,但可能使得处于 beta版的时间较长。您的程序可能永远都脱离不了 beta 版。迅速得到错误的答案,仍然是错误的。无论是否能确认管理层会花大笔金钱来确保成功,都可以采取一些防御措施。

8、从许多功能正确的组件来创建程序,可以尽可能少写代码而又能提高程序的正确性。11.1.2 重分解重分解是采取小的增量式改变的过程。组件可以一步就写出来,创建全新而独一无二的东西,这样做代价昂贵、风险较大而且浪费时间;或者我们可以采取小的步骤,分层实现各种能力,这样就不那么昂贵,风险较低而且快速。设计师的关键作用之一 找到和减少冒险。如果没有设计师,必须由程序员来完成该工作。管理者喜欢快速而廉价。那么很清楚,许多情况下最好的选择就是对组件进行小的修改,将增量式的改变分层添加到已有的组件中。为示范进行这种小的修改所需代码的合理数量,设计了下面的组件:unit UDBShortNavigator;/

9、UDBShortNavigator.pas - Toggles between short list of buttons/ and long list/ Copyright (c) 2000. All Rights Reserved./ by Software Conceptions, Inc. Okemos, MI USA (800) 471-5890/ Written by Paul KimmelinterfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls,Forms, Dialogs,ExtCtrls, DB

10、Ctrls;typeTNavigatorButtonSet = ( nbsFull, nbsPartial );TDBShortNavigator = class(TDBNavigator)private Private declarations FButtonSet : TNavigatorButtonSet;procedure SetButtonSet(const Value: TNavigatorButtonSet);protected268 Delphi 6 应用开发指南 Protected declarations public Public declarations publish

11、ed Published declarations property ButtonSet : TNavigatorButtonSet read FButtonSetwrite SetButtonSet;end;procedure Register;implementationprocedure Register;beginRegisterComponents(PKTools, TDBShortNavigator);end; TDBShortNavigator procedure TDBShortNavigator.SetButtonSet(const Value:TNavigatorButto

12、nSet);constFULL_SET = nbFirst, nbPrior, nbNext, nbLast, nbInsert,nbDelete, nbEdit, nbPost, nbCancel, nbRefresh;PARTIAL_SET = nbFirst, nbPrior, nbNext, nbLast;SETS : arrayTNavigatorButtonSet of TButtonSet = (FULL_SET,PARTIAL_SET);beginif( FButtonSet = Value ) then exit;FButtonSet := Value;VisibleButt

13、ons := SETSFButtonSet;end;end.TDBShortNavigator 继承了 TDBNavigator,添加了一个 ButtonSet 特性。将该特性在nbsFull 和 nbsPartial 之间切换,即可显示所有的导航按钮或仅仅显示基本的四个按钮(如图 11.2 所示)。图 11.2 TDBShortNavigator 可以快速地在显示部分或全部导航按钮之间切换第 11 章 用组件开发一致的界面 269很显然该组件并没有多少代码。而这正是我们所需要的。小的改变快速、便宜而且可靠。然而,有人可能认为这是不重要或不相关的。由混沌理论可知,即使蛾的翅膀振动一下也可能影响

14、到很远的地方。那么我们可以考虑蛾困在 Mark 型计算机的中继转换开关中的情况。据说是 COBOL 的发明者 Grace Hopper 杜撰了 bug 这个词,现在整个工业界都在使用它,连世界历史上最重大的媒体事件之一 Y2K 问题也是它的标志。并不是说上述的导航器子类在历史上也能有这样幸运的角色;轶事能被记录本来就是戏剧性的。小的事件能够发挥值得记载的作用,并具有相当的影响。千里之行,始于足下,高级的系统正是由小块的优质代码所组成的。11.1.3 小的改变有什么好处除了本节开始所描述的好处之外,还包括快速、廉价、可靠等等,这些好处都是由小的、增量式的改变得到的。TDBShortNavigat

15、or 这样的组件有利于代码的收敛。收敛是指所有该算法的代码都聚集在一起;如果没有最好的代码,那么一个实例的代码是次好的,代码多于一个实例是较差的。发散是指出现算法的多个副本;这是最坏的情况。当子类化 TDBNavigator 这样的组件来进行小的改变时,可以促进代码的收敛。改变可见按钮数量的所有代码都包含在同一个地方。因此只有一个代码段需要测试、调试和扩展。如果要为按钮定义三个状态,可以在同一地方快速而有效地修改代码。注意:您可能听说过比其他的程序员多产一个数量级的程序员。也就是他个人的产量是其他人的十倍。这 怎么可能呢?很显然一个人不可能比程序 员的平均打字速度快十倍。这是技巧与策略方面的

16、问题。即使最好的程序员也不太可能在语法和程序编码方面比平均程度强十倍;他只是使用了一些具有累积效应的策略。其中必有一种策略 倾向于编写收敛的代码 。这种程序员可以比一般人快上十倍或更多,而且其代码也可能好于平均的水平。我们提到过,修改并不重要。重要的是修改表示了什么。像 TDBShortNavigator 这样的组件就表明了编写内聚代码的倾向。这种累积效应往往分布在程序员的职业生涯或工程的生命周期中。11.1.4 采取好的策略编写收敛的代码,或编写的代码只具有算法的单一副本,这是一个策略。这可能是成为高产开发者的最佳途径之一。有两个习惯可促进采用该策略,并逐渐使之成为一种第二天性。首先:考虑多

17、次修改你的代码。我们知道谚语“天才是 1%的灵感加 99%的汗水”,这意味着当一个人思考解决方案时,只有出现了非常好的机会,灵感才能发挥作用。其次:当发现重复出现的代码时,立即把涉及到的算法编写为过程。随着实践的进行,这种迭代式的修改会变得更加自然,如果随时进行修改,也更容易发挥作用。反之,如果等到程序完成之后才进行修改工作,可能会遇到困难。管理者和其他程序员可能不想立即投入很多时间进行修改,而这时代码已经相互纠缠在一起以至于小的修改也可能引起代码的混乱。270 Delphi 6 应用开发指南11.1.5 组件化我们就继续讨论上一节的问题,如果你发现自己正在编写处理组件内部数据的代码,那么最好

18、子类化组件以封装新的行为。组件化的规则是:如果代码涉及到组件内部的数据,例如组件所拥有的对象列表,那么代码实际上描述了组件的行为。对象的行为就是方法。通过将外部的、隐式的算法提升为方法,可以使代码在类的层次上趋向于收敛。类不一定是组件;任何表示类行为的代码都应该作为方法合并到类中。有三个地方可以方便地重用代码。可以子类化包括组件在内的任何类,以重用代码。可以定义组件模板,这是 Delphi 新近添加的功能,利用该方法可以很容易地在一个或多个组件中重用新的行为;而且能够创建窗体或框架模板,这样就可以重用整个窗体或框架及其所包含的组件。11.2 创建组件模板首先将组件添加到数据模块或窗体,设置它们

19、的特性,创建事件处理程序,并编写代码。然后选定一个或多个组件,从 Component 菜单里选择 Create Component Template 菜单项。所有被选中的组件、事件处理程序、以及相关的代码,都添加到了 VCL 面板的Template 属性页上。选择该组件模板并将其拖动到任意的窗体或数据模块上,即可重新创建包括代码在内的各个组件。将模板添加到窗体或数据模块后,可以修改其位置、大小和特性等,就像是分别添加的一样。当选择 Create Component Template 菜单项时,会显示 Component Template Information 对话框(见图 11.3)。点击

20、OK,则接受缺省的组件名、面板属性页以及组件图标,当然也可以修改这些信息。可以给模板组件命名所喜欢的名字,将其放置在任何面板属性页上。如果输入的属性页名字不存在,Delphi 将创建新的属性页。模板组件惟一的限制就是其图标必须是 2424 像素位图,与其他组件的图标类似。图 11.3 Component Template Information 对话框11.2.1 定义组件模板编写基本的组件相当容易。创建组件模板甚至更容易。定义组件模板的步骤与创建窗体基本相同。增加组件,修改其特性,并编写事件特性。像其他单元一样,对窗体(或数第 11 章 用组件开发一致的界面 271据模块)进行单元测试。工作

21、完成后,就可以创建组件模板,选择组件,并将其添加到组件模板。注意:Delphi 组件模板存储在 Delphi 的 Bin 目录下的二进制文件 Delphi.dct中。Windows 错误地把该文件和 FoxPro DataBase Container 文件类型关联在一起。考虑第 3 章的 Edit 菜单。您可以花费一些时间来查找所有的 Windows 消息,并在应用程序中对 Edit 菜单编写 SendMessage 代码;而下一次在另一个程序里创建 Edit 菜单时,您还得做同样的事情。从菜单资源模板重新创建菜单您可以选择使用 Insert Template 对话框中的 Edit 菜单,如图

22、 11.4 所示。使用 Menu Designer 上下文菜单添加一个菜单的步骤如下:图 11.4 Insert Template 对话框可以从存储的资源中重新创建菜单。但并不包括代码1从 VCL 的 Standard 属性页上选择 MainMenu 组件。2双击 MainMenu 图标向窗体添加菜单。3右击 MainMenu 组件,显示 TMainMenu 组件的组件编辑器菜单,并选择 Menu Designer 菜单项(如图 11.5 所示)。这样可以打开菜单编辑器,如图 11.4 的背景所示。4右击鼠标,打开菜单编辑器的上下文菜单,并选择 Insert From Template 菜单项

23、,如图 11.6 所示。5从 Insert Template 对话框中(如图 11.4 所示),双击 Edit 菜单模板,以添加编辑菜单。这就是所有的工作。上述五个步骤将把 TMenuItem 组件添加到窗体类定义的开头。272 Delphi 6 应用开发指南使用菜单资源模板需要对 OnClick 事件方法重新编写代码。更好的方法是使用组件模板,这可以包括代码。图 11.5 点击 TMainMenu 组件的组件编辑器菜单上的 Menu Designer 菜单项图 11.6 菜单设计器的上下文菜单,对于管理菜单资源模板很方便创建并安装菜单组件模板组件模板是 Delphi 新增的功能。使用菜单资源

24、模板存储菜单必须重新编写代码,而使用组件模板则不必如此。还使用上一节提到的 Edit 菜单,它是在第 3 章中实现的。我们现在把整个菜单和代码都保存为组件模板。1对 Edit 菜单编写代码(使用第 3 章的例子,或步骤后列出的代码)使控件呈现正确的行为。2用代码测试 Edit 菜单后,选择包含 Edit 菜单的 TMainMenu 组件并点击Component | Create Component Template 菜单项。procedure TForm1.Edit1Click(Sender: TObject);begin/ CanUndo testUndo1.Enabled := Boole

25、an(SendMessage(第 11 章 用组件开发一致的界面 273Screen.ActiveControl.Handle,EM_CANUNDO, 0, 0 );end;procedure TForm1.Copy1Click(Sender: TObject);begin/ Copy menuSendMessage( Screen.ActiveControl.Handle, WM_COPY, 0, 0 );end;procedure TForm1.Cut1Click(Sender: TObject);begin/ Cut menuSendMessage( Screen.ActiveContr

26、ol.Handle, WM_CUT, 0, 0 );end;procedure TForm1.Paste1Click(Sender: TObject);begin/ Paste menuSendMessage( Screen.ActiveControl.Handle, WM_PASTE, 0, 0 );end;procedure TForm1.SelectAll1Click(Sender: TObject);begin/ select all textSendMessage( Screen.ActiveControl.Handle, EM_SETSEL, 0, -1 );end;procedu

27、re TForm1.Undo1Click(Sender: TObject);begin/ Undo menuSendMessage( Screen.ActiveControl.Handle, WM_UNDO, 0, 0 );end;该代码与第 3 章中的类似。因此我们不再对细节进行重复。现在我们已经有了 Edit菜单的组件模板,每次需要菜单、相应的菜单项和代码时就可以使用该模板。使用组件模板菜单现在已经有了 Edit 菜单模板,它可以像其他的组件一样使用。要使用组件模板,从Template 属性页上选择对应的模板,像其他菜单一样拖动到窗体上。菜单组件及其拥有的TMenuItems、以前写过的代码都可以添加到任何窗体上,而无需测试,也不会产生任何混乱的情况。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 重点行业资料库 > 1

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。