www.gusucode.com > eMule电驴下载VC++源代码-源码程序 > eMule电驴下载VC++源代码-源码程序\code\srchybrid\CustomAutoComplete.cpp
//-------------------------------------------------------------------------------------------- // Name: CCustomAutoComplete (CCUSTOMAUTOCOMPLETE.H) // Type: Wrapper class // Description: Matches IAutoComplete, IEnumString and the registry (optional) to provide // custom auto-complete functionality for EDIT controls - including those in // combo boxes - in WTL projects. // // Author: Klaus H. Probst [kprobst@vbbox.com] // URL: http://www.vbbox.com/ // Copyright: This work is copyright ? 2002, Klaus H. Probst // Usage: You may use this code as you see fit, provided that you assume all // responsibilities for doing so. // Distribution: Distribute freely as long as you maintain this notice as part of the // file header. // // // Updates: 09-Mai-2003 [bluecow]: // - changed original string list code to deal with a LRU list // and auto cleanup of list entries according 'iMaxItemCount'. // - splitted original code into cpp/h file // - removed registry stuff // - added file stuff // 15-Jan-2004 [Ornis]: // - changed adding strings to replace existing ones on a new position // // // Notes: // // // Dependencies: // // The usual ATL/WTL headers for a normal EXE, plus <atlmisc.h> // //-------------------------------------------------------------------------------------------- #include "stdafx.h" #include "CustomAutoComplete.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif CCustomAutoComplete::CCustomAutoComplete() { InternalInit(); } CCustomAutoComplete::CCustomAutoComplete(const CStringArray& p_sItemList) { InternalInit(); SetList(p_sItemList); } CCustomAutoComplete::~CCustomAutoComplete() { if (m_pac) m_pac.Release(); } BOOL CCustomAutoComplete::Bind(HWND p_hWndEdit, DWORD p_dwOptions, LPCTSTR p_lpszFormatString) { ATLASSERT(::IsWindow(p_hWndEdit)); if ((m_fBound) || (m_pac)) return FALSE; HRESULT hr = m_pac.CoCreateInstance(CLSID_AutoComplete); if (SUCCEEDED(hr)) { if (p_dwOptions){ CComQIPtr<IAutoComplete2> pAC2(m_pac); if (pAC2){ pAC2->SetOptions(p_dwOptions); pAC2.Release(); } } USES_CONVERSION; if (SUCCEEDED(hr = m_pac->Init(p_hWndEdit, this, NULL, T2W(p_lpszFormatString)))) { m_fBound = TRUE; return TRUE; } } return FALSE; } VOID CCustomAutoComplete::Unbind() { if (!m_fBound) return; if (m_pac){ m_pac.Release(); m_fBound = FALSE; } } BOOL CCustomAutoComplete::SetList(const CStringArray& p_sItemList) { ATLASSERT(p_sItemList.GetSize() != 0); Clear(); m_asList.Append(p_sItemList); return TRUE; } int CCustomAutoComplete::FindItem(const CString& rstr) { for (int i = 0; i < m_asList.GetCount(); i++) if (m_asList[i].Compare(rstr) == 0) return i; return -1; } BOOL CCustomAutoComplete::AddItem(const CString& p_sItem, int iPos) { if (p_sItem.GetLength() != 0) { int oldpos=FindItem(p_sItem); if (oldpos == -1) { // use a LRU list if (iPos == -1) m_asList.Add(p_sItem); else m_asList.InsertAt(iPos, p_sItem); while (m_asList.GetSize() > m_iMaxItemCount) m_asList.RemoveAt(m_asList.GetSize() - 1); return TRUE; } else if (iPos!=-1) { m_asList.RemoveAt(oldpos); if (oldpos<iPos) --iPos; m_asList.InsertAt(iPos, p_sItem); while (m_asList.GetSize() > m_iMaxItemCount) m_asList.RemoveAt(m_asList.GetSize() - 1); return TRUE; } } return FALSE; } int CCustomAutoComplete::GetItemCount() { return (int)m_asList.GetCount(); } BOOL CCustomAutoComplete::RemoveItem(const CString& p_sItem) { if (p_sItem.GetLength() != 0) { int iPos = FindItem(p_sItem); if (iPos != -1) { m_asList.RemoveAt(iPos); return TRUE; } } return FALSE; } BOOL CCustomAutoComplete::Clear() { if (m_asList.GetSize() != 0) { m_asList.RemoveAll(); return TRUE; } return FALSE; } BOOL CCustomAutoComplete::Disable() { if ((!m_pac) || (!m_fBound)) return FALSE; return SUCCEEDED(EnDisable(FALSE)); } BOOL CCustomAutoComplete::Enable(VOID) { if ((!m_pac) || (m_fBound)) return FALSE; return SUCCEEDED(EnDisable(TRUE)); } const CStringArray& CCustomAutoComplete::GetList() const { return m_asList; } // // IUnknown implementation // STDMETHODIMP_(ULONG) CCustomAutoComplete::AddRef() { ULONG nCount = ::InterlockedIncrement(reinterpret_cast<LONG*>(&m_nRefCount)); return nCount; } STDMETHODIMP_(ULONG) CCustomAutoComplete::Release() { ULONG nCount = 0; nCount = (ULONG) ::InterlockedDecrement(reinterpret_cast<LONG*>(&m_nRefCount)); if (nCount == 0) delete this; return nCount; } STDMETHODIMP CCustomAutoComplete::QueryInterface(REFIID riid, void** ppvObject) { HRESULT hr = E_NOINTERFACE; if (ppvObject != NULL) { *ppvObject = NULL; if (IID_IUnknown == riid) *ppvObject = static_cast<IUnknown*>(this); else if (IID_IEnumString == riid) *ppvObject = static_cast<IEnumString*>(this); if (*ppvObject != NULL) { hr = S_OK; ((LPUNKNOWN)*ppvObject)->AddRef(); } } else { hr = E_POINTER; } return hr; } // // IEnumString implementation // STDMETHODIMP CCustomAutoComplete::Next(ULONG celt, LPOLESTR* rgelt, ULONG* pceltFetched) { USES_CONVERSION; HRESULT hr = S_FALSE; if (!celt) celt = 1; for (ULONG i = 0; i < celt; i++) { if (m_nCurrentElement == (ULONG)m_asList.GetSize()) break; rgelt[i] = (LPWSTR)::CoTaskMemAlloc((ULONG) sizeof(WCHAR) * (m_asList[m_nCurrentElement].GetLength() + 1)); wcscpy(rgelt[i], T2W(m_asList[m_nCurrentElement])); if (pceltFetched) *pceltFetched++; m_nCurrentElement++; } if (i == celt) hr = S_OK; return hr; } STDMETHODIMP CCustomAutoComplete::Skip(ULONG celt) { m_nCurrentElement += celt; if (m_nCurrentElement > (ULONG)m_asList.GetSize()) m_nCurrentElement = 0; return S_OK; } STDMETHODIMP CCustomAutoComplete::Reset(void) { m_nCurrentElement = 0; return S_OK; } STDMETHODIMP CCustomAutoComplete::Clone(IEnumString** ppenum) { if (!ppenum) return E_POINTER; CCustomAutoComplete* pnew = new CCustomAutoComplete(); pnew->AddRef(); *ppenum = pnew; return S_OK; } void CCustomAutoComplete::InternalInit() { m_nCurrentElement = 0; m_nRefCount = 0; m_fBound = FALSE; m_iMaxItemCount = 30; } HRESULT CCustomAutoComplete::EnDisable(BOOL p_fEnable) { ATLASSERT(m_pac); HRESULT hr = m_pac->Enable(p_fEnable); if (SUCCEEDED(hr)) m_fBound = p_fEnable; return hr; } BOOL CCustomAutoComplete::LoadList(LPCTSTR pszFileName) { FILE* fp = _tfopen(pszFileName, _T("rt")); if (fp == NULL) return FALSE; TCHAR szItem[256]; while (fgets(szItem, ARRSIZE(szItem), fp) != NULL){ CString strItem(szItem); strItem.Trim(_T(" \r\n")); AddItem(strItem, -1); } fclose(fp); return TRUE; } BOOL CCustomAutoComplete::SaveList(LPCTSTR pszFileName) { FILE* fp = _tfopen(pszFileName, _T("wt")); if (fp == NULL) return FALSE; for (int i = 0; i < m_asList.GetCount(); i++) fprintf(fp, "%s\n", m_asList[i]); fclose(fp); return !ferror(fp); } CString CCustomAutoComplete::GetItem(int pos){ if (pos>=m_asList.GetCount()) return NULL; else return m_asList.GetAt(pos); }