博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自动过滤选择的组合框 (转)
阅读量:2505 次
发布时间:2019-05-11

本文共 12422 字,大约阅读时间需要 41 分钟。

自动过滤选择的组合框 (转)[@more@]

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

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 window
typedef struct
{
 int nid;
 CString strDepict;
}CInfoForACComboBox;

typedef CArray 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:

// 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 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
 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_MSG

 DECLARE_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_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)
 AFX_MSG_MAP(CACComboBox)
 ON_CONTROL_REFLECT(CBN_KILLFOCUS, OnKillfocus)
 ON_CONTROL_REFLECT(CBN_SELCHANGE, OnSelchange)
 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_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_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  %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/

你可能感兴趣的文章
IOS中调用系统拨打电话发送短信
查看>>
30行JavaScript代码实现一个比特币量化策略
查看>>
thinkphp5 数据库配置设置
查看>>
数组的示例
查看>>
java 循环变量
查看>>
Js获取日期时间及其它操作
查看>>
20141103
查看>>
HTML <hr> 标签定义和用法
查看>>
使用File查询出所有的文件和目录的信息
查看>>
.NET Micro Framework V4.2 QFE2新版本简介
查看>>
Vue.js学习笔记(2)vue-router
查看>>
python中函数和方法的区别
查看>>
(转载)java线程 - 线程唤醒后并被执行时,是在上次阻塞的代码行重新往下执行,而不是从头开始执行...
查看>>
【codeforces 483B】Friends and Presents
查看>>
【codeforces 767B】The Queue
查看>>
【codeforces 190C】STL
查看>>
041魔法方法:构造和析构
查看>>
7月/暑假集训总结1
查看>>
通悉IDC刘雨生带您查看BGP线路服务器的优势
查看>>
js在html中的三种写法
查看>>