熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Delphi編程 >> 正文

Delphi深度探索之自動完成外殼擴展

2022-06-13   來源: Delphi編程 
    自動完成簡介

  大家一定都非常熟悉IE浏覽器的地址輸入編輯框它提供了自動完成的功能自動完成(Auto Complete)功能簡化了編輯框的輸入功能它可以根據已經輸入的部分字符串進行預測和匹配的例子演示了自動完成可以依據輸入的pro給出Pascal的保留字中與其相匹配的字符串列表procedureprogramproperty

  在利用自動完成功能前必須要知道自動完成並不是任意版本的Windows都支持自動完成功能實際上是由Internet Explorer 引入並必須有版及以上的Shelldll的支持很多早期的系統包括很多安裝了IE 的系統並不支持這項特性所以使用自動完成功能時必須確保要安裝的系統支持這項功能如果不支持就需要安裝IE和集成外殼

  自動完成功能是通過一組COM接口來實現的這些接口使我們可以連接自動完成到編輯框添加編輯框可以枚舉的字符串列表並配置其顯示屬性

   自動完成的用途

  使用自動完成功能可以增強程序的易用性它可以節省用戶反復輸入一些常用字符串的時間並減少輸入錯誤它還可以用於部分字符匹配的查找系統可以用它實現對數據庫內容的快速查找另外它還支持向浏覽器歷史最近運行程序和外殼目錄輸入等功能中添加自定義的完成列表

   配置自動完成

  需要知道的是在Delphi裡並沒有提供自動完成功能相關COM接口的pascal聲明單元由於一般這類接口在微軟都是以C語言的頭文件形式提供接口Delphi不可能及時提供最新的相應的Pascal包裝單元所以為了使用這項功能本文中額外提供了一個shlintf單元翻譯了相應的頭文件的聲明下表總結了Shlintf的內容

COM對象 接 口 CLSID_AutoComplete IAutoComplete CLSID_ACLHistory IAutoComplete CLSID_ACListISF IACList CLSID_ACLMRU IACList CLSID_ACLMulti ICurrentWorkingDirectory   IObjMgr

  自動完成功能最基本的一個接口就是IAutoComplete接口它的聲明如下

type
IAutoComplete = interface(IUnknown)
[SID_IAutoComplete]
function Init(hwndEdit: HWND; punkACL: IUnknown; pwszRegKeyPath: PWideChar;
pwszQuickComplete: PWideChar): HResult; stdcall;
function Enable(fEnable: Boolean): HResult; stdcall;
end;

  IautoComplete接口有兩個方法Init和Enable

  Init方法用來把IAutoComple接口以及自動完成列表同編輯框相連接參數pwszRegKeyPath和pwszQuickComplete使得IAutoComplete接口可以按預定義的格式擴展部分輸入的字符串快捷鍵為CTRL+ENTER比如設定pwszQuickComplete為http://www%scn/當用戶輸入csai 到編輯框並按下快捷鍵CTRL+ENTER編輯框中的文本就會更新為http://wwwcsaicn/

  Enable方法是根據fEnable標識來切換自動完成功能的開關狀態的缺省時是激活的

  下圖顯示了IAutoComplete接口是如何自動完成字符串的當用戶在編輯框中輸入字符時一種可能是最能匹配已經輸入字符串的候選字符會被反白顯示

  回過頭再來看看Init方法的punkACL參數它是一個必須的參數而且必須指向一個提供字符串的接口注意不是我們熟悉的Delphi中提供的TStrings對象而是一個IEnumString字符串接口IEnumString接口負責生成一個用於自動完成的候選字符串列表除了IEnumString接口外punkACL參數還可以是IACList和IACList等其他接口

  IACList接口簡單地說就是可以對候選字符串分類來改善自動完成的效率本文中將不加介紹

  要注意的是Microsoft並沒有停止對自動完成功能的改進在Internet Explorer Microsoft 還提供了IAutoComplete接口IAutoComplete接口進行了進一步的擴展它使得我們可以設定一系列的選項來設定自動完成的可視化表達以及操作下面是 IAutoComplete接口的聲明

type
IAutoComplete = interface(IAutoComplete)
[SID_IAutoComplete]
function SetOptions(dwFlag: DWORD): HResult; stdcall;
function GetOptions(out dwFlag: DWORD):HResult; stdcall;
end;

  IAutoComplete接口引入了兩種新的方法這兩種方法使用同樣的標識組合作為參數下表列出了可用的標識及其意義

標 識 說 明 ACO_NONE 不使用自動完成 ACO_AUTOSUGGEST 使用下拉列表 ACO_AUTOAPPEND 允許自動附加在init方法中pwszQuickComplete參數所代表的字符串 ACO_SEARCH 在下拉列表最後添加查找文本 ACO_FILTERPREFIXES 防止自動完成匹配常用前綴比如www http://等 ACO_USETAB TAB鍵可以用來選擇下拉列表項 ACF_UPDOWNKEYDROPSLIST 上下按鍵可以用來調出下拉列表框 ACO_RTLREADING 按由右到左的順序讀

  就像下圖所顯示的那樣IAutoComplete同IAutoComplete的顯示方式有一點不同就是因為IAutoComplete支持不同的顯示模式這些模式可以通過SetOptions 方法來設定

   實現自動完成

  自動完成功能是通過COM對象來實現的下面代碼用As操作符來獲得IAutoComplete接口

FAutoComplete :=
CreateComObject(CLSID_AutoComplete) as IAutoComplete;

  獲得接口後我們就可以實現自動完成功能了下面代碼是一個簡單的例子

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: IAutoComplete;
FStrings: IUnknown;
end;
var
AutoCompleteForm: TAutoCompleteForm;
implementation
{$R *DFM}
{ TAutoCompleteForm }
procedure TAutoCompleteFormFormCreate(Sender: TObject);
begin
FAutoComplete := CreateComObject(CLSID_AutoComplete) as IAutoComplete;
FStrings := TEnumStringCreate(SourceMemoLines) as IUnknown;

OleCheck(FAutoCompleteSetOptions(ACO_AUTOSUGGESTor ACO_UPDOWNKEYDROPSLIST));

OleCheck(FAutoCompleteInit(CompletionEditHandle FStrings nil nil));
end;
end

  上面的例程首先獲得IAutoComplete接口如果系統不支持IAutoComplete接口as操作符將引發EinvalidCastError異常接下來的一行代碼會創建一個TEnumString類的實例並取得IUnknown接口這個接口將作為FAutoComplete的Init方法的punkACL參數TEnumString類是從TInterfacedObject類繼承的實現在StrTools單元中實現它的目的是使TStrings類同IEnumString接口兼容然後設定顯示選項使自動完成支持下拉列表和自動建議最後初始化FAutoComplete並同編輯框相連接被連接的編輯框就支持自動完成了

   標准自動完成列表

  除了支持標准的編輯框的自動完成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 IAutoComplete;
FStrings := CreateComObject(CLSID_ACListISF);
WorkingDirectory := FStrings as ICurrentWorkingDirectory;
OleCheck(WorkingDirectorySetDirectory(C:\));

OleCheck(FAutoCompleteSetOptions(ACO_AUTOSUGGEST or ACO_UPDOWNKEYDROPSLIST));

OleCheck(FAutoCompleteInit(CompletionEditHandle FStrings nil nil));
end;

   改進自動完成

  雖然自動完成功能實現起來很簡單但為了更好在Delphi中使VCL框架一致應該創建對它的VCL封裝另外的改進應該是要提供對其他嵌入編輯框的控件的自動完成功能的實現如下圖TAutoComplete組件被連接到了一個TtreeView控件上

  總的來說自動完成功能是一項非常棒的功能它可以簡化用戶同經常輸入的文本交互的過程用好自動完成功能會使得你的程序顯得很專業


From:http://tw.wingwit.com/Article/program/Delphi/201311/24788.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.