📄 reportctrl.cpp
字号:
return CListCtrl::PreTranslateMessage(pMsg);
}
CEdit* CReportCtrl::GetEditControl()
{
return m_pWndEdit;
}
BOOL CReportCtrl::Create(CWnd* pParentWnd, UINT nID, LPCRECT lpRect, DWORD dwStyle)
{
// TODO: Add your specialized code here and/or call the base class
ASSERT(pParentWnd != NULL);
dwStyle &= ~MUST_NOT_STYLE;
dwStyle |= MUST_STYLE;
CRect rect;
if (lpRect == NULL)
pParentWnd->GetClientRect(&rect);
else
rect = *lpRect;
return CListCtrl::Create(dwStyle, rect, pParentWnd, nID);
}
void CReportCtrl::PreSubclassWindow()
{
// TODO: Add your specialized code here and/or call the base class
LONG lStyle = ::GetWindowLong(GetSafeHwnd(), GWL_STYLE);
lStyle &= ~MUST_NOT_STYLE;
lStyle |= MUST_STYLE;
::SetWindowLong(GetSafeHwnd(), GWL_STYLE, lStyle);
SetExtendedStyle(0);
ASSERT(GetHeaderCtrl() != NULL);
CListCtrl::PreSubclassWindow();
}
BOOL CReportCtrl::IsSortable() const
{
if (!HasColumnHeader())
return FALSE;
LONG lStyle = ::GetWindowLong(GetHeaderCtrl()->GetSafeHwnd(), GWL_STYLE);
return (lStyle & HDS_BUTTONS) != 0;
}
BOOL CReportCtrl::HasColumnHeader() const
{
return (GetStyle() & LVS_NOCOLUMNHEADER) == 0;
}
void CReportCtrl::ResizeToFitParent()
{
// resize the list ctrl to fit parent client area
if (GetSafeHwnd() != NULL)
{
CRect rect;
GetParent()->GetClientRect(&rect);
MoveWindow(&rect);
}
}
BOOL CReportCtrl::ModifyStyleEx(DWORD dwRemove, DWORD dwAdd, UINT nFlags)
{
dwRemove &= ~MUST_EX_STYLE;
dwRemove |= MUST_NOT_EX_STYLE;
dwAdd &= ~MUST_NOT_EX_STYLE;
dwAdd |= MUST_EX_STYLE;
return CListCtrl::ModifyStyleEx(dwRemove, dwAdd, nFlags);
}
BOOL CReportCtrl::ModifyStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags)
{
dwRemove &= ~MUST_STYLE;
dwRemove |= MUST_NOT_STYLE;
dwAdd &= ~MUST_NOT_STYLE;
dwAdd |= MUST_STYLE;
return CListCtrl::ModifyStyle(dwRemove, dwAdd, nFlags);
}
void CReportCtrl::_MouseClkMonitor(UINT nMsg, UINT nFlags, CPoint point, BOOL bTriggerEdit)
{
LVHITTESTINFO hti;
hti.pt = point;
const int IDX = SubItemHitTest(&hti);
const BOOL BEFORE = CListCtrl::GetCheck(IDX) > 0;
const BOOL WAS_EDIT = _IsEditVisible();
EndEdit(TRUE);
const BOOL WASACTIVE = bTriggerEdit ? ExamItemStates(IDX, RC_ITEM_FOCUSED | RC_ITEM_SELECTED) : FALSE;
switch (nMsg)
{
case WM_LBUTTONDOWN:
CListCtrl::OnLButtonDown(nFlags, point);
break;
case WM_LBUTTONDBLCLK:
CListCtrl::OnLButtonDblClk(nFlags, point);
break;
case WM_MBUTTONDOWN:
CListCtrl::OnMButtonDown(nFlags, point);
break;
case WM_MBUTTONDBLCLK:
CListCtrl::OnMButtonDblClk(nFlags, point);
break;
case WM_RBUTTONDOWN:
CListCtrl::OnRButtonDown(nFlags, point);
break;
case WM_RBUTTONDBLCLK:
CListCtrl::OnRButtonDblClk(nFlags, point);
break;
default:
break;
}
const BOOL STATSCHANGED = _ItemCheckMonitor(IDX, BEFORE, CListCtrl::GetCheck(IDX) > 0, nMsg);
if (bTriggerEdit && m_bAllowEdit && !STATSCHANGED && !WAS_EDIT && WASACTIVE)
StartEdit(IDX, hti.iSubItem);
}
BOOL CReportCtrl::SetItemImage(int nItem, int nSubItem, int nImageIndex)
{
return CListCtrl::SetItem(nItem, nSubItem, LVIF_IMAGE, NULL, nImageIndex, 0, 0, 0);
}
int CReportCtrl::GetItemImage(int nItem, int nSubItem) const
{
LVITEM lvi;
lvi.iItem = nItem;
lvi.iSubItem = nSubItem;
lvi.mask = LVIF_IMAGE;
return CListCtrl::GetItem(&lvi) ? lvi.iImage : -1;
}
CImageList* CReportCtrl::SetImageList(CImageList *pImageList)
{
return CListCtrl::SetImageList(pImageList, LVSIL_SMALL);
}
CImageList* CReportCtrl::GetImageList() const
{
return CListCtrl::GetImageList(LVSIL_SMALL);
}
CImageList* CReportCtrl::SetImageList(UINT nBitmapID, COLORREF crMask)
{
m_imgList.DeleteImageList();
m_imgList.Create(nBitmapID, 16, 4, crMask);
return CListCtrl::SetImageList(&m_imgList, LVSIL_SMALL);
}
BOOL CReportCtrl::StartEdit(int nItem, int nSubItem)
{
// Get the grid width and height
if (!m_bAllowEdit || !_IsValidIndex(nItem) || nSubItem < 0 || nSubItem >= GetColumnCount())
return FALSE;
if (m_ptEditting.x == nItem && m_ptEditting.y == nSubItem)
return TRUE;
EndEdit(TRUE);
m_ptEditting.x = nItem;
m_ptEditting.y = nSubItem;
SetAllItemStates(RC_ITEM_SELECTED, RC_ITEM_UNSELECTED); // unselect all
SetItemStates(m_ptEditting.x, RC_ITEM_SELECTED | RC_ITEM_FOCUSED);
// determine editbox font and alignment
const DWORD FMT = _GetHeaderTextFormat(nSubItem);
if (FMT != m_dwPrevEditFmt)
{
m_dwPrevEditFmt = FMT;
// Funny thing:
// Changing CEdit style among ES_LEFT, ES_CENTER, ES_RIGHT at runtime works
// sometimes and fails other times. It just cannot guarantee to be succeed.
// So I decided to destroy and recreate the CEdit every time when the text
// format changes.
if (m_pWndEdit->GetSafeHwnd() != NULL)
m_pWndEdit->DestroyWindow();
if (!m_pWndEdit->Create(ES_AUTOHSCROLL | ES_NOHIDESEL | WS_CHILD | WS_BORDER | FMT, CRect(0, 0, 1, 1), this, 0))
return FALSE;
}
else
{
if (m_pWndEdit->GetSafeHwnd() == NULL
&& !m_pWndEdit->Create(ES_AUTOHSCROLL | ES_NOHIDESEL | WS_CHILD | WS_BORDER | FMT, CRect(0, 0, 1, 1), this, 0))
{
return FALSE;
}
}
m_pWndEdit->SetFont(GetFont());
CRect rcEdit;
ListView_GetSubItemRect(GetSafeHwnd(), m_ptEditting.x, m_ptEditting.y, LVIR_LABEL, &rcEdit);
if (m_ptEditting.y > 0 && GetImageList() != NULL && GetItemImage(m_ptEditting.x, m_ptEditting.y) >= 0)
rcEdit.DeflateRect(16, 0, 0, 0);
// Move the editbox to that grid, obtain text from the grid, display the
// editbox, and, finally, highlights all text in the editbox and set the
// windows focus to the editbox.
m_pWndEdit->MoveWindow(&rcEdit);
m_pWndEdit->SetWindowText(GetItemText(m_ptEditting.x, m_ptEditting.y));
m_pWndEdit->ShowWindow(SW_SHOW);
m_pWndEdit->SetSel(0, -1);
m_pWndEdit->SetFocus();
return TRUE;
}
BOOL CReportCtrl::EndEdit(BOOL bCommit)
{
if (!_IsEditVisible())
return FALSE;
CString str;
m_pWndEdit->GetWindowText(str);
BOOL bChanged = bCommit && str.Compare(GetItemText(m_ptEditting.x, m_ptEditting.y)) != 0;
if (bChanged)
{
// update the list item
CListCtrl::SetItemText(m_ptEditting.x, m_ptEditting.y, str);
_UnsetSortedColumn();
GetParent()->SendMessage(WM_EDIT_COMMITTED, (WPARAM)m_ptEditting.x, (LPARAM)m_ptEditting.y);
}
m_pWndEdit->ShowWindow(SW_HIDE);
m_ptEditting.x = -1;
m_ptEditting.y = -1;
return bChanged;
}
BOOL CReportCtrl::SetHeaderImage(int nColumn, int nImageIndex, BOOL bLeftSide)
{
if (GetHeaderCtrl()->GetImageList() == NULL)
CListCtrl::GetHeaderCtrl()->SetImageList(GetImageList());
HDITEM hi;
::memset(&hi, 0, sizeof(HDITEM));
hi.mask = HDI_FORMAT;
if (!GetHeaderCtrl()->GetItem(nColumn, &hi))
return FALSE;
hi.mask |= HDI_IMAGE;
hi.fmt |= HDF_IMAGE;
if (!bLeftSide)
hi.fmt |= HDF_BITMAP_ON_RIGHT; // draw the image on right side of text
hi.iImage = nImageIndex;
return CListCtrl::GetHeaderCtrl()->SetItem(nColumn, &hi);
}
int CReportCtrl::GetSortedColumn() const
{
return m_nSortCol;
}
BOOL CReportCtrl::IsSortAscending() const
{
return m_bSortAscending;
}
void CReportCtrl::_UnsetSortedColumn()
{
m_nSortCol = -1;
m_bSortAscending = TRUE;
}
DWORD CReportCtrl::_GetHeaderTextFormat(int nColumn) const
{
if (!HasColumnHeader())
return ES_LEFT;
HDITEM hd;
hd.mask = HDI_FORMAT;
if (!GetHeaderCtrl()->GetItem(nColumn, &hd))
return ES_LEFT;
if (hd.fmt & HDF_CENTER)
{
return ES_CENTER;
}
else if (hd.fmt & HDF_RIGHT)
{
return ES_RIGHT;
}
else
{
return ES_LEFT;
}
}
int CReportCtrl::GetHeaderImage(int nColumn) const
{
HDITEM hi;
::memset(&hi, 0, sizeof(HDITEM));
hi.mask = HDI_IMAGE;
return !GetHeaderCtrl()->GetItem(nColumn, &hi) ? hi.iImage : -1;
}
CImageList* CReportCtrl::SetHeaderImageList(CImageList *pImageList)
{
return CListCtrl::GetHeaderCtrl()->SetImageList(pImageList);
}
CImageList* CReportCtrl::SetHeaderImageList(UINT nBitmapID, COLORREF crMask)
{
m_headerImgList.Create(nBitmapID, 16, 4, crMask);
return SetHeaderImageList(&m_headerImgList);
}
BOOL CReportCtrl::ExamItemStates(int nItem, DWORD dwStates) const
{
if (dwStates == RC_ITEM_NONE)
return FALSE;
if (dwStates & RC_ITEM_ALL)
return TRUE;
return (GetItemStates(nItem) & dwStates) == dwStates;
}
int CReportCtrl::GetItemCount(DWORD dwStates) const
{
const int ITEMS = CListCtrl::GetItemCount();
if (dwStates == RC_ITEM_ALL)
return ITEMS;
int nCount = 0;
for (int i = 0; i <ITEMS; i++)
{
if (ExamItemStates(i, dwStates))
nCount++;
}
return nCount;
}
int CReportCtrl::GetFirstItem(DWORD dwStates, int nStartAfter) const
{
const int ITEMS = CListCtrl::GetItemCount();
nStartAfter = max(-1, nStartAfter);
for (int i = nStartAfter + 1; i <ITEMS; i++)
{
if (ExamItemStates(i, dwStates))
return i;
}
return -1;
}
int CReportCtrl::GetLastItem(DWORD dwStates, int nStartBefore) const
{
const int ITEMS = CListCtrl::GetItemCount();
nStartBefore = nStartBefore < 0 ? ITEMS - 1 : min(ITEMS, nStartBefore);
for (int i = nStartBefore - 1; i >= 0; i--)
{
if (ExamItemStates(i, dwStates))
return i;
}
return -1;
}
void CReportCtrl::InvertItems(int nType)
{
const int ITEMS = CListCtrl::GetItemCount();
if (nType == RC_INVERT_SELECTION)
{
for (int i = 0; i < ITEMS; i++)
SetItemStates(i, ExamItemStates(i, RC_ITEM_SELECTED) ? RC_ITEM_UNSELECTED : RC_ITEM_SELECTED);
}
else if (nType == RC_INVERT_CHECKMARK)
{
for (int i = 0; i < ITEMS; i++)
SetItemStates(i, ExamItemStates(i, RC_ITEM_CHECKED) ? RC_ITEM_UNCHECKED : RC_ITEM_CHECKED);
}
}
DWORD CReportCtrl::GetItemStates(int nItem) const
{
DWORD dwStates = 0;
if (CListCtrl::GetItemState(nItem, LVIS_SELECTED))
dwStates |= RC_ITEM_SELECTED;
else
dwStates |= RC_ITEM_UNSELECTED;
if (CListCtrl::GetCheck(nItem) > 0)
dwStates |= RC_ITEM_CHECKED;
else
dwStates |= RC_ITEM_UNCHECKED;
if (CListCtrl::GetItemState(nItem, LVIS_FOCUSED))
dwStates |= RC_ITEM_FOCUSED;
else
dwStates |= RC_ITEM_UNFOCUSED;
return dwStates;
}
BOOL CReportCtrl::SetItemStates(int nItem, DWORD dwNewStates)
{
BOOL bResult = _SetItemStatesNoVerify(nItem, dwNewStates);
if (dwNewStates & RC_ITEM_CHECKED)
_EnsureSingleCheck(nItem);
return bResult;
}
int CReportCtrl::SetAllItemStates(DWORD dwOldStates, DWORD dwNewStates)
{
if (dwNewStates == RC_ITEM_NONE || dwOldStates == RC_ITEM_NONE)
return 0;
int nCount = 0;
const int ITEMS = CListCtrl::GetItemCount();
for (int i = 0; i < ITEMS; i++)
{
if (dwOldStates == RC_ITEM_ALL || ExamItemStates(i, dwOldStates))
{
SetItemStates(i, dwNewStates);
nCount++;
}
}
if (dwNewStates & RC_ITEM_CHECKED)
_EnsureSingleCheck(-1);
return nCount;
}
void CReportCtrl::_EnsureSingleCheck(int nItem)
{
if (m_nChkStyle == RC_CHKBOX_SINGLE)
{
const int FIRST = nItem < 0 ? GetFirstItem(RC_ITEM_CHECKED) : nItem;
if (FIRST >= 0)
{
const int ITEMS = CListCtrl::GetItemCount();
for (int i = FIRST + 1; i < ITEMS; i++)
{
if (CListCtrl::GetCheck(i))
CListCtrl::SetCheck(i, FALSE);
}
}
}
}
BOOL CReportCtrl::_SetItemStatesNoVerify(int nItem, DWORD dwNewStates)
{
if (dwNewStates == RC_ITEM_NONE)
return FALSE;
BOOL bResult = TRUE;
if (dwNewStates & RC_ITEM_SELECTED)
bResult &= CListCtrl::SetItemState(nItem, LVIS_SELECTED, LVIS_SELECTED);
if (dwNewStates & RC_ITEM_UNSELECTED)
bResult &= CListCtrl::SetItemState(nItem, 0, LVIS_SELECTED);
if (dwNewStates & RC_ITEM_CHECKED)
bResult &= CListCtrl::SetCheck(nItem, TRUE);
if (dwNewStates & RC_ITEM_UNCHECKED)
bResult &= CListCtrl::SetCheck(nItem, FALSE);
if (dwNewStates & RC_ITEM_FOCUSED)
bResult &= CListCtrl::SetItemState(nItem, LVIS_FOCUSED, LVIS_FOCUSED);
if (dwNewStates & RC_ITEM_UNFOCUSED)
bResult &= CListCtrl::SetItemState(nItem, 0, LVIS_FOCUSED);
return bResult;
}
BOOL CReportCtrl::SetCheck(int nItem, BOOL bCheck)
{
const BOOL RES = CListCtrl::SetCheck(nItem, bCheck);
if (RES && bCheck)
_EnsureSingleCheck(nItem);
return RES;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -