[转]李战大师-真珠美学悟透delphi 第七章 操作界面与操作逻辑

第8章          操作界面与操作逻辑

咱俩在前面包车型地铁早已研商过,用户界面与买卖逻辑分离的利益。那样的诀别能够让软件种类结构特别客观,结构易于掌握,从而增强软件的一帆风顺和可维护性。
正如自身谈到过,大家谈论的指标是为了找寻将软件结构从一无所知归于有序的实用方法,那是编辑本书的第壹目标之一。有序的事物简单明白,易于精通就便宜控制,通晓之后你将会发现其背后的哲理是那样的简单,从而进步到更高的境地去感受地道软件结构的协调美。
本章的话题将重点谈论哪些将客户端的先后有序化,希望大家的商讨对持有的软件同行和爱侣都抱有辅助。

首先节 分离操作界面与操作逻辑
怎么样设计协调的软件操作界面,是人机工程学研讨的一个至关心重视要课题。好用的软件都有秀丽可爱的样子,不但布局平衡合理,对你的操作意图也是名花解语,并且处理大方得体,就连对你的作答也关切入微。要是,你编写的软件象那样将根本字重复的一无所长报告你的用户:“亲爱的,你从前曾经输入了号码为991028的出库单,不可重复输入。是不是想查看在此以前的出库单呢?”,你的软件一定会销量大增。大概那时候IBM的OS2正是因为说了过多用户看不懂的废话,才被用户放弃,失去人心,而被BillGates一统天下。
咱俩后天不打算探讨什么打扮软件的颜值,而要谈谈在雅观的界面后边,应该如何更好地组织软件结构,大大方方地处理用户的操作命令。
如果,你早就规划好软件初阶的操作格局,用带图标的菜系作为用户发号司令的工具,并在MenuItem的OnClick事件中编辑成功工作处理的经过语句。一切都毋庸置疑,而购买销售的逻辑处理也是放到服务器端的RemoteDataMoudle中拍卖的,经典的三层类别布局。可是您的业主不爱好菜单,他对按钮情有独钟,于是你须求将Menu换来Button,然后将操作完成代码移到Button的OnClick事件进程中,可能将Button的OnClick事件指向原来的MenuItemClick事件处理进程。软件提交用户试用之后,用户强烈供给将软件修改为Microsoft Word
2000那样的界面,既有菜单又有按钮,而且还可以提供键盘的快捷键输入(因为他们的老马习惯了原来DOS下那套老程序的键盘输入方式)。于是,你又不得不修改软件的界面控件,仁同一视复将操作处理代码调整,以便各个命令输入格局都能被响应。最终,历经千辛万苦终于能到位整个软件界面包车型客车修改工作。
同理可得,区别的人有两样的欣赏和急需,他们各自都有操作软件的习惯。可是他们运用软件的指标是同样的,正是,向您的软件爆发钦赐的操作指令,使用该操作所表示的软件功效!
在各类不一致的用户的必要之中,搞清全数用户的最后指标之后,大家相应密切地想一想,区别的用户为了完结平等目标,使用了分化的手段。哦!原来指标和手腕是五回事,只然则各个人用不一致的手法达到平等的指标。
就此,大家理应将操作界面与操作逻辑分离,应该首先分清手段和目标,然后将手段与指标联系起来。那样,操作界面的更动将不会潜移默化到操作逻辑,手段是伎俩,指标是指标。为了达到目标,能够不择手段,正是其一道理!
商业事务那里,或然有人会说:这么些道理何人都懂。那么,若是在我们开发软件的长河中,多使用那几个浅显的道理,就不难设计出大致而又实用的软件结构。
操作界面与操作逻辑的分别能够为大家带来如何好处吗?
1. 不难领会
你能够在编写工作操作代码时,不关注软件的界面操作情势,而在吹嘘你的软件时,只考虑界面的美学难题。外表是表面,内心是内心,唯有你知道,外表赏心悦目的界面连接着精美内秀的操作代码,表里如一。你的爱侣们既可欣赏到地道的软件外表,也简单读懂你的心中。

2. 容易维护
随便以后盛行什么软件界面,是时新HomePage式样依旧OutLook的经典面版。你能够只修改与界面有关的片段,就可满足须求。也可将您的软件到底万象更新,以全新的面容出现。甚至,可表演四川灯戏有名的人传内不传外传男不传女的独自绝招-变脸。但软件或然软件,软件的内在功效逻辑并未改观。但是,由于知足了用户喜新厌旧,追逐流行前卫的习惯,将使软件公司的总经理们的钱包越来越鼓。

3. 可扩张性强
人机工程学不断赢得的新突破,将为软件使用者提供越多的命令输入格局。今后,语音识别技术已慢慢商用化。你曾经得以利用IBM
ViaVoice提供的语音识别援助模块,开发能辨别语音指令的控件。将这么的控件出席你的软件中,并与你之前编写的操作逻辑关系,你的软件就象长了耳朵,有了智慧,能够聆听你的述说。作者也相信,总有一天可编写制定一种可以看懂你的神色的控件,那么,软件将得以根据你的心绪对你抚以差别冷暖的保护。但软件的神魄依旧原先的操作逻辑代码!

4. 相符大规模软件开发
广大软件开发讲求分工同盟,各尽其才。若是您是软件集团的业主,那么,在系统一分配析规划职员形成软件设计之后,你能够找一批时装设计师为你的软件设计美貌性感的界面,请精于编码的程序员编写操作逻辑。而你能够轻松地保管和操纵各道工序的成色,而且权利肯定。

纵然天涯海角的吹了一通,但我们还得重返大家大旨。操作界面与操作逻辑的分手,到底要遵照哪些方法和条件呢?
先是,你应当综合整理当前模块要向用户提供的作用,划分出强烈的操作命令集。也正是说,设计可提须求用户的命令,那有点象老式命令行程序的可用命令清单列表。记住,这么些命令集显示的是用户执行操作的指标。
下一场,在依据指令集中的每一命令规划操作逻辑代码,依据编写程序的貌似原则编写制定操作逻辑代码。有关编写程序的相似标准,可参照《初恋DELPHI》一书。
最终,要升迁一点的便是,操作命令有时是受程序状态控制的。有的程序员为了兑今后某中状态下取缔用户产生内定的操作命令,想尽办法控制菜单、按钮等一声令下控件的属性,封闭扼杀和打压全体可执行命令的控件。可是,你想禁止的是命令,而不是控件!
上面大家将会谈论在暌违操作界面和操作逻辑方面,DELPHI为大家提供的很有价值的东西,即TActionList和TAction。

第二节 使用TActionList和TAction
“Action”一词的含义是行为、行动或动作,TAction便是空虚了用户想要通过软件界面表现的一言一行、开始展览的步履或执行的动作,而TActionList就讲述了动作的指令清单。你能够将3个TActionList元件加入到您的Form、Frame或DataModule中,双击此部件可定义要求的TAction对象。
创办DELPHI大厦的设计师和工程师们,为多数限令控件(如TButton,TMenuItem等等)设计了Action属性,并且平时碰巧出以后Object
Inspecter窗口属性页面包车型客车第③项上,综上说述他们的用心良苦。但好歹,他们为大家提供了1个简易的法子,将指令控件的Action属性与TActionList元件中定义的TAction对象关联。
鉴于,在TAction对象的OnExecute事件中编辑的操作逻辑代码可自行被提到的指令控件调用,由此,更换命令控件的种类,不用修改或调整操作逻辑代码。那样就可将操作界面与操作逻辑分开。
假如在好几状态下您要禁止用户执行某种操作,可安装相关TAction对象的Enabled属性为FALSE,则相关的吩咐控件将通通被冰冻,该变白脸的变脸白,该变灰脸的变灰脸,而不管她是生旦净末丑。
又一次感激创制DELPHI的大师们,是她们在台后为大家做了上上下下,而且还将他们的双手互博放到Source\VCL\ActnList.pas单元中。
既然如此有法师们的美女拳,我们就相应拿来修炼,增强我们的内功。
先是,在ActnList单元中,TActionList是那样申明的:
  TActionList = class(TCustomActionList)
  published
    property Images;
    property OnChange;
    property OnExecute;
    property OnUpdate;
  end;
TActionList只发布了TCustomActionList的部分性质和事件。其实,TActionList正是用来装TAction的容器,并提供了管制TAction的措施。有关TActionList的事无巨细用法,大家将在随着支付的TActionManager控件中探讨。

再来看看TAction的宣示的:
  TAction = class(TCustomAction)
  published
    property Caption;
    property Checked;
    property Enabled;
    property HelpContext;
    property Hint;
    property ImageIndex;
    property ShortCut;
    property Visible;
    property OnExecute;
    property OnHint;
    property OnUpdate;
  end;
TAction是从TCustomAction类继承的,与前边一样,只可是将父类的一部分特色发布。小编不想逐一解读TAction的各种类层次的原代码,相信读过《初恋DELPHI》一书的意中人都能够解读那么些代码。小编只想谈谈TAction发表给我们的那一个特征,能为大家提供什么作用。由于还有一部分特色是在TAction的老伯类中刊登的,在议论时也将同步谈到,然而有的不首要的性状就不再赘言了。
Caption属性:填写此属性,你能够用简短的题目向用户表达命令操作的含义。此属性将自动更新相关命令控件的Caption属性,所以按钮和菜单的Caption属性要在此输入。
Category属性:操作命令的连串,主借使为着有利于你分类管理你的操作命令集。此属性是在TAction的祖父辈TContainedAction中刊登的,在大家跟着支付的TActionManager控件中,你将见到哪些此属性管理操作命令。
Enabled属性:控制命令操作是还是不是可实行,可自控关系命令控件是还是不是同意实施。封杀命令控件应该从此间入手。
ImageIndex属性:表示操作命令的图标索引,与TActionList的Images联系。有图标的授命控件能够享受到她的恩惠。
ShortCut属性:用键盘发出操作命令的飞速键,为喜好键盘操作的人们带来的教义。
Visible属性:控制Enabled能够让命令控件变灰,控制此属性能够让命令控件消失在用户前面。注意,固然三令五申控件消失,但用户仍可通过火速键发出操作命令,而Enabled才可真的封杀命令。
OnExecute事件:能够在此事件中编辑操作逻辑代码,用户触发相关的通令控件时,将自行调用此事件的操作逻辑代码。
别的的特点就协调查看DELPHI的联机支持吧!
千帆竞发摸底TActionList和TAction之后,我们将发轫推行。下边包车型地铁PRETTYPOEM程序演示了TActionList和TAction的基本用法,很简单。假如您不想浪费时间可径直跳到背后的MULTIFACE程序,看看怎么样表演四川曲艺剧的绝活儿-变脸。
你能够在随书所附的光盘中找到此程序的原代码。

文件PRETTYPOEM.DPR

program PRETTYPOEM;

uses
  Forms,
  Main in ‘Main.pas’ {fMain};

{$R *.RES}

begin
  Application.Initialize;
  Application.CreateForm(TfMain, fMain);
  Application.Run;
end.

文件Main.pas
unit Main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,
  Menus, ActnList, ComCtrls, ToolWin, StdCtrls, ImgList;

type
  TfMain = class(TForm)
    MainMenu: TMainMenu;
    ActionList: TActionList;
    actGuCheng: TAction;
    actXiMuRong: TAction;
    actLiQingZhao: TAction;
    actSuShi: TAction;
    N1: TMenuItem;
    N2: TMenuItem;
    N3: TMenuItem;
    N4: TMenuItem;
    N5: TMenuItem;
    N6: TMenuItem;
    ToolBar1: TToolBar;
    ToolButton1: TToolButton;
    ToolButton2: TToolButton;
    ToolButton3: TToolButton;
    ToolButton4: TToolButton;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    cbDisableLiQingZhao: TCheckBox;
    actDisableLiQingZhao: TAction;
    actHideLiQingZhao: TAction;
    cbHideLiQingZhao: TCheckBox;
    ImageList: TImageList;
    labPoem: TLabel;
    labShadow: TLabel;
    procedure actGuChengExecute(Sender: TObject);
    procedure actXiMuRongExecute(Sender: TObject);
    procedure actDisableLiQingZhaoExecute(Sender: TObject);
    procedure actHideLiQingZhaoExecute(Sender: TObject);
    procedure actSuShiExecute(Sender: TObject);
    procedure actLiQingZhaoExecute(Sender: TObject);
  private
    { Private declarations }
    procedure RecitePoem(Poem:string);
  public
    { Public declarations }
  end;

var
  fMain: TfMain;

implementation

{$R *.DFM}
procedure TfMain.RecitePoem(Poem: string);
begin
  labPoem.Caption:=Poem;
  labShadow.Caption:=Poem;
end;

procedure TfMain.actGuChengExecute(Sender: TObject);
begin
  RecitePoem(‘黑夜给自个儿土黑的双眼 笔者却用她寻找光明’);
end;

procedure TfMain.actXiMuRongExecute(Sender: TObject);
begin
  RecitePoem(‘溪水急着要流向大海  而浪潮却渴望重归土地’);
end;

procedure TfMain.actSuShiExecute(Sender: TObject);
begin
  RecitePoem(‘人有悲欢离合  月有阴晴圆缺’);
end;

procedure TfMain.actLiQingZhaoExecute(Sender: TObject);
begin
  RecitePoem(‘生当做人杰  死亦为鬼雄’);
end;

procedure TfMain.actDisableLiQingZhaoExecute(Sender: TObject);
begin
  actLiQingZhao.Enabled:=not cbDisableLiQingZhao.Checked;
end;

procedure TfMain.actHideLiQingZhaoExecute(Sender: TObject);
begin
  actLiQingZhao.Visible:=not cbHideLiQingZhao.Checked;
end;

end.

文件Main.dfm

object fMain: TfMain
  Left = 192
  Top = 107
  Width = 442
  Height = 195
  BorderIcons = [biSystemMenu,
biMinimize]
  Caption = ‘谈古论今’
  Color = clBtnFace
  Font.Charset = GB2312_CHARSET
  Font.Color = clWindowText
  Font.Height = -12
  Font.Name = ‘宋体’
  Font.Style = []
  Menu = MainMenu
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 12
  object labShadow: TLabel
    Left = 17
    Top = 41
    Width = 380
    Height = 20
    Caption = ‘古今诗词名句欣赏,请采用你热爱的小说家。’
    Font.Charset = GB2312_CHARSET
    Font.Color = clBlack
    Font.Height = -20
    Font.Name = ‘隶书’
    Font.Style = []
    ParentFont = False
    Transparent = True
  end
  object labPoem: TLabel
    Left = 16
    Top = 40
    Width = 380
    Height = 20
    Caption = ‘古今诗词名句欣赏,请采取你喜爱的小说家。’
    Font.Charset = GB2312_CHARSET
    Font.Color = clBlue
    Font.Height = -20
    Font.Name = ‘隶书’
    Font.Style = []
    ParentFont = False
    Transparent = True
  end
  object ToolBar1: TToolBar
    Left = 0
    Top = 0
    Width = 434
    Height = 26
    AutoSize = True
    ButtonWidth = 63
    Caption = ‘ToolBar’
    EdgeBorders = [ebTop, ebBottom]
    Flat = True
    Images = ImageList
    List = True
    ShowCaptions = True
    TabOrder = 0
    object ToolButton1: TToolButton
      Left = 0
      Top = 0
      Action = actGuCheng
    end
    object ToolButton2: TToolButton
      Left = 63
      Top = 0
      Action = actXiMuRong
    end
    object ToolButton3: TToolButton
      Left = 126
      Top = 0
      Action = actSuShi
    end
    object ToolButton4: TToolButton
      Left = 189
      Top = 0
      Action = actLiQingZhao
    end
  end
  object Button1: TButton
    Left = 12
    Top = 80
    Width = 75
    Height = 25
    Action = actGuCheng
    TabOrder = 1
  end
  object Button2: TButton
    Left = 116
    Top = 80
    Width = 75
    Height = 25
    Action = actXiMuRong
    TabOrder = 2
  end
  object Button3: TButton
    Left = 12
    Top = 112
    Width = 75
    Height = 25
    Action = actSuShi
    TabOrder = 3
  end
  object Button4: TButton
    Left = 116
    Top = 112
    Width = 75
    Height = 25
    Action = actLiQingZhao
    TabOrder = 4
  end
  object cbDisableLiQingZhao: TCheckBox
    Left = 232
    Top = 116
    Width = 81
    Height = 17
    Action = actDisableLiQingZhao
    TabOrder = 5
  end
  object cbHideLiQingZhao: TCheckBox
    Left = 328
    Top = 116
    Width = 81
    Height = 17
    Action = actHideLiQingZhao
    TabOrder = 6
  end
  object MainMenu: TMainMenu
    Images = ImageList
    Left = 332
    Top = 4
    object N1: TMenuItem
      Caption = ‘现代情怀’
      object N2: TMenuItem
        Action = actGuCheng
      end
      object N3: TMenuItem
        Action = actXiMuRong
      end
    end
    object N4: TMenuItem
      Caption = ‘古典风采’
      object N5: TMenuItem
        Action = actSuShi
      end
      object N6: TMenuItem
        Action = actLiQingZhao
      end
    end
  end
  object ActionList: TActionList
    Images = ImageList
    Left = 360
    Top = 4
    object actGuCheng: TAction
      Category = ‘现代情怀’
      Caption = ‘顾城’
      ImageIndex = 0
      ShortCut = 16455
      OnExecute = actGuChengExecute
    end
    object actXiMuRong: TAction
      Category = ‘现代情怀’
      Caption = ‘席慕容’
      ImageIndex = 1
      ShortCut = 16472
      OnExecute = actXiMuRongExecute
    end
    object actSuShi: TAction
      Category = ‘古典风韵’
      Caption = ‘苏轼’
      ImageIndex = 2
      ShortCut = 16467
      OnExecute = actSuShiExecute
    end
    object actLiQingZhao: TAction
      Category = ‘古典风韵’
      Caption = ‘李清照’
      ImageIndex = 3
      ShortCut = 16460
      OnExecute = actLiQingZhaoExecute
    end
    object actDisableLiQingZhao: TAction
      Category = ‘控制’
      Caption = ‘禁止李清照’
      OnExecute = actDisableLiQingZhaoExecute
    end
    object actHideLiQingZhao: TAction
      Category = ‘控制’
      Caption = ‘隐藏李清照’
      OnExecute = actHideLiQingZhaoExecute
    end
  end
  object ImageList: TImageList
    Left = 388
    Top = 4
  end
end

此程序运营之后,你能够通过菜单、工具条、按钮和连忙键调出你喜爱的诗句。Action的标题和图标都自动反映在菜单、工具条和按钮上,细心的情侣会发觉,菜单上还同时将我们定义的连忙键显示出来,可知VCL的开发者所做的行事比我们想像的还要多。至于菜单名后的热键字符,是由MainMenu的AutoHotKeys属性引起的。
你能够用选拔框禁止或隐蔽李清照的名字,可是只隐藏李清照的名字时,依旧可通过Ctrl+L调出她的随笔。
休息一下,在我们初步谈论运转时更改软件界面包车型地铁话题之前,先来感触以下作家们的心怀。作家们的诗词是美貌的,但小说中含有的哲理才是他俩内心所追求的地步。编写程序也是那样。