带有历史信息的ComboBox

#pragma once

#include <list>

#define MAXSTRSIZE 1500     //"值"字符串的最大长度
#define MAXVALUE 10       //注册表保留最大的历史记录数目, 最好设置为1-25之间

class CHisInfoComboBox : public CComboBox
{
	DECLARE_DYNAMIC(CHisInfoComboBox)

public:
	CHisInfoComboBox();
	virtual ~CHisInfoComboBox();

public:
	bool SetHistoryInfoToReg();             
	bool GetHistoryInfoFromReg();

	bool SetHistoryInfoToBuffer();          //把历史信息放进内存
	bool GetHistoryInfoFromBuffer();        //从内存取出历史信息
		
protected:
	void InitHisInfo();
public:
	afx_msg void OnCbnKillfocus();
	afx_msg void OnDestroy();
	afx_msg void OnCbnEditchange();
	afx_msg void OnCbnDropdown();
	afx_msg void OnCbnSetfocus();
protected:
	DECLARE_MESSAGE_MAP()

private:
	CRegKey m_regKey;	
	CString m_strKey;
	std::list<CString> m_lContentOfList;	
	bool m_bFlag;	
};

// CHisInfoComboBox

IMPLEMENT_DYNAMIC(CHisInfoComboBox, CComboBox)

CHisInfoComboBox::CHisInfoComboBox():m_bFlag(false)
{
	
}

CHisInfoComboBox::~CHisInfoComboBox()
{
	
}


BEGIN_MESSAGE_MAP(CHisInfoComboBox, CComboBox)
	ON_CONTROL_REFLECT(CBN_KILLFOCUS, &CHisInfoComboBox::OnCbnKillfocus)	
	ON_WM_CREATE()
	ON_WM_CREATE()
	ON_WM_CLOSE()
	ON_WM_DESTROY()
	ON_CONTROL_REFLECT(CBN_EDITCHANGE, &CHisInfoComboBox::OnCbnEditchange)
	ON_CONTROL_REFLECT(CBN_DROPDOWN, &CHisInfoComboBox::OnCbnDropdown)
	ON_CONTROL_REFLECT(CBN_SETFOCUS, &CHisInfoComboBox::OnCbnSetfocus)
END_MESSAGE_MAP()




void CHisInfoComboBox::InitHisInfo()
{
	
	if (!m_bFlag)
	{
		int ID; 
		CString strID;
		CString strTmp;

		ID = GetDlgCtrlID(); 
		strID.Format(_T("%d"), ID);
		strTmp = _T("Test\\ComboBox ");
		strTmp += strID;

		m_strKey = strTmp;
		m_regKey.Create(HKEY_CURRENT_USER, strTmp);
		m_regKey.Close();

		m_bFlag = true;
	}
	
}
bool CHisInfoComboBox::SetHistoryInfoToReg()
{	
	if (!m_bFlag)
	    return false;
	
	std::list<CString>::iterator itBeg;
	std::list<CString>::iterator itEnd;		

	CRegKey regKey;
	regKey.Open(HKEY_CURRENT_USER, m_strKey);

	while (m_lContentOfList.size() > MAXVALUE)      //注册表只保留最近的MAXVALUE条历史记录
	{
		itBeg = m_lContentOfList.begin();
		itEnd = m_lContentOfList.end();
		m_lContentOfList.erase(--itEnd);   //去掉最久的历史记录
	}

	itBeg = m_lContentOfList.begin();
	itEnd = m_lContentOfList.end();

	char ch = 'A';                        
	for (; itBeg != itEnd; ++itBeg)
	{		
		if (*itBeg == _T(""))
			continue;
		
		CString strTmp(ch);
		ch += 1;		
		regKey.SetStringValue(strTmp, *itBeg);
	}	
	
	regKey.Close();
	return true;
}

bool CHisInfoComboBox::GetHistoryInfoFromReg()
{	
	InitHisInfo();	

	DWORD dwCountOfSubKey;
	DWORD dwCountOfValue;
	DWORD dwType;
	DWORD wValNameSize;
	DWORD dwValSize;

	LONG lResult;
	TCHAR *strValName;
	TCHAR *strVal;

	wValNameSize = MAXSTRSIZE;	
	dwValSize = MAXSTRSIZE;

	strValName = new TCHAR[wValNameSize];
	if (!strValName)
		return false;

	strVal = new TCHAR[dwValSize];
	if (!strVal)
		return false;

	CRegKey regKey;
	regKey.Open(HKEY_CURRENT_USER, m_strKey);
	lResult = ::RegQueryInfoKey(regKey.m_hKey, NULL, NULL, NULL,  &dwCountOfSubKey,
		                        NULL, NULL, &dwCountOfValue, NULL, NULL, NULL, NULL);			
								

	if (lResult != ERROR_SUCCESS)
	    return false;

	for (int i = 0; i < (int)dwCountOfValue; ++i)
	{
		wValNameSize = MAXSTRSIZE;
		lResult = RegEnumValue(regKey.m_hKey, i, strValName, &wValNameSize, NULL, &dwType,NULL, NULL);

		if (lResult != ERROR_SUCCESS)		
			return false;

		if (wcscmp(strValName, _T("")) == 0)
			continue;

		dwValSize = MAXSTRSIZE;
		dwType = REG_SZ;
			
		regKey.QueryStringValue(strValName, strVal, &dwValSize);		
		m_lContentOfList.push_front(strVal);			
	}

	delete []strValName;
	delete []strVal;
	strValName = NULL;
	strVal = NULL;

	regKey.Close();	
	return true;
}


void CHisInfoComboBox::OnCbnKillfocus()
{	
	SetHistoryInfoToBuffer();
}



void CHisInfoComboBox::OnDestroy()
{
	
	CComboBox::OnDestroy();
	// TODO: 在此处添加消息处理程序代码
	SetHistoryInfoToReg();
}


bool CHisInfoComboBox::SetHistoryInfoToBuffer()
{
	CString strText;
	GetWindowText(strText);
	strText.TrimLeft(_T(' '));   

	if (strText == _T(""))
 		return true;	

	if (FindString(0, strText) == CB_ERR)						
	   m_lContentOfList.push_front(strText);	

	return true;
}

//示例:假设历史记录为word, hello, one, three
//若编辑框为空 , 则下拉列表显示word, hello,one, three
//若编辑框内容为e, 则下拉列表显示hello, one, three


bool CHisInfoComboBox::GetHistoryInfoFromBuffer()
{	
	CString strText;
	GetWindowText(strText);
	strText.TrimLeft(_T(" "));	
	
	std::list<CString>::iterator itBeg;
	std::list<CString>::iterator itEnd;
	
	for (itBeg = m_lContentOfList.begin(), itEnd = m_lContentOfList.end(); itBeg != itEnd; ++itBeg)		
	{		
		if (strText == _T(""))                       
		{
			if (FindString(0, *itBeg) == CB_ERR)
				AddString(*itBeg);
		}  		
		else
		{
			if (itBeg->FindOneOf(strText) != -1)         
			{			
				if (FindString(0, *itBeg) == CB_ERR)				
					AddString(*itBeg);
			}
			else
			{
				int i = FindString(0, *itBeg);
				DeleteString(i);
			}
		}		
	}	
	return true;
}



void CHisInfoComboBox::OnCbnEditchange()
{
	// TODO: 在此添加控件通知处理程序代码		
	GetHistoryInfoFromBuffer();
	int nCount = GetCount();
	if (nCount)
	{		
		PostMessage(CB_SHOWDROPDOWN, TRUE);
	}	
 	else
 		PostMessage(CB_SHOWDROPDOWN, FALSE);   
}


void CHisInfoComboBox::OnCbnDropdown()
{
	// TODO: 在此添加控件通知处理程序代码	
    GetHistoryInfoFromBuffer();
}


void CHisInfoComboBox::OnCbnSetfocus()     //编辑框获得焦点时从注册表读入历史信息
{
	// TODO: 在此添加控件通知处理程序代码
	if (!m_bFlag)
	    GetHistoryInfoFromReg();
}
此类具有自动匹配功能,最新的历史信息始终在下拉列表的最上面,只导入最新的规定的数目历史信息

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章