📄 listviewctrlex.cpp
字号:
imgInfo.rcImage.right - imgInfo.rcImage.left),
__min(pRect->bottom - pRect->top + 1,
imgInfo.rcImage.bottom - imgInfo.rcImage.top)),
CPoint(0, 0),
(pItem->state & LVIS_SELECTED &&
m_pListCtrl->GetFocus() == m_pListCtrl ?
ILD_SELECTED : ILD_NORMAL) | pItem->state & LVIS_OVERLAYMASK,
SRCCOPY, CLR_NONE);
}
}
}
}
/*** Draw state icon *********************************************************/
void CListBase::DrawStateIcon(CDC* pDC, LVITEM* pItem, LPRECT pRect)
{
ASSERT(m_pListCtrl);
int nImage = (pItem->state & LVIS_STATEIMAGEMASK) >> 12;
if (nImage > 0)
{
CImageList* pimglst = m_pListCtrl->GetImageList(LVSIL_STATE);
if (pimglst)
{
IMAGEINFO imgInfo;
// image indices are zero-based
if (pimglst->GetImageInfo(--nImage, &imgInfo))
{
pimglst->DrawIndirect(
pDC, nImage, CPoint(pRect->left, pRect->top),
CSize(__min(pRect->right - pRect->left + 1,
imgInfo.rcImage.right - imgInfo.rcImage.left),
__min(pRect->bottom - pRect->top + 1,
imgInfo.rcImage.bottom - imgInfo.rcImage.top)),
CPoint(0, 0),
pItem->state & LVIS_SELECTED &&
m_pListCtrl->GetFocus() == m_pListCtrl ? ILD_SELECTED : ILD_NORMAL,
SRCCOPY, CLR_NONE);
}
}
}
}
/*** Allow or disallow the hiding of a column ********************************/
void CListBase::EnableColumnHiding(int nColumn, bool bEnableIt)
{
if (nColumn >= 0 && nColumn < m_aColumnData.GetSize())
if (bEnableIt)
{
if (!m_aColumnData[nColumn]->m_bHidingAllowed)
// The first column is allowed to be hidden only
// if the list view control is owner-drawn.
if (nColumn > 0 || m_pListCtrl->GetStyle() & LVS_OWNERDRAWFIXED)
{
m_aColumnData[nColumn]->m_bHidingAllowed = true;
++m_nColumnHidingAllowed;
}
}
else
if (m_aColumnData[nColumn]->m_bHidingAllowed)
{
ShowColumn(nColumn); // display column if hidden
m_aColumnData[nColumn]->m_bHidingAllowed = false;
--m_nColumnHidingAllowed;
}
ASSERT(m_nColumnHidingAllowed >= 0);
}
/*** Draw the label of an item or subitem ************************************/
void CListBase::DrawSubItemText(CDC* pDC, LVITEM* pItem, LVCOLUMN* pColumn,
LPRECT pRect)
{
if (*pItem->pszText)
if (pRect->right - pRect->left > 0)
pDC->DrawText(pItem->pszText, -1, pRect,
(pColumn->fmt & LVCFMT_CENTER ? DT_CENTER :
pColumn->fmt & LVCFMT_RIGHT ? DT_RIGHT : DT_LEFT) |
DT_END_ELLIPSIS | DT_SINGLELINE | DT_NOPREFIX |
DT_NOCLIP | DT_VCENTER);
}
/*** Duplicate column information ********************************************/
LVCOLUMN* CListBase::DupLVColumn(LVCOLUMN* pLVColumn) const
{
LVCOLUMN* pLVColumn2 = new LVCOLUMN(*pLVColumn);
// mask unnecessary fields
if (!(pLVColumn2->mask & LVCF_FMT)) pLVColumn2->fmt = 0;
if (!(pLVColumn2->mask & LVCF_IMAGE)) pLVColumn2->iImage = 0;
if (!(pLVColumn2->mask & LVCF_ORDER)) pLVColumn2->iOrder = 0;
if (!(pLVColumn2->mask & LVCF_SUBITEM)) pLVColumn2->iSubItem = 0;
if (pLVColumn2->mask & LVCF_TEXT)
{
ASSERT(pLVColumn2->pszText);
pLVColumn2->pszText = new TCHAR[_tcslen(pLVColumn->pszText) + 1];
_tcscpy(pLVColumn2->pszText, pLVColumn->pszText);
}
else
pLVColumn2->pszText = 0;
if (!(pLVColumn2->mask & LVCF_WIDTH)) pLVColumn2->cx = 0;
pLVColumn2->cchTextMax = 0;
return pLVColumn2;
}
/*** Duplicate item information **********************************************/
LVITEM* CListBase::DupLVItem(LVITEM* pLVItem) const
{
LVITEM* pLVItem2 = new LVITEM(*pLVItem);
// mask unnecessary fields
if (!(pLVItem2->mask & LVIF_IMAGE)) pLVItem2->iImage = 0;
if (!(pLVItem2->mask & LVIF_INDENT)) pLVItem2->iIndent = 0;
if (!(pLVItem2->mask & LVIF_PARAM)) pLVItem2->lParam = 0;
if (pLVItem2->mask & LVIF_STATE)
pLVItem2->state &= pLVItem2->stateMask;
else
{
pLVItem2->state = 0;
pLVItem2->stateMask = 0;
}
if (pLVItem2->mask & LVIF_TEXT)
{
ASSERT(pLVItem2->pszText);
if (pLVItem2->pszText != LPSTR_TEXTCALLBACK)
{
pLVItem2->pszText = new TCHAR[_tcslen(pLVItem->pszText) + 1];
_tcscpy(pLVItem2->pszText, pLVItem->pszText);
}
}
else
pLVItem2->pszText = 0;
pLVItem2->iSubItem = 0;
pLVItem2->cchTextMax = 0;
return pLVItem2;
}
/*** Enable or disable sort icon *********************************************/
void CListBase::EnableSortIcon(BOOL bEnable, int nSortColumn)
{
ASSERT(m_pListCtrl);
ASSERT(m_pListCtrl->GetHeaderCtrl());
m_bSortIconEnabled = bEnable;
if (nSortColumn != 0) m_nSortColumn = nSortColumn;
if (bEnable && m_visualStyle == NotPresent)
{
CreateSortIcons ();
m_pListCtrl->GetHeaderCtrl()->SetImageList(&m_imglstSortIcons);
}
SetSortIcon(); // display or hide sort icon
}
/*** Gets the position of the first checked item in the list view control ****/
POSITION CListBase::GetFirstCheckedItemPosition() const
{
ASSERT(m_pListCtrl);
int nItemCount = m_pListCtrl->GetItemCount();
for (int nItem = 0; nItem < nItemCount; ++nItem)
if (m_pListCtrl->GetCheck(nItem))
return reinterpret_cast<POSITION>(static_cast<INT_PTR>(nItem + 1));
return 0;
}
/*** Gets the index of the next checked item in the list view control ********/
int CListBase::GetNextCheckedItem(POSITION& pos) const
{
ASSERT(pos);
ASSERT(m_pListCtrl);
int nOldPos = static_cast<int>(reinterpret_cast<INT_PTR>(pos));
int nItemCount = m_pListCtrl->GetItemCount();
pos = 0;
for (int nItem = nOldPos; nItem < nItemCount; ++nItem)
if (m_pListCtrl->GetCheck(nItem))
{
pos = reinterpret_cast<POSITION>(static_cast<INT_PTR>(nItem + 1));
break;
}
return nOldPos - 1;
}
/*** Get attributes of this list view control ********************************/
bool CListBase::GetState(LPBYTE* ppState, LPUINT pnStateLen) const
{
ASSERT(m_pListCtrl);
int nColumnCount = static_cast<int>(m_aColumnData.GetSize());
if (nColumnCount > 0 && ppState)
{
UINT nStateLen =
2 * sizeof(int) + nColumnCount * (sizeof(bool) + 2 * sizeof(int));
*ppState = new BYTE[nStateLen];
LPBYTE p = *ppState;
*reinterpret_cast<LPINT>(p) = nColumnCount;
p += sizeof(int);
*reinterpret_cast<LPINT>(p) = m_nSortColumn;
for (int nColumn = 0; nColumn < nColumnCount; nColumn++)
{
p += sizeof(int);
*reinterpret_cast<bool*>(p) = m_aColumnData[nColumn]->m_bHidingAllowed ?
m_aColumnData[nColumn]->m_bVisible : true;
p += sizeof(bool);
*reinterpret_cast<LPINT>(p) = m_aColumnData[nColumn]->m_bVisible ?
m_pListCtrl->GetColumnWidth(nColumn) :
m_aColumnData[nColumn]->m_nWidth,
p += sizeof(int);
*reinterpret_cast<LPINT>(p) = m_aColumnData[nColumn]->m_nOrder;
}
if (pnStateLen) *pnStateLen = nStateLen;
return true;
}
else
return false;
}
/*** Small icon always should be kept left ***********************************/
bool CListBase::KeepLabelLeft(bool bKeepLeft)
{
bool bSuccess = true;
if (bKeepLeft)
if ((m_pListCtrl->GetStyle() & LVS_OWNERDRAWFIXED) == 0)
{
bKeepLeft = false;
bSuccess = false;
}
if (bSuccess && bKeepLeft != m_bKeepLabelLeft)
{
m_bKeepLabelLeft = bKeepLeft;
m_pListCtrl->Invalidate();
}
return bSuccess;
}
/*** Restore attributes of this list view control ****************************/
bool CListBase::RestoreState(LPCTSTR pszSection, LPCTSTR pszEntry)
{
ASSERT(m_pListCtrl);
bool bSuccess = false;
if (static_cast<int>(m_aColumnData.GetSize()) > 0)
{
LPBYTE pState;
UINT nStateLen;
if (AfxGetApp()->GetProfileBinary(pszSection, pszEntry, &pState,
&nStateLen))
{
bSuccess = SetState(pState, nStateLen);
delete[] pState;
}
}
return bSuccess;
}
/*** Save attributes of this list view control *******************************/
bool CListBase::SaveState(LPCTSTR pszSection, LPCTSTR pszEntry) const
{
LPBYTE pState;
UINT nStateLen;
if (GetState(&pState, &nStateLen)) // get current state
{
bool bSuccess =
AfxGetApp()->WriteProfileBinary(pszSection, pszEntry, pState, nStateLen)
!= FALSE;
delete[] pState;
return bSuccess;
}
else
return false;
}
/*** Set column to be sorted *************************************************/
void CListBase::SetSortColumn(int nColumn)
{
ASSERT(abs(nColumn) <= m_aColumnData.GetSize());
ASSERT(m_pListCtrl);
if (nColumn != m_nSortColumn)
{
m_nSortColumn = nColumn;
SetSortIcon();
if (abs(nColumn) != abs(m_nSortColumn)) m_pListCtrl->Invalidate();
}
}
/*** Set attributes of this list view control ********************************/
bool CListBase::SetState(LPBYTE pState, UINT nStateLen)
{
ASSERT(m_pListCtrl);
int nColumnCount = static_cast<int>(m_aColumnData.GetSize());
if (nColumnCount > 0 &&
nStateLen ==
2*sizeof(int) + nColumnCount * (sizeof(bool) + 2*sizeof(int)) &&
*reinterpret_cast<LPINT>(pState) == nColumnCount)
{
pState += sizeof(int);
int nColumn = *reinterpret_cast<LPINT>(pState);
if (abs(nColumn) <= nColumnCount)
SetSortColumn(nColumn);
else
return false; // wrong sort column
for (nColumn = 0; nColumn < nColumnCount; nColumn++)
{
COLUMN_DATA* pColData = m_aColumnData[nColumn];
// restore display status of column
pState += sizeof(int);
bool bVisible = *reinterpret_cast<bool*>(pState);
if (bVisible != pColData->m_bVisible)
if (pColData->m_bHidingAllowed || !pColData->m_bVisible)
ShowColumn(nColumn, bVisible);
pState += sizeof(bool);
// restore width of column
m_pListCtrl->SetColumnWidth(nColumn, *reinterpret_cast<LPINT>(pState));
pState += sizeof(int);
// restore column order
int nOrder = *reinterpret_cast<LPINT>(pState);
if (nOrder < nColumnCount)
pColData->m_nOrder = nOrder;
else
return false;
}
// set column order
LPINT pnColOrder = new int[nColumnCount];
for (nColumn = 0; nColumn < nColumnCount; nColumn++)
pnColOrder[m_aColumnData[nColumn]->m_nOrder] = nColumn;
m_pListCtrl->SetColumnOrderArray(nColumnCount, pnColOrder);
delete[] pnColOrder;
}
return true;
}
/*** Show or hide an individual column ***************************************/
void CListBase::ShowColumn(int nColumn, bool bShowIt)
{
ASSERT(m_pListCtrl);
ASSERT(nColumn >= 0 && nColumn < m_aColumnData.GetSize());
if (m_aColumnData[nColumn]->m_bHidingAllowed)
if (bShowIt)
{
if (!m_aColumnData[nColumn]->m_bVisible)
{
// show column
bool bNoColumnWasVisible = true;
for (INT_PTR i = m_aColumnData.GetUpperBound(); i >= 0; i--)
if (m_aColumnData[i]->m_bVisible)
{
bNoColumnWasVisible = false;
break;
}
m_aColumnData[nColumn]->m_bVisible = true;
int nPhysicalColumn = GetPhysicalIndex(nColumn);
LVCOLUMN lvColumn = *m_aColumnData[nColumn]->m_pLVColumn;
lvColumn.mask |= LVCF_ORDER;
lvColumn.iOrder = GetPhysicalOrder(m_aColumnData[nColumn]->m_nOrder);
if (m_pListCtrl->DefWindowProc(LVM_INSERTCOLUMN,
nPhysicalColumn,
reinterpret_cast<LPARAM>(&lvColumn)) !=
-1)
{
if (nPhysicalColumn == 0)
// rejustify first column of listview control to enable a right-
// justified or centerd first column
JustifyFirstColumn(lvColumn.fmt);
if (m_nSortColumn != 0 && abs(m_nSortColumn) - 1 == nColumn)
// restore sort icon
SetSortIcon();
if (!(m_pListCtrl->GetStyle() & LVS_OWNERDATA))
{
if (nPhysicalColumn > 0)
for (int nItem = m_pListCtrl->GetItemCount(); --nItem >= 0;)
{
LVITEM lvItem = {LVIF_PARAM, nItem, 0};
if (m_pListCtrl->DefWindowProc(LVM_GETITEM, 0,
reinterpret_cast<LPARAM>(&lvItem)))
{
LVITEM* pLVItem =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -