📄 028.htm
字号:
<p><span class="p2">安装控件编辑器同样和安装控件和属性编辑器相似,只需加入到我们的控件库中,就可以在设计时执行Execute方法!控件编辑器可以为单独的类创建,也可以为一套类(包括所有的继承),这里,这个控件编辑器为TCommomDialog的一套控件而设置的。</span></p>
<pre><span class="p2"><b>unit</b> CompEdit;
<i>{ TCommonDialogComponentEditor version 0.1 }</i>
<b>interface</b>
<b>uses</b>
DsgnIntf;
<b>Type</b>
TCommonDialogComponentEditor = <b>class</b>(TComponentEditor)
<b>public</b>
<b>procedure</b> Edit; <b>override</b>;
<b>end</b>;
<b>procedure</b> Register;
<b>implementation</b>
<b>uses</b>
Dialogs;
<b>procedure</b> TCommonDialogComponentEditor.Edit;
<b>begin</b>
<b>if</b> (Component <b>IS</b> TOpenDialog) <b>then</b> <i>{ also TSaveDialog }</i>
(Component <b>AS</b> TOpenDialog).Execute
<b>else</b>
<b>if</b> (Component <b>IS</b> TPrintDialog) <b>then</b>
(Component <b>AS</b> TPrintDialog).Execute
<b>else</b>
<b>if</b> (Component <b>IS</b> TPrinterSetupDialog) <b>then</b>
(Component <b>AS</b> TPrinterSetupDialog).Execute
<b>else</b>
<b>if</b> (Component <b>IS</b> TColorDialog) <b>then</b>
(Component <b>AS</b> TColorDialog).Execute
<b>else</b>
<b>inherited</b> Edit <i>{ default behaviour }</i>
<b>end</b> <i>{Edit}</i>;
<b>procedure</b> Register;
<b>begin</b>
<i>{ register TCommonDialogComponentEditor for
TCommonDialog and all its derived classes }</i>
RegisterComponentEditor(TCommonDialog, TDialogEditor)
<b>end</b>;
<b>end</b>.
</span></pre>
<p><span class="p2">安装后,拖一个TOpenDialog到表单中,连击它,看看吧!嘿嘿</span></p>
<p align="center"> </p>
<p><span class="p2">不幸的是,我们测试TFontDialog时,缺省的行为(编辑OnApply事件)并没有发生,我们确实调用了inherited
Edit方法,但这是TComponentEditor.editor方法,而不是缺省的控件编辑器(TDefaultEditor)的Edit方法。有两种方法补救:一种是只为TCommonDialog的5种继承的控件安装,或者是从TDefaultEditor继承,而不是从TComponentEditor类继承。</span></p>
<p><span class="p2"><font size="4"><b>菜单控件编辑器 Menu Component Editor</b></font><br>
控件编辑器不是只能作一件事(在Edit中所作的),实际上,我们能创建自己的弹出菜单来提供几个选择,让我们再来作通用对话框的‘Execute/Preview’,但这次加入一些信息显示。为了避免打断TCommonDialog继承类的缺省行为,我们只注册TCommonDialogComponentEditor到5个没有缺省事件属性的类,这回我们要重载两个函数和一个过程:函数GetVerbCount、GetVerb和过程ExecuteVerb。</span></p>
<pre><span class="p2">
TCommonDialogComponentEditor = <b>class</b>(TComponentEditor)
<b>public</b>
<b>function</b> GetVerbCount: Integer; <b>override</b>;
<b>function</b> GetVerb(Index: Integer): string; <b>override</b>;
<b>procedure</b> ExecuteVerb(Index: Integer); <b>override</b>;
<b>end</b>;
</span></pre>
<p><span class="p2">因为有两个菜单选项,一个是运行Dialog.Excute,另一个是显示“About”信息,函数GetverbCount应该返回2。</span></p>
<pre>
<span class="p2"><b>function</b> TCommonDialogComponentEditor.GetVerbCount: Integer;
<b>begin</b>
GetVerbCount := 2
<b>end</b> <i>{GetVerbCount}</i>;
</span></pre>
<p><span class="p2">我们知道Delphi总是从0开始记数的,另一个函数,GetVerb的Index参数可能得到0和1两种可能的菜单输入选择。在0时我们应返回‘Execute’,在1(或其它值)应返回‘About’</span></p>
<pre>
<span class="p2"><b>function</b> TCommonDialogComponentEditor.GetVerb(Index: Integer): string;
<b>begin</b>
<b>if</b> Index >= 1 <b>then</b> GetVerb := '&About...'
<b>else</b> GetVerb := '&Execute...'
<b>end</b> <i>{GetVerb}</i>;
</span></pre>
<p><span class="p2">为了显示是哪一个通用对话框,我可以作如下改写:</span></p>
<pre><span class="p2">
GetVerb := '&Execute ' + Component.ClassName + '...'
</span></pre>
<p><span class="p2">最后,我们要执行动作,在0时,和以前在TDialogEditor中一样,在比0大时显示对话框
</span></p>
<pre>
<span class="p2"><b>procedure</b> TCommonDialogComponentEditor.ExecuteVerb(Index: Integer);
<b>begin</b>
<b>if</b> index >= 1 <b>then</b>
MessageDlg('TCommonDialogComponentEditor (c) 1996 by Dr.Bob',
mtInformation, [mbOk], 0)
<b>else</b>
<b>if</b> (Component <b>IS</b> TOpenDialog) <b>then</b> <i>{ also TSaveDialog }</i>
(Component <b>AS</b> TOpenDialog).Execute
<b>else</b>
<b>if</b> (Component <b>IS</b> TPrintDialog) <b>then</b>
(Component <b>AS</b> TPrintDialog).Execute
<b>else</b>
<b>if</b> (Component <b>IS</b> TPrinterSetupDialog) <b>then</b>
(Component <b>AS</b> TPrinterSetupDialog).Execute
<b>else</b>
<b>if</b> (Component <b>IS</b> TColorDialog) <b>then</b>
(Component <b>AS</b> TColorDialog).Execute;
<b>end</b> <i>{ExecuteVerb}</i>;
</span></pre>
<p><span class="p2">注意,可以使用Compent属性来得到确实的控件</span></p>
<p><span class="p2">试试吧,能得到如下的弹出式菜单 </span></p>
<p align="center"> </p>
<p><span class="p2">如果我们执行TColorDialog,选择另一种颜色,关闭对话框,在对象查看器中还是原来的值,为什么没有更新?</span></p>
<p><span class="p2">实际上,我们忘记调用了Designer.Modified
方法来通知设计者(包括对象查看器)控件已经改变了,例如某个属性的值改变了。</span></p>
<p><span class="p2">全部代码如下:</span></p>
<pre><span class="p2"><b>unit</b> CompMenu;
<i>{ TCommonDialogComponentEditor version 0.5 }</i>
<b>interface</b>
<b>uses</b>
DsgnIntf;
<b>Type</b>
TCommonDialogComponentEditor = <b>class</b>(TComponentEditor)
<b>function</b> GetVerbCount: Integer; <b>override</b>;
<b>function</b> GetVerb(index: Integer): String; <b>override</b>;
<b>procedure</b> Executeverb(index: Integer); <b>override</b>;
<b>end</b>;
<b>procedure</b> Register;
<b>implementation</b>
<b>uses</b>
Dialogs;
<b>function</b> TCommonDialogComponentEditor.GetVerbCount: Integer;
<b>begin</b>
GetVerbCount := 2
<b>end</b> <i>{GetVerbCount}</i>;
<b>function</b> TCommonDialogComponentEditor.GetVerb(index : Integer): String;
<b>begin</b>
<b>if</b> Index >= 1 <b>then</b> GetVerb := '&About...'
<b>else</b> GetVerb := '&Execute...'
<b>end</b> <i>{GetVerb}</i>;
<b>procedure</b> TCommonDialogComponentEditor.ExecuteVerb(index: Integer);
<b>begin</b>
<b>if</b> index >= 1 <b>then</b>
MessageDlg('TCommonDialogComponentEditor (c) 1996 by Dr.Bob',
mtInformation, [mbOk], 0)
<b>else</b>
<b>if</b> (Component <b>IS</b> TOpenDialog) <b>then</b> <i>{ also TSaveDialog }</i>
(Component <b>AS</b> TOpenDialog).Execute
<b>else</b>
<b>if</b> (Component <b>IS</b> TPrintDialog) <b>then</b>
(Component <b>AS</b> TPrintDialog).Execute
<b>else</b>
<b>if</b> (Component <b>IS</b> TPrinterSetupDialog) <b>then</b>
(Component <b>AS</b> TPrinterSetupDialog).Execute
<b>else</b>
<b>if</b> (Component <b>IS</b> TColorDialog) <b>then</b>
(Component <b>AS</b> TColorDialog).Execute;
Designer.Modified <i>{ inform the Object Inspector of the change }</i>
<b>end</b> <i>{Edit}</i>;
<b>procedure</b> Register;
<b>begin</b>
RegisterComponentEditor(TCommonDialog, TCommonDialogComponentEditor)
<b>end</b>;
<b>end</b>.
</span></pre>
<p><span class="p2"><font size="4"><b>菜单缺省控件编辑器Menu Default Component
Editors</b></font><br>
现在我们知道了如何为没有缺省行为的TCommonDialogs写一个新的控件编辑器,如何扩展有缺省行为的,但是又不丢失其原有的行为?例如,提供弹出菜单第一项(缺省)选择OnEvent转向代码编写,第二项预览执行,第二项选择信息显示。为了做到这一个,我们需要另一个从TDefaultEditor继承的TCommomDialogDefaultEditor类。同样我们要重载两个函数和一个过程。</span></p>
<pre><span class="p2">
TCommonDialogDefaultEditor = <b>class</b>(TDefaultEditor) <i>{ not TComponentEditor }</i>
<b>public</b>
<b>function</b> GetVerbCount: Integer; <b>override</b>;
<b>function</b> GetVerb(Index: Integer): string; <b>override</b>;
<b>procedure</b> ExecuteVerb(Index: Integer); <b>override</b>;
<b>end</b>;
</span></pre>
<p><span class="p2">现在要3个选项,一个是缺省动作(TDefaultEditor.Edit),一个为Dialog.Excute,一个显示信息。所以GetVerbCount应返回3。</span></p>
<pre>
<span class="p2"><b>function</b> TCommonDialogDefaultEditor.GetVerbCount: Integer;
<b>begin</b>
GetVerbCount := 3
<b>end</b> <i>{GetVerbCount}</i>;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -