微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

delphi – 为什么从代码调用eventhandler是不好的做法?

假设你有一个菜单项和一个按钮做同样的任务。
为什么不好的做法是将任务的代码放入一个控件的动作事件中,然后从其他控件调用该事件?
Delphi允许这样做vb6,但realbasic不,并说,你应该把代码放入一个方法,然后调用菜单和按钮

解决方法

这是一个如何组织你的程序的问题。在您描述的方案中,菜单项的行为将按照按钮的方式来定义:
procedure TJbForm.MenuItem1Click(Sender: TObject);
begin
  // Three different ways to write this,with subtly different
  // ways to interpret it:

  Button1Click(Sender);
  // 1. "Call some other function. The name suggests it's the
  //    function that also handles button clicks."

  Button1.OnClick(Sender);
  // 2. "Call whatever method we call when the button gets clicked."
  //    (And hope the property isn't nil!)

  Button1.Click;
  // 3. "Pretend the button was clicked."
end;

任何这三个实现将工作,但为什么应该菜单项如此依赖按钮?什么是那么特别的按钮,它应该定义菜单项?如果一个新的UI设计没有按钮,菜单会发生什么?一个更好的方法是把事件处理程序的动作分解出来,使它独立于它附加的控件。有几种方法可以做到:

>一个是完全摆脱MenuItem1Click方法,并将Button1Click方法分配给MenuItem1.OnClick事件属性。对于被分配到菜单项事件的按钮而言,这是令人困惑的,所以你需要重命名事件处理程序,但是没关系,因为与VB不同,Delphi的方法名称不定义它们处理什么事件。只要签名匹配,您就可以将任何方法分配给任何事件处理程序。两个组件的OnClick事件都是TNotifyEvent类型,因此它们可以共享单个实现。命名方法,他们做什么,而不是他们属于什么。
>另一种方法是将按钮的事件处理程序代码移动到一个单独的方法中,然后从两个组件的事件处理程序调用方法

procedure HandleClick;
begin
  // Do something.
end;

procedure TJbForm.Button1Click(Sender: TObject);
begin
  HandleClick;
end;

procedure TJbForm.MenuItem1Click(Sender: TObject);
begin
  HandleClick;
end;

这样,真正做的东西的代码不直接绑定到任何组件,并且让您更容易地更改这些控件,例如通过重命名或用不同的控件替换它们的自由。将代码与组件分离导致我们采用第三种方式:
>在Delphi 4中引入的TAction组件是专为您描述的情况而设计的,其中有多个UI路径用于同一个命令。 (其他语言和开发环境提供类似的概念;它不是Delphi独有的)。将事件处理代码放在TAction的OnExecute事件处理程序中,然后将该操作分配给按钮和菜单项的Action属性

procedure TJbForm.Action1Click(Sender: TObject);
begin
  // Do something
  // (Depending on how closely this event's behavior is tied to
  // manipulating the rest of the UI controls,it might make
  // sense to keep the HandleClick function I mentioned above.)
end;

想要添加一个UI元素,像按钮一样?没问题。添加它,设置它的Action属性,你完成了。不需要编写更多的代码,使新的控件看起来和行为像旧的。你已经写了一次代码

TAction不仅仅是事件处理程序。它可以确保您的UI控件具有统一的属性设置,包括字幕,提示,可见性,启用度和图标。当命令在当时无效时,相应地设置操作的Enabled属性,并且任何链接的控件将自动被禁用。无需担心通过工具栏禁用命令,但仍然通过菜单启用,例如。您甚至可以使用操作的OnUpdate事件,以便操作可以根据当前条件更新自己,而不是需要知道何时发生可能需要立即设置Enabled属性的事情。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


 从网上看到《Delphi API HOOK完全说明》这篇文章,基本上都是大家转来转去,原文出处我已经找不到了。这篇文章写的很不错,但最后部分“PermuteFunction 的终极版本”描述的不太清楚,完全按照该文章代码执行,是不行的。可能是作者故意这样做的?本文最后提供修正后的下载地址。原文如下:一、关于API Hook1.什么是API Hook不知道大家是否还记得,在DO
  从网上看到《Delphi API HOOK完全说明》这篇文章,基本上都是大家转来转去,原文出处我已经找不到了。 这篇文章写的很不错,但最后部分“PermuteFunction 的终极版本”描述的不太清楚,完全按照该文章代码执行,是不行的。需要修改mess.pas中代码才行。其实文中提到的一个结构,代码中并没有使用typePIMAGE_IMPORT_DESCRIPTOR = ^IMA
ffmpeg 是一套强大的开源的多媒体库 一般都是用 c/c++ 调用, 抽空研究了一下该库的最新版 ,把部分api 翻译成了dephi版的 记录一下 地址 ffmpegvcl.zip
32位CPU所含有的寄存器有:4个数据寄存器(EAX、EBX、ECX和EDX)2个变址和指针寄存器(ESI和EDI) 2个指针寄存器(ESP和EBP)6个段寄存器(ES、CS、SS、DS、FS和GS)
1 mov dst, src dst是目的操作数,src是源操作数,指令实现的功能是:将源操作数送到目的操作数中,即:(dst) <--(src) 1.dst和src类型必须匹配,即必须同为字节
有三个API函数可以运行可执行文件WinExec、ShellExecute和CreateProcess。 1.CreateProcess因为使用复杂,比较少用。 2.WinExec主要运行EXE文件。如:WinExec('Notepad.exe Readme.txt', SW_SHOW); 3.ShellExecute不仅可以运行EXE文件,也可以运行已经关联的文件。 首先必须引用shellapi
API原型: Declare Function MoveFileEx& Lib "kernel32" Alias "MoveFileExA" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String, ByVal dwFlags As Long) 参数 类型及说明 lpExistingFileName String,欲移
附带通用控件安装方法: ---------- 基本安装 1、对于单个控件,Componet-->install component..-->PAS或DCU文件-->install; 2、对于带*.dpk文件的控件包,File-->Open(下拉列表框中选*.dpk)-->install即可; 3、对于带*.bpl文件的控件包,Install Packages-->Add-->bpl文件名即可; 4
type   TRec=Record     msg:string;     pic:TMemoryStream; end; procedure TForm2.BitBtn1Click(Sender: TObject); var   ms:TMemoryStream;   Rec1,Rec2:TRec;   cc:tmemorystream;   jpg:TJPEGImage; begin   R