📄 048.htm
字号:
face="宋体" lang="ZH-CN" size="3">事件处理过程是可选的</p>
<p> </p>
<p> ⑴</font><font size="3"> </font><font face="宋体" lang="ZH-CN" size="3">事件是方法指针</p>
<p> </font><font face="Arial" size="3">Delphi</font><font face="宋体" lang="ZH-CN"
size="3">使用方法指针实现事件。一个方法指针是指向特定对象实例的特定方法的特定指针。作为部件编写者,能将方法指针作为一种容器。你的代码一发现事情发生,就调用由用户定义的方法。 </p>
<p> 方法指针的工作方式就象其它的过程类型,但它们保持一个隐含的指向对象实例的指针。所有的控制都继承了一个名为</font><font
face="Arial" size="3">Click</font><font face="宋体" lang="ZH-CN" size="3">的方法,以处理</font><font
face="Arial" size="3">Click</font><font face="宋体" lang="ZH-CN" size="3">事件。</font><font
face="Arial" size="3">Click</font><font face="宋体" lang="ZH-CN" size="3">方法调用用户的</font><font
face="Arial" size="3">Click</font><font face="宋体" lang="ZH-CN" size="3">事件处理过程。</p>
<p> </p>
<p> </font><font face="Arial" size="3">procedure TControl.Click;</p>
<p>begin</p>
<p>if Assigned(OnClick ) then OnClick( Self );</p>
<p>end;</p>
<p></font><font size="3"> </font><font face="Arial" size="3"></p>
<p></font><font face="宋体" lang="ZH-CN" size="3">如果用户给</font><font
face="Arial" size="3">Control</font><font face="宋体" lang="ZH-CN" size="3">的</font><font
face="Arial" size="3">OnClick</font><font face="宋体" lang="ZH-CN" size="3">事件赋了处理过程</font><font
face="Arial" size="3">(Handle)</font><font face="宋体" lang="ZH-CN" size="3">,那鼠标点按</font><font
face="Arial" size="3">Control</font><font face="宋体" lang="ZH-CN" size="3">时将导致方法被调用。</p>
<p> ⑵</font><font size="3"> </font><font face="宋体" lang="ZH-CN" size="3">事件是属性</p>
<p> 部件采用属性的形式实现事件。不象大多数其它属性,事件不使用方法来使实现</font><font
face="Arial" size="3">read</font><font face="宋体" lang="ZH-CN" size="3">和</font><font
face="Arial" size="3">write</font><font face="宋体" lang="ZH-CN" size="3">部分。事件属性使用了相同类型的私有对象域作为属性。按约定域名在属性名前加“</font><font
face="Arial" size="3">F</font><font face="宋体" lang="ZH-CN" size="3">”。例如</font><font
face="Arial" size="3">OnClick</font><font face="宋体" lang="ZH-CN" size="3">方法的指针,存在</font><font
face="Arial" size="3">TNotifyEvent</font><font face="宋体" lang="ZH-CN" size="3">类型</font><font
face="Arial" size="3">FOnClick</font><font face="宋体" lang="ZH-CN" size="3">域中。</font><font
face="Arial" size="3">OnClick</font><font face="宋体" lang="ZH-CN" size="3">事件属性的声明如下:</p>
<p></font><font size="3"> </font><font face="Arial" size="3"></p>
<p>type</p>
<p>TControl=class ( TComponent )</p>
<p>private</p>
<p>FOnClick: TNofiFyEvent; { </font><font face="宋体" lang="ZH-CN" size="3">声明保存方法指针的域</font><font
size="3"> </font><font face="Arial" size="3">}</p>
<p>protected</p>
<p>property OnClick: TNotifyEvent read FOnClick write FOnClick;</p>
<p>end; </p>
<p></font><font size="3"> </font><font face="Arial" size="3"></p>
<p></font><font face="宋体" lang="ZH-CN" size="3"> 象其它类型的属性一样,你能在运行时设置和改变事件的值。将事件做成属性的主要好处是部件用户能在设计时使用</font><font
face="Arial" size="3">Object Inspector</font><font face="宋体" lang="ZH-CN" size="3">设置事件处理过程。</p>
<p> ⑶</font><font size="3"> </font><font face="宋体" lang="ZH-CN" size="3">事件处理过程类型</p>
<p> 因为一个事件是指向事件处理过程的指针,因此事件属性必须是方法指针类型,被用作事件处理过程的代码,必须是相应的对象的方法。</p>
<p> 所有的事件方法都是过程。为了与所给类型的事件兼容,一个事件处理过程必须有相同数目和相同类型的相同顺序的参数。</font><font
face="Arial" size="3">Delphi</font><font face="宋体" lang="ZH-CN" size="3">定义了所有标准事件处理过程的方法类型,当你创建自己的事件时,你能使用已有的事件类型,或创建新的。虽然不能用函数做事件处理过程,但可以用</font><font
face="Arial" size="3">var</font><font face="宋体" lang="ZH-CN" size="3">参数得到返回信息。</p>
<p> 在事件处理过程中传递</font><font face="Arial" size="3">var</font><font
face="宋体" lang="ZH-CN" size="3">参数的典型例子是</font><font face="Arial"
size="3">TKeyPressEvent</font><font face="宋体" lang="ZH-CN" size="3">类型的</font><font
face="Arial" size="3">KeyPressed</font><font face="宋体" lang="ZH-CN" size="3">事件。</font><font
face="Arial" size="3">TKeyPressEvent</font><font face="宋体" lang="ZH-CN" size="3">定义中含有两个参数。一个指示哪个对象产生该事件。另一个指示那个键按下:</p>
<p> </p>
<p> </font><font face="Arial" size="3">type</p>
<p>TKeyPressEvent=procedure( Sender: TObject; var key: char) of Object;</p>
<p></font><font size="3"> </font><font face="Arial" size="3"></p>
<p></font><font face="宋体" lang="ZH-CN" size="3">通常</font><font face="Arial"
size="3">key</font><font face="宋体" lang="ZH-CN" size="3">参数包含用户按下键的字符。在某些情况下,部件的用户可能想改变字符值。例如在编辑器中强制所有字符为大写,在这种情况下,用户能定义下列的事件处理过程:</p>
<p></font><font size="3"> </font><font face="Arial" size="3"></p>
<p></font><font face="宋体" lang="ZH-CN" size="3"> </font><font face="Arial" size="3">procedure
TForml.EditlKeyPressed( Sender: TObject; var key: char);</p>
<p>begin</p>
<p>key := Upcase( key );</p>
<p>end;</p>
<p></font><font size="3"> </font><font face="Arial" size="3"></p>
<p></font><font face="宋体" lang="ZH-CN" size="3">也可使用</font><font face="Arial"
size="3">var</font><font face="宋体" lang="ZH-CN" size="3">参数让用户覆盖缺省的处理。</p>
<p> ⑷</font><font size="3"> </font><font face="宋体" lang="ZH-CN" size="3">事件处理过程是可选的</p>
<p> 在为部件创建事件时要记住部件用户可能并不编写该事件的处理过程。这意味着你的部件不能因为部件用户没有编写处理代码而出错。这种事件处理过程的可选性有两个方面:</font><font
face="Arial" size="3"></p>
<p></font><font face="宋体" lang="ZH-CN" size="3"> </font><font size="3"> </font><font
face="宋体" lang="ZH-CN" size="3">①</font><font size="3"> </font><font face="宋体"
lang="ZH-CN" size="3">部件用户并非不得不处理事件</font><font face="Arial"
size="3"></p>
<p></font><font face="宋体" lang="ZH-CN" size="3">事件总是不断地发生在</font><font
face="Arial" size="3">Windows</font><font face="宋体" lang="ZH-CN" size="3">应用程序中。例如,在部件上方移动鼠标就引起</font><font
face="Arial" size="3">Windows</font><font face="宋体" lang="ZH-CN" size="3">发送大量的</font><font
face="Arial" size="3">Mouse-Move</font><font face="宋体" lang="ZH-CN" size="3">消息给部件,部件将鼠标消息传给</font><font
face="Arial" size="3">OnMouseMove</font><font face="宋体" lang="ZH-CN" size="3">事件。在大多数情况下,部件用户不需要关心</font><font
face="Arial" size="3">MouseMove</font><font face="宋体" lang="ZH-CN" size="3">事件,这不会产生问题,因为部件不依赖鼠标事件的处理过程。同样,自定义部件也不能依赖用户的事件处理过程。</p>
<p> </font><font size="3"> </font><font face="宋体" lang="ZH-CN" size="3">②</font><font
size="3"> </font><font face="宋体" lang="ZH-CN" size="3">部件用户能在事件处理过程写任意的代码</p>
<p> 一般说来,对用户在事件处理过程中的代码没有限制。</font><font
face="Arial" size="3">Delphi</font><font face="宋体" lang="ZH-CN" size="3">部件库的部件都支持这种方式以使所写代码产生错误的可能性最小。显然,不能防止用户代码出现逻辑错误。</p>
<p> </font><font face="Arial" size="3">2. </font><font face="宋体" lang="ZH-CN"
size="3">怎样实现标准事件</p>
<p> </font><font face="Arial" size="3">Delphi</font><font face="宋体" lang="ZH-CN"
size="3">带的所有控制继承了大多数</font><font face="Arial" size="3">Windows</font><font
face="宋体" lang="ZH-CN" size="3">事件,这些就是标准事件。尽管所有这些事件都嵌在标准控制中,但它们缺省是</font><font
face="Arial" size="3">protected</font><font face="宋体" lang="ZH-CN" size="3">,这意味着用户无法访问它们,当创建控制时,则可选择这些事件使用户可用。将这些标准事件嵌入自定义控制需要考虑如下:</font><font
face="Arial" size="3"></p>
<p></font><font face="宋体" lang="ZH-CN" size="3"> </font><font size="3"> </font><font
face="宋体" lang="ZH-CN" size="3">●</font><font size="3"> </font><font face="宋体"
lang="ZH-CN" size="3">什么是标准事件</p>
<p> </font><font size="3"> </font><font face="宋体" lang="ZH-CN" size="3">●</font><font
size="3"> </font><font face="宋体" lang="ZH-CN" size="3">怎样使事件可见</p>
<p> </font><font size="3"> </font><font face="宋体" lang="ZH-CN" size="3">●</font><font
size="3"> </font><font face="宋体" lang="ZH-CN" size="3">怎样修改标准事件处理过程</p>
<p> </p>
<p> ⑴</font><font size="3"> </font><font face="宋体" lang="ZH-CN" size="3">什么是标准事件</p>
<p> 有两种标准事件:用于所有控制和只用于标准</font><font
face="Arial" size="3">Windows</font><font face="宋体" lang="ZH-CN" size="3">控制。</p>
<p> 最基本的事件都定义在对象</font><font face="Arial" size="3">TControl</font><font
face="宋体" lang="ZH-CN" size="3">中。窗口控制、图形控制和自定义控制都继承了这些事件,下面列出用于所有控制的事件:</p>
<p> </font><font face="Arial" size="3">OnClick OnDragDrop OnEndDrag OnMouseMove</p>
<p></font><font face="宋体" lang="ZH-CN" size="3"> </font><font face="Arial" size="3">OnDblClick
OnDragOver OnMouseDown OnMouseUp</p>
<p></font><font face="宋体" lang="ZH-CN" size="3"> </p>
<p> 所有标准事件在</font><font face="Arial" size="3">TControl</font><font
face="宋体" lang="ZH-CN" size="3">中都定义了相应的</font><font face="Arial"
size="3">protected</font><font face="宋体" lang="ZH-CN" size="3">动态方法,只是没有加“</font><font
face="Arial" size="3">On</font><font face="宋体" lang="ZH-CN" size="3">”例如</font><font
face="Arial" size="3">OnClick</font><font face="宋体" lang="ZH-CN" size="3">事件调用名为</font><font
face="Arial" size="3">Click</font><font face="宋体" lang="ZH-CN" size="3">的方法。</p>
<p> 标准控制(从</font><font face="Arial" size="3">TWinControl</font><font
face="宋体" lang="ZH-CN" size="3">继承)具有下列事件:</font><font
face="Arial" size="3"></p>
<p></font><font face="宋体" lang="ZH-CN" size="3"> </font><font face="Arial" size="3">OnEnter
OnKeyDown OnkeyPress OnKeyUp OnExit</font><font face="宋体" lang="ZH-CN" size="3"></p>
<p></font><font size="3"> </font><font face="Arial" size="3"></p>
<p></font><font face="宋体" lang="ZH-CN" size="3">正如</font><font face="Arial"
size="3">TControl</font><font face="宋体" lang="ZH-CN" size="3">中的标准事件,窗口控制也有相应</font><font
face="Arial" size="3">protected</font><font face="宋体" lang="ZH-CN" size="3">动态方法。</p>
<p> ⑵</font><font size="3"> </font><font face="宋体" lang="ZH-CN" size="3">怎样使事件可见</p>
<p> 标准事件的声明是</font><font face="Arial" size="3">protected</font><font
face="宋体" lang="ZH-CN" size="3">,如果想使用户在运行时或设计时能访问它们,就需要将它们重声明为</font><font
face="Arial" size="3">public</font><font face="宋体" lang="ZH-CN" size="3">和</font><font
size="3"> </font><font face="Arial" size="3">published</font><font face="宋体"
lang="ZH-CN" size="3">。重声明属性而不描述它的实现将继承相同的实现方法,只是改变了访问级别。例如,创建一个部件并使它的</font><font
face="Arial" size="3">OnClick</font><font face="宋体" lang="ZH-CN" size="3">事件出现在运行时,你可增加下面的部件声明:</p>
<p></font><font size="3"> </font><font face="Arial" size="3"></p>
<p></font><font face="宋体" lang="ZH-CN" size="3"> </font><font size="3"> </font><font
face="Arial" size="3">type</p>
<p>TMyControl=class(TCustomControl)</p>
<p>published</p>
<p>property OnClick; { </font><font face="宋体" lang="ZH-CN" size="3">使</font><font
face="Arial" size="3">OnClick</font><font face="宋体" lang="ZH-CN" size="3">在</font><font
face="Arial" size="3">objectinspector</font><font face="宋体" lang="ZH-CN" size="3">中可见</font><font
size="3"> </font><font face="Arial" size="3">}</p>
<p>end;</p>
<p></font><font size="3"> </font><font face="Arial" size="3"></p>
<p></font><font face="宋体" lang="ZH-CN" size="3">⑶</font><font size="3"> </font><font
face="宋体" lang="ZH-CN" size="3">怎样修改标准事件处理过程</p>
<p> 如果想修改自定义部件响应某种事件的方法,可以重写代码并将其赋给事件。将联接每个标准事件的方法声明的</font><font
face="Arial" size="3">protected</font><font face="宋体" lang="ZH-CN" size="3">是出于慎密的考虑。通过,覆盖实现方法,能修改内部事件处理过程,通过调用继承的方法,能保持标准事件处理过程。</p>
<p> 调用继承的方法的顺序是很重要的。一般首先调用继承的方法,允许用户的事件处理过程代码在你的定制代码前执行。然而也有在调用继承的方法之前执行自己的代码情况出现。</p>
<p> 下面是一个覆盖</font><font face="Arial" size="3">Click</font><font
face="宋体" lang="ZH-CN" size="3">事件的例子:</p>
<p></font><font size="3"> </font><font face="Arial" size="3"></p>
<
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -