Integrated automatic completion function in the application

zhaozj2021-02-08  229

Integrated automatic completion function in the application

Many content translations in this article have automatically complete this article.

Introduction

Automatic completion function, the user is input, the program automatically prompts the user input entry, and / or automatically enter the remainder, and many programs are integrated in the user interface since IE provides the automatic completion of the form and the address bar. Features. When properly, it can greatly reduce the time of user input. Although this function is so useful, even one example is not found in the platform development kit. Paul Dilascia completed this feature in the C Q & A article in August 2000, but his method is too dependent on MFC, so that it is not good to port to non-MFC procedures. Here is the illustration of his program:

In his article, it was the final comparison of the use of the South between the COM interface and his method. Interested to see.

Automatic completion in the Windows housing

Windows files open and save dialogs, and run dialogs, IE's address bar has auto-completion.

This feature is also available in the Windows API. The Windows Shell Light API provides the ShautOComplete function that is bound to the edit box to the edit box to the edit_aclhistory, clsid_aclmru, and clsid_aclistisf. This function allows you to provide automatic completion of the COM interface, but if you want to better control the auto-completed behavior or list entry, you need to use some COM interfaces, such as IAUTOCOMPLETE, and IACLIST.

Create a simple auto-completion object

You can use the following steps to create a simple auto-completion object. Simply automatically complete the object from a resource to extract the desired string required. In order to make the code clearly, the code for the error check is omitted and the same.

Create automatic auto-completion objects; CoCreateInstance (CLSID_AUTOCOMPLETE, NULL, CLSCTX_INPROC_SERVER, IID_IAUTOCOMPLETE, (LPVOID *) & PAC); Create Automatic Complete Resources You can use predefined auto-completion resources, or write your own automatic completion resource.

Use predefined auto-complete resource IUnknown * punkSource; CoCreateInstance (clsidSource, NULL, CLSCTX_INPROC_SERVER, IID_IACList, (LPVOID *) & punkSource); following shell object has IAutoComplete interface, you can give your application to provide auto-complete feature used after CoCreateInstance created.

CLSID_ACLHISTORY - IE maintenance, matching the current user's history. CLSID_ACLMRU - is also IE maintenance, matches the current user's recent documentation record. CLSID_ACListISF - matching shell namespace (including the file system and virtual directory, such as My Computer and Control Panel) to write your own auto-complete resource IUnknown * punkSource; CCustomAutoCompleteSource * pcacs = new CCustomAutoCompleteSource (); hr = pcacs-> QueryInterface (IID_IUnknown (Void **) & punksource); PCACS-> Release (); You can write automatic completion resource objects that implement the IenumString interface. The implementation of IACLIST and IACLIST2 is optional. IEnumString implement the same interfaces, and other interfaces IEnumXXXX, IEnumString interface has the following four methods HRESULT Next (ULONG celt, LPOLESTR * rgelt, ULONG * pceltFetched); HRESULT Skip (ULONG celt); HRESULT Reset (void); HRESULT Clone (IEnumString ** Ppenum); You can quickly construct the object of the IenumString interface with the macro and automation class of the MFC or ATL, or you can manually implement the IenumString interface. Typically, the list item is from a string array or a database. Below is the recommended string array of recommendations of IenumString implementation methods (as examples of CSTRINGARRAY)

Next: Extract the specified quantity string and add the current string index. Skip: Add Current String Index: Current String Index Reset to 0 Cloney: Copy String Array and Current String Index Database

Next: Extract the specified quantity string and move the current record position backward. SKIP: Backward Move Current Record Location RESET: Reset Current Record Location to Recording Sets Lead Clone: ​​Copy Record Set or Record Set Parameters and / or Reset Current Recording Location. Set Auto Complete Resources If you need, you may set some options via the IACLIST or IAClist2 interface from defining automatic completion resources, such as filtering some list entries. This is especially useful for CLSID_ACLISF objects. You can view the documentation of IAClist2 :: SetOptions to view valid options. IAClist2 * PAL2; IF (successded (PUNKSource-> Queryinterface)) {PAL2-> setOptions (ACLO_FILESYSONLY); PAL2-> Release ();} For some specific resources, you may need to query Other interfaces are more complex settings, such as when the resource manager or IE browses to a new directory, the content of the auto-completed list is also changed. For CLSID_ACLISF objects, you can set up ACLO_CURRENTDIR to enumerate the contents of the current directory so you need to query its IACLIST interface and set its current location. There are two ways to set the current directory. If it is passed, they are equivalent.

You can use this interface to tell the current location of the object with this interface. Because the current location is not a real directory, for example, a desktop or my computer so this method is more flexible than the next. IPersistFolder * ppf; extern LPITEMIDLIST pidlCurrentDirectory; // this is a valid namespace location if (SUCCEEDED (pal-> QueryInterface (IID_IPersistFolder, (LPVOID *) & ppf))) {ppf-> Initialize (pidlCurrentDirectory); ppf-> Release ( );} You can pass the current directory to the object by using the ICURRENTWORKINGDIRECTORY. ICurrentWorkingDirectory * pcwd; if (SUCCEEDED (pal-> QueryInterface (IID_ICurrentWorkingDirectory, (LPVOID *) & pcwd))) {pcwd-> SetDirectory (pwszDirectory); pcwd-> Release ();} If you write a custom auto-complete resources Then you can write a modified setting method, such as limiting the maximum number of enumerations, or by filtering enumeration depending on the user's input and context filtering (which is especially useful when enumerating database records). Bind to the edit box iautocomplete :: init will automatically complete the resource bind to an edit box. There are some undisclosed methods to get the handle of the edit box in the ComboBox control, but the ComboBoxEx control provides a method of directly accessing the edit box (CBEM_GETEDITCONTROL), so I recommend using the ComboBoxEx control. EXTERN HWND HWNDIT; / / To add auto-completed target window Extern LPUNKNOWN PUNKSOURCE; // The second step of the iUnknown interface pointer for automatic resource created. Pac-> init (hwndedit, punksource, null, null); You can view the IAUTOCOMPLETE :: init of the document to understand the meaning of other parameters. IAUTOCOMPLETE :: init will increase the reference count of the object, and reduce the reference count count of the object when the edit box is destroyed, see step 6. An auto-completed object can only be bound to a window at a time. Set the act of automatic completion objects If needed, you can change the behavior of the automatic completion of the object via the IAUTOCOMPLETE2 interface setting option. You can view the documentation for IAUTOCOMPLETE2 :: SETOPTIONS to learn about other parameters. IAutoComplete2 * pac2; if (SUCCEEDED (pac-> QueryInterface (IID_IAutoComplete2, (LPVOID *) & pac2))) {pac2-> SetOptions (ACO_AUTOSUGGEST); pac2-> Release ();} object is released pac-> Release (); punkSource -> Release (); Automatic completion of the object is still bound to the edit box after the release (because IAUTOCOMPLETE:: INIT adds an object's reference count) and is automatically released when the edit box is destroyed. You should not destroy the object in advance when you need to access the object. For example, after you automatically complete the object bind to the dialog, you still need to set the automatic completion of the resource through the method of step 3. Create a composite automatic object

Composite automatic completion objects look up from multiple autoplex resources. For example, the address bar of IE finds the contents of the accessed URL and the current directory. You can use the following steps to create a composite automatic completion object.

Create an automatic auto-completion object ketocomplete * PAC; COCREATEINSTANCE (CLSID_AUTOCOMPLETE, NULL, CLSCTX_INPROC_SERVER, IID_IAUTOCOMPLETE, (LPVOID *) & PAC); Create a composite automatic resource object manager. It combines multiple auto-completion resources into an automatic completion of resources. IOBJMGR * POM; CoCreateInstance (CLSID_ACLMULTI, NULL, CLSCTX_INPROC_SERVER, IID_IOBJMGR, (LPVOID *) & POM); steps 2 and 3 of each of the simple automatic auto-completion objects, complete creation and initialization work. Connection is simple and automatically completed objects to composite automatic resource object manager. EXTERN LPUNKNOWN PUNKSOURCE; / / The iUnknown interface pointer for automatic completion resources created in step 3. POM-> Append (PUNKSource); Bind to the edit box and step 4 of the previous example, in addition to the IUNKNOWN interface pointer of the auto-completed resource to the IUNKNOWN interface pointer of the composite automatic completion resource object manager. PAC-> init (hwndedit, pom, null, null); sets the auto-completed options with one example. Release the object PAC-> Release (); pom-> release (); punksource-> release (); / * Create an object of each step 3 must be released * / You can release the object immediately after using the object, but you may You need to keep the object interface pointer for later modifying the option. Automatically complete mode

Automatic completion of two independent modes: Automatic extension and automatic recommendations. You can call IAUTOCOMPLETE2 :: SETOPTIONS to enable / disable these two modes, respectively.

Automatic extension: In this mode, Auto-completion feature automatically adds the most likely candidate string to the current sub-copy or highlights. The edit box shows and the extended string has been entered and highlighted. If the user continues to enter characters, they are added to some strings that have been entered. If the user entered characters and the first symbol of the extended part, the highlight of this character is turned off, and the remaining extended strings continue to highlight the status; otherwise, automatically complete the new string of the trial to enter the new string to generate a new string The candidate extension string is added to the current string of the current string and highlighted. If you don't find a candidate extended string, the behavior of the edit box is the same as if there is no automatic function. This process continues to the user to complete the input. Automatic prompt: In this mode, you automatically prompt to display a drop-down list, display one or more suggestions complete strings. Users can choose one of them, usually with a mouse, or continue to input to reduce the number of matched list items. During the input, the list content may change according to the input string. If you set an ACO_SEARCH flag in the dwflag parameter of IAUTOCOMPLETE2 :: SetOptions, then automatically complete the option to search according to the current part of the string at the end of the list. This option is also displayed even when there is no prompt candidate string. If the user selects this option, the application should start a search engine to help users. Although it is possible to determine whether the search option is selected by the string match, the prefix of the search option is different due to the difference in language. You should consider how to remove the prefix such as "search for" or "Search".

Reference document IAutoComplete and custom IEnumString implementation for WTL dialogshttp: //www.codeproject.com/wtl/customautocomplete_wtl.asp Here is my implementation if IEnumString based database defined (AFX_ENUMSTRING_H__4D5D61AD_CD0D_!

477C

_

880F

_8e5eeb5b1e

8f

__Included _) # define AFX_ENUMSTRING_H__4D5D61AD_CD0D_

477C

_

880F

_8e5eeb5b1e

8f

__Included_

#if _msc_ver> 1000 # pragma overce # endif //_msc_ver> 1000 // enumstring.h: header file //

/// CenumString Command Target # include #include "esuihelper.h"

class _ES_UI_EXPORT CEnumString: public IEnumString {public: CEnumString (); // protected constructor used by dynamic creation // Attributespublic: ULONG m_nRefCount; // Operationspublic: STDMETHODIMP_ (ULONG) AddRef (); STDMETHODIMP_ (ULONG) Release (); STDMETHODIMP QueryInterface (Refiid Riid, Void ** PPVObject);

STDMETHODIMP Next (ULONG celt, LPOLESTR * rgelt, ULONG * pceltFetched); STDMETHODIMP Skip (ULONG celt); STDMETHODIMP Reset (void); STDMETHODIMP Clone (IEnumString ** ppenum); BOOL Bind (HWND p_hWndEdit, DWORD p_dwOptions = 0, LPCTSTR p_lpszFormatString = NULL); void unbind (); // Overrides // ClassWizard Generated Virtual Function overrides // {{AFX_VIRTUAL (CENUMSTRING) //}} AFX_VIRTUAL

// Implementationprotected: virtual ~ CEnumString (); CComPtr m_pac; BOOL m_fBound; // Generated message map functions // {{AFX_MSG (CEnumString) // NOTE - the ClassWizard will add and remove member functions here //}. } AFX_MSG

}

/

// {{AFX_INSERT_LOCATION}} // Microsoft Visual C Will Insert Additional Declarations Immediately Before The Previous Line.

#ndif //! defined (AFX_ENUMSTRING_H__4D5D61AD_CD0D_

477C

_

880F

_8e5eeb5b1e

8f

__Included_) // Enumstring.cpp: Implementation File //

#include "stdafx.h" #include "enumstring.h" #ifdef _debug # define new debug_new # undef this_filestatic char this_file [] = __file __; # ENDIF

/// cenumstring

Cenumstring :: cenumstring () {m_fbound = false; m_nrefcount = 0;}

Cenumstring :: ~ cenumstring () {

}

/// CEnumString message handlersULONG FAR EXPORT CEnumString :: AddRef () {TRACE_LINE ( ​​"CEnumString :: AddRef / n"); return :: InterlockedIncrement (reinterpret_cast (& m_nRefCount));}

Ulong far export cenumstring :: release () {trace_LINE ("cenumstring :: release / n"); ulong ncount = 0; ncount = (ulong) :: InterlockedDecrement (ReinterPret_cast ;

IF (ncount == 0) delete this;

Return ncount;

}

HRESULT FAR EXPORT CENUMSTRING :: Queryinterface (Refiid Riid, Void Far * Far * PPVObject) {HRESULT HR = E_NOINTERFACE; if (PPVObject! = Null) {* ppvobject = null;

IF (IID_IUNKNOWN == RIID) * pPVObject = static_cast (this);

IF (IID_IENUMSTRING == RIID) * PPVObject = static_cast (this);

IF (* ppvobject! = null) {hr = s_ok; (lpunknown) * pPVObject) -> addref ();}

} Else {hr = e_pointer;} Return HR;

STDMETHODIMP CENUMSTRING :: Next (Ulong Celt, LPolestr * Rgelt, Ulong * PCELTFETCHED) {RETURN E_NOTIMPL;}

STDMETHODIMP CENUMSTRING :: Skip (Ulong Celt) {RETURN E_NOTIMPL;}

STDMETHODIMP CEnumString :: Reset (void) {return E_NOTIMPL;} STDMETHODIMP CEnumString :: Clone (IEnumString ** ppenum) {if return E_POINTER (ppenum!); CEnumString * pnew = new CEnumString; pnew-> AddRef (); * ppenum = PNEW; RETURN S_OK;} Bool CenumString :: Bind (hwnd p_hwndedit, dword p_dwOptions / * = 0 - * /, lpctstr p_lpszformatstring / * = null * /) {= ((m_fbound) || (m_pac)) Return False; HRESULT HR = s_ok; hr = m_pac.cocreateInstance (CLSID_AUTOCOMPLETE); if (successded (HR)) {

IF (p_dwoptions) {ccomqiptr PAC2 (M_PAC);

Atlassert (PAC2);

HR = PAC2-> SetOptions (p_dwoptions); // this never limited ();

}

HR = m_pac-> init (p_hwndedit, this, null, (lpolestr) p_lpszformatstring); if (succeeded (hr)) {m_fbound = true; return true;}} return false;} void cenumstring :: unbind () {

IF (! m_fbound) return;

Atlassert (M_PAC);

IF (m_pac) {m_pac.release (); m_fbound = false;

}} # Include "../esuihelper/EnumString.h"#include" DataType.h "class CDataType; class _ES_DATATYPE_EXPORT CEnumDataType: public CEnumString {public: CEnumDataType (LPCTSTR lpszDataType); virtual ~ CEnumDataType (); CDataType * m_pDataType; protected : CString m_strDataType; STDMETHODIMP Next (ULONG celt, LPOLESTR * rgelt, ULONG * pceltFetched); STDMETHODIMP Skip (ULONG celt); STDMETHODIMP Reset (void); STDMETHODIMP Clone (IEnumString ** ppenum); ado20 :: _ RecordsetPtr m_pRecordset;}; CEnumDataType :: CEnumDataType (LPCTSTR lpszDataType): m_strDataType (lpszDataType) {m_pDataType = g_pDataTypeManager-> GetDataType (m_strDataType); ASSERT (m_pDataType); m_pRecordset.CreateInstance ( "ADODB.Recordset"); try {if (! m_pRecordset = NULL) {if (m_pRecordset-> State & adStateOpen) {return;}} ESRecordsetOpen ((LPCTSTR) m_pDataType-> m_strSQLAutoComplete, _variant_t ((IDispatch *) g_connection, true), m_pRecordset, adOpenDynamic, adLockOptimistic, adCmdUnspecified); m_pRecordset-> Requery (adCmdUnknown); if (m_precordset-> bof = = Variant_false) m_precordset-> MoveFirst ();} catch (_COM_ERROR & E) {ESERRPRINTPROVIDERROR (G_Connection); EserrPrintComerror (E);}}

CEnumDataType :: ~ CEnumDataType () {try {if (m_pRecordset = NULL!) {If (m_pRecordset-> State & adStateOpen) {m_pRecordset-> Close ();}}} catch (_com_error & e) {ESErrPrintProviderError (g_connection); ESErrPrintComError (e );}} Stdmethodimp cenumdattype :: Next (Ulong Celt, LPolestr * Rgelt, Ulong * PCELTFETCHED) {if (m_precordset == null) Return OLE_E_BLANK;

HRESULT HR = S_FALSE; ZeromeMory (Rgelt, Sizeof (Olechar *) * CELT);

转载请注明原文地址:https://www.9cbs.com/read-1881.html

New Post(0)