📄 comboboxsuper.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 + -