📄 listviewex.cpp
字号:
// CListViewEx.cpp : implementation file
#include "stdafx.h"
#include "ListViewEx.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CListViewEx
CListViewEx::CListViewEx()
{
}
CListViewEx::~CListViewEx()
{
}
BEGIN_MESSAGE_MAP(CListViewEx, CListView)
//{{AFX_MSG_MAP(CListViewEx)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CListViewEx drawing
void CListViewEx::OnDraw(CDC* pDC)
{
}
/////////////////////////////////////////////////////////////////////////////
// CListViewEx diagnostics
#ifdef _DEBUG
void CListViewEx::AssertValid() const
{
CListView::AssertValid();
}
void CListViewEx::Dump(CDumpContext& dc) const
{
CListView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CListViewEx message handlers
// FUNCTION: DrawListViewItem(const LPDRAWITEMSTRUCT)
//
// PURPOSE: Draws one item in the listview control.
//
// PARAMETERS:
// lpDrawItem - Pointer to the information needed to draw the item. The
// item number is in the itemID member.
//
void CListViewEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItem)
{
HIMAGELIST himl;
LV_ITEM lvi;
int cxImage = 0, cyImage = 0;
UINT uFirstColWidth;
RECT rcClip;
int iColumn = 1;
UINT uiFlags = ILD_TRANSPARENT;
CListCtrl& lc = GetListCtrl();
ASSERT(lc.GetSafeHwnd() == lpDrawItem->hwndItem);
// Get the item image to be displayed
lvi.mask = LVIF_IMAGE | LVIF_STATE | LVIF_PARAM;
lvi.iItem = lpDrawItem->itemID;
lvi.iSubItem = 0;
lc.GetItem(&lvi);
// Check to see if this item is selected
if (lpDrawItem->itemState & ODS_SELECTED)
{
// Set the text background and foreground colors
SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
SetBkColor(lpDrawItem->hDC, GetSysColor(COLOR_HIGHLIGHT));
// Also add the ILD_BLEND50 so the images come out selected
uiFlags |= ILD_BLEND50;
}
else
{
// Set the text background and foreground colors to the standard window
// colors
SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOWTEXT));
SetBkColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOW));
}
// Get the image list and draw the image
himl = lc.GetImageList(LVSIL_SMALL)->GetSafeHandle();
if (himl)
{
ImageList_Draw(himl, lvi.iImage, lpDrawItem->hDC,
lpDrawItem->rcItem.left, lpDrawItem->rcItem.top,
uiFlags);
// Find out how big the image we just drew was
ImageList_GetIconSize(himl, &cxImage, &cyImage);
}
// Calculate the width of the first column after the image width. If
// There was no image, then cxImage will be zero.
uFirstColWidth = lc.GetColumnWidth(0) - cxImage;
// Set up the new clipping rect for the first column text and draw it
rcClip.left = lpDrawItem->rcItem.left + cxImage;
rcClip.right = lpDrawItem->rcItem.left + lc.GetColumnWidth(0);
rcClip.top = lpDrawItem->rcItem.top;
rcClip.bottom = lpDrawItem->rcItem.bottom;
DrawItemColumn(lpDrawItem->hDC, GetColumnText(0, lvi.lParam), &rcClip);
CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
ASSERT(pHeader);
int nColumns = pHeader->GetItemCount();
// Update the clip rect to the nth column
for( int i = 1; i < nColumns; i++ )
{
rcClip.left = rcClip.right;
rcClip.right = rcClip.left + lc.GetColumnWidth(i);
DrawItemColumn(lpDrawItem->hDC, GetColumnText(i, lvi.lParam), &rcClip);
}
// If we changed the colors for the selected item, undo it
if (lpDrawItem->itemState & ODS_SELECTED)
{
// Set the text background and foreground colors
SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOWTEXT));
SetBkColor(lpDrawItem->hDC, GetSysColor(COLOR_WINDOW));
}
// If the item is focused, now draw a focus rect around the entire row
if (lpDrawItem->itemState & ODS_FOCUS)
{
// Adjust the left edge to exclude the image
rcClip = lpDrawItem->rcItem;
rcClip.left += cxImage;
// Draw the focus rect
DrawFocusRect(lpDrawItem->hDC, &rcClip);
}
}
// FUNCTION: DrawItemColumn(HDC, LPTSTR, LPRECT)
//
// PURPOSE: Draws the text for one of the columns in the list view.
//
// PARAMETERS:
// hdc - Handle of the DC to draw the text into.
// lpsz - String to draw.
// prcClip - Rectangle to clip the string to.
//
void CListViewEx::DrawItemColumn(HDC hdc, LPCTSTR lpsz, LPRECT prcClip)
{
TCHAR szString[256];
// Check to see if the string fits in the clip rect. If not, truncate
// the string and add "...".
lstrcpy(szString, lpsz);
CalcStringEllipsis(hdc, szString, 256, prcClip->right - prcClip->left);
// print the text
ExtTextOut(hdc, prcClip->left + 2, prcClip->top + 1, ETO_CLIPPED | ETO_OPAQUE,
prcClip, szString, lstrlen(szString), NULL);
}
// FUNCTION: CalcStringEllipsis(HDC, LPTSTR, int, UINT)
//
// PURPOSE: Determines whether the specified string is too wide to fit in
// an allotted space, and if not truncates the string and adds some
// points of ellipsis to the end of the string.
//
// PARAMETERS:
// hdc - Handle of the DC the string will be drawn on.
// lpszString - Pointer to the string to verify
// cchMax - Maximum size of the lpszString buffer.
// uColWidth - Width of the space in pixels to fit the string into.
//
// RETURN VALUE:
// Returns TRUE if the string needed to be truncated, or FALSE if it fit
// into uColWidth.
//
BOOL CListViewEx::CalcStringEllipsis(HDC hdc, LPTSTR lpszString, int cchMax, UINT uColWidth)
{
const TCHAR szEllipsis[] = TEXT("...");
SIZE sizeString;
SIZE sizeEllipsis;
int cbString;
LPTSTR lpszTemp;
BOOL fSuccess = FALSE;
static BOOL fOnce = TRUE;
static FARPROC pGetTextExtentPoint;
// Adjust the column width to take into account the edges
uColWidth -= 4;
__try
{
// Allocate a string for us to work with. This way we can mangle the
// string and still preserve the return value
lpszTemp = (LPTSTR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cchMax);
if (!lpszTemp)
{
//ErrorHandler();
__leave;
}
lstrcpy(lpszTemp, lpszString);
// Get the width of the string in pixels
cbString = lstrlen(lpszTemp);
if (!GetTextExtentPoint32(hdc, lpszTemp, cbString, &sizeString))
{
//ErrorHandler();
__leave;
}
// If the width of the string is greater than the column width shave
// the string and add the ellipsis
if ((ULONG)sizeString.cx > uColWidth)
{
if (!GetTextExtentPoint32(hdc, szEllipsis, lstrlen(szEllipsis),
&sizeEllipsis))
{
//ErrorHandler();
__leave;
}
while (cbString > 0)
{
lpszTemp[--cbString] = 0;
if (!GetTextExtentPoint32(hdc, lpszTemp, cbString, &sizeString))
{
//ErrorHandler();
__leave;
}
if ((ULONG)(sizeString.cx + sizeEllipsis.cx) <= uColWidth)
{
// The string with the ellipsis finally fits, now make sure
// there is enough room in the string for the ellipsis
if (cchMax >= (cbString + lstrlen(szEllipsis)))
{
// Concatenate the two strings and break out of the loop
lstrcat(lpszTemp, szEllipsis);
lstrcpy(lpszString, lpszTemp);
fSuccess = TRUE;
__leave;
}
}
}
}
else
{
// No need to do anything, everything fits great.
fSuccess = TRUE;
}
}
__finally
{
// Free the memory
HeapFree(GetProcessHeap(), 0, (LPVOID)lpszTemp);
return (fSuccess);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -