无需IAutoComplete的自动完成






4.90/5 (44投票s)
一个不使用 IAutoComplete 但仍保留相同外观和感觉的自动完成控件。
引言
CodeProject 上已经有几篇关于自动完成功能的文章。许多人通过子类化 CEdit
或 CComboBox
来完成控件中的输入或在下拉列表中显示各种选项。另一种选择是使用 IAutoComplete
结合 IEnumString
和许多其他 I 函数。
当我看到 Klaus Probst 的 WTL-AutoComplete 功能时,我想,“很酷,但所有这些都应该可以在没有 Internet Explorer 和晦涩调用的情况下工作”。而且,更容易。
如何使用
将文件(ACEdit.cpp/h + ACListWnd.cpp/h)复制到项目目录,然后将它们添加到项目中,并插入标头,最好是在 stdafx.h 中。
#include "ACEdit.h"
声明一个 CEdit
或 CComboBox
并将其子类化为 CACEdit
bevorehand: CEdit m_EditCtrl1; afterwards: CACEdit m_EditCtrl1;
之后,在 OnInitDialog
中初始化控件并定义模式。
m_EditCtrl1.Init();
m_EditCtrl1.SetMode(); // default = _MODE_STANDARD_
可能的模式包括
_MODE_STANDARD_
_MODE_SEPARATION_
_MODE_FILESYSTEM_
_MODE_FS_ONLY_FILE_
_MODE_FS_ONLY_DIR_
_MODE_FS_START_DIR_
_MODE_SD_ONLY_FILE_
_MODE_SD_ONLY_DIR_
_MODE_CURSOR_O_LIST_
_MODE_FIND_ALL_
.
更多解释请参见下文。如果您忘记 Init()
,则会在 SetMode()
中稍后进行初始化。
最后,插入字符串。有两种不同的方法可以做到这一点:AddSearchString
和 AddSearchStrings
。
m_EditCtrl1.AddSearchString("Test1"); m_EditCtrl1.AddSearchString("Test2"); m_EditCtrl1.AddSearchString("Tiger"); m_EditCtrl1.AddSearchString("Dog"); or static LPCTSTR STRINGS[] = { _T("Test1"), _T("Test2"), _T("Tiger"), _T("Dog"), NULL }; m_EditCtrl1.AddSearchStrings(STRINGS);
在插入字符串之前,函数 AddSearchStrings()
会调用 RemoveSearchAll()
,并清空类型为 CStringArray
的内部项目列表。AddSearchStrings()
可以与 AddSearchString()
结合使用,但反之则不行。目前尚未实现特定字符串的删除。
这就是一个简单的自动完成所需的一切。此外,还可以实现分隔符。m_EditCtrl1.SetSeparator(_T("\\"));
会使 `\` 作为行首或行尾。如果您输入 XXX\t\YYY,在我们的示例中,您将看到一个列表,其中包括 Test1、Test2 和 Tiger。
但是,如果用户输入 xxTi,,则会失败。如果您使用常量,例如 <Parameter1>(用花括号括起来的常量,在我们的示例中是 <>)。那么就有可能将 SetSeparator()
命令扩展为一个前缀,这是您常量中的第一个字符。前缀不能是 SearchStrings
的一部分。但是,它确实会出现在列表中,并且是结果的一部分。
... m_EditCtrl1.AddSearchString("PARAMETER1>"); // without prefix! m_EditCtrl1.AddSearchString("PARAMETER2>"); m_EditCtrl1.AddSearchString("PARAMETER3>"); m_EditCtrl1.SetSeparator("<",'<'); ...
此示例在输入 XXX< 或 /< 时也会产生结果。
以及文件系统的自动完成
... m_DirEdit.SetMode(_MODE_FILESYSTEM_); ...
现在,当您开始键入路径时,控件将下拉一个列表,其中包含与您迄今为止键入的内容匹配的路径 - 在开始菜单中运行命令(在 Win2K 或带有 IE 5.0 的计算机上)。
SetMode(_MODE_FS_ONLY_FILE_)
仅列出文件,SetMode(_MODE_FS_ONLY_DIR_)
仅列出目录。
m_DirEdit.SetMode(_MODE_FS_START_DIR_);
m_DirEdit.SetStartDirectory(_T("C:\\Windows\\"));
...
如果您使用 SetMode() _MODE_FS_START_DIR_, _MODE_SD_ONLY_FILE_
或 _MODE_SD_ONLY_DIR_
,则可以通过 SetStartDirectory()
指定一个目录。在上面的示例中,控件列出了 C:\Windows 中的所有文件,但与 _MODE_FILESYSTEM_
不同,它不显示路径 (C:\Windows)。
版本 1.2
-修复:_MODE_SD_ONLY_DIR_
-修复:OnActivateApp()
VC6/VC7 编译器适配
-修复:OnGetMinMaxInfo()
遵循“yogurt”(参见评论)的建议
-_MODE_FIND_ALL_
用于 SetMode()
,如果您输入 on,该函数将查找 One、One1、Melon、Lemon 等。
版本 1.1
ComboBox 支持
-int AddString( LPCTSTR lpszString);
-int GetLBText( int nIndex, LPTSTR lpszText );
-void GetLBText( int nIndex, CString& rString );
-int SetDroppedWidth(UINT nWidth);
-int FindString( int nStartAfter, LPCTSTR lpszString );
-int SelectString( int nStartAfter, LPCTSTR lpszString );
-void ShowDropDown(BOOL bShowIt = TRUE );
-void ResetContent();
-int GetCurSel();
和
_MODE_CURSOR_O_LIST_
(用光标键打开列表)
如果使用 SetMode()
设置了此标志,则已经可以在空输入字段中用光标键(向上/向下)指示搜索字符串列表。但这仅适用于 CEdit 控件,因为 ComboBox 中的光标键具有不同的功能。
结论
该控件的外观与 Windows 中的功能(触发了该项目)相似,但它完全无需IAutoComplete
即可工作。当然有多种扩展它的方法,但由于它能按预期工作,我对它很满意。希望这个控件对您有用——我写它的时候很愉快。来源
- WTL 对话框的 IAutoComplete 和自定义 IEnumString 实现
(Klaus Probst)
我的灵感来源 - 自动完成和 ACTest 演示应用程序
(Paul DiLascia)
ComboBox/Edit 控件的识别技巧 - 增强的CCheckComboBox
(Magerusan Grigore Cosmin)
展示如何在选定(创建)时使窗口保持非活动状态