📄 xlistctrl.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
// DrawImage
int CXListCtrl::DrawImage(int nItem,
int nSubItem,
CDC* pDC,
COLORREF crText,
COLORREF crBkgnd,
CRect rect,
XLISTCTRLDATA *pXLCD)
{
if (rect.IsRectEmpty())
{
return 0;
}
GetDrawColors(nItem, nSubItem, crText, crBkgnd);
pDC->FillSolidRect(&rect, crBkgnd);
int nWidth = 0;
rect.left += m_HeaderCtrl.GetSpacing();
CImageList* pImageList = GetImageList(LVSIL_SMALL);
if (pImageList)
{
SIZE sizeImage;
sizeImage.cx = sizeImage.cy = 0;
IMAGEINFO info;
int nImage = -1;
if (pXLCD)
nImage = pXLCD[nSubItem].nImage;
if (nImage == -1)
return 0;
if (pImageList->GetImageInfo(nImage, &info))
{
sizeImage.cx = info.rcImage.right - info.rcImage.left;
sizeImage.cy = info.rcImage.bottom - info.rcImage.top;
}
if (nImage >= 0)
{
if (rect.Width() > 0)
{
POINT point;
point.y = rect.CenterPoint().y - (sizeImage.cy >> 1);
point.x = rect.left;
SIZE size;
size.cx = rect.Width() < sizeImage.cx ? rect.Width() : sizeImage.cx;
size.cy = rect.Height() < sizeImage.cy ? rect.Height() : sizeImage.cy;
// save image list background color
COLORREF rgb = pImageList->GetBkColor();
// set image list background color
pImageList->SetBkColor(crBkgnd);
pImageList->DrawIndirect(pDC, nImage, point, size, CPoint(0, 0));
pImageList->SetBkColor(rgb);
nWidth = sizeImage.cx + m_HeaderCtrl.GetSpacing();
}
}
}
return nWidth;
}
///////////////////////////////////////////////////////////////////////////////
// DrawText
void CXListCtrl::DrawText(int nItem,
int nSubItem,
CDC *pDC,
COLORREF crText,
COLORREF crBkgnd,
CRect& rect,
XLISTCTRLDATA *pXLCD)
{
ASSERT(pDC);
ASSERT(pXLCD);
if (rect.IsRectEmpty())
{
return;
}
GetDrawColors(nItem, nSubItem, crText, crBkgnd);
pDC->FillSolidRect(&rect, crBkgnd);
CString str;
str = GetItemText(nItem, nSubItem);
if (!str.IsEmpty())
{
// get text justification
HDITEM hditem;
hditem.mask = HDI_FORMAT;
m_HeaderCtrl.GetItem(nSubItem, &hditem);
int nFmt = hditem.fmt & HDF_JUSTIFYMASK;
UINT nFormat = DT_VCENTER | DT_SINGLELINE;
if (m_bUseEllipsis) //+++
nFormat |= DT_END_ELLIPSIS;
if (nFmt == HDF_CENTER)
nFormat |= DT_CENTER;
else if (nFmt == HDF_LEFT)
nFormat |= DT_LEFT;
else
nFormat |= DT_RIGHT;
CFont *pOldFont = NULL;
CFont boldfont;
// check if bold specified for subitem
if (pXLCD && pXLCD[nSubItem].bBold)
{
CFont *font = pDC->GetCurrentFont();
if (font)
{
LOGFONT lf;
font->GetLogFont(&lf);
lf.lfWeight = FW_BOLD;
boldfont.CreateFontIndirect(&lf);
pOldFont = pDC->SelectObject(&boldfont);
}
}
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(crText);
pDC->SetBkColor(crBkgnd);
rect.DeflateRect(m_nPadding, 0); //+++
pDC->DrawText(str, &rect, nFormat);
rect.InflateRect(m_nPadding, 0); //+++
if (pOldFont)
pDC->SelectObject(pOldFont);
}
}
///////////////////////////////////////////////////////////////////////////////
// GetSubItemRect
BOOL CXListCtrl::GetSubItemRect(int nItem,
int nSubItem,
int nArea,
CRect& rect)
{
ASSERT(nItem >= 0);
ASSERT(nItem < GetItemCount());
if ((nItem < 0) || nItem >= GetItemCount())
return FALSE;
ASSERT(nSubItem >= 0);
ASSERT(nSubItem < GetColumns());
if ((nSubItem < 0) || nSubItem >= GetColumns())
return FALSE;
BOOL bRC = CListCtrl::GetSubItemRect(nItem, nSubItem, nArea, rect);
// if nSubItem == 0, the rect returned by CListCtrl::GetSubItemRect
// is the entire row, so use left edge of second subitem
if (nSubItem == 0)
{
if (GetColumns() > 1)
{
CRect rect1;
bRC = GetSubItemRect(nItem, 1, LVIR_BOUNDS, rect1);
rect.right = rect1.left;
}
}
//+++
if (nSubItem == 0)
{
if (GetColumns() > 1)
{
CRect rect1;
// in case 2nd col width = 0
for (int i = 1; i < GetColumns(); i++)
{
bRC = GetSubItemRect(nItem, i, LVIR_BOUNDS, rect1);
if (rect1.Width() > 0)
{
rect.right = rect1.left;
break;
}
}
}
}
return bRC;
}
///////////////////////////////////////////////////////////////////////////////
// OnLButtonDown
void CXListCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
//XLISTCTRL_TRACE(_T("in CXListCtrl::OnLButtonDown\n"));
int nItem = -1;
//+++
LVHITTESTINFO lvhit;
lvhit.pt = point;
SubItemHitTest(&lvhit);
if (lvhit.flags & LVHT_ONITEMLABEL)
{
// XLISTCTRL_TRACE(_T("lvhit.iItem=%d lvhit.iSubItem=%d ~~~~~\n"), lvhit.iItem, lvhit.iSubItem);
nItem = lvhit.iItem;
}
if (nItem == -1)
{
#ifndef DO_NOT_INCLUDE_XCOMBOLIST
if (m_pCombo)
OnComboEscape(0, 0);
#endif
}
else
{
XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) CListCtrl::GetItemData(nItem);
if (!pXLCD)
{
return;
}
if (!pXLCD[0].bEnabled)
return;
CRect rect;
int nSubItem = -1;
// check if a subitem checkbox was clicked
for (int i = 0; i < GetColumns(); i++)
{
GetSubItemRect(nItem, i, LVIR_BOUNDS, rect);
if (rect.PtInRect(point))
{
nSubItem = i;
break;
}
}
if (nSubItem == -1)
{
// -1 = no checkbox for this subitem
#ifndef DO_NOT_INCLUDE_XCOMBOLIST
if (m_pCombo)
{
OnComboEscape(0, 0);
}
#endif
}
else
{
if (pXLCD[nSubItem].nCheckedState >= 0)
{
int nChecked = pXLCD[nSubItem].nCheckedState;
nChecked = (nChecked == 0) ? 1 : 0;
pXLCD[nSubItem].nCheckedState = nChecked;
pXLCD[nSubItem].bModified = TRUE;
m_bListModified = TRUE;
UpdateSubItem(nItem, nSubItem);
CWnd *pWnd = GetParent();
if (!pWnd)
pWnd = GetOwner();
if (pWnd && ::IsWindow(pWnd->m_hWnd))
pWnd->SendMessage(WM_XLISTCTRL_CHECKBOX_CLICKED,
nItem, nSubItem);
// now update checkbox in header
// -1 = no checkbox in column header
if (GetHeaderCheckedState(nSubItem) != XHEADERCTRL_NO_IMAGE)
{
int nCheckedCount = CountCheckedItems(nSubItem);
if (nCheckedCount == GetItemCount())
SetHeaderCheckedState(nSubItem, XHEADERCTRL_CHECKED_IMAGE);
else
SetHeaderCheckedState(nSubItem, XHEADERCTRL_UNCHECKED_IMAGE);
}
}
else if (pXLCD[nSubItem].bCombo)
{
CListCtrl::OnLButtonDown(nFlags, point);
DrawComboBox(nItem, nSubItem);
}
else if (pXLCD[nSubItem].bEdit)
{
CListCtrl::OnLButtonDown(nFlags, point);
DrawEdit(nItem, nSubItem);
}
}
}
CListCtrl::OnLButtonDown(nFlags, point);
}
///////////////////////////////////////////////////////////////////////////////
// OnRButtonDown - added so we can ignore disabled items
void CXListCtrl::OnRButtonDown(UINT nFlags, CPoint point)
{
// XLISTCTRL_TRACE(_T("in CXListCtrl::OnRButtonDown\n"));
int nItem = -1;
//+++
LVHITTESTINFO lvhit;
lvhit.pt = point;
SubItemHitTest(&lvhit);
if (lvhit.flags & LVHT_ONITEMLABEL)
{
// XLISTCTRL_TRACE(_T("lvhit.iItem=%d lvhit.iSubItem=%d ~~~~~\n"), lvhit.iItem, lvhit.iSubItem);
nItem = lvhit.iItem;
}
if (nItem != -1)
{
XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) CListCtrl::GetItemData(nItem);
if (!pXLCD)
{
return;
}
if (!pXLCD[0].bEnabled)
return;
}
CListCtrl::OnRButtonDown(nFlags, point);
}
///////////////////////////////////////////////////////////////////////////////
// OnNcLButtonDown
void CXListCtrl::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
TRACE(_T("in CXListCtrl::OnNcLButtonDown\n"));
if (m_pEdit)
{
OnXEditKillFocus(0, 0);
}
CListCtrl::OnNcLButtonDown(nHitTest, point);
}
///////////////////////////////////////////////////////////////////////////////
// OnPaint
void CXListCtrl::OnPaint()
{
Default();
if (GetItemCount() <= 0)
{
CDC* pDC = GetDC();
int nSavedDC = pDC->SaveDC();
CRect rc;
GetWindowRect(&rc);
ScreenToClient(&rc);
CHeaderCtrl* pHC = GetHeaderCtrl();
if (pHC != NULL)
{
CRect rcH;
pHC->GetItemRect(0, &rcH);
rc.top += rcH.bottom;
}
rc.top += 10;
CString strText;
strText = _T("There are no items to show in this view.");
COLORREF crText = m_crWindowText;
COLORREF crBkgnd = m_crWindow;
CBrush brush(crBkgnd);
pDC->FillRect(rc, &brush);
pDC->SetTextColor(crText);
pDC->SetBkColor(crBkgnd);
pDC->SelectStockObject(ANSI_VAR_FONT);
//pDC->DrawText(strText, -1, rc, DT_CENTER | DT_WORDBREAK | DT_NOPREFIX | DT_NOCLIP);
pDC->RestoreDC(nSavedDC);
ReleaseDC(pDC);
}
}
///////////////////////////////////////////////////////////////////////////////
// InsertItem
int CXListCtrl::InsertItem(const LVITEM* pItem)
{
ASSERT(pItem->iItem >= 0);
if (pItem->iItem < 0)
return -1;
int index = CListCtrl::InsertItem(pItem);
if (index < 0)
return index;
XLISTCTRLDATA *pXLCD = new XLISTCTRLDATA [GetColumns()];
ASSERT(pXLCD);
if (!pXLCD)
return -1;
pXLCD[0].crText = m_crWindowText;
pXLCD[0].crBackground = m_crWindow;
pXLCD[0].nImage = pItem->iImage;
pXLCD[0].dwItemData = pItem->lParam; //+++
CListCtrl::SetItemData(index, (DWORD) pXLCD);
return index;
}
///////////////////////////////////////////////////////////////////////////////
// InsertItem
int CXListCtrl::InsertItem(int nItem, LPCTSTR lpszItem)
{
ASSERT(nItem >= 0);
if (nItem < 0)
return -1;
return InsertItem(nItem,
lpszItem,
m_crWindowText,
m_crWindow);
}
///////////////////////////////////////////////////////////////////////////////
// InsertItem
int CXListCtrl::InsertItem(int nItem,
LPCTSTR lpszItem,
COLORREF crText,
COLORREF crBackground)
{
ASSERT(nItem >= 0);
if (nItem < 0)
return -1;
int index = CListCtrl::InsertItem(nItem, lpszItem);
if (index < 0)
return index;
XLISTCTRLDATA *pXLCD = new XLISTCTRLDATA [GetColumns()];
ASSERT(pXLCD);
if (!pXLCD)
return -1;
pXLCD[0].crText = crText;
pXLCD[0].crBackground = crBackground;
pXLCD[0].nImage = -1;
CListCtrl::SetItemData(index, (DWORD) pXLCD);
return index;
}
///////////////////////////////////////////////////////////////////////////////
// SetItem
int CXListCtrl::SetItem(const LVITEM* pItem)
{
ASSERT(pItem->iItem >= 0);
if (pItem->iItem < 0)
return -1;
BOOL rc = CListCtrl::SetItem(pItem);
if (!rc)
return FALSE;
XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) CListCtrl::GetItemData(pItem->iItem);
if (pXLCD)
{
pXLCD[pItem->iSubItem].nImage = pItem->iImage;
UpdateSubItem(pItem->iItem, pItem->iSubItem);
rc = TRUE;
}
else
{
rc = FALSE;
}
return rc;
}
///////////////////////////////////////////////////////////////////////////////
// SetItemImage
BOOL CXListCtrl::SetItemImage(int nItem, int nSubItem, int nImage)
{
ASSERT(nItem >= 0);
ASSERT(nItem < GetItemCount());
if ((nItem < 0) || nItem >= GetItemCount())
return FALSE;
ASSERT(nSubItem >= 0);
ASSERT(nSubItem < GetColumns());
if ((nSubItem < 0) || nSubItem >= GetColumns())
return FALSE;
BOOL rc = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -