本文共 12422 字,大约阅读时间需要 41 分钟。
经过两天的编码,完成了一个自动过滤选择的组合框,具有以下优点:
1。丝毫不妨碍组合框原有的功能2。根据在编辑框里已经输入的单词,从组合框的列表选项过滤出匹配的项,并使用下拉列表显示出来以供用户选择。3。不需要特别的设置。从ViewClassWizardMember Variables里生成一个CComboBox,然后在源里把CComboBox替换成CACComboBox即可;或者让ClassWizard认识CACComboBox(删除MyApp.clw,选ViewClassWizard,按提示重新生成MyApp.clw,绝大多数时候能成功),从ViewClassWizardMember Variables里直接生成一个CACComboBox。4。你可以经过简单修改使之成为具有其他类似功能(自动填写??)的组合框。由于时间仓促,没有写详细的注释。感兴趣的朋友请等几天后向我索要。联系方法:
to:linger0822@163">linger0822@163.net代码如下:
// File: ACComboBox.h//// Desc: // 根据用户在编辑框里已经输入的单词,从组合框的列表选项过滤出匹配的项,并使用下拉列表显示出来以供用户选择//// Copyright (c) 2001 EagleFly Studio.//// Original Author: Zhengpeng.Lan// Author:// // Create Time: 2001/10/10// Modify Time: 2001/10/11//#if !defined(AFX_ACCOMBOBOX_H__81CBBD04_3955_4076_A688_74D3EA9730D9__INCLUDED_)#define AFX_ACCOMBOBOX_H__81CBBD04_3955_4076_A688_74D3EA9730D9__INCLUDED_#if _MSC_VER > 1000
#pragma once#endif // _MSC_VER > 1000#include "afxtempl.h"
// ACComboBox.h : header file
//class CACComboBox;/// CWndForACComboBox windowtypedef struct{ int nid; CString strDepict;}CInfoForACComboBox;typedef CArray CInfoForACComboBoxArray;
class CWndForACComboBox : public CWnd
{ friend CACComboBox;private:// Construction LPCTSTR lpWndCls;// Constructionpublic: CWndForACComboBox();// Attributes
public: CComboBox * m_pComboBox; int m_nMaxCount; CInfoForACComboBoxArray m_aInfo; int m_nMousePos; int m_nBeginShow;inline void RemoveAll()
{ m_aInfo.RemoveAll(); CWnd::SetScrollRange(SB_VERT,0,0); } inline void Add(CInfoForACComboBox &info) { m_aInfo.Add(info); } inline int GetSize() { return m_aInfo.GetSize(); } inline void ShowList() { if(IsWindow(GetSafeHwnd())) { ShowWindow(SW_SHOWNOACTIVATE); } }// Operationspublic:// Overrs
// ClassWizard generated virtual function overrides AFX_VIRTUAL(CWndForACComboBox) public: virtual BOOL Create(CComboBox * pWnd); AFX_VIRTUAL// Implementation
public: virtual ~CWndForACComboBox();// Generated message map functions
protected: AFX_MSG(CWndForACComboBox) afx_msg void OnDestroy(); afx_msg void OnPaint(); afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); afx_msg void OnLButtonUp(UINT nFlags, CPoint point); afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); afx_msg void OnKillFocus(CWnd* pNewWnd); afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); AFX_MSG DECLARE_MESSAGE_MAP()}; /// CACComboBox windowclass CACComboBox : public CComboBox
{ private: CEdit* m_pEdit;// Construction
public: CACComboBox();// Attributes
public: CWndForACComboBox m_wndList; inline void WindowMove(void) { if(IsWindow(m_wndList.GetSafeHwnd())) m_wndList.Invalidate(FALSE); }// Operationspublic: virtual void HandleCompletion();// Overrides
// ClassWizard generated virtual function overrides AFX_VIRTUAL(CACComboBox) protected: virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam); virtual void PreSubclassWindow(); AFX_VIRTUAL// Implementation
public: virtual ~CACComboBox();// Generated message map functions
protected: AFX_MSG(CACComboBox) afx_msg void OnKillfocus(); afx_msg void OnSelchange(); AFX_MSGDECLARE_MESSAGE_MAP()
};/
/
AFX_INSERT_LOCATION}}// Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_ACCOMBOBOX_H__81CBBD04_3955_4076_A688_74D3EA9730D9__INCLUDED_)
// File: ACComboBox.cpp//// Desc: // 根据用户在编辑框里已经输入的单词,从组合框的列表选项过滤出匹配的项,并使用下拉列表显示出来以供用户选择//// Copyright (c) 2001 EagleFly Studio.//// Original Author: Zhengpeng.Lan// Author:// // Create Time: 2001/10/10// Modify Time: 2001/10/11//#include "stdafx.h"
#include "ACComboBox.h"#ifdef _DE
#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/
// CACComboBoxCACComboBox::CACComboBox()
:CComboBox(){ m_pEdit = NULL;}CACComboBox::~CACComboBox()
{ if(m_pEdit) delete m_pEdit;} BEGIN_MESSAGE_MAP(CACComboBox, CComboBox) AFX_MSG_MAP(CACComboBox) ON_CONTROL_REFLECT(CBN_KILLFOCUS, OnKillfocus) ON_CONTROL_REFLECT(CBN_SELCHANGE, OnSelchange) AFX_MSG_MAPEND_MESSAGE_MAP()/
// CACComboBox message handlers/// CWndForACComboBoxCWndForACComboBox::CWndForACComboBox()
:CWnd(){ lpWndCls = AfxRegisterWndClass(0); m_pComboBox = NULL; m_nMaxCount = 8; m_aInfo.SetSize(0,8); m_nMouseP= -1; m_nBeginShow = 0;}CWndForACComboBox::~CWndForACComboBox()
{}
BEGIN_MESSAGE_MAP(CWndForACComboBox, CWnd) AFX_MSG_MAP(CWndForACComboBox) ON_WM_DESTROY() ON_WM_PAINT() ON_WM_KEYDOWN() ON_WM_LBUTTONUP() ON_WM_MOUSEWHEEL() ON_WM_KILLFOCUS() ON_WM_MOUSEMOVE() ON_WM_VSCROLL() AFX_MSG_MAPEND_MESSAGE_MAP() /// CWndForACComboBox message handlersBOOL CWndForACComboBox::Create(CComboBox * pWnd)
{ ASSERT(pWnd);CRect rect;
CWnd * pParentWnd = pWnd->GetParent();pWnd->GetWindowRect(&rect);
// pParentWnd->ScreenToClient(&rect);BOOL bRet = CWnd::CreateEx( WS_EX_TOPMOST | WS_EX_TOOLWINDOW,
lpWndCls, NULL, WS_POPUP | WS_VSCROLL, rect.left, rect.top, rect.Width(), rect.Height(), pParentWnd->GetSafeHwnd(), NULL, NULL);if(bRet)
SetOwner(pParentWnd);m_pComboBox = pWnd;
return bRet;}void CWndForACComboBox::OnDestroy()
{ CWnd::OnDestroy(); m_aInfo.RemoveAll(); }void CWndForACComboBox::OnPaint()
{ CRect rect; CFont * pFont; LOGFONT logFont;if(m_pComboBox)
{ ASSERT(::IsWindow(m_pComboBox->GetSafeHwnd())); CWnd * pParentWnd = m_pComboBox->GetParent(); m_pComboBox->GetWindowRect(&rect); pFont = pParentWnd->GetFont(); ASSERT(pFont); pFont->GetLogFont(&logFont);if(logFont.lfHeight < 0) logFont.lfHeight = -logFont.lfHeight;
if(m_aInfo.GetSize() > m_nMaxCount) { logFont.lfWidth = m_nMaxCount * logFont.lfHeight; } else { logFont.lfWidth = m_aInfo.GetSize() * logFont.lfHeight; } if(logFont.lfWidth + rect.bottom > ::GetSystemMetrics(SM_CYSCREEN)) { rect.bottom = rect.top; rect.top = rect.bottom - logFont.lfWidth - 2; if(rect.top < 0) rect.top = 0; } else { rect.top = rect.bottom; rect.bottom = rect.top + logFont.lfWidth + 2; } rect.right = rect.left + m_pComboBox->GetDroppedWidth();// pParentWnd->ScreenToClient(&rect); MoveWindow(&rect); if(rect.Height() < m_aInfo.GetSize() * logFont.lfHeight) { TRACE("%d %drn",rect.Height(),m_aInfo.GetSize() * logFont.lfHeight); SCROLLINFO info;info.cbSize = sizeof(info);
info.fMask = SIF_PAGE; info.nPage = rect.Height() / logFont.lfHeight; CWnd::SetScrollRange(SB_VERT,0,m_aInfo.GetSize() - 1,FALSE); CWnd::ShowScrollBar(SB_VERT,TRUE); CWnd::SetScrollInfo(SB_VERT,&info); } else { CWnd::ShowScrollBar(SB_VERT,FALSE); } } CPaintDC dc(this); // device context for painting(0,0,rect.Width(),rect.Height(),RGB(255,255,255));
dc.Rectangle(0,0,rect.Width(),rect.Height()); logFont.lfWidth = 1; dc.(pFont); int m_nBeginShow = CWnd::GetScrollPos(SB_VERT); for(int i=m_nBeginShow;i { if(i == m_nMousePos) { dc.SetBkColor(RGB(0,0,128)); dc.FillSolidRect(1,logFont.lfWidth,rect.Width() - 2,logFont.lfHeight,RGB(0,0,128)); dc.SetTextColor(RGB(255,255,255)); } else { dc.SetBkColor(RGB(255,255,255)); dc.SetTextColor(RGB(0,0,0)); } dc.TextOut(3,logFont.lfWidth,m_aInfo[i].strDepict); logFont.lfWidth += logFont.lfHeight; }}void CWndForACComboBox::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{ // TODO: Add your message handler code here and/or call default CWnd::OnKeyDown(nChar, nRepCnt, nFlags);}void CWndForACComboBox::OnLButtonUp(UINT nFlags, CPoint point)
{ CFont * pFont; LOGFONT logFont;if(m_pComboBox)
{ pFont = m_pComboBox->GetParent()->GetFont(); pFont->GetLogFont(&logFont); if(logFont.lfHeight < 0) logFont.lfHeight = -logFont.lfHeight; m_nMousePos = (point.y - 1) / logFont.lfHeight + CWnd::GetScrollPos(SB_VERT); if(m_nMousePos >= 0 && m_nMousePos < m_aInfo.GetSize()) m_pComboBox->SetCurSel(m_aInfo[m_nMousePos].nid); ShowWindow(SW_HIDE); } CWnd::OnLButtonUp(nFlags, point);}BOOL CWndForACComboBox::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{ // TODO: Add your message handler code here and/or call default return CWnd::OnMouseWheel(nFlags, zDelta, pt);}void CWndForACComboBox::OnKillFocus(CWnd* pNewWnd)
{ CWnd::OnKillFocus(pNewWnd); if(pNewWnd->GetSafeHwnd() != m_pComboBox->GetSafeHwnd() && pNewWnd->GetSafeHwnd() != GetSafeHwnd() && IsWindow(GetSafeHwnd())) ShowWindow(SW_HIDE);}void CWndForACComboBox::OnMouseMove(UINT nFlags, CPoint point)
{ CFont * pFont; LOGFONT logFont; ::ShowCursor(TRUE); if(m_pComboBox) { pFont = m_pComboBox->GetParent()->GetFont(); pFont->GetLogFont(&logFont); if(logFont.lfHeight < 0) logFont.lfHeight = -logFont.lfHeight; logFont.lfWidth = point.y / logFont.lfHeight + CWnd::GetScrollPos(SB_VERT); if(logFont.lfWidth != m_nMousePos) { m_nMousePos = logFont.lfWidth; Invalidate(); } } CWnd::OnMouseMove(nFlags, point);}void CWndForACComboBox::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{ if(m_aInfo.GetSize() <= 0) { CWnd::OnVScroll(nSBCode, nPos, pScrollBar); return ; }switch(nSBCode)
{ // case SB_BOTTOM://Scroll to bottom.// case SB_ENDSCROLL://End scroll. case SB_LINEDOWN://Scroll one line down. { RECT rc; LOGFONT logFont; CFont * pFont;GetClientRect(&rc);
pFont = m_pComboBox->GetParent()->GetFont(); pFont->GetLogFont(&logFont); ASSERT(logFont.lfHeight != 0); if(logFont.lfHeight < 0) logFont.lfHeight = -logFont.lfHeight; rc.left = (rc.bottom - rc.top) / logFont.lfHeight;int nPos = GetScrollPos(SB_VERT) + 1;
if(nPos + rc.left <= m_aInfo.GetSize()) { SetScrollPos(SB_VERT,nPos); Invalidate(); } } break; case SB_LINEUP://Scroll one line up. { int nPos = GetScrollPos(SB_VERT) - 1; if(nPos >= 0) { SetScrollPos(SB_VERT,nPos); Invalidate(); } } break; case SB_PAGEDOWN://Scroll one page down. { RECT rc; LOGFONT logFont; CFont * pFont;GetClientRect(&rc);
pFont = m_pComboBox->GetParent()->GetFont(); pFont->GetLogFont(&logFont); ASSERT(logFont.lfHeight != 0); if(logFont.lfHeight < 0) logFont.lfHeight = -logFont.lfHeight;rc.top = rc.bottom / logFont.lfHeight;
int nPos = GetScrollPos(SB_VERT); if(nPos < m_aInfo.GetSize() - rc.top) { nPos += rc.top; if(nPos > m_aInfo.GetSize() - rc.top) nPos = m_aInfo.GetSize() - rc.top; SetScrollPos(SB_VERT,nPos); Invalidate(); } } break; case SB_PAGEUP://Scroll one page up. { RECT rc; LOGFONT logFont; CFont * pFont;GetClientRect(&rc);
pFont = m_pComboBox->GetParent()->GetFont(); pFont->GetLogFont(&logFont); ASSERT(logFont.lfHeight != 0); if(logFont.lfHeight < 0) logFont.lfHeight = -logFont.lfHeight;rc.top = rc.bottom / logFont.lfHeight;
int nPos = GetScrollPos(SB_VERT); if(nPos > 0) { nPos -= rc.top; if(nPos < 0) nPos = 0; SetScrollPos(SB_VERT,nPos); Invalidate(); } } break;// case SB_THUMBPOSITION://Scroll to the absolute position. The current position is provided in nPos. case SB_THUMBTRACK://Drag scroll box to specified position. The current position is provided in nPos. { SetScrollPos(SB_VERT,nPos); Invalidate(); } break;// case SB_TOP://Scroll to top } CWnd::OnVScroll(nSBCode, nPos, pScrollBar);}void CACComboBox::HandleCompletion()
{ // Make sure we can 'talk' to the edit control if( m_pEdit == NULL ) { m_pEdit = new CEdit(); m_pEdit->SubclassWindow(GetDlgItem(1001)->GetSafeHwnd()); }// Save the state of the edit control
CString text,bestText; CInfoForACComboBox info; int n = GetCount();m_wndList.RemoveAll();
m_pEdit->GetWindowText(text); CPoint ptCaret = m_pEdit->GetCaretPos();// int start,end;
// m_pEdit->GetSel(start,end);// Perfoactual completion
int bestindex = -1; int bestfrom = INT_MAX; int from; for ( int x = 0; x < n; x++ ) { GetLBText(x,info.strDepict); info.nid = x;from = info.strDepict.Find(text);
if(from != -1)
{ m_wndList.Add(info); if( from != -1 && from < bestfrom ) { bestindex = x; bestText = info.strDepict; bestfrom = from; } } }if ( bestindex != -1)
{ // Restore the edit control m_pEdit->SetWindowText(bestText); m_pEdit->SetSel(text.GetLength(),bestText.GetLength()); m_pEdit->SetCaretPos(ptCaret); } if(m_wndList.GetSize() != 0) { m_wndList.ShowList(); m_wndList.Invalidate(); } else { m_wndList.ShowWindow(SW_HIDE); }}BOOL CACComboBox::OnCommand(WPARAM wParam, LPARAM lParam)
{ if(HI(wParam) == EN_CHANGE) { HandleCompletion(); return TRUE; } return CComboBox::OnCommand(wParam, lParam);}void CACComboBox::PreSubclassWindow()
{ CComboBox::PreSubclassWindow();m_wndList.Create(this);
}void CACComboBox::OnKillfocus()
{ m_wndList.OnKillFocus(GetFocus());}void CACComboBox::OnSelchange()
{ m_wndList.ShowWindow(SW_HIDE); }来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10748419/viewspace-1007846/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/10748419/viewspace-1007846/