帶有歷史信息的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();
}
此類具有自動匹配功能,最新的歷史信息始終在下拉列表的最上面,只導入最新的規定的數目歷史信息

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