📄 reportctrl.cpp
字号:
_UnsetSortedColumn();
return CListCtrl::SetItemText(nItem, nSubItem, lpText);
}
int CReportCtrl::GetColumnCount() const
{
return GetHeaderCtrl()->GetItemCount();
}
int CReportCtrl::InsertItem(const LVITEM *pItem)
{
EndEdit(TRUE);
_UnsetSortedColumn();
const int IDX = CListCtrl::InsertItem(pItem);
if (IDX >= 0)
_AllocItemMemory(IDX);
return IDX;
}
int CReportCtrl::InsertItem(int nItem, LPCTSTR lpItem, int nImage)
{
EndEdit(TRUE);
_UnsetSortedColumn();
const int IDX = CListCtrl::InsertItem(nItem, lpItem, nImage);
if (IDX >= 0)
_AllocItemMemory(IDX);
return IDX;
}
int CReportCtrl::InsertItem(UINT nMask, int nItem, LPCTSTR lpItem, UINT nState, UINT nStateMask, int nImage, LPARAM lParam)
{
EndEdit(TRUE);
_UnsetSortedColumn();
const int IDX = CListCtrl::InsertItem(nMask, nItem, lpItem, nState, nStateMask, nImage, lParam);
if (IDX >= 0)
_AllocItemMemory(IDX);
return IDX;
}
void CReportCtrl::SetGridLines(BOOL bSet)
{
DWORD dwStype = GetExtendedStyle();
if (bSet)
dwStype |= LVS_EX_GRIDLINES;
else
dwStype &= ~LVS_EX_GRIDLINES;
SetExtendedStyle(dwStype);
}
int CReportCtrl::InsertColumn(int nCol, const LVCOLUMN *pColumn)
{
EndEdit(TRUE);
const int IDX = CListCtrl::InsertColumn(nCol, pColumn);
if (IDX >= 0)
_UpdateColumn(IDX, TRUE);
return IDX;
}
int CReportCtrl::InsertColumn(int nCol, LPCTSTR lpColumnHeading, int nFormat, int nWidth, int nSubItem)
{
EndEdit(TRUE);
const int IDX = CListCtrl::InsertColumn(nCol, lpColumnHeading, nFormat, nWidth, nSubItem);
if (IDX >= 0)
_UpdateColumn(IDX, TRUE);
return IDX;
}
BOOL CReportCtrl::DeleteColumn(int nCol)
{
EndEdit(TRUE);
const BOOL RES = CListCtrl::DeleteColumn(nCol);
if (RES)
_UpdateColumn(nCol, FALSE);
return RES;
}
void CReportCtrl::SetCheckboxeStyle(int nStyle)
{
m_nChkStyle = nStyle;
EndEdit(TRUE);
DWORD dwStype = GetExtendedStyle();
if (nStyle == 0)
{
dwStype &= ~LVS_EX_CHECKBOXES;
}
else
{
dwStype |= LVS_EX_CHECKBOXES;
_EnsureSingleCheck(-1);
}
SetExtendedStyle(dwStype);
}
int CReportCtrl::MoveTo(int nItem, int nNewPosition)
{
if (!_IsValidIndex(nItem))
return -1;
EndEdit(TRUE);
const int ITEMS = CListCtrl::GetItemCount();
nNewPosition = max(0, nNewPosition);
nNewPosition = min(ITEMS - 1, nNewPosition);
if (nItem == nNewPosition)
return nNewPosition;
_UnsetSortedColumn();
// Backup all states and attributes
const int COLS = GetColumnCount();
const DWORD STATES = GetItemStates(nItem);
const DWORD DATA = CListCtrl::GetItemData(nItem);
CArray<int, int> aImages;
CStringArray aTexts;
aImages.SetSize(COLS);
aTexts.SetSize(COLS);
for (int i = 0; i < COLS; i++)
{
aImages[i] = GetItemImage(nItem, i);
aTexts[i] = GetItemText(nItem, i);
}
// Delete the item
CListCtrl::DeleteItem(nItem);
// Insert a new item to the new position
const int IDX = CListCtrl::InsertItem(nNewPosition, "");
// Restore all states & attributes to the newly inserted item
for (int j = 0; j < COLS; j++)
{
CListCtrl::SetItemText(IDX, j, aTexts[j]);
SetItemImage(IDX, j, aImages[j]);
}
CListCtrl::SetItemData(IDX, DATA);
SetItemStates(IDX, STATES);
return IDX;
}
int CReportCtrl::MoveUp(int nItem, int nCount)
{
return MoveTo(nItem, nItem - nCount);
}
BOOL CReportCtrl::MoveDown(int nItem, int nCount)
{
return MoveTo(nItem, nItem + nCount);
}
BOOL CReportCtrl::SwapItems(int nItem1, int nItem2)
{
EndEdit(TRUE);
if (!_IsValidIndex(nItem1) || !_IsValidIndex(nItem2))
return FALSE;
if (nItem1 == nItem2)
return TRUE;
_UnsetSortedColumn();
// record previous states first
const DWORD STATES1 = GetItemStates(nItem1);
const DWORD STATES2 = GetItemStates(nItem2);
const DWORD DATA1 = CListCtrl::GetItemData(nItem1);
const DWORD DATA2 = CListCtrl::GetItemData(nItem2);
// swap item texts and images
for (int i = 0; i < GetColumnCount(); i++)
{
CString str = GetItemText(nItem1, i);
CListCtrl::SetItemText(nItem1, i, GetItemText(nItem2, i));
CListCtrl::SetItemText(nItem2, i, str);
UINT nImg = GetItemImage(nItem1, i);
SetItemImage(nItem1, i, GetItemImage(nItem2, i));
SetItemImage(nItem2, i, nImg);
}
// swap item data
CListCtrl::SetItemData(nItem1, DATA2);
CListCtrl::SetItemData(nItem2, DATA1);
// restore states
SetItemStates(nItem1, STATES2);
SetItemStates(nItem2, STATES1);
return TRUE;
}
int CReportCtrl::MoveToTop(int nItem)
{
return MoveTo(nItem, -1);
}
int CReportCtrl::MoveToBottom(int nItem)
{
return MoveTo(nItem, INT_MAX);
}
BOOL CReportCtrl::SetItemText(int nItem, int nSubItem, TCHAR val)
{
return SetItemText(nItem, nSubItem, CString(val));
}
BOOL CReportCtrl::SetItemText(int nItem, int nSubItem, INT val)
{
return SetItemText(nItem, nSubItem, (LONG)val);
}
BOOL CReportCtrl::SetItemText(int nItem, int nSubItem, UINT val)
{
return SetItemText(nItem, nSubItem, (ULONG)val);
}
BOOL CReportCtrl::SetItemText(int nItem, int nSubItem, DOUBLE val, int nPrecision)
{
CString sText, sFmt;
if (nPrecision >= 0)
{
sFmt.Format(_T("%%.%df"), nPrecision);
sText.Format(sFmt, val);
}
else
{
sText.Format(_T("%f"), val);
sText.TrimRight(_T('0'));
sText.TrimRight(_T('.'));
}
return SetItemText(nItem, nSubItem, sText);
}
BOOL CReportCtrl::SetItemText(int nItem, int nSubItem, const COleDateTime &dateTime, DWORD dwFlags)
{
return SetItemText(nItem, nSubItem, dateTime.GetStatus() == COleDateTime::valid ? dateTime.Format(dwFlags) : _T(""));
}
BOOL CReportCtrl::SetItemText(int nItem, int nSubItem, LONG val)
{
CString str;
str.Format(_T("%d"), val);
return SetItemText(nItem, nSubItem, str);
}
BOOL CReportCtrl::SetItemText(int nItem, int nSubItem, ULONG val)
{
CString str;
str.Format(_T("%u"), val);
return SetItemText(nItem, nSubItem, str);
}
BOOL CReportCtrl::DeleteAllColumns()
{
while (GetColumnCount() > 0)
DeleteColumn(0);
return TRUE;
}
LPCTSTR CReportCtrl::GetSortSeparator() const
{
return m_pszSeparator;
}
void CReportCtrl::SetSortSeparator(LPCTSTR lpSortSeparator)
{
if (m_pszSeparator != NULL)
{
delete [] m_pszSeparator;
m_pszSeparator = NULL;
}
if (lpSortSeparator != NULL)
m_pszSeparator = _tcsdup(lpSortSeparator);
}
int CReportCtrl::InsertItemEx(int nItem, LPCTSTR lpText, ...)
{
EndEdit(TRUE);
_UnsetSortedColumn();
const int IDX = CListCtrl::InsertItem(nItem, lpText);
if (IDX < 0)
return -1;
va_list list;
va_start(list, lpText);
for(int iColumn = 1; iColumn < GetColumnCount(); iColumn++)
{
LPCTSTR lp = va_arg(list, LPCTSTR);
if (lp != NULL)
{
CListCtrl::SetItemText(IDX, iColumn, lp);
}
else
{
break;
}
}
va_end(list);
if (IDX >= 0)
_AllocItemMemory(IDX);
return IDX;
}
BOOL CReportCtrl::_IsEditVisible() const
{
return m_bAllowEdit
&& m_ptEditting.x >= 0 && m_ptEditting.x < CListCtrl::GetItemCount()
&& m_ptEditting.y >= 0 && m_ptEditting.y < GetColumnCount();
}
void CReportCtrl::SetEditable(BOOL bSet)
{
if (!bSet)
EndEdit(TRUE);
m_bAllowEdit = bSet;
}
BOOL CReportCtrl::IsEditable() const
{
return m_bAllowEdit;
}
BOOL CReportCtrl::_ItemCheckMonitor(int nIndex, BOOL bBefore, BOOL bAfter, UINT nMsg)
{
if (!_IsValidIndex(nIndex)
|| m_nChkStyle == RC_CHKBOX_NONE
|| (bBefore && bAfter)
|| (!bBefore && !bAfter))
{
return FALSE;
}
if (m_nChkStyle == RC_CHKBOX_SINGLE)
{
// Only one item can be checked
if (!bBefore && bAfter)
{
SetAllItemStates(RC_ITEM_CHECKED, RC_ITEM_UNCHECKED); // uncheck all
SetItemStates(nIndex, RC_ITEM_CHECKED);
}
}
else if (m_nChkStyle == RC_CHKBOX_DISABLED)
{
// Cannot change the item checked/unchecked states by mouse clicks
SetItemStates(nIndex, bBefore ? RC_ITEM_CHECKED : RC_ITEM_UNCHECKED);
return TRUE;
}
SetAllItemStates(RC_ITEM_SELECTED, RC_ITEM_UNSELECTED); // unselect all
SetItemStates(nIndex, RC_ITEM_SELECTED | RC_ITEM_FOCUSED);
GetParent()->SendMessage(WM_ON_CHKBOX, (WPARAM)nIndex, (LPARAM)nMsg);
return TRUE;
}
int CReportCtrl::GetCheckboxStyle() const
{
return m_nChkStyle;
}
void CReportCtrl::_StringSplit(const CString &str, CStringArray &arr, TCHAR chDelimitior)
{
int nStart = 0, nEnd = 0;
arr.RemoveAll();
while (nEnd < str.GetLength())
{
// determine the paragraph ("xxx,xxx,xxx;")
nEnd = str.Find(chDelimitior, nStart);
if( nEnd == -1 )
{
// reached the end of string
nEnd = str.GetLength();
}
CString s = str.Mid(nStart, nEnd - nStart);
if (!s.IsEmpty())
arr.Add(s);
nStart = nEnd + 1;
}
}
BOOL CReportCtrl::SetSortable(BOOL bSet)
{
if (!HasColumnHeader())
return FALSE;
LONG lStyle = ::GetWindowLong(GetHeaderCtrl()->GetSafeHwnd(), GWL_STYLE);
if (bSet)
{
lStyle |= HDS_BUTTONS;
}
else
{
lStyle &= ~HDS_BUTTONS;
_UnsetSortedColumn();
}
::SetWindowLong(GetHeaderCtrl()->GetSafeHwnd(), GWL_STYLE, lStyle);
CListCtrl::GetHeaderCtrl()->RedrawWindow();
return TRUE;
}
DWORD CReportCtrl::SetExtendedStyle(DWORD dwNewStyle)
{
dwNewStyle &= ~MUST_NOT_EX_STYLE;
dwNewStyle |= MUST_EX_STYLE;
return CListCtrl::SetExtendedStyle(dwNewStyle);
}
BOOL CReportCtrl::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Add your specialized code here and/or call the base class
cs.style &= ~MUST_NOT_STYLE;
cs.style |= MUST_STYLE;
return CListCtrl::PreCreateWindow(cs);
}
BOOL CReportCtrl::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if (pMsg->message == WM_KEYDOWN)
{
if (!_IsEditVisible())
{
// disable user from check/uncheck the checkboxes using space key
// things get nasty if the user is HOLDING the space bar down
if (pMsg->wParam == VK_SPACE)
return TRUE;
}
else
{
POINT pt = m_ptEditting;
switch (pMsg->wParam)
{
case VK_ESCAPE: // Cancel edit
EndEdit(FALSE);
return TRUE;
case VK_RETURN: // Commit edit
EndEdit(TRUE);
return TRUE;
case VK_TAB: // switch edit sub items
if (pt.y == GetColumnCount() - 1)
pt.y = 0;
else
pt.y++;
EndEdit(TRUE);
StartEdit(pt.x, pt.y);
return TRUE;
case VK_UP: // edit upper item
if (pt.x > 0)
{
pt.x--;
EndEdit(TRUE);
StartEdit(pt.x, pt.y);
EnsureVisible(pt.x, FALSE);
return TRUE;
}
break;
case VK_DOWN: // edit lower item
if (pt.x < CListCtrl::GetItemCount() - 1)
{
pt.x++;
EndEdit(TRUE);
StartEdit(pt.x, pt.y);
EnsureVisible(pt.x, FALSE);
return TRUE;
}
break;
default:
break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -