⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ngdisableditemcombobox.cpp

📁 ResOrg 图形化管理Vc项目的资源ID的工具的源代码。 ResOrg - Manage and Renumber Resource Symbol IDs Introduction The
💻 CPP
字号:
// NGDisabledItemComboBox.cpp : implementation file
//
//	This code is derived from that accompanying the article
//	"CComboBox with disabled items" published by Petr Novotny
//	(Petr.Novotny@antek.cz) on www.codeproject.com 
//
//	Modifications for compatibility with dropped lists by Anna-Jayne Metcalfe
//	(ajm@sonardyne.co.uk or code@annasplace.me.uk)
//
#include "StdAfx.h"
#include "NGDisabledItemComboBox.h"

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


const UINT nMessage=::RegisterWindowMessage( _T("ComboSelEndOK") );		// _T("") needed for Unicode builds

/////////////////////////////////////////////////////////////////////////////
// CNGDisabledItemComboBox

CNGDisabledItemComboBox::CNGDisabledItemComboBox(void)
{
	m_ListBox.SetParent(this);
}

CNGDisabledItemComboBox::~CNGDisabledItemComboBox(void)
{
}



// default implementation
BOOL CNGDisabledItemComboBox::IsItemEnabled(UINT nIndex) const
{
	if (nIndex < (DWORD)GetCount())
	{
		DWORD uData=GetItemData(nIndex);

		return (uData&1);
	}
	return TRUE;	// whatever
}


BEGIN_MESSAGE_MAP(CNGDisabledItemComboBox, CComboBox)
	//{{AFX_MSG_MAP(CNGDisabledItemComboBox)
	ON_WM_CHARTOITEM()
	ON_CONTROL_REFLECT(CBN_SELENDOK, OnSelendok)
	ON_WM_KEYDOWN()
	//}}AFX_MSG_MAP
	ON_MESSAGE(WM_CTLCOLORLISTBOX, OnCtlColor)
	ON_REGISTERED_MESSAGE(nMessage, OnRealSelEndOK)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CNGDisabledItemComboBox message handlers

void CNGDisabledItemComboBox::PreSubclassWindow(void) 
{
	ASSERT( (GetStyle() & (CBS_OWNERDRAWFIXED | CBS_HASSTRINGS)) == (CBS_OWNERDRAWFIXED | CBS_HASSTRINGS) );

	CComboBox::PreSubclassWindow();
}


void CNGDisabledItemComboBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
	CDC* pDC = CDC::FromHandle (lpDrawItemStruct->hDC);

	if (((LONG)(lpDrawItemStruct->itemID) >= 0) &&
		(lpDrawItemStruct->itemAction & (ODA_DRAWENTIRE | ODA_SELECT)))
	{
		BOOL bDisabled = !IsWindowEnabled () || !IsItemEnabled(lpDrawItemStruct->itemID);

		COLORREF newTextColor = bDisabled ?
			RGB(0x80, 0x80, 0x80) : GetSysColor (COLOR_WINDOWTEXT);  // light gray

		COLORREF oldTextColor = pDC->SetTextColor (newTextColor);

		COLORREF newBkColor = GetSysColor (COLOR_WINDOW);
		COLORREF oldBkColor = pDC->SetBkColor (newBkColor);

		if (newTextColor == newBkColor)
			newTextColor = RGB(0xC0, 0xC0, 0xC0);   // dark gray

		if (!bDisabled && ((lpDrawItemStruct->itemState & ODS_SELECTED) != 0))
		{
			pDC->SetTextColor (GetSysColor (COLOR_HIGHLIGHTTEXT));
			pDC->SetBkColor (GetSysColor (COLOR_HIGHLIGHT));
		}

		CString sText;
		GetLBText(lpDrawItemStruct->itemID, sText);

		const RECT &rc=lpDrawItemStruct->rcItem;

		pDC->ExtTextOut(rc.left + 2,
				  rc.top + 2,// + max(0, (cyItem - m_cyText) / 2),
				  ETO_OPAQUE, &rc,
				  sText, sText.GetLength (), NULL);

		pDC->SetTextColor (oldTextColor);
		pDC->SetBkColor (oldBkColor);
	}
	else if ((LONG)(lpDrawItemStruct->itemID)<0)	// drawing edit text
	{
		COLORREF newTextColor = GetSysColor (COLOR_WINDOWTEXT);  // light gray
		COLORREF oldTextColor = pDC->SetTextColor (newTextColor);

		COLORREF newBkColor = GetSysColor (COLOR_WINDOW);
		COLORREF oldBkColor = pDC->SetBkColor (newBkColor);

		if ((lpDrawItemStruct->itemState & ODS_SELECTED) != 0)
		{
			pDC->SetTextColor (GetSysColor (COLOR_HIGHLIGHTTEXT));
			pDC->SetBkColor (GetSysColor (COLOR_HIGHLIGHT));
		}

		CString sText;
		GetWindowText(sText);
		const RECT &rc=lpDrawItemStruct->rcItem;

		pDC->ExtTextOut(rc.left + 2,
				  rc.top + 2,// + max(0, (cyItem - m_cyText) / 2),
				  ETO_OPAQUE, &rc,
				  sText, sText.GetLength (), NULL);

		pDC->SetTextColor (oldTextColor);
		pDC->SetBkColor (oldBkColor);
	}

	if ((lpDrawItemStruct->itemAction & ODA_FOCUS) != 0)
		pDC->DrawFocusRect(&lpDrawItemStruct->rcItem);
	
}


void CNGDisabledItemComboBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) 
{
	// TODO: Add your code to determine the size of specified item
	UNREFERENCED_PARAMETER(lpMeasureItemStruct);
}


int CNGDisabledItemComboBox::OnCharToItem(UINT nChar, CListBox* pListBox, UINT nIndex) 
{
	// TODO: Add your message handler code here and/or call default
	
	int nItem = CComboBox::OnCharToItem(nChar, pListBox, nIndex);
	if ( (nItem >= 0) && !IsItemEnabled(nItem))
	{
		return -2;
	}
	return nItem;
}


void CNGDisabledItemComboBox::OnSelendok(void) 
{
	GetWindowText(m_sSavedText);
	PostMessage(nMessage);	
}


LRESULT CNGDisabledItemComboBox::OnRealSelEndOK(WPARAM,LPARAM)
{
	CString sCurrentText;
	GetWindowText(sCurrentText);

	int nIndex = FindStringExact(-1, sCurrentText);

	if (nIndex >=0 && !IsItemEnabled(nIndex))
	{
		SetWindowText(m_sSavedText);

		GetParent()->SendMessage(	WM_COMMAND,
									MAKELONG( GetWindowLong(m_hWnd, GWL_ID), CBN_SELCHANGE),
									(LPARAM)m_hWnd);
	}
	return 0;
}


LRESULT CNGDisabledItemComboBox::OnCtlColor(WPARAM,LPARAM lParam)
{
	if ( (m_ListBox.m_hWnd == NULL) && (lParam != 0) && (lParam != (LPARAM)m_hWnd) )
	{
		m_ListBox.SubclassWindow((HWND)lParam);
	}
	return Default();
}


void CNGDisabledItemComboBox::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	if (!GetDroppedState())
	{
		switch (nChar)
		{
			case VK_UP:
				{
					// Go up until we find a valid selection
					// then set the current selection to that one
					int nSel = GetCurSel();
					if (nSel != CB_ERR)
					{
						while (nSel > 0)
						{
							if (IsItemEnabled(--nSel))
							{
								SetCurSel(nSel);
								break;
							}
						}
					}
				}
				return;

			case VK_DOWN:
				{
					// Go up until we find a valid selection
					// then set the current selection to that one
					int nSel = GetCurSel();
					if (nSel != CB_ERR)
					{
						while (nSel < GetCount() )
						{
							if (IsItemEnabled(++nSel))
							{
								SetCurSel(nSel);
								break;
							}
						}
					}
				}
				return;

			case VK_PRIOR:
				{
					// Select first non-disabled item
					int nSel = 0;
					while (nSel <= GetCount() )
					{
						if (IsItemEnabled(nSel))
						{
							SetCurSel(nSel);
							break;
						}
						nSel++;
					}
				}
				return;

			case VK_NEXT:
				{
					// Select last non-disabled item
					int nSel = GetCount();
					while (nSel > 0)
					{
						if (IsItemEnabled(--nSel))
						{
							SetCurSel(nSel);
							break;
						}
					}
				}
				return;

			default:
				break;
		}
	}
	CComboBox::OnKeyDown(nChar, nRepCnt, nFlags);
}


void CNGDisabledItemComboBox::PostNcDestroy(void)
{
//	m_ListBox.UnsubclassWindow();
	m_ListBox.Detach();
	
	CComboBox::PostNcDestroy();
}



/////////////////////////////////////////////////////////////////////////////
// CListBoxInsideComboBox

CListBoxInsideComboBox::CListBoxInsideComboBox(void)
{
	m_pParent = NULL;
}


CListBoxInsideComboBox::~CListBoxInsideComboBox(void)
{
}


BEGIN_MESSAGE_MAP(CListBoxInsideComboBox, CWnd)
	//{{AFX_MSG_MAP(CListBoxInsideComboBox)
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_KEYDOWN()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CListBoxInsideComboBox operations

void CListBoxInsideComboBox::SetParent(CNGDisabledItemComboBox* pCB)
{
	m_pParent = pCB;
}


/////////////////////////////////////////////////////////////////////////////
// CListBoxInsideComboBox message handlers

void CListBoxInsideComboBox::OnMouseMove(UINT nFlags, CPoint point) 
{
	CRect rect;
	GetClientRect(rect);

	if (rect.PtInRect(point))
	{
		BOOL bOutside = FALSE;
		int nIndex = ((CListBox*)this)->ItemFromPoint(point, bOutside);

		if (!bOutside && !m_pParent->IsItemEnabled(nIndex))
		{
			return;	// don't click there
		}
	}
	
	CWnd::OnMouseMove(nFlags, point);
}


void CListBoxInsideComboBox::OnLButtonDown(UINT nFlags, CPoint point) 
{
	CRect rect;
	GetClientRect(rect);

	if (rect.PtInRect(point))
	{
		BOOL bOutside = FALSE;
		int nIndex = ((CListBox*)this)->ItemFromPoint(point, bOutside);

		if (!bOutside && !m_pParent->IsItemEnabled(nIndex))
		{
			return;	// don't click there
		}
	}
	
	CWnd::OnLButtonDown(nFlags, point);
}


void CListBoxInsideComboBox::OnLButtonUp(UINT nFlags, CPoint point) 
{
	CRect rect;
	GetClientRect(rect);

	if (rect.PtInRect(point))
	{
		BOOL bOutside = FALSE;
		int nIndex = ((CListBox*)this)->ItemFromPoint(point, bOutside);

		if (!bOutside && !m_pParent->IsItemEnabled(nIndex))
		{
			return;	// don't click there
		}
	}
	
	CWnd::OnLButtonUp(nFlags, point);
}


void CListBoxInsideComboBox::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	if (m_pParent->GetDroppedState())
	{
		switch (nChar)
		{
			case VK_LEFT:
			case VK_UP:
				{
					// Go up until we find a valid selection
					// then set the current selection to that one
					int nSel = ((CListBox*)this)->GetCurSel();
					if (nSel != LB_ERR)
					{
						while (nSel > 0)
						{
							if (m_pParent->IsItemEnabled(--nSel))
							{
								((CListBox*)this)->SetCurSel(nSel);
								break;
							}
						}
					}
				}
				return;

			case VK_RIGHT:
			case VK_DOWN:
				{
					// Go up until we find a valid selection
					// then set the current selection to that one
					int nSel = ((CListBox*)this)->GetCurSel();
					if (nSel != LB_ERR)
					{
						while (nSel < ((CListBox*)this)->GetCount() )
						{
							if (m_pParent->IsItemEnabled(++nSel))
							{
								((CListBox*)this)->SetCurSel(nSel);
								break;
							}
						}
					}
				}
				return;

			case VK_HOME:
			case VK_PRIOR:
				{
					// Select first non-disabled item
					int nSel = 0;
					while (nSel <= ((CListBox*)this)->GetCount() )
					{
						if (m_pParent->IsItemEnabled(nSel))
						{
							((CListBox*)this)->SetCurSel(nSel);
							break;
						}
						nSel++;
					}
				}
				return;

			case VK_END:
			case VK_NEXT:
				{
					// Select last non-disabled item
					int nSel = ((CListBox*)this)->GetCount();
					while (nSel > 0)
					{
						if (m_pParent->IsItemEnabled(--nSel))
						{
							((CListBox*)this)->SetCurSel(nSel);
							break;
						}
					}
				}
				return;

			default:
				break;
		}
	}
	CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -