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

📄 comboboxsuper.h

📁 这是一本学习 window编程的很好的参考教材
💻 H
字号:
#if !defined(AFX_COLORCOMBO_H__20020314_DDA3_617F_0D88_0080AD509054__INCLUDED_)
#define AFX_COLORCOMBO_H__20020314_DDA3_617F_0D88_0080AD509054__INCLUDED_

#pragma once

/////////////////////////////////////////////////////////////////////////////
// ComboBoxSuper
//
// Written by Bjarke Viksoe (bjarke@viksoe.dk)
// Copyright (c) 2002-2003 Bjarke Viksoe.
//
// Add the following macro to the parent's message map:
//   REFLECT_NOTIFICATIONS()
//
// This code may be used in compiled form in any way you desire. This
// source file may be redistributed by any means PROVIDING it is 
// not sold for profit without the authors written consent, and 
// providing that this notice and the authors name is included. 
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to you or your
// computer whatsoever. It's free, so don't hassle me about it.
//
// Beware of bugs.
//
#include <atlctrls.h>
#include <atlcrack.h>
#include <atlframe.h>
#include <map>
#include <vector>





/////////////////////////////////////////////////////////////////////////////
// 
const DEFAULT_COLUMN_COUNT = 100;
const DEFAULT_COLUMN_WIDTH = 50;

template< class T, class TBase = CComboBox, class TWinTraits = CWinTraitsOR<LBS_OWNERDRAWVARIABLE|LBS_NOTIFY> >
class ATL_NO_VTABLE CComboBoxSuperImpl : 
	public CWindowImpl< T, TBase, TWinTraits >,
	public COwnerDraw< CComboBoxSuperImpl >
{
public:
	DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())
	struct ItemData
	{
		ItemData() : crTextColor(RGB(0,0,0)),nImageIndex(-1),bBold(FALSE){}
		COLORREF crTextColor;
		int nImageIndex;
		std::map<int,WTL::CString> mapStrings;
		BOOL bBold;
		DWORD dwItemData;
	};

	std::vector<int> m_vecColumnWidth;

	CImageList* m_pImageList;
	BOOL m_bUseImage;

	// Operations

	BOOL SubclassWindow(HWND hWnd)
	{
		 ATLASSERT(m_hWnd==NULL);
		 ATLASSERT(::IsWindow(hWnd));
		 BOOL bRet = CWindowImpl< T, TBase, TWinTraits >::SubclassWindow(hWnd);
		
		 return bRet;
	}

	CComboBoxSuperImpl( )
		: CWindowImpl< T, TBase,TWinTraits >( ),
		m_pImageList( NULL ),
		m_bUseImage( TRUE )
	{	m_vecColumnWidth.resize(DEFAULT_COLUMN_COUNT);
		for (int i=0; i<DEFAULT_COLUMN_COUNT;i++)
		{
			m_vecColumnWidth[i] = DEFAULT_COLUMN_WIDTH;
		}

	}
	// Implementation

	
	// Message map and handlers

	BEGIN_MSG_MAP(CComboBoxSuperImpl)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		CHAIN_MSG_MAP_ALT(COwnerDraw<CComboBoxSuperImpl>, 1)
		DEFAULT_REFLECTION_HANDLER()
	END_MSG_MAP()

	LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
		LRESULT lRes = DefWindowProc(uMsg, wParam, lParam);
		
		return lRes;
	}

	// COwnerDraw

	void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
	{
		if( lpDrawItemStruct->itemID == -1 ) return;

		ItemData* pItemData = NULL;

		if (lpDrawItemStruct->itemData!=NULL)
		{
			pItemData = (ItemData*)lpDrawItemStruct->itemData;
		}

		WTL::CString str;
		GetLBText(lpDrawItemStruct->itemID, str);
		CDC dc;
		BOOL bSelected = FALSE;

		dc.Attach(lpDrawItemStruct->hDC);

		// Save these value to restore them when done drawing.
		COLORREF crOldTextColor = dc.GetTextColor();
		COLORREF crOldBkColor = dc.GetBkColor();

		// If this item is selected, set the background color and the text color to appropriate 
		// values. Erase the rect by filling it with the background color.
		if ((lpDrawItemStruct->itemAction | ODA_SELECT) &&
			(lpDrawItemStruct->itemState & ODS_SELECTED))
		{
			dc.SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
			dc.SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
			dc.FillSolidRect(&lpDrawItemStruct->rcItem, ::GetSysColor(COLOR_HIGHLIGHT));
			bSelected = TRUE;
		}
		else
		{
			dc.FillSolidRect(&lpDrawItemStruct->rcItem, crOldBkColor);
		}

		CRect rect(lpDrawItemStruct->rcItem);
		rect.DeflateRect(1,0);

		// If we use images, and there is data, and the index is valid:
		if (m_pImageList && m_bUseImage && pItemData && pItemData->nImageIndex!=-1)
		{
			DrawIconEx(dc.m_hDC,rect.left,rect.top,
				m_pImageList->ExtractIcon(pItemData->nImageIndex),0, 0, 0, NULL, DI_NORMAL);
		}

		// If we use images - move text to the right:
		if (m_bUseImage && m_pImageList)
		{
			IMAGEINFO sImageInfo;
			m_pImageList->GetImageInfo(0, &sImageInfo);
			rect.left += sImageInfo.rcImage.right;
		}

		CFont OldFont;
		CFont boldFont;
		if (pItemData && pItemData->bBold)
		{
			CFont curFont(dc.GetCurrentFont());
			LOGFONT lf;
			curFont.GetLogFont(&lf);
			lf.lfWeight = FW_BOLD;
			boldFont.CreateFontIndirect(&lf);
			OldFont.Attach((HFONT)::SelectObject(dc.m_hDC,&boldFont));
		}

		// If the item has its own color, replace text color (exception - color is black, and
		// the item is selected - then we leave the highlight text color)
		if (pItemData && (!bSelected || (bSelected && pItemData->crTextColor != RGB(0,0,0))))
		{
			dc.SetTextColor(pItemData->crTextColor);
		}

		// If we need to display columns - a bit more complicated...
		if (m_vecColumnWidth.size()>1)
		{
			CPen linePen;
			linePen.CreatePen(PS_SOLID, 0, RGB(192,192,192));
			CPen OldPen((HPEN)::SelectObject(dc,&linePen));

			int nCurX=0;
			for (int i=0; i<m_vecColumnWidth.size(); i++)
			{
				if (i!=m_vecColumnWidth.size()-1)
				{
					dc.MoveTo(rect.left+nCurX+m_vecColumnWidth[i],rect.top);
					dc.LineTo(rect.left+nCurX+m_vecColumnWidth[i],rect.bottom);
				}
				CRect rc(rect);
				rc.left=rect.left+nCurX+1;
				if (i!=m_vecColumnWidth.size()-1)
				{
					rc.right=rect.left+nCurX+m_vecColumnWidth[i];
				}
				else
				{
					rc.right = rect.right;
				}
				nCurX += m_vecColumnWidth[i];

				if (i==0)
				{
					dc.DrawText(str, -1, &rc, DT_LEFT|DT_SINGLELINE|DT_VCENTER);
				}
				else if (pItemData)
				{
					if (pItemData->mapStrings.find(i)!=pItemData->mapStrings.end())
					{
						dc.DrawText(pItemData->mapStrings[i], -1, &rc, DT_LEFT|DT_SINGLELINE|DT_VCENTER);
					}
				}
			}

			::SelectObject(dc,OldPen);
		}
		else
		{
			// Normal one column text display:
			dc.DrawText(str, -1, &rect, DT_LEFT|DT_SINGLELINE|DT_VCENTER);
		}

		if (pItemData && pItemData->bBold)
		{
			::SelectObject(dc,OldFont);
			boldFont.DeleteObject();
		}

		// Reset the background color and the text color back to their original values.
		dc.SetTextColor(crOldTextColor);
		dc.SetBkColor(crOldBkColor);

		dc.Detach();
		return ;
	}


	void DeleteItem(LPDELETEITEMSTRUCT lpDeleteItemStruct)
	{

		if (lpDeleteItemStruct->itemData)
		{
			ItemData* pItemData = (ItemData*)lpDeleteItemStruct->itemData;
			delete pItemData;
			lpDeleteItemStruct->itemData = NULL;
		}

		return ;
	}
	void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
	{

	}
	/*********************************************************************************************
	* 
	* @ChangesHistory
	********************************************************************************************/
	void SetItemBold(int nItemIndex,  BOOL bBold=TRUE)
	{
		ItemData* pItemData = GetOrCreateItemData(nItemIndex);
		if (pItemData)
		{
			pItemData->bBold = bBold;
			Invalidate();
		}
	}

	/*********************************************************************************************
	* 
	* @ChangesHistory
	********************************************************************************************/
	WTL::CString GetItemText(int nItemIndex,int nColumn)
	{
		if (0==nColumn)
		{
			WTL::CString str;
			GetLBText(nItemIndex, str);
			return str;
		}

		ItemData* pItemData = GetOrCreateItemData(nItemIndex);
		if (pItemData)
		{
			return pItemData->mapStrings[nColumn];
		}
		else
		{
			return "";
		}
	}

	/*********************************************************************************************
	* 
	* @ChangesHistory
	********************************************************************************************/
	void SetItemImage(int nItemIndex, int nImageIndex)
	{
		ItemData* pItemData = GetOrCreateItemData(nItemIndex);
		if (pItemData)
		{
			pItemData->nImageIndex = nImageIndex;
			Invalidate();
		}
	}

	/*********************************************************************************************
	* 
	* @ChangesHistory
	********************************************************************************************/
	void SetItemColor(int nItemIndex, COLORREF rcTextColor)
	{
		ItemData* pItemData = GetOrCreateItemData(nItemIndex);
		if (pItemData)
		{
			pItemData->crTextColor = rcTextColor;
			Invalidate();
		}
	}

	/*********************************************************************************************
	* 
	* @ChangesHistory
	********************************************************************************************/
	void SetItemText(int nItemIndex, int nColumn, CString str)
	{
		ItemData* pItemData = GetOrCreateItemData(nItemIndex);
		if (pItemData)
		{
			pItemData->mapStrings[nColumn] = str;
		}
	}

	/*********************************************************************************************
	* 
	* @ChangesHistory
	********************************************************************************************/
	void SetColumnWidth(int nColumnIndex, int nWidth)
	{
		if (nColumnIndex<0 || nColumnIndex>=m_vecColumnWidth.size()) return;

		m_vecColumnWidth[nColumnIndex] = nWidth;

		Invalidate();
	}
	
		/** Sets to TRUE for using the image list, of FALSE to disable the use of the image-list. */
	void SetUseImage(BOOL bUseImage=TRUE) { m_bUseImage=bUseImage; Invalidate(); }



	/** Sets the image list to use - will be show only if SetUseImage is called. */
	void SetImageList(CImageList* pImageList) { m_pImageList = pImageList; }
	void SetColumnCount(int nColumnCount )
	{
		int nPrevColumnCount = m_vecColumnWidth.size();
		m_vecColumnWidth.resize(nColumnCount);

		for (int i=nPrevColumnCount; i<m_vecColumnWidth.size(); i++)
		{
			m_vecColumnWidth[i] = DEFAULT_COLUMN_WIDTH;
		}

		Invalidate();
	}


	ItemData* GetOrCreateItemData(int nItemIndex)
	{
		if (nItemIndex<0 || nItemIndex>=GetCount()) return NULL;

		ItemData* pItemData = (ItemData*)(TBase::GetItemData(nItemIndex));

		if (NULL==pItemData)
		{
			pItemData = new ItemData;
			TBase::SetItemData(nItemIndex,(DWORD)(pItemData));
		}

		return pItemData;
	}

	};
	class CComboBoxSuper : public CComboBoxSuperImpl<CComboBoxSuper>
	{
	public:
		DECLARE_WND_SUPERCLASS(_T("WTL_ComboBoxSuper"), GetWndClassName())
	};

#endif // !defined(AFX_COLORCOMBO_H__20020314_DDA3_617F_0D88_0080AD509054__INCLUDED_)

⌨️ 快捷键说明

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