// XListCtrl.cpp Version 1.4 - article available at www.codeproject.com
//
// Author: Hans Dietrich
// hdietrich@gmail.com
//
// History
// Version 1.4 - 2006 September 1
// - See article for changes
//
// Version 1.3 - 2005 February 9
// - See article for changes
//
// Version 1.0 - 2002 February 4
// - Initial public release
//
// License:
// This software is released into the public domain. You are free to use
// it in any way you like, except that you may not sell this source code.
//
// This software is provided "as is" with no expressed or implied warranty.
// I accept no liability for any damage or loss of business that this
// software may cause.
//
///////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "XListCtrl.h"
#include "SortCStringArray.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
XLISTCTRLLIBDLLEXPORT UINT WM_XLISTCTRL_COMBO_SELECTION = ::RegisterWindowMessage(_T("WM_XLISTCTRL_COMBO_SELECTION"));
XLISTCTRLLIBDLLEXPORT UINT WM_XLISTCTRL_EDIT_END = ::RegisterWindowMessage(_T("WM_XLISTCTRL_EDIT_END"));
XLISTCTRLLIBDLLEXPORT UINT WM_XLISTCTRL_CHECKBOX_CLICKED = ::RegisterWindowMessage(_T("WM_XLISTCTRL_CHECKBOX_CLICKED"));
/////////////////////////////////////////////////////////////////////////////
// CXListCtrl
BEGIN_MESSAGE_MAP(CXListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CXListCtrl)
ON_NOTIFY_REFLECT_EX(NM_CLICK, OnClick)
ON_NOTIFY_REFLECT_EX(LVN_COLUMNCLICK, OnColumnClick)
ON_WM_CREATE()
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
ON_WM_DESTROY()
ON_WM_LBUTTONDOWN()
ON_WM_PAINT()
ON_WM_SYSCOLORCHANGE()
ON_WM_ERASEBKGND()
ON_WM_KEYDOWN()
ON_WM_RBUTTONDOWN()
ON_WM_NCLBUTTONDOWN()
//}}AFX_MSG_MAP
#ifndef DO_NOT_INCLUDE_XCOMBOLIST
ON_WM_TIMER()
ON_REGISTERED_MESSAGE(WM_XCOMBOLIST_VK_ESCAPE, OnComboEscape)
ON_REGISTERED_MESSAGE(WM_XCOMBOLIST_COMPLETE, OnComboComplete)
#endif
#ifndef NO_XLISTCTRL_TOOL_TIPS
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
#endif
ON_REGISTERED_MESSAGE(WM_XEDIT_KILL_FOCUS, OnXEditKillFocus)
ON_REGISTERED_MESSAGE(WM_XEDIT_VK_ESCAPE, OnXEditEscape)
END_MESSAGE_MAP()
///////////////////////////////////////////////////////////////////////////////
// ctor
CXListCtrl::CXListCtrl()
{
#ifndef DO_NOT_INCLUDE_XCOMBOLIST
m_bComboIsClicked = FALSE;
m_nComboItem = 0;
m_nComboSubItem = 0;
m_pCombo = NULL;
m_bFontIsCreated = FALSE;
#endif
m_dwExtendedStyleX = 0;
m_bHeaderIsSubclassed = FALSE;
m_bUseEllipsis = TRUE; //+++
m_bListModified = FALSE; //+++
m_bInitialCheck = FALSE;
m_strInitialString = _T("");
m_nPadding = 5; //+++
m_pEdit = NULL; //+++
m_nEditItem = 0; //+++
m_nEditSubItem = 0; //+++
GetColors();
}
///////////////////////////////////////////////////////////////////////////////
// dtor
CXListCtrl::~CXListCtrl()
{
#ifndef DO_NOT_INCLUDE_XCOMBOLIST
if (m_pCombo)
delete m_pCombo;
#endif
if (m_pEdit)
delete m_pEdit;
}
///////////////////////////////////////////////////////////////////////////////
// PreSubclassWindow
void CXListCtrl::PreSubclassWindow()
{
CListCtrl::PreSubclassWindow();
// for Dialog based applications, this is a good place
// to subclass the header control because the OnCreate()
// function does not get called.
SubclassHeaderControl();
}
///////////////////////////////////////////////////////////////////////////////
// OnCreate
int CXListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CListCtrl::OnCreate(lpCreateStruct) == -1)
{
ASSERT(FALSE);
return -1;
}
// When the CXListCtrl object is created via a call to Create(), instead
// of via a dialog box template, we must subclass the header control
// window here because it does not exist when the PreSubclassWindow()
// function is called.
SubclassHeaderControl();
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// SubclassHeaderControl
void CXListCtrl::SubclassHeaderControl()
{
if (m_bHeaderIsSubclassed)
return;
// if the list control has a header control window, then
// subclass it
// Thanks to Alberto Gattegno and Alon Peleg��and their article
// "A Multiline Header Control Inside a CListCtrl" for easy way
// to determine if the header control exists.
CHeaderCtrl* pHeader = GetHeaderCtrl();
if (pHeader)
{
VERIFY(m_HeaderCtrl.SubclassWindow(pHeader->m_hWnd));
m_bHeaderIsSubclassed = TRUE;
m_HeaderCtrl.SetListCtrl(this);
}
}
///////////////////////////////////////////////////////////////////////////////
// OnClick
BOOL CXListCtrl::OnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
XLISTCTRL_TRACE(_T("in CXListCtrl::OnClick\n"));
pNMHDR = pNMHDR;
*pResult = 0;
return FALSE; // return FALSE to send message to parent also -
// NOTE: MSDN documentation is incorrect
}
///////////////////////////////////////////////////////////////////////////////
// OnCustomDraw
void CXListCtrl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
// Take the default processing unless we set this to something else below.
*pResult = CDRF_DODEFAULT;
// First thing - check the draw stage. If it's the control's prepaint
// stage, then tell Windows we want messages for every item.
if (pLVCD->nmcd.dwDrawStage == CDDS_PREPAINT)
{
*pResult = CDRF_NOTIFYITEMDRAW;
}
else if (pLVCD->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
{
// This is the notification message for an item. We'll request
// notifications before each subitem's prepaint stage.
*pResult = CDRF_NOTIFYSUBITEMDRAW;
}
else if (pLVCD->nmcd.dwDrawStage == (CDDS_ITEMPREPAINT | CDDS_SUBITEM))
{
// This is the prepaint stage for a subitem. Here's where we set the
// item's text and background colors. Our return value will tell
// Windows to draw the subitem itself, but it will use the new colors
// we set here.
int nItem = static_cast<int> (pLVCD->nmcd.dwItemSpec);
int nSubItem = pLVCD->iSubItem;
XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) pLVCD->nmcd.lItemlParam;
ASSERT(pXLCD);
COLORREF crText = m_crWindowText;
COLORREF crBkgnd = m_crWindow;
if (pXLCD)
{
crText = pXLCD[nSubItem].crText;
crBkgnd = pXLCD[nSubItem].crBackground;
if (!pXLCD[0].bEnabled)
crText = m_crGrayText;
}
// store the colors back in the NMLVCUSTOMDRAW struct
pLVCD->clrText = crText;
pLVCD->clrTextBk = crBkgnd;
CDC* pDC = CDC::FromHandle(pLVCD->nmcd.hdc);
CRect rect;
GetSubItemRect(nItem, nSubItem, LVIR_BOUNDS, rect);
if (pXLCD && (pXLCD[nSubItem].bShowProgress))
{
DrawProgress(nItem, nSubItem, pDC, crText, crBkgnd, rect, pXLCD);
*pResult = CDRF_SKIPDEFAULT; // We've painted everything.
}
else if (pXLCD && (pXLCD[nSubItem].nCheckedState != -1))
{
DrawCheckbox(nItem, nSubItem, pDC, crText, crBkgnd, rect, pXLCD);
*pResult = CDRF_SKIPDEFAULT; // We've painted everything.
}
else
{
rect.left += DrawImage(nItem, nSubItem, pDC, crText, crBkgnd, rect, pXLCD);
DrawText(nItem, nSubItem, pDC, crText, crBkgnd, rect, pXLCD);
*pResult = CDRF_SKIPDEFAULT; // We've painted everything.
}
}
}
///////////////////////////////////////////////////////////////////////////////
// DrawProgress
void CXListCtrl::DrawProgress(int nItem,
int nSubItem,
CDC *pDC,
COLORREF crText,
COLORREF /*crBkgnd*/,
CRect& rect,
XLISTCTRLDATA *pXLCD)
{
UNUSED_ALWAYS(nItem);
XListCtrl_Demo
5星 · 超过95%的资源 需积分: 50 154 浏览量
2014-10-21
16:19:15
上传
评论 1
收藏 195KB ZIP 举报
凌乱哥
- 粉丝: 135
- 资源: 37
- 1
- 2
前往页