3. 实现自动完成
自动完成功能是通过COM对象来实现的,下面代码用As操作符来获得IAutoComplete2接口:
FAutoComplete :=
CreateComObject(CLSID_AutoComplete) as IAutoComplete2;
获得接口后我们就可以实现自动完成功能了,下面代码是一个简单的例子:
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs, ShlIntf, ActiveX,
ComObj, StdCtrls, StrTools;
type
TAutoCompleteForm = class(TForm)
CompletionEdit: TEdit;
CompletionLabel: TLabel;
SourceGroupBox: TGroupBox;
SourceMemo: TMemo;
procedure FormCreate(Sender: TObject);
private
FAutoComplete: IAutoComplete2;
FStrings: IUnknown;
end;
var
AutoCompleteForm: TAutoCompleteForm;
implementation
{$R *.DFM}
{ TAutoCompleteForm }
procedure TAutoCompleteForm.FormCreate(Sender: TObject);
begin
FAutoComplete := CreateComObject(CLSID_AutoComplete) as IAutoComplete2;
FStrings := TEnumString.Create(SourceMemo.Lines) as IUnknown;
OleCheck(FAutoComplete.SetOptions(ACO_AUTOSUGGESTor ACO_UPDOWNKEYDROPSLIST));
OleCheck(FAutoComplete.Init(CompletionEdit.Handle, FStrings, nil, nil));
end;
end.
上面的例程首先获得IAutoComplete2接口,如果系统不支持IAutoComplete2接口,as操作符将引发 EinvalidCastError异常。接下来的一行代码会创建一个TEnumString类的实例并取得IUnknown接口,这个接口将作为 FAutoComplete的Init方法的punkACL参数,TEnumString类是从TInterfacedObject类继承的,实现在 StrTools单元中,实现它的目的是使TStrings类同IEnumString接口兼容。然后,设定显示选项使自动完成支持下拉列表和自动建议。 最后初始化FAutoComplete并同编辑框相连接,被连接的编辑框就支持自动完成了。
4. 标准自动完成列表
除了支持标准的编辑框的自动完成,Microsoft还允许通过下表中的一组COM对象来存取标准自动完成列表。
COM对象说 明
CLSID_History允许存取历史列表项
CLSID_ACListISF允许操作外壳命名空间的内容
CLSID_MRU提供最近运行过的程序列表
上面列出的COM对象提供了一个IUnknown接口,接口可以作为IAutoComplete接口的Init方法的punkACL参数。每个 IUnknown接口都支持IEnumString和IACList接口,同时还支持其他特殊接口。比如,外壳空间的IUnknown接口还公开了 ICurrentWorkingDirectory和IPersistFolder接口。使用这些对象可以根据外壳空间的变化动态地改变候选字符串列表。
ICurrentWorkingDirectory和IPersistFolder接口的区别在于IPersistFolder使用item lists 而不是字符串。Item lists 便于存取虚拟文件夹比如控制面板。
下面的代码演示了如何使用自动完成功能来设定C:\\下的外壳内容为候选字符串列表:
var
WorkingDirectory: ICurrentWorkingDirectory;
begin
FAutoComplete := CreateComObject(CLSID_AutoComplete) as IAutoComplete2;
FStrings := CreateComObject(CLSID_ACListISF);
WorkingDirectory := FStrings as ICurrentWorkingDirectory;
OleCheck(WorkingDirectory.SetDirectory(’C:\\’));
OleCheck(FAutoComplete.SetOptions(ACO_AUTOSUGGEST or ACO_UPDOWNKEYDROPSLIST));
OleCheck(FAutoComplete.Init(CompletionEdit.Handle, FStrings, nil, nil));
end;
5. 改进自动完成
虽然自动完成功能实现起来很简单,但为了更好在Delphi中使VCL框架一致,应该创建对它的VCL封装。另外的改进应该是要提供对其他嵌入编辑框的控件的自动完成功能的实现。TAutoComplete组件被连接到了一个TtreeView控件上。
总的来说,自动完成功能是一项非常棒的功能,它可以简化用户同经常输入的文本交互的过程。用好自动完成功能,会使得你的程序显得很专业。
责任编辑:小草