📄 listctrlx.cpp
字号:
CListCtrl::OnSysColorChange();
UpdateHdrImageList();
}
void CListCtrlX::OnSetFocus(CWnd* pOldWnd)
{
CListCtrl::OnSetFocus(pOldWnd);
SetItemFocus(*this);
}
void CListCtrlX::OnDestroy()
{
CListCtrl::OnDestroy();
m_imlHdr.DeleteImageList();
}
void CListCtrlX::OnInitMenuPopup(CMenu *pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
CListCtrl::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
if (!m_bRouteMenuCmdsToMainFrame)
{
// NOTE: To enable the 'OnUpdateCmdUI'-stuff for a dialog or a control we
// must explicitly call an appropriate function (which was stolen from
// 'CFrameWnd') - otherwise out 'OnUpdateCmdUI'-callbacks would not be called.
//WndInitMenuPopupUpdateCmdUI(this, pPopupMenu, nIndex, bSysMenu);
}
}
void CListCtrlX::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu)
{
CListCtrl::OnMenuSelect(nItemID, nFlags, hSysMenu);
if (!m_bRouteMenuCmdsToMainFrame)
{
// To enable the display of the statusbar message strings for the
// currently selected menu item, we must explicitly call an appropriate
// function (which is stolen from 'CFrameWnd').
//WndMenuSelectUpdateMessageText(nItemID, nFlags, hSysMenu);
}
}
void CListCtrlX::OnContextMenu(CWnd * /*pWnd*/, CPoint point)
{
if (m_uIDMenu == (UINT)-1 && m_pMenu == NULL){
Default();
return;
}
CMenu* pMenu = NULL;
CMenu menuPopup;
if (m_pMenu == NULL && m_uIDMenu != (UINT)-1){
if (menuPopup.LoadMenu(m_uIDMenu))
pMenu = menuPopup.GetSubMenu(0);
}
else
pMenu = m_pMenu;
if (pMenu != NULL)
{
// If the context menu was not opened using the right mouse button,
// but the keyboard (Shift+F10), get a useful position for the context menu.
if (point.x == -1 && point.y == -1)
{
int iIdxItem = GetNextItem(-1, LVNI_SELECTED | LVNI_FOCUSED);
if (iIdxItem != -1)
{
RECT rc;
if (GetItemRect(iIdxItem, &rc, LVIR_BOUNDS))
{
point.x = rc.left + GetColumnWidth(0) / 2;
point.y = rc.top + (rc.bottom - rc.top) / 2;
ClientToScreen(&point);
}
}
else
{
point.x = 16;
point.y = 32;
ClientToScreen(&point);
}
}
pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
point.x, point.y,
m_bRouteMenuCmdsToMainFrame ? AfxGetMainWnd() : (m_pParent ? m_pParent : this));
}
}
void CListCtrlX::InitColumnOrders(int iColumns, const LCX_COLUMN_INIT* pColumns)
{
::InitColumnOrders(*this, iColumns, pColumns);
}
void CListCtrlX::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar == VK_SPACE)
{
if (GetExtendedStyle() & LVS_EX_CHECKBOXES)
{
// Check *all* selected items
int nCurrItem = GetNextItem(-1, LVNI_FOCUSED);
if (nCurrItem != -1 && ::GetKeyState(VK_CONTROL) >= 0)
CheckSelectedItems(nCurrItem);
}
}
else if (nChar == 'A' && (GetKeyState(VK_CONTROL) & 0x8000))
{
//////////////////////////////////////////////////////////////////
// Ctrl+A: Select all items
//
if ((GetStyle() & LVS_SINGLESEL) == 0)
SetItemState(-1, LVIS_SELECTED, LVIS_SELECTED);
}
/*else if (nChar == 'C' && (GetKeyState(VK_CONTROL) & 0x8000))
{
//////////////////////////////////////////////////////////////////
// Ctrl+C: Copy listview items to clipboard
//
OnCopy(0, 0);
}*/
else if (nChar == 'F' && (GetKeyState(VK_CONTROL) & 0x8000))
{
//////////////////////////////////////////////////////////////////
// Ctrl+F: Search item
//
OnFindStart();
}
else if (nChar == VK_F3)
{
if (GetKeyState(VK_SHIFT) & 0x8000)
{
//////////////////////////////////////////////////////////////////
// Shift+F3: Search previous
//
OnFindPrev();
}
else
{
//////////////////////////////////////////////////////////////////
// F3: Search next
//
OnFindNext();
}
}
CListCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CListCtrlX::CheckSelectedItems(int nCurrItem)
{
ASSERT( GetExtendedStyle() & LVS_EX_CHECKBOXES );
// first check if this item is selected
LVITEM lvi;
lvi.iItem = nCurrItem;
lvi.iSubItem = 0;
lvi.mask = LVIF_STATE;
lvi.stateMask = LVIS_SELECTED;
GetItem(&lvi);
// if item is not selected, don't do anything
if (!(lvi.state & LVIS_SELECTED))
return;
// new check state will be reverse of the current state,
BOOL bCheck = !GetCheck(nCurrItem);
int nItem = -1;
int nOldItem = -1;
while ((nItem = GetNextItem(nOldItem, LVNI_SELECTED)) != -1)
{
if (nItem != nCurrItem)
SetCheck(nItem, bCheck);
nOldItem = nItem;
}
}
void CreateItemReport(CListCtrl& lv, CString& rstrReport)
{
// Get nr. of listview columns
CHeaderCtrl* hdr = lv.GetHeaderCtrl();
int iCols = hdr->GetItemCount();
if (iCols == 0)
return;
// Get max. chars per column
int* paiColWidths = new int[iCols];
if (paiColWidths != NULL)
{
TCHAR szItem[512];
int iItems = lv.GetItemCount();
memset(paiColWidths, 0, sizeof(*paiColWidths) * iCols);
for (int iCol = 0; iCol < iCols; iCol++)
{
LVCOLUMN lvc;
lvc.mask = LVCF_TEXT | LVCF_WIDTH;
lvc.pszText = szItem;
lvc.cchTextMax = ARRSIZE(szItem);
if (lv.GetColumn(iCol, &lvc) && lvc.cx > 0)
{
int iLen = _tcslen(lvc.pszText);
if (iLen > paiColWidths[iCol])
paiColWidths[iCol] = iLen;
for (int iItem = 0; iItem < iItems; iItem++)
{
LVITEM lvi;
lvi.mask = LVIF_TEXT;
lvi.iItem = iItem;
lvi.iSubItem = iCol;
lvi.pszText = szItem;
lvi.cchTextMax = ARRSIZE(szItem);
if (lv.GetItem(&lvi))
{
int iLen = _tcslen(lvi.pszText);
if (iLen > paiColWidths[iCol])
paiColWidths[iCol] = iLen;
}
}
}
}
CString strLine;
for (int iCol = 0; iCol < iCols; iCol++)
{
if (paiColWidths[iCol] > 0)
{
LVCOLUMN lvc;
lvc.mask = LVCF_TEXT;
lvc.pszText = szItem;
lvc.cchTextMax = ARRSIZE(szItem);
if (lv.GetColumn(iCol, &lvc))
{
TCHAR szFmtItem[ARRSIZE(szItem)+32];
_sntprintf(szFmtItem, ARRSIZE(szFmtItem), _T("%-*s"), paiColWidths[iCol] + 2, szItem);
strLine += szFmtItem;
}
}
}
if (!strLine.IsEmpty()) {
if (!rstrReport.IsEmpty())
rstrReport += _T("\r\n");
rstrReport += strLine;
rstrReport += _T("\r\n");
for (int i = 0; i < strLine.GetLength(); i++)
rstrReport += _T("-");
}
for (int iItem = 0; iItem < iItems; iItem++)
{
CString strLine;
for (int iCol = 0; iCol < iCols; iCol++)
{
if (paiColWidths[iCol] > 0)
{
LVITEM lvi;
lvi.mask = LVIF_TEXT;
lvi.iItem = iItem;
lvi.iSubItem = iCol;
lvi.pszText = szItem;
lvi.cchTextMax = ARRSIZE(szItem);
if (lv.GetItem(&lvi))
{
TCHAR szFmtItem[ARRSIZE(szItem)+32];
_sntprintf(szFmtItem, ARRSIZE(szFmtItem), _T("%-*s"), paiColWidths[iCol] + 2, szItem);
strLine += szFmtItem;
}
}
}
if (!strLine.IsEmpty()) {
if (!rstrReport.IsEmpty())
rstrReport += _T("\r\n");
rstrReport += strLine;
}
}
delete paiColWidths;
if (!rstrReport.IsEmpty())
rstrReport += _T("\r\n");
}
}
LRESULT CListCtrlX::OnCopy(WPARAM wParam, LPARAM lParam)
{
CString strReport;
CreateItemReport(*this, strReport);
if (!strReport.IsEmpty())
theApp.CopyTextToClipboard(strReport);
return 0;
}
void InitColumnOrders(CListCtrl& lv, int iColumns, const LCX_COLUMN_INIT* pColumns)
{
ASSERT( lv.GetHeaderCtrl()->GetItemCount() == iColumns );
LPINT piOrders = new INT[iColumns];
if (piOrders != NULL)
{
for (int iCol = 0; iCol < iColumns; iCol++)
{
for (int j = 0; j < iColumns; j++)
{
if (pColumns[j].iOrder == iCol)
{
piOrders[iCol] = j;
break;
}
}
if (j >= iColumns)
{
ASSERT(0);
piOrders[iCol] = iCol;
}
}
VERIFY( lv.SetColumnOrderArray(iColumns, piOrders) );
delete piOrders;
}
}
void SetItemFocus(CListCtrl &ctl)
{
if (ctl.GetItemCount() > 0)
{
int iItem = ctl.GetNextItem(-1, LVNI_FOCUSED);
if (iItem == -1)
{
int iItem = ctl.GetNextItem(-1, LVNI_SELECTED);
if (iItem == -1)
iItem = 0;
ctl.SetItemState(iItem, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
ctl.SetSelectionMark(iItem);
}
}
}
void CListCtrlX::DoFind(int iStartItem, int iDirection /*1=down, 0 = up*/, BOOL bShowError)
{
CWaitCursor curHourglass;
if (iStartItem < 0) {
MessageBeep((UINT)-1);
return;
}
int iNumItems = iDirection ? GetItemCount() : 0;
int iItem = iStartItem;
while ( iDirection ? iItem < iNumItems : iItem >= 0 )
{
CString strItemText(GetItemText(iItem, m_iFindColumn));
if (!strItemText.IsEmpty())
{
if ( m_bFindMatchCase
? _tcsstr(strItemText, m_strFindText) != NULL
: stristr(strItemText, m_strFindText) != NULL )
{
// Deselect all listview entries
DeselectAllItems();
// Select the found listview entry
SetItemState(iItem, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
SetSelectionMark(iItem);
EnsureVisible(iItem, FALSE/*bPartialOK*/);
SetFocus();
return;
}
}
if (iDirection)
iItem++;
else
iItem--;
}
if (bShowError)
AfxMessageBox(_T("No matching entry found."), MB_ICONINFORMATION);
else
MessageBeep((UINT)-1);
}
void CListCtrlX::OnFindStart()
{
CListViewSearchDlg dlg;
dlg.m_pListView = this;
dlg.m_strFindText = m_strFindText;
dlg.m_iSearchColumn = m_iFindColumn;
if (dlg.DoModal() != IDOK || dlg.m_strFindText.IsEmpty())
return;
m_strFindText = dlg.m_strFindText;
m_iFindColumn = dlg.m_iSearchColumn;
DoFindNext(TRUE/*bShowError*/);
}
void CListCtrlX::OnFindNext()
{
DoFindNext(FALSE/*bShowError*/);
}
void CListCtrlX::DoFindNext(BOOL bShowError)
{
int iStartItem = GetNextItem(-1, LVNI_SELECTED | LVNI_FOCUSED);
if (iStartItem == -1)
iStartItem = 0;
else
iStartItem = iStartItem + (m_iFindDirection ? 1 : -1);
DoFind(iStartItem, m_iFindDirection, bShowError);
}
void CListCtrlX::OnFindPrev()
{
int iStartItem = GetNextItem(-1, LVNI_SELECTED | LVNI_FOCUSED);
if (iStartItem == -1)
iStartItem = 0;
else
iStartItem = iStartItem + (!m_iFindDirection ? 1 : -1);
DoFind(iStartItem, !m_iFindDirection, FALSE/*bShowError*/);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -