📄 listviewctrlex.cpp
字号:
/******************************************************************************
$Author$
$Modtime$
$Revision$
Description: Implementation of class "CListBase"
(list control with sort icons and colored sort column)
$Log$
******************************************************************************/
#include "stdafx.h"
#include "ListViewCtrlEx.h"
#include "Resource.h"
/*** Definition of class "CListCtrlEx" ***************************************/
IMPLEMENT_DYNCREATE(CListCtrlEx, CListCtrl)
/*** Public member functions *************************************************/
/*** A column header has been clicked ****************************************/
BOOL CListCtrlEx::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
{
return CListBase::OnColumnclick(pNMHDR, pResult);
}
/*** Protected member functions **********************************************/
/*** A list view (sub)item will be drawn *************************************/
void CListCtrlEx::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
CListBase::OnCustomDraw(pNMHDR, pResult);
}
/*** The background will be erased *******************************************/
BOOL CListCtrlEx::OnEraseBkgnd(CDC* pDC)
{
if (CListBase::OnEraseBkgnd(pDC))
return TRUE;
else
return CListCtrl::OnEraseBkgnd(pDC);
}
/*** List control has been scrolled horizontally *****************************/
void CListCtrlEx::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
CListCtrl::OnHScroll (nSBCode, nPos, pScrollBar);
InvalidateNonItemArea();
}
/*** A key has been pressed *************************************************/
void CListCtrlEx::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (!CListBase::OnKeyDown(nChar))
CListCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
}
/*** A key has been released *************************************************/
void CListCtrlEx::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CListBase::OnKeyUp(nChar);
CListCtrl::OnKeyUp(nChar, nRepCnt, nFlags);
}
/*** List control loses input focus ******************************************/
void CListCtrlEx::OnKillFocus(CWnd* pNewWnd)
{
CListCtrl::OnKillFocus(pNewWnd);
CListBase::OnKillFocus();
}
/*** The user double-clicks the left mouse button ****************************/
void CListCtrlEx::OnLButtonDblClk(UINT nFlags, CPoint point)
{
if (!CListBase::OnLButtonDblClk(point))
CListCtrl::OnLButtonDblClk(nFlags, point);
}
/*** The user presses the left mouse button **********************************/
void CListCtrlEx::OnLButtonDown(UINT nFlags, CPoint point)
{
if (!CListBase::OnLButtonDown(point))
CListCtrl::OnLButtonDown(nFlags, point);
}
/*** Divider in header control has been dragged ******************************/
BOOL CListCtrlEx::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
BOOL bRet = CListCtrl::OnNotify(wParam, lParam, pResult);
if (CListBase::OnNotify(lParam)) return TRUE; else return bRet;
}
/*** List control gains input focus ******************************************/
void CListCtrlEx::OnSetFocus(CWnd* pOldWnd)
{
CListCtrl::OnSetFocus(pOldWnd);
CListBase::OnSetFocus();
}
/*** System colors have been changed *****************************************/
void CListCtrlEx::OnSysColorChange()
{
CListCtrl::OnSysColorChange();
CListBase::OnSysColorChange();
}
/*** Table of message handlers ***********************************************/
BEGIN_MESSAGE_MAP(CListCtrlEx, CListCtrl)
//{{AFX_MSG_MAP(CListCtrlEx)
ON_WM_SYSCOLORCHANGE()
ON_WM_ERASEBKGND()
ON_WM_HSCROLL()
ON_WM_KILLFOCUS()
ON_WM_SETFOCUS()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONDBLCLK()
ON_WM_KEYDOWN()
ON_WM_KEYUP()
//}}AFX_MSG_MAP
ON_NOTIFY_REFLECT_EX(LVN_COLUMNCLICK, OnColumnclick)
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
END_MESSAGE_MAP()
/*** Definition of class "CListViewEx" ***************************************/
IMPLEMENT_DYNCREATE(CListViewEx, CListView)
/*** Protected member functions **********************************************/
/*** A column header has been clicked ****************************************/
BOOL CListViewEx::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
{
return CListBase::OnColumnclick(pNMHDR, pResult);
}
/*** A list view (sub)item will be drawn *************************************/
void CListViewEx::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
CListBase::OnCustomDraw(pNMHDR, pResult);
}
/*** The background will be erased *******************************************/
BOOL CListViewEx::OnEraseBkgnd(CDC* pDC)
{
if (CListBase::OnEraseBkgnd(pDC))
return TRUE;
else
return CListView::OnEraseBkgnd(pDC);
}
/*** List control has been scrolled horizontally *****************************/
void CListViewEx::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
CListView::OnHScroll (nSBCode, nPos, pScrollBar);
InvalidateNonItemArea();
}
/*** A key has been pressed *************************************************/
void CListViewEx::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (!CListBase::OnKeyDown(nChar))
CListView::OnKeyDown(nChar, nRepCnt, nFlags);
}
/*** A key has been released *************************************************/
void CListViewEx::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CListBase::OnKeyUp(nChar);
CListView::OnKeyUp(nChar, nRepCnt, nFlags);
}
/*** List control loses input focus ******************************************/
void CListViewEx::OnKillFocus(CWnd* pNewWnd)
{
CListView::OnKillFocus(pNewWnd);
CListBase::OnKillFocus();
}
/*** The user double-clicks the left mouse button ****************************/
void CListViewEx::OnLButtonDblClk(UINT nFlags, CPoint point)
{
if (!CListBase::OnLButtonDblClk(point))
CListView::OnLButtonDblClk(nFlags, point);
}
/*** The user presses the left mouse button **********************************/
void CListViewEx::OnLButtonDown(UINT nFlags, CPoint point)
{
if (!CListBase::OnLButtonDown(point))
CListView::OnLButtonDown(nFlags, point);
}
/*** Divider in header control has been dragged ******************************/
BOOL CListViewEx::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
BOOL bRet = CListView::OnNotify(wParam, lParam, pResult);
if (CListBase::OnNotify(lParam)) return TRUE; else return bRet;
}
/*** List control gains input focus ******************************************/
void CListViewEx::OnSetFocus(CWnd* pOldWnd)
{
CListView::OnSetFocus(pOldWnd);
CListBase::OnSetFocus();
}
/*** System colors have been changed *****************************************/
void CListViewEx::OnSysColorChange()
{
CListView::OnSysColorChange();
CListBase::OnSysColorChange();
}
/*** Table of message handlers ***********************************************/
BEGIN_MESSAGE_MAP(CListViewEx, CListView)
//{{AFX_MSG_MAP(CListViewEx)
ON_WM_SYSCOLORCHANGE()
ON_WM_ERASEBKGND()
ON_WM_HSCROLL()
ON_WM_KILLFOCUS()
ON_WM_SETFOCUS()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONDBLCLK()
ON_WM_KEYDOWN()
ON_WM_KEYUP()
//}}AFX_MSG_MAP
ON_NOTIFY_REFLECT_EX(LVN_COLUMNCLICK, OnColumnclick)
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
END_MESSAGE_MAP()
/*** Definition of "workhorse" class "CListBase" *****************************/
const int CListBase::m_nFirstColXOff = 2; // x-offset of first column
const int CListBase::m_nNextColXOff = 6; // x-offset of other columns
const int CListBase::m_nIconXOff = 4; // x-offset of icon
/*** Public member functions *************************************************/
/*** Enable or disable coloring of sort column *******************************/
#if _MSC_VER == 1300
#pragma runtime_checks("c", off) // due to a flaw in the definition of
#endif // Get[R|G|B]Value
void CListBase::ColorSortColumn(bool bEnable)
{
ASSERT(m_pListCtrl);
if (bEnable == m_bColorSortColumn) return;
m_bColorSortColumn = bEnable;
if (bEnable) //开启排序列颜色模式.
{
DWORD dwColNormalColor = m_pListCtrl->GetBkColor();
// emulate sort column coloring of Windows XP explorer
//根据当前控件背景色的RGB值,调整排序列颜色值.
UINT nRed = GetRValue(dwColNormalColor);
UINT nGreen = GetGValue(dwColNormalColor);
UINT nBlue = GetBValue(dwColNormalColor);
/*
if (nRed > 240 && nGreen > 240 && nBlue > 240)
{
nRed -= 8;
nGreen -= 8;
nBlue -= 8;
}
else
{
if (nRed < 232) nRed += nRed / 10; else nRed = 255;
if (nGreen < 232) nGreen += nGreen / 10; else nGreen = 255;
if (nBlue < 232) nBlue += nBlue / 10; else nBlue = 255;
}
*/
m_dwColSortColor = RGB(nRed, nGreen, nBlue);
}
}
#if _MSC_VER == 1300
#pragma runtime_checks("c", restore)
#endif
/*** Draw the entire item (called if window has style LVS_OWNERDRAWFIXED) ****/
void CListBase::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
ASSERT(m_pListCtrl);
LVITEM* pItem = GetLVITEM(lpDrawItemStruct->itemID);
bool bAlwaysSelected = pItem->state & LVIS_SELECTED &&
(m_pListCtrl->GetStyle() & LVS_SHOWSELALWAYS) != 0;
bool bLVHasFocus = m_pListCtrl->GetFocus() == m_pListCtrl;
bool bItemHasFocus = pItem->state & LVIS_FOCUSED && bLVHasFocus;
bool bSelected = pItem->state & LVIS_SELECTED && bLVHasFocus;
bool bFullRowSelected =
(m_pListCtrl->GetExtendedStyle() & LVS_EX_FULLROWSELECT) != 0;
CRect rcItem; // rectangle bounding complete item
m_pListCtrl->GetItemRect(pItem->iItem, rcItem, LVIR_BOUNDS);
CRect rcSubItem0; // rectangle bounding subitem 0
GetRealSubItemRect(pItem->iItem, 0, LVIR_BOUNDS, rcSubItem0);
CRect rcLabel; // rectangle bounding item label
GetRealSubItemRect(pItem->iItem, 0, LVIR_LABEL, rcLabel);
CRect rcSelection; // rectangle bounding selection
if (bFullRowSelected)
{
rcSelection = rcItem;
if (IndexToOrder(0) == 0 || m_bKeepLabelLeft)
{
rcSelection.left = rcLabel.left;
int nWidthOfCol0 = m_pListCtrl->GetColumnWidth(OrderToIndex(0));
if (rcSelection.left > nWidthOfCol0) rcSelection.left = nWidthOfCol0;
}
}
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CBrush brushHiLite;
DWORD dwNormalText = GetSysColor(COLOR_WINDOWTEXT);
DWORD dwHiLiteBk = 0;
if (bSelected)
{
dwHiLiteBk = GetSysColor(COLOR_HIGHLIGHT);
brushHiLite.CreateSolidBrush(dwHiLiteBk);
}
else if (bAlwaysSelected)
{
dwHiLiteBk = GetSysColor(COLOR_3DFACE);
brushHiLite.CreateSolidBrush(dwHiLiteBk);
}
LVCOLUMN lvc;
lvc.mask = LVCF_FMT | LVCF_WIDTH;
// display all subitems
int nIndex;
for (int nColumn = 0;
m_pListCtrl->GetColumn(nIndex = OrderToIndex(nColumn), &lvc);
nColumn++)
{
LVITEM* pSubItem = nIndex > 0 ? GetLVITEM(pItem->iItem, nIndex) : pItem;
CRect rcSubItem; // rectangle bounding subitem
CRect rcText; // output rectangle
DWORD dwBkColor = // background color of curremt column
nIndex+1 == abs(m_nSortColumn) ?
m_dwColSortColor : m_pListCtrl->GetBkColor();
CBrush brushBk(dwBkColor);
// consider column margins
if (nColumn > 0)
{
// move output rectangle over next column
rcSubItem.left = rcSubItem.right;
rcSubItem.right += lvc.cx;
}
else
{
rcSubItem = rcItem;
rcSubItem.right = rcSubItem.left + lvc.cx;
}
if (nIndex == 0 && !m_bKeepLabelLeft || nColumn == 0 && m_bKeepLabelLeft)
{
rcText = rcLabel;
rcText.left += m_nFirstColXOff;
rcText.right -= nIndex > 0 ? m_nNextColXOff : m_nFirstColXOff;
}
else
{
rcText = rcSubItem;
rcText.left += m_nNextColXOff;
rcText.right -= m_nNextColXOff;
}
int nLabelWidth = GetLabelWidth(pDC, pSubItem, rcText.Width());
bool bHiLite = false;
if (bSelected || bAlwaysSelected || bItemHasFocus && !bFullRowSelected)
if (nIndex == 0 && nColumn != 0 && !m_bKeepLabelLeft && !bFullRowSelected
||
nColumn == 0 && (m_bKeepLabelLeft || nIndex == 0))
{
// calculate selection area
CRect rcSubItemSelection(rcLabel);
if (!bFullRowSelected)
{
int nFormat = nIndex == 0 && nColumn == 0 || !m_bKeepLabelLeft ?
m_nFormatOfSubItem0 : lvc.fmt & LVCFMT_JUSTIFYMASK;
switch (nFormat)
{
case LVCFMT_LEFT:
rcSubItemSelection.right =
rcSubItemSelection.left +
m_nFirstColXOff + nLabelWidth + m_nNextColXOff;
break;
case LVCFMT_RIGHT:
rcSubItemSelection.left =
rcSubItemSelection.right -
m_nFirstColXOff - nLabelWidth - m_nNextColXOff;
break;
case LVCFMT_CENTER:
{
int nSelectionWidth =
m_nNextColXOff + nLabelWidth + m_nNextColXOff;
rcSubItemSelection.left =
rcLabel.left + (rcLabel.Width() - nSelectionWidth) / 2;
rcSubItemSelection.right =
rcSubItemSelection.left + nSelectionWidth;
break;
}
default:
ASSERT(false);
break;
}
if (rcSubItemSelection.left < rcLabel.left)
rcSubItemSelection.left = rcLabel.left;
if (rcSubItemSelection.right > rcLabel.right)
rcSubItemSelection.right = rcLabel.right;
rcSelection = rcSubItemSelection;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -