您的位置:首页 > 运维架构

(MFC Combo Box)Switch between drop-list and drop-down mode

2013-03-19 19:29 351 查看
参考此贴:http://www.codeguru.com/cpp/controls/combobox/article.php/c1823/Switch-between-droplist-and-dropdown-mode.htm

实现源码(经过少量修改,原版本请参考上贴)

// FineCombo.h : header file
//
// Copyright (c) 1999 Bruno Vais
//
// Distribute and use freely, except:
// a) Don't alter or remove this notice.
// b) Mark the changes you make.
//
// This file is provided "as is" with no expressed or implied warranty.
// Use at your own risk. Expect bugs.
//
// Send bug reports, bug fixes, enhancements, request, etc. to:
//
//  bvais@usa.net
//
//  v1.0  21.06.1999  Initial release

//
//  v1.1  19.03.2013  Modified by zhuyf
//
//  GetEditText()功能修改如下:
//  当Combo Box为Dropdown时,返回m_edit文本;当Combo Box为Drop List时,返回Combo Box文本
//

#pragma once

class CFineEdit : public CEdit
{
// Construction
public:
CFineEdit();

// Attributes
public:
CComboBox *m_combo;
// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CFineEdit)
//}}AFX_VIRTUAL

// Implementation
public:
void Create(CRect, CWnd *);
virtual ~CFineEdit();

// Generated message map functions
protected:
//{{AFX_MSG(CFineEdit)
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnDestroy();
afx_msg void OnKillFocus(CWnd *pNewWnd);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
private:
CFont m_font;

};

class CFineCombo : public CComboBox
{
// Construction
public:
CFineCombo();

// Attributes
public:
CFineEdit m_edit;
// Operations
public:
CString GetEditText();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CFineCombo)
//}}AFX_VIRTUAL

// Implementation
public:
void SwitchToDrop(BOOL);
virtual ~CFineCombo();

// Generated message map functions
protected:
//{{AFX_MSG(CFineCombo)
afx_msg void OnDropdown();
afx_msg void OnCloseup();
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
private:

};


// FineCombo.cpp : implementation file
//
// Copyright (c) 1999 Bruno Vais
//
// Distribute and use freely, except:
// a) Don't alter or remove this notice.
// b) Mark the changes you make.
//
// This file is provided "as is" with no expressed or implied warranty.
// Use at your own risk. Expect bugs.
//
// Send bug reports, bug fixes, enhancements, request, etc. to:
//
//  bvais@usa.net
//
//  v1.0  21.06.1999  Initial release

//
//  v1.1  19.03.2013  Modified by zhuyf
//
//  GetEditText()功能修改如下:
//  当Combo Box为Dropdown时,返回m_edit文本;当Combo Box为Drop List时,返回Combo Box文本
//

#include "stdafx.h"
#include "FineCombo.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CFineCombo

CFineCombo::CFineCombo()
{
}

CFineCombo::~CFineCombo()
{
}

BEGIN_MESSAGE_MAP(CFineCombo, CComboBox)
//{{AFX_MSG_MAP(CFineCombo)
ON_CONTROL_REFLECT(CBN_DROPDOWN, OnDropdown)
ON_CONTROL_REFLECT(CBN_CLOSEUP, OnCloseup)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFineCombo message handlers

void CFineCombo::SwitchToDrop(BOOL id)
{
CEdit *edit=(CEdit *)GetWindow(GW_CHILD);
if (edit)    // if the combo already has the dropdown style
return; // return

if (id && !m_edit.m_hWnd)
{
CRect thisRect, dadRect;

GetWindowRect(&thisRect);
GetParent()->GetWindowRect(&dadRect);

int left = thisRect.left - dadRect.left;
int top = thisRect.top - dadRect.top;

CRect editRect(left+3, top+2, left+thisRect.Width()-15, top+19);

m_edit.Create(editRect, GetParent());
m_edit.m_combo = this;

// I have to put the edit in front of the combo in the Z-order
// because otherwise when you click on it it will drop down the combo
::SetWindowPos(m_hWnd, m_edit.m_hWnd, 0,0,0,0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE);

CString str;
int index = GetCurSel();
if (index != -1)
{
GetLBText(GetCurSel(), str);
m_edit.SetWindowText(str);
}
else
m_edit.SetWindowText(_T(""));

ModifyStyle(WS_TABSTOP, 0); // taking out the combo from the tablist
m_edit.SetFocus();

}
else
{
// if empty edit box
CString txt;
m_edit.GetWindowText(txt);

int sel = FindString(-1, txt);
if (sel != -1)
{
SetCurSel(sel);
GetLBText(sel, txt);
}

if (m_edit.m_hWnd)
m_edit.DestroyWindow();

ModifyStyle(0, WS_TABSTOP); // adding the combo to the tablist
SetFocus();
}

}

void CFineCombo::OnDropdown()
{
if (m_edit.m_hWnd)
{
CString txt;
m_edit.GetWindowText(txt);

int sel = FindString(-1, txt);
if (sel != -1)
{
SetCurSel(sel);
GetLBText(sel, txt);
m_edit.SetWindowText(txt);
}
}
}

void CFineCombo::OnCloseup()
{
if (m_edit.m_hWnd)
{
CString str;
int sel = GetCurSel();

if (sel != -1)
{
GetLBText(sel, str);
m_edit.SetWindowText(str);
m_edit.SetFocus();
}
}
}

CString CFineCombo::GetEditText()
{
CString txt;

if (m_edit.m_hWnd)
m_edit.GetWindowText(txt);
else
// txt = _"";
GetWindowText(txt); // Modified by zhuyf

return txt;
}

/////////////////////////////////////////////////////////////////////////////
// CFineEdit

CFineEdit::CFineEdit()
{

}

CFineEdit::~CFineEdit()
{
}

BEGIN_MESSAGE_MAP(CFineEdit, CEdit)
//{{AFX_MSG_MAP(CFineEdit)
ON_WM_KEYDOWN()
ON_WM_DESTROY()
ON_WM_KILLFOCUS()
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFineEdit message handlers

void CFineEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CString txt, wtxt;
int sel;

Invalidate();

switch (nChar)
{
case 40: // DOWNARROW
GetWindowText(wtxt);
sel = m_combo->FindStringExact(-1, wtxt);
if (sel != -1)
{
if (m_combo->SetCurSel(sel+1) != -1)
{
m_combo->GetLBText(sel+1, txt);
SetWindowText(txt);
}
}
else
{
sel = m_combo->FindString(-1, wtxt);
if (sel != -1)
{
m_combo->SetCurSel(sel);
m_combo->GetLBText(sel,txt);
SetWindowText(txt);
}
else // empty edit box
{
m_combo->SetCurSel(0);
m_combo->GetLBText(0, txt);
SetWindowText(txt);
}
}
break;

case 38: // UPARROW
GetWindowText(wtxt);
sel = m_combo->FindStringExact(-1, wtxt);
if (sel != -1)
{
if (m_combo->SetCurSel(sel-1) != -1)
{
m_combo->GetLBText(sel-1, txt);
SetWindowText(txt);
}
}
else
{
sel = m_combo->FindString(-1, wtxt);
if (sel != -1)
{
m_combo->SetCurSel(sel);
m_combo->GetLBText(sel, txt);
SetWindowText(txt);
}
else // empty edit box
{
m_combo->SetCurSel(0);
m_combo->GetLBText(0, txt);
SetWindowText(txt);
}
}
break;

default:
CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
}
}

void CFineEdit::Create(CRect rect, CWnd *father)
{
CEdit::Create(WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL|WS_TABSTOP, rect, father, 5000);

/*
NONCLIENTMETRICS nonc;
nonc.cbSize= sizeof(NONCLIENTMETRICS);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &nonc, 0);
m_font.CreateFontIndirect(&nonc.lfMessageFont);
SetFont(&m_font,FALSE);
*/
}

void CFineEdit::OnDestroy()
{
CEdit::OnDestroy();
//m_font.Detach();
}

void CFineEdit::OnKillFocus(CWnd* pNewWnd)
{
CEdit::OnKillFocus(pNewWnd);
Invalidate(); // because the caret remains somewhere in the left side
}

void CFineEdit::OnLButtonDown(UINT nFlags, CPoint point)
{
Invalidate(); // same as above
CEdit::OnLButtonDown(nFlags, point);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: