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

📄 listctrlex.cpp

📁 用Visual C++编写的查看磁盘信息的工具
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************\
* file   : ListCtrlEx.cpp
* created: 1997.09.22
*
* Zafir Anjum   - Original author.
* Mark Findlay  - IE4 fixes.
* Matthew Bells - Better TitleTips.
*
* description:
* A super CListControl.
* <P>features:
* <UL>
*   <LI>Title Tip item expantion
*   <LI>full row selection<BR>
*       <I>Note:</I> this is also a feature in IE 4.0 with
*       LVS_EX_FULLROWSELECT.
*   <LI>notifies parent selection has changed
*   <LI>supports column dragging (with IE4) which changes the column order
* </UL>
*
\******************************************************************************/
// ListCtrlEx.cpp : implementation of the CListCtrlEx class

#include "..\stdafx.h"
#include <assert.h>
#include "ListCtrlEx.h"

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

/////////////////////////////////////////////////////////////////////////////
// CListCtrlEx

IMPLEMENT_DYNCREATE(CListCtrlEx, CListCtrl)

BEGIN_MESSAGE_MAP(CListCtrlEx, CListCtrl)
	//{{AFX_MSG_MAP(CListCtrlEx)
	ON_WM_PAINT()
	ON_WM_SETFOCUS()
	ON_WM_KILLFOCUS()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_KEYDOWN()
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
	ON_MESSAGE(LVM_SETTEXTCOLOR, OnSetTextColor)
	ON_MESSAGE(LVM_SETTEXTBKCOLOR, OnSetTextBkColor)
	ON_MESSAGE(LVM_SETBKCOLOR, OnSetBkColor)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CListCtrlEx construction/destruction

CListCtrlEx::CListCtrlEx()
{
	m_bFullRowSel = TRUE;
	m_bClientWidthSel = FALSE;

	m_clrText = ::GetSysColor(COLOR_WINDOWTEXT);
	m_clrTextBk = ::GetSysColor(COLOR_WINDOW);
	m_clrBkgnd = ::GetSysColor(COLOR_WINDOW);
}

CListCtrlEx::~CListCtrlEx()
{
}

// Make sure the control is owner drawn
BOOL CListCtrlEx::PreCreateWindow(CREATESTRUCT& cs)
{
	// default is report view and full row selection
	cs.style &= ~LVS_TYPEMASK;
	cs.style |= LVS_REPORT | LVS_OWNERDRAWFIXED;
	//m_bFullRowSel = TRUE;

	return(CListCtrl::PreCreateWindow(cs));
}

BOOL CListCtrlEx::SetFullRowSel(BOOL bFullRowSel)
{
	// no painting during change
	LockWindowUpdate();

	m_bFullRowSel = bFullRowSel;

	BOOL bRet;

	if (m_bFullRowSel)
		bRet = ModifyStyle(0L, LVS_OWNERDRAWFIXED);
	else
		bRet = ModifyStyle(LVS_OWNERDRAWFIXED, 0L);

	// repaint window if we are not changing view type
	if (bRet && (GetStyle() & LVS_TYPEMASK) == LVS_REPORT)
		Invalidate();

	// repaint changes
	UnlockWindowUpdate();

	return(bRet);
}

BOOL CListCtrlEx::GetFullRowSel()
{
	return(m_bFullRowSel);
}

/////////////////////////////////////////////////////////////////////////////
// CListCtrlEx drawing

/*
* DrawItem() is called by the framework whenever an item needs to be drawn
* for owner drawn controls.
* Note:
* <UL>
*   <LI>LVS_SHOWSELALWAYS: non owner drawn controls show an item is
*     highlighted when the control does not have focus with a different
*     highlight color is (usually gray). This is not supported for
*     this control.
* </UL>
*/

void CListCtrlEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
	int iSavedDC = pDC->SaveDC();             // Save DC state
        
	int iItem = lpDrawItemStruct->itemID;

	// Get item image and state info
	LV_ITEM lvi;
	lvi.mask = LVIF_IMAGE | LVIF_STATE;
	lvi.iItem = iItem;
	lvi.iSubItem = 0;
	lvi.stateMask = 0xFFFF;		// get all state flags
	GetItem(&lvi);

	BOOL bHighlight = (
		(lvi.state & LVIS_DROPHILITED) ||
		((lvi.state & LVIS_SELECTED) && ((GetFocus() == this) || (GetStyle() & LVS_SHOWSELALWAYS)))
		);

	// Get rectangles for drawing
	CRect rcBounds;
	CRect rcLabel;
	CRect rcIcon;
	GetItemRect(iItem, rcBounds, LVIR_BOUNDS);
	GetItemRect(iItem, rcLabel, LVIR_LABEL);
	GetItemRect(iItem, rcIcon, LVIR_ICON);
	CRect rcItem(rcBounds);

	CString sLabel = GetItemText(iItem, 0);

	// Labels are offset by a certain amount  
	// This offset is related to the width of a space character
	int offset = pDC->GetTextExtent(_T(" "), 1 ).cx*2;

	rcBounds.left = rcLabel.left;
	CRect rcWnd;
	GetClientRect(&rcWnd);
	if(m_bClientWidthSel && rcBounds.right<rcWnd.right)
		rcBounds.right = rcWnd.right;

	// Draw the background
	if(bHighlight)
	{
		pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
		pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
		pDC->FillRect(rcBounds, &CBrush(::GetSysColor(COLOR_HIGHLIGHT)));
	}
	else
	{
		pDC->FillRect(rcBounds, &CBrush(m_clrTextBk));
	}

	// Set clip region
	rcItem.right = rcItem.left + GetColumnWidth(0);
/*
	CRgn rgn;
	rgn.CreateRectRgnIndirect(&rcItem);
	pDC->SelectClipRgn(&rgn);
	rgn.DeleteObject();
*/

	// Draw state icon
	if(lvi.state & LVIS_STATEIMAGEMASK)
	{
		int nImage = ((lvi.state & LVIS_STATEIMAGEMASK)>>12) - 1;
		CImageList* pImageList = GetImageList(LVSIL_STATE);
		if(pImageList)
		{
			pImageList->Draw(pDC, nImage,
				CPoint(rcItem.left, rcItem.top), ILD_TRANSPARENT);
		}
	}

	// Draw normal and overlay icon
	CImageList* pImageList = GetImageList(LVSIL_SMALL);
	if(pImageList)
	{
		/*UINT nOvlImageMask = lvi.state & LVIS_OVERLAYMASK;
		pImageList->Draw(pDC, lvi.iImage, 
			CPoint(rcIcon.left, rcIcon.top),
			(bHighlight?ILD_BLEND50:0) | ILD_TRANSPARENT | nOvlImageMask );*/

		//Do not draw overlay icon
		pImageList->Draw(pDC, lvi.iImage, 
			CPoint(rcIcon.left, rcIcon.top),ILD_TRANSPARENT);
	}

	// Draw item label - Column 0
	rcLabel.left += offset/2-1;
	rcLabel.right -= offset;
	pDC->DrawText(sLabel,-1,rcLabel,DT_LEFT | DT_SINGLELINE | DT_NOPREFIX
		| DT_VCENTER | DT_END_ELLIPSIS);

	// Draw labels for remaining columns
	LV_COLUMN lvc;
	lvc.mask = LVCF_FMT | LVCF_WIDTH;

/*
// set clip region
 	rcBounds.right = rcHighlight.right > rcBounds.right ? rcHighlight.right :
	rcBounds.right;
	rgn.CreateRectRgnIndirect(&rcBounds);
	pDC->SelectClipRgn(&rgn);
*/
	for(int nColumn = 1; GetColumn(nColumn, &lvc); nColumn++)
	{
		rcItem.left = rcItem.right;
		rcItem.right += lvc.cx;

		sLabel = GetItemText(iItem, nColumn);

		// Get the text justification
		UINT nJustify = DT_LEFT;
		switch(lvc.fmt & LVCFMT_JUSTIFYMASK)
		{
		case LVCFMT_RIGHT:
			nJustify = DT_RIGHT;
			break;
		case LVCFMT_CENTER:
			nJustify = DT_CENTER;
			break;
		default:
			break;
		}

		rcLabel = rcItem;
		rcLabel.left += offset;
		rcLabel.right -= offset;

		pDC->DrawText(sLabel, -1, rcLabel,
			nJustify | DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER | DT_END_ELLIPSIS);
	}

	// draw focus rectangle if item has focus
	if ((lvi.state & LVIS_FOCUSED) && (GetFocus() == this))
		pDC->DrawFocusRect(rcBounds);

	pDC->RestoreDC(iSavedDC);                 // Restore DC.
}

/////////////////////////////////////////////////////////////////////////////
// CListCtrlEx diagnostics

#ifdef _DEBUG

void CListCtrlEx::Dump(CDumpContext& dc) const
{
	CListCtrl::Dump(dc);

	dc << "m_bFullRowSel = " << m_bFullRowSel;
	dc << "\n";
}

#endif //_DEBUG


/**
* @param iRow    [in] row of cell
* @param iColunm [in] column of cell
* @return Rectangle corresponding to the given cell.
*/

CRect CListCtrlEx::GetCellRect(int iRow, int iColumn)const
{
	// Make sure that the ListView is in LVS_REPORT
	if((GetStyle() & LVS_TYPEMASK) != LVS_REPORT)
		return CRect(0,0,0,0);

	// Get the number of columns
	{
		CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
		int iColumnCount = pHeader->GetItemCount();
		assert(iColumn < iColumnCount);
	}

	CRect rect;
	GetItemRect(iRow, &rect, LVIR_BOUNDS);
	// Now find the column
	for(int colnum = 0; colnum < iColumn; colnum++)
	{
		rect.left += GetTrueColumnWidth(colnum);
	}

	// Found the column
	rect.right = rect.left + GetTrueColumnWidth(iColumn);

	RECT rectClient;
	GetClientRect(&rectClient);
	if(rect.right > rectClient.right)
		rect.right = rectClient.right;

	return rect;
}

/**

⌨️ 快捷键说明

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