Dismiss Notice

REGISTRATION IS AFTER ADMIN ACTIVATION

DONATIONS WITH PAYPAL CLICK TO BUTTON

1 MONTH VIP - 5$; 3 MONTHS VIP - 10$; 6 MONTHS VIP - 20$; 1 YEAR VIP - 30$; 2 YEARS VIP - 50$; GOLD USER FOR LIFE VIP - 150$

DONATIONS WITH Bitcoin Address:3NRs3CK3fhXifrNYxHEZKpETDd9vNLMsMD

Dismiss Notice
The registration is approved by the Administrator. It takes about 1 day to approve your registration
Dismiss Notice
For open hidden message no need write thanks, thank etc. Enough is click to like button on right side of thread.

Auto Completion

Discussion in 'Delphi Programming' started by N0body, Jan 30, 2014.

  1. N0body
    Online

    N0bodyN0body is a Verified Member DelphiFan Administrator Staff Member DF Staff

    A common feature of Microsoft Windows is auto completion. Auto completion functions to expand text as you type, making suggestions to reduce repetitive tasks. With auto completion, partial words can be expanded into more complete phrases that match a stored list of choices. The end result is less typing and more accurate text entry.

    At its most basic level, auto completion is a set of Microsoft COM interfaces. These interfaces allow you to associate auto completion with an edit window, attach a list of strings from which it can enumerate, and configure display options. In this article we'll show how you to create and use auto completion, explain how it works, and provide ideas to enhance your applications.


    [​IMG]



    Reasons to use auto completion

    There are plenty of reasons to include auto completion in your next project. You can use auto completion to save the time it takes to access frequently used features, or re-enter commonly typed names. Auto completion can tap into a system defined set of completion lists for working with Internet history, commonly run programs, and shell folder items. Also, you could theoretically use auto completion to draw suggestions from a database, or even a web service.

    Setting up auto completion

    Before attempting to use auto completion, you should have a unit that defines it's related interfaces and constants. These items are defined in Microsoft's Plaform SDK headers ShlObj.h and ShlGuid.h. A translation of those headers are included in the  Controls Library ShlIntf unit.

    Here is a table summarizing the common auto complete interfaces and coclasses.

    CoClasses

    Code:
    CLSID_AutoComplete

    Code:
    CLSID_ACLHistory

    Code:
    CLSID_ACListISF

    Code:
    CLSID_ACLMRU

    Code:
    CLSID_ACLMulti

    Interfaces

    Code:
    IAutoComplete

    Code:
    IAutoComplete2

    Code:
    IACList

    Code:
    IACList2

    Code:
    ICurrentWorkingDirectory

    Code:
    IObjMgr

    Note: The simple definition of a CoClass (component class) is an COM object that can be created on demand typically through a call to CoCreateInstance.

    To start using with auto completion, it's helpful to understand it's primary interface 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;


    As you can see, IAutoComplete is a simple interface with has two methods: Init and Enable.

    The Init method serves to associate an IAutoComplete interface with an edit window and an auto complete list (more on the auto complete list in a bit). The additional parameters pwszRegKeyPath and pwszQuickComplete can be used to allow the IAutoComplete interface to expand partial text into formatted strings. These parameters can optionally point to strings that determine a format to be used if the user enters partial text, then presses CTRL+ENTER.



    [​IMG]



    The Enable method simply activates or deactivates auto completion based on the value of the fEnable flag. Auto completion is enabled by default.

    The figure above shows how IAutoComplete looks when it expands strings. As you begin typing in the edit window, auto completion will highlight a candidate that best approximates a match for the partial string. Again, by default, this is the way auto completion operates. Later we'll show how you can extend auto completion to use a drop down list.

    Now let's look at the the punkACL parameter of the Init method. This required parameter points to an interface that exposes a string list. A string list is a COM object that exposes an IEnumString interface. The IEnumString interface is responsible for generating a list of candidates for completed strings. The punkACL parameter can expose additional interfaces such as IACList and IACList2.

    The IACList and IACList2 interfaces are an auto complete list interfaces that can be used to improve efficiency by organizing candidate strings.

    The IAutoComplete2 interface extends IAutoComplete by adding the ability to retrieve and set a number of options that affect the not only auto completion's visual representation, but also how it operates. Below is a listing of IAutoComplete2.
    type
    IAutoComplete2 = interface(IAutoComplete)
    [SID_IAutoComplete]
    function SetOptions(dwFlag: DWORD): HResult; stdcall;
    function GetOptions(out dwFlag: DWORD): HResult; stdcall;
    end;


    IAutoComplete2 introduces two new methods. Both methods use the same parameter types, which is a single unsigned integer consisting of a set of logically combined flags. Here is a table of the auto completion options flags and their meanings.

    Flag
    Description

    Code:
    ACO_NONE

    Don't use auto completion.

    Code:
    ACO_AUTOSUGGEST

    Use a drop down list.

    Code:
    ACO_SEARCH

    Add the text "Search for" to the end of the drop down list.

    Code:
    ACO_FILTERPREFIXES

    Prevents auto completion from matching common prefixes such as"www.", "http://".

    Code:
    ACO_USETAB

    The TAB key is used to select an item from the drop down list.

    Code:
    ACF_UPDOWNKEYDROPSLIST

    The UP ARROW and DOWN ARROW keys to cause the drop down list to appear.

    Code:
    ACO_RTLREADING

    Used for right to left reading.



    [​IMG]

    Notice that the TAB key option must be specifically enabled. This is because the TAB key is normally used to navigate between controls, not within a control. Setting ACO_USETAB as a flag allows the user to navigate to the drop down list by pressing TAB. When the drop down list is closed, the TAB key allows the user to navigate from normally between controls. When the list is dropped down, pressing the ESCAPE key closes the list.

    Working with COM interfaces

    Since auto completion is implemented as a set of COM interfaces, it helps to be familiar with some COM fundamentals.

    For example, to create an instance of an IAutoComplete complete component class with COM you might use the following code:
    CoInitialize(nil);
    OleCheck(CoCreateInstance(CLSID_AutoComplete, nil, CLSCTX_INPROC_SERVER,
    IID_IAutoComplete2, FAutoComplete));

    Thankfully Delphi's run time library makes working with COM easy. The ComObj unit takes care initializing and uninitializing the COM libraries for you, so you never have to call CoInitialize. It defines a function named CreateComObject which creates a single unknown interface of the class associated with it class id parameter. Internally CreateComObject calls CoCreateInstance, requesting and unknown interface from the CoClass.
    FAutoComplete := CreateComObject(CLSID_AutoComplete) as IAutoComplete2;
    To convert an unknown interface returned from CreateComObject into something useful, use interface querying with the "as" operator. Interface querying with the "as" operator performs safe checked calls, so if the interface being queried for is not supported, an exception will be raised.

    Sample application

    We now have enough information assembled to create our first auto completion application. Below is a listing of the main unit. As you can see, it takes very little code to get auto completion up and running.
    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_AUTOSUGGEST or ACO_UPDOWNKEYDROPSLIST));
    OleCheck(FAutoComplete.Init(CompletionEdit.Handle, FStrings, nil, nil));

    end;

    end.

    The first line of the event handler above creates an instance of the auto complete CoClass. It queries the unknown result form CreateComObject for an IAutoComplete2 interface. If your system does not support IAutoComplete2, this line will cause an EInvalidCastError exception to be raised. The next line creates an instance of the TEnumString class and queries it for IUnknown. This interface is used later as the punkACL parameter in the Init method of FAutoComplete. The TEnumString class is derived from TInterfacedObject and defined in the StrTools unit. It basic purpose is to make a TStrings object IEnumString compatible. Next we set the options of FAutoComplete to include the drop down list and auto suggest. Finally we initialize the FAutoComplete, associating it with the edit window, and providing an auto completion list from which it can enumerate candidate strings.

    Figure one at the top of this article show a screen shot of the TAutoCompleteForm class in action.

    Standard auto completion lists

    In addition to creating a control and managing string candidates for you, Windows also provides access to a set standard auto completion lists. These mostly undocumented interfaces are exposed through a set of CoClasses summarized in the table below.
    CoClass
    Description

    Code:
    CLSID_History

    The history class provides access to the items in your history folder.

    Code:
    CLSID_ACListISF

    The shell folder class lets you work with to the contents of the shell's namespace.

    Code:
    CLSID_MRU

    The most recently used class contains a list of strings of recently run programs.


    The CoClasses above can be used to retrieve an unknown interface from Windows. To link the unknown interface to an instance of IAutoComplete, pass it to IAutoComplete.Init as the punkACL parameter. Each unknown interface will support both IEnumString, and IACList, and quite possibly a few others. For example, the shell folder unknown interface exposes both ICurrentWorkingDirectory and IPersistFolder. Using this information, you can dynamically change the candidate list of auto completion to reflect the contents of any container in the shell namespace. The difference between ICurrentWorkingDirectory and IPersistFolder is that IPersistFolder uses item lists, rather than strings. Items lists can be useful if you wish to navigate to virtual folders such as the control panel.

    Here is an example showing how to use auto completion to select candidates from the contents of the root drive.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;

    Improving auto completion


    [​IMG]



    Although we have seen that auto completion is relatively easy to work with, there are a few changes that can be made to make it fit better into Delphi's object framework. The most obvious improvement to the auto completion interfaces would be to create a friendly component wrapper around them, encapsulating their various aspects into a single class. Another improvement would be to allow auto completion to work with controls that contain an embedded edit window. In figure four below, a TAutoComplete component is linked to a TTreeView control.

    Conclusion

    By now, you are probably thinking of all the good use you can get out of auto completion in your own programs. Use your imagination, and experiment with the source code in this article.

    To summarize, auto completion is an elegant way to access frequently used text. As we have seen from the sample application, adding auto completion to a Delphi program can be accomplished using few lines of code. By allowing users to pick items from an auto completion list, you can give your applications a very polished look.
     
  2. barisatalay
    Offline

    barisatalay DF Senior

    RE:

    Thank you :)
     
  3. danielps
    Offline

    danielps Guest

    ty so mutch!
     
  4. wozengcong
    Offline

    wozengcong Guest

    RE:

    Thanks
     
  5. Lgogo
    Online

    LgogoLgogo is a Featured Member DF Expert DF Donator

    RE:

    Can you post the Source code;
    :huh:
     
  6. xarox
    Offline

    xarox DF Member

    RE:

    Merci :D
     
  7. Connrad
    Offline

    Connrad Guest

    Fine thing! Thank you very much!!! :idea:
     
  8. joe.belladonna
    Offline

    joe.belladonna DF Junior

  9. falcon2000
    Offline

    falcon2000 Guest

    Thanks for work !
     
  10. lordeMF
    Offline

    lordeMF DF Member

    RE:

    bomzinho
     
  11. zorerkek
    Offline

    zorerkek Guest

    RE:

    fine thanks friends
     

Share This Page

Laws
Our website, law, laws, copyright and aims to be respectful of individual rights. Our site, as defined in the law of 5651 serves as a provider of space. According to the law, contrary to the law of site management has no obligation to monitor content. Therefore, our site has adopted the principle of fit and remove. Works are subject to copyright laws and is shared in a manner that violated their legal rights, or professional associations, rights holders who, adsdelphi@gmail.com I can reach us at e-mail address. Complaints considered to be infringing on the examination of the content will be removed from our site.
Donate Help To Us and Be VIP
DONATIONS WITH PAYPAL CLICK TO BUTTON
6 MONTHS VIP - 20$; 1 YEAR VIP - 30$; 2 YEARS VIP - 50$; GOLD USER FOR LIFE VIP - 150$
Social Block