1. 创建已经实现IAutoComplete接口的COM对象,需要初始化CoInitialize(NULL);
IAutoComplete *pac = NULL;
HRESULT hRet = CoCreateInstance(CLSID_AutoComplete,
NULL,
CLSCTX_INPROC_SERVER,
IID_IAutoComplete,
(LPVOID*)&pac);
2. 修改类型为自动建议的下拉列表(类似开始运行那种)
IAutoComplete2 *pac2;
if (SUCCEEDED(pac->QueryInterface(IID_IAutoComplete2, (LPVOID*)&pac2))){
pac2->SetOptions(ACO_AUTOSUGGEST);
pac2->Release();
}
ACO_NONE 没有自动完成
ACO_AUTOSUGGEST 启用自动建议的下拉列表框
ACO_AUTOAPPEND 启用自动添加
ACO_SEARCH 在完成的串中添加搜索项目,选中此项目启动搜索引擎
ACO_FILTERPREFIXES 不匹配逗号前缀,如“www.”,“http://”等
ACO_USETAB 使用Tab键从下拉框清单中选择
ACF_UPDOWNKEYDROPSLIST 使用上下箭头键显示自动建议的下拉框清单
ACO_RTLREADING 常规窗口从左到右显示文本。Windows 可以被映射显示诸如 Hebrew 或 Arabic 这样从右到左阅读的语言。通常,某个控制的文本与其父窗口文本的阅读/显示方向相同。如果设置ACO_RTLREADING,那么文本阅读方向与其父窗口文本阅读方向相反。
3. 实现IEnumString接口
包含基类IUnknown接口AddRef、Release、QueryInterface和IEnumString的Next、Skip、Reset、Clone
EnumString.h
#pragma once
#include <objidl.h>
#include <deque>
using namespace std;
class CEnumString :
public IEnumString,
public deque<CString>
{
public:
CEnumString(void);
~CEnumString(void;
// *** IUnknown ***
STDMETHOD_(ULONG, AddRef) (void)
{
InterlockedIncrement((LONG*)&m_ulRefs);
return m_ulRefs;
}
STDMETHOD_(ULONG, Release) (void)
{
ULONG ulRefs = m_ulRefs;
if (InterlockedDecrement((LONG*)&m_ulRefs) == 0)
{
delete this;
return 0;
}
return ulRefs - 1;
}
STDMETHOD(QueryInterface) (REFIID riid, LPVOID * ppv)
{
if ((riid == IID_IEnumString) || (riid == IID_IUnknown))
{
*ppv = (IEnumString *) this;
}
else if(riid == IID_IEnumACString)
{
*ppv = (IEnumACString *) this;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
// *** IEnumString ***
STDMETHOD(Next)(ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched);
STDMETHOD(Skip)(ULONG celt);
STDMETHOD(Reset)(void);
STDMETHOD(Clone)(IEnumString **ppenum);
private:
ULONG m_ulRefs;
UINT m_nPos;
};
EnumString.cpp
#include "StdAfx.h"
#include "EnumString.h"
CEnumString::CEnumString(void)
{
m_ulRefs = 1;
m_nPos = 0;
}
CEnumString::~CEnumString(void)
{
clear();
}
HRESULT CEnumString::Next(ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched)
{
HRESULT hr = S_FALSE;
*pceltFetched = 0;
if (!celt)
{
return S_OK;
}
if (!rgelt)
{
return E_FAIL;
}
if (m_nPos < size())
{
rgelt[0] = (LPTSTR)(LPCTSTR)(this->operator [](m_nPos++));
hr = S_OK;
}
if (S_OK == hr)
{
*pceltFetched = 1;
}
return hr;
}
HRESULT CEnumString::Reset(void)
{
HRESULT hr = S_OK;
m_nPos = 0;
return hr;
}
HRESULT CEnumString::Skip(ULONG celt)
{
return E_NOTIMPL;
}
HRESULT CEnumString::Clone(IEnumString **ppenum)
{
HRESULT hr = E_OUTOFMEMORY;
*ppenum = NULL;
CEnumString * p = new CEnumString();
if (p)
{
hr = p->Reset();
if (FAILED(hr))
p->Release();
else
*ppenum = (IEnumString *)p;
}
return hr;
}
4. 关联控件句柄(编辑框)
CEnumString* pEnumString = new CEnumString();
pac->Init(m_ACCombo.GetWindow(GW_CHILD)->GetSafeHwnd(), (IUnknown*)pEnumString, NULL, NULL);
5. 释放
pac->Release();
pEnumString->Release();