65.9K
CodeProject 正在变化。 阅读更多。
Home

无需IAutoComplete的自动完成

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (44投票s)

2002 年 7 月 21 日

CPOL

3分钟阅读

viewsIcon

376292

downloadIcon

8012

一个不使用 IAutoComplete 但仍保留相同外观和感觉的自动完成控件。

Sample Image

引言

CodeProject 上已经有几篇关于自动完成功能的文章。许多人通过子类化 CEditCComboBox 来完成控件中的输入或在下拉列表中显示各种选项。另一种选择是使用 IAutoComplete 结合 IEnumString 和许多其他 I 函数。

当我看到 Klaus Probst 的 WTL-AutoComplete 功能时,我想,“很酷,但所有这些都应该可以在没有 Internet Explorer 和晦涩调用的情况下工作”。而且,更容易。

如何使用

将文件(ACEdit.cpp/h + ACListWnd.cpp/h)复制到项目目录,然后将它们添加到项目中,并插入标头,最好是在 stdafx.h 中。

#include "ACEdit.h"
声明一个 CEditCComboBox 并将其子类化为 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() 中稍后进行初始化。

最后,插入字符串。有两种不同的方法可以做到这一点:AddSearchStringAddSearchStrings

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、Test2Tiger

但是,如果用户输入 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 即可工作。当然有多种扩展它的方法,但由于它能按预期工作,我对它很满意。希望这个控件对您有用——我写它的时候很愉快。

来源

© . All rights reserved.