实现类似于Windows开始运行中的带有自动匹配下拉列表的组合框(或编辑框)

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();


 

 

 

 

你可能感兴趣的:(实现类似于Windows开始运行中的带有自动匹配下拉列表的组合框(或编辑框))