📄 gfxlistctrl.cpp
字号:
lxhd.CtrlId = iCtrlId < 0 ? GetDlgCtrlID() : iCtrlId;
lxhd.iItem = plvItem->iItem;
lxhd.iSubItem = GetColumnIndex(plvItem->iSubItem);
lxhd.dwFlag = 0;
lxhd.dwItemData = GetItemData(plvItem->iItem);
lxhd.csText = plvItem->pszText;
if (SendInfoExMsg(&lxhd))
ModifyItemEx(lxhd.iItem, plvItem->iSubItem, lxhd.dwItemData, lxhd.csText);
else ModifyItemEx(lxhd.iItem, plvItem->iSubItem, lxhd.dwItemData);
}
}
//
void CGfxListCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if( GetFocus() != this ) SetFocus();
if (dwFlag & fCellToolTip && wndToolTip.IsWindowVisible()) wndToolTip.ShowWindow(SW_HIDE);
CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
}
void CGfxListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if( GetFocus() != this ) SetFocus();
if (dwFlag & fCellToolTip && wndToolTip.IsWindowVisible()) wndToolTip.ShowWindow(SW_HIDE);
CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
}
//确保列可见
bool CGfxListCtrl::EnsureSubItemVisible(const int iSubItem)
{
//确保列索引有效
int nColumnCount = GetColumnCount();
int iColWidth = GetColumnWidth(iSubItem);
if (iSubItem >= nColumnCount || iColWidth < 5) return false;
//得到列偏移(以像素为单位)
int offset = 0;
for (int i = 0; i < iSubItem; i++) offset += GetColumnWidth(i);
//滚动列表试图控件以使子项可见
CRect rect, subRect;
GetItemRect(0, &rect, LVIR_BOUNDS);
subRect.SetRect(offset + rect.left, 0, offset + iColWidth + rect.left, 0);
CRect rcClient;
GetClientRect(&rcClient);
if (subRect.left < rcClient.left)
{
CSize sz(rcClient.left + subRect.left, 0);
Scroll(sz);
return true;
}
else if (subRect.right > rcClient.right)
{
CSize sz(subRect.right - rcClient.right, 0);
Scroll(sz);
return true;
}
return true;
}
// 单击选中相应条目子项
void CGfxListCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
if( GetFocus() != this ) SetFocus();
CListCtrl::OnLButtonDown(nFlags, point);
}
//获取行索引为nItem、列索引为nCol的子项矩形(rcItem)
void CGfxListCtrl::GetSubItemRect(const int nItem, const int nCol, CRect & rcItem)
{
// CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
/* int nColumnCount = GetColumnCount();//pHeader->GetItemCount();
int iColWidth = GetColumnWidth(nCol);
if (nCol >= nColumnCount || iColWidth < 5) return;*/
//此处逻辑有问题,应改为:
int nColumnCount = GetColumnCount();
int iColWidth;
//检查nCol的有效性
if (nCol < 0 || nCol >= nColumnCount || (iColWidth = GetColumnWidth(nCol)) < 5) return;
int offset = 0;
for (int i = 0; i < nCol; i++) offset += GetColumnWidth(i);
CRect rect;
GetItemRect(nItem, &rect, LVIR_BOUNDS);
rect.bottom --;
rect.left += offset;
rect.right = rect.left + GetColumnWidth(nCol);
rcItem = rect;
}
LRESULT CGfxListCtrl::OnUserTab(WPARAM wParam, LPARAM lParam)
{
if (wParam == 0)
{
int nColumnCount = GetColumnCount();
int col = ((int *)lParam)[1]+1;
int row = ((int *)lParam)[0];
if (col >= nColumnCount)
{
col = 0;
row ++;
if (row >= GetItemCount()) return 0L;
}
bool bFind = dwhEdit&(1 << GetColumnIndex(col)) || dwhCombo&(1 << GetColumnIndex(col)) || dwhComboEx&(1 << GetColumnIndex(col));
while (!bFind)
{
col ++;
if (col >= nColumnCount)
{
col = 0;
row ++;
if (row >= GetItemCount()) return 0L;
}
bFind = dwhEdit&(1 << GetColumnIndex(col)) || dwhCombo&(1 << GetColumnIndex(col)) || dwhComboEx&(1 << GetColumnIndex(col));
}
iSubItemFocus = col;
if (GetSelectedCount() == 1)
{
int sidx = GetNextItem(-1, LVNI_SELECTED);
if (sidx != row) RemoveAllSelection();
}
SetItemState(row, LVIS_SELECTED | LVIS_FOCUSED , LVIS_SELECTED | LVIS_FOCUSED);
if (pCategoryManager == NULL || pCategoryManager->IsListItemACategory(GetItemData(row)) < 0)
{
int irealcol = GetColumnIndex(col);
if (dwhEdit&(1 << irealcol)) EditSubLabel(row, col, false);
else if (dwhCombo&(1 << irealcol)) ComboSubLabel(row, col, false, false);
else if (dwhComboEx&(1 << irealcol)) ComboSubLabel(row, col, true, false);
}
}
if (wParam == 1) // Prev Tab
{
int nColumnCount = GetColumnCount();
int col = ((int *)lParam)[1] - 1;
int row = ((int *)lParam)[0];
if (col < 0)
{
col = nColumnCount-1;
row --;
if (row < 0) return 0L;
}
bool bFind = dwhEdit&(1 << GetColumnIndex(col)) || dwhCombo&(1 << GetColumnIndex(col)) || dwhComboEx&(1 << GetColumnIndex(col));
while (!bFind)
{
col --;
if (col < 0)
{
col = nColumnCount-1;
row --;
if (row < 0) return 0L;
}
bFind = dwhEdit&(1 << GetColumnIndex(col)) || dwhCombo&(1 << GetColumnIndex(col)) || dwhComboEx&(1 << GetColumnIndex(col));
}
iSubItemFocus = col;
if (GetSelectedCount() == 1)
{
int sidx = GetNextItem(-1, LVNI_SELECTED);
if (sidx != row) RemoveAllSelection();
}
SetItemState(row, LVIS_SELECTED | LVIS_FOCUSED , LVIS_SELECTED | LVIS_FOCUSED);
if (pCategoryManager == NULL || pCategoryManager->IsListItemACategory(GetItemData(row)) < 0)
{
int irealcol = GetColumnIndex(col);
if (dwhEdit&(1 << irealcol)) EditSubLabel(row, col, false);
else if (dwhCombo&(1 << irealcol)) ComboSubLabel(row, col, false, false);
else if (dwhComboEx&(1 << irealcol)) ComboSubLabel(row, col, true, false);
}
return (LRESULT) 0L;
}
if (wParam == 2) // Left
{
if (iSubItemFocus > 0) iSubItemFocus--;
int sidx = GetNextItem(-1, LVNI_SELECTED);
if (sidx >= 0)
{
CRect rect;
GetItemRect(sidx, &rect, LVIR_BOUNDS);
rect.bottom --;
InvalidateRect(rect);
EnsureSubItemVisible(iSubItemFocus);
}
}
if (wParam == 3) // Right
{
int nColumnCount = GetColumnCount();
if (iSubItemFocus < nColumnCount - 1) iSubItemFocus++;
int sidx = GetNextItem(-1, LVNI_SELECTED);
if (sidx >= 0)
{
CRect rect;
GetItemRect(sidx, &rect, LVIR_BOUNDS);
rect.bottom --;
InvalidateRect(rect);
EnsureSubItemVisible(iSubItemFocus);
}
}
if (wParam == 4) // Up
{
int sidx = GetNextItem(-1, LVNI_FOCUSED);
if (sidx >= 0)
{
sidx --;
if (sidx >= 0)
{
if (GetSelectedCount() == 1) SetItemState(sidx+1, 0, LVIS_SELECTED | LVIS_FOCUSED);
SetItemState(sidx, LVIS_SELECTED | LVIS_FOCUSED , LVIS_SELECTED | LVIS_FOCUSED);
}
}
}
if (wParam == 5) // Down
{
int sidx = GetNextItem(-1, LVNI_FOCUSED);
if (sidx >= 0)
{
sidx ++;
if (sidx < GetItemCount() - 1)
{
if (GetSelectedCount() == 1) SetItemState(sidx-1, 0, LVIS_SELECTED | LVIS_FOCUSED);
SetItemState(sidx, LVIS_SELECTED | LVIS_FOCUSED , LVIS_SELECTED | LVIS_FOCUSED);
}
}
}
return 0L;
}
void CGfxListCtrl::RemoveAllSelection()
{
int idx = GetNextItem(-1, LVNI_SELECTED);
while (idx >= 0)
{
SetItemState(idx, 0, LVIS_SELECTED | LVIS_FOCUSED);
idx = GetNextItem(idx, LVNI_SELECTED);
}
}
void CGfxListCtrl::OnKeydown(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pNMHDR;
if (dwFlag & fCellToolTip && wndToolTip.IsWindowVisible()) wndToolTip.ShowWindow(SW_HIDE);
if (pLVKeyDow->wVKey == VK_LEFT)
{
if (iSubItemFocus > 0) iSubItemFocus--;
else { *pResult = 1; return; }
int sidx = GetNextItem(-1, LVNI_FOCUSED|LVNI_FOCUSED);
if (sidx >= 0)
{
if (EnsureSubItemVisible(iSubItemFocus))
{
CRect src;
GetSubItemRect(sidx, iSubItemFocus, src);
InvalidateRect(src);
GetSubItemRect(sidx, iSubItemFocus+1, src);
InvalidateRect(src);
}
*pResult = 1;
return;
}
}
if (pLVKeyDow->wVKey == VK_RIGHT)
{
int nColumnCount = GetColumnCount();
if (iSubItemFocus < nColumnCount - 1) iSubItemFocus++;
else { *pResult = 1; return; }
int sidx = GetNextItem(-1, LVNI_FOCUSED|LVNI_FOCUSED);
if (sidx >= 0)
{
if (EnsureSubItemVisible(iSubItemFocus))
{
CRect src;
GetSubItemRect(sidx, iSubItemFocus, src);
InvalidateRect(src);
GetSubItemRect(sidx, iSubItemFocus-1, src);
InvalidateRect(src);
}
*pResult = 1;
return;
}
}
*pResult = 0;
}
BOOL CGfxListCtrl::PreTranslateMessage(MSG* pMsg)
{
if (dwFlag & fReturnModify || dwFlag & fReturnDblClk)
{
if (pMsg->message == WM_KEYDOWN)
{
if (pMsg->wParam == VK_RETURN)
{
int sidx = GetNextItem(-1, LVNI_SELECTED);
if (pCategoryManager != NULL)
{
int cate = pCategoryManager->IsListItemACategory(GetItemData(sidx));
if (cate >= 0)
{
if (pCategoryManager->pCategory[cate].bExpanded)
{
pCategoryManager->RemoveCategoryItems(cate, sidx, this);
CRect rcAllLabels;
GetItemRect(sidx,rcAllLabels,LVIR_BOUNDS);
CRect rc;
GetClientRect(&rc);
if (rc.right > rcAllLabels.right)
{
rc.left = rcAllLabels.right;
rc.top = rcAllLabels.bottom;
InvalidateRect(rc, true);
}
}
else
{
pCategoryManager->FillCategoryItems(cate, sidx, this);
}
pCategoryManager->pCategory[cate].bExpanded = !(pCategoryManager->pCategory[cate].bExpanded);
CRect rcLittleBox;
GetSubItemRect(sidx, 0, rcLittleBox);
rcLittleBox.bottom ++;
rcLittleBox.right ++;
InvalidateRect(rcLittleBox, false);
if (dwFlag&fScrollBarAlways)
{
ShowScrollBar(SB_BOTH);
int iPageItem = GetCountPerPage();
int iItemCount = GetItemCount();
if (iItemCount < iPageItem) EnableScrollBar(SB_VERT, ESB_DISABLE_BOTH);
else EnableScrollBar(SB_VERT, ESB_ENABLE_BOTH);
CRect rcAllLabels;
GetItemRect(0,rcAllLabels,LVIR_BOUNDS);
EnableScrollBar(SB_HORZ, rcAllLabels.Width() < m_cxClient ? ESB_DISABLE_BOTH : ESB_ENABLE_BOTH);
}
return true;
}
}
if (sidx >= 0 && iSubItemFocus >= 0 && dwFlag & fReturnModify)
{
// if (pCategoryManager == NULL || pCategoryManager->IsListItemACategory(GetItemData(sidx)) < 0)
{
int irealcol = GetColumnIndex(iSubItemFocus);
if (dwhEdit&(1 << irealcol))
{
EditSubLabel(sidx, iSubItemFocus, false);
return true;
}
else if (dwhCombo&(1 << irealcol))
{
ComboSubLabel(sidx, iSubItemFocus, false, false);
return true;
}
else if (dwhComboEx&(1 << irealcol))
{
ComboSubLabel(sidx, iSubItemFocus, true, false);
return true;
}
}
}
if (dwFlag & fReturnDblClk)
{
NMHDR nh;
nh.hwndFrom = GetSafeHwnd();
nh.idFrom = iCtrlId < 0 ? GetDlgCtrlID() : iCtrlId;
nh.code = NM_DBLCLK;
GetReciper()->SendMessage(WM_NOTIFY, nh.idFrom, (LPARAM) &nh);
return true;
}
}
}
}
return CListCtrl::PreTranslateMessage(pMsg);
}
void CGfxListCtrl::SetSubItemImage(const int iItem, const int iSubItem, const int iIndex)
{
if (dwFlag&fSubItemImages)
{
ASSERT(dwhImages & (1 << iSubItem));
CString cs;
cs.Format("%d", iIndex);
SetItemText(iItem, iSubItem, cs);
}
}
void CGfxListCtrl::SetHeaderImageList(CImageList * pIma)
{
wndHeader.pImageList = pIma;
}
void CGfxListCtrl::SetColumnImage(const int iCol, const int iImage)
{
ASSERT(wndHeader.GetSafeHwnd());
CString cs;
cs.Format("%d_", iImage);
HD_ITEM hditem;
hditem.mask = HDI_FORMAT;
wndHeader.GetItem(iCol, &hditem );
hditem.fmt |= HDF_OWNERDRAW;
hditem.mask |= HDI_TEXT;
hditem.pszText = cs.LockBuffer();
hditem.cchTextMax = cs.GetLength();
wndHeader.SetItem(iCol, &hditem );
cs.UnlockBuffer();
}
void CGfxListCtrl::ResetScrollBar()
{
ShowScrollBar(SB_BOTH);
int iPageItem = GetCountPerPage();
int iItemCount = GetItemCount();
if (iItemCount < iPageItem) EnableScrollBar(SB_VERT, ESB_DISABLE_BOTH);
else EnableScrollBar(SB_VERT, ESB_ENABLE_BOTH);
if (iItemCount > 0)
{
CRect rcAllLabels;
GetItemRect(0,rcAllLabels,LVIR_BOUNDS);
EnableScrollBar(SB_HORZ, rcAllLabels.Width() < m_cxClient ? ESB_DISABLE_BOTH : ESB_ENABLE_BOTH);
}
else EnableScrollBar(SB_HORZ, ESB_DISABLE_BOTH);
}
int CGfxListCtrl::GetColumnCount() const
{
CHeaderCtrl* pHeader = (CHeaderCtrl*) GetDlgItem(0);
return pHeader ? pHeader->GetItemCount() : 0;
}
bool CGfxListCtrl::DoCopyInClipboard(const bool bOnlySel)
{
CString source;
CWaitCursor tom;
int nCol = GetColumnCount();
if (nCol < 0) return false;
if (bOnlySel)
{
if (GetSelectedCount() > 0)
{
int idx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -