分享
 
 
 

自动过滤选择的组合框

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

经过两天的编码调试,完成了一个自动过滤选择的组合框,具有以下优点:

1。丝毫不妨碍组合框原有的功能

2。根据用户在编辑框里已经输入的单词,从组合框的列表选项过滤出匹配的项,并使用下拉列表显示出来以供用户选择。

3。不需要特别的设置。从View\ClassWizard\Member Variables里生成一个CComboBox,然后在源文件里把CComboBox替换成CACComboBox即可;或者让ClassWizard认识CACComboBox(删除MyApp.clw,选View\ClassWizard,按提示重新生成MyApp.clw,绝大多数时候能成功),从View\ClassWizard\Member Variables里直接生成一个CACComboBox。

4。你可以经过简单修改使之成为具有其他类似功能(自动填写??)的组合框。

由于时间仓促,没有写详细的注释。感兴趣的朋友请等几天后向我索要。联系方法:

linger0822@163.net

代码如下:

file://-----------------------------------------------------------------------------

// File: ACComboBox.h

//

// Desc:

// 根据用户在编辑框里已经输入的单词,从组合框的列表选项过滤出匹配的项,并使用下拉列表显示出来以供用户选择

//

// Copyright (c) 2001 EagleFly Studio.

//

// Original Author: Zhengpeng.Lan

// Author:

//

// Create Time: 2001/10/10

// Modify Time: 2001/10/11

//

file://-----------------------------------------------------------------------------

#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 window

typedef struct

{

int nid;

CString strDepict;

}CInfoForACComboBox;

typedef CArray<CInfoForACComboBox,CInfoForACComboBox &> CInfoForACComboBoxArray;

class CWndForACComboBox : public CWnd

{

friend CACComboBox;

private:

// Construction

LPCTSTR lpWndCls;

// Construction

public:

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

}

}

// Operations

public:

// Overrides

// ClassWizard generated virtual function overrides

file://{{AFX_VIRTUAL(CWndForACComboBox)

public:

virtual BOOL Create(CComboBox * pWnd);

file://}}AFX_VIRTUAL

// Implementation

public:

virtual ~CWndForACComboBox();

// Generated message map functions

protected:

file://{{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);

file://}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

/////////////////////////////////////////////////////////////////////////////

// CACComboBox window

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

}

// Operations

public:

virtual void HandleCompletion();

// Overrides

// ClassWizard generated virtual function overrides

file://{{AFX_VIRTUAL(CACComboBox)

protected:

virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);

virtual void PreSubclassWindow();

file://}}AFX_VIRTUAL

// Implementation

public:

virtual ~CACComboBox();

// Generated message map functions

protected:

file://{{AFX_MSG(CACComboBox)

afx_msg void OnKillfocus();

afx_msg void OnSelchange();

file://}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////

file://{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_ACCOMBOBOX_H__81CBBD04_3955_4076_A688_74D3EA9730D9__INCLUDED_)

file://-----------------------------------------------------------------------------

// File: ACComboBox.cpp

//

// Desc:

// 根据用户在编辑框里已经输入的单词,从组合框的列表选项过滤出匹配的项,并使用下拉列表显示出来以供用户选择

//

// Copyright (c) 2001 EagleFly Studio.

//

// Original Author: Zhengpeng.Lan

// Author:

//

// Create Time: 2001/10/10

// Modify Time: 2001/10/11

//

file://-----------------------------------------------------------------------------

#include "stdafx.h"

#include "ACComboBox.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CACComboBox

CACComboBox::CACComboBox()

:CComboBox()

{

m_pEdit = NULL;

}

CACComboBox::~CACComboBox()

{

if(m_pEdit)

delete m_pEdit;

}

BEGIN_MESSAGE_MAP(CACComboBox, CComboBox)

file://{{AFX_MSG_MAP(CACComboBox)

ON_CONTROL_REFLECT(CBN_KILLFOCUS, OnKillfocus)

ON_CONTROL_REFLECT(CBN_SELCHANGE, OnSelchange)

file://}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CACComboBox message handlers

/////////////////////////////////////////////////////////////////////////////

// CWndForACComboBox

CWndForACComboBox::CWndForACComboBox()

:CWnd()

{

lpWndCls = AfxRegisterWndClass(0);

m_pComboBox = NULL;

m_nMaxCount = 8;

m_aInfo.SetSize(0,8);

m_nMousePos = -1;

m_nBeginShow = 0;

}

CWndForACComboBox::~CWndForACComboBox()

{

}

BEGIN_MESSAGE_MAP(CWndForACComboBox, CWnd)

file://{{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()

file://}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CWndForACComboBox message handlers

BOOL 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 %d\r\n",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

file://dc.FillSolidRect(0,0,rect.Width(),rect.Height(),RGB(255,255,255));

dc.Rectangle(0,0,rect.Width(),rect.Height());

logFont.lfWidth = 1;

dc.SelectObject(pFont);

int m_nBeginShow = CWnd::GetScrollPos(SB_VERT);

for(int i=m_nBeginShow;i<m_aInfo.GetSize() && logFont.lfWidth < rect.Height() - 2;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);

// Perform actual 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(HIWORD(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);

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有