📄 xlistctrl.cpp
字号:
ASSERT(nSubItem >= 0);
ASSERT(nSubItem < GetColumns());
if ((nSubItem < 0) || nSubItem >= GetColumns())
return FALSE;
XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) CListCtrl::GetItemData(nItem);
if (!pXLCD)
{
return FALSE;
}
crText = pXLCD[nSubItem].crText;
crBackground = pXLCD[nSubItem].crBackground;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// SetItemColors
void CXListCtrl::SetItemColors(int nItem, //+++
int nSubItem,
COLORREF crText,
COLORREF crBackground)
{
ASSERT(nItem >= 0);
ASSERT(nItem < GetItemCount());
if ((nItem < 0) || nItem >= GetItemCount())
return;
ASSERT(nSubItem >= 0);
ASSERT(nSubItem < GetColumns());
if ((nSubItem < 0) || nSubItem >= GetColumns())
return;
XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) CListCtrl::GetItemData(nItem);
if (pXLCD)
{
pXLCD[nSubItem].crText = crText;
pXLCD[nSubItem].crBackground = crBackground;
}
}
///////////////////////////////////////////////////////////////////////////////
// SetComboBox
//
// Note: SetItemText may also be used to set the initial combo selection.
//
BOOL CXListCtrl::SetComboBox(int nItem,
int nSubItem,
BOOL bEnableCombo,
CStringArray *psa, // should not be allocated on stack
int nComboListHeight,
int nInitialComboSel,
BOOL bSort /*= FALSE*/)
{
ASSERT(nItem >= 0);
ASSERT(nItem < GetItemCount());
if ((nItem < 0) || nItem >= GetItemCount())
return FALSE;
ASSERT(nSubItem >= 0);
ASSERT(nSubItem < GetColumns());
if ((nSubItem < 0) || nSubItem >= GetColumns())
return FALSE;
ASSERT(psa);
if (!psa)
return FALSE;
ASSERT(nComboListHeight > 0);
ASSERT(nInitialComboSel >= 0 && nInitialComboSel < psa->GetSize());
if ((nInitialComboSel < 0) || (nInitialComboSel >= psa->GetSize()))
nInitialComboSel = 0;
XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) CListCtrl::GetItemData(nItem);
if (!pXLCD)
{
return FALSE;
}
// update flag
pXLCD[nSubItem].bCombo = bEnableCombo;
if (bEnableCombo)
{
// sort CStringArray before setting initial selection
if (bSort)
CSortCStringArray::SortCStringArray(psa);
//...........................changed by kuan
pXLCD[nSubItem].sa.RemoveAll();
for(int i=0;i<psa->GetSize();i++)
pXLCD[nSubItem].sa.Add(psa->GetAt(i));
//...............................
//pXLCD[nSubItem].psa = psa; //ori code
pXLCD[nSubItem].nComboListHeight = nComboListHeight;
pXLCD[nSubItem].nInitialComboSel = nInitialComboSel;
pXLCD[nSubItem].bSort = bSort;
CString str = _T("");
/*
if ((pXLCD[nSubItem].nInitialComboSel >= 0) &&
(pXLCD[nSubItem].psa->GetSize() > pXLCD[nSubItem].nInitialComboSel))
{
int index = pXLCD[nSubItem].nInitialComboSel;
str = pXLCD[nSubItem].psa->GetAt(index);
}
*/
//....................................add by kuan
if ((pXLCD[nSubItem].nInitialComboSel >= 0) &&
(pXLCD[nSubItem].sa.GetSize() > pXLCD[nSubItem].nInitialComboSel))
{
int index = pXLCD[nSubItem].nInitialComboSel;
str = pXLCD[nSubItem].sa.GetAt(index);
}
//...............................................
SetItemText(nItem, nSubItem, str);
}
UpdateSubItem(nItem, nSubItem);
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// GetComboText
//
// Actually this does nothing more than GetItemText()
//
CString CXListCtrl::GetComboText(int nItem, int nSubItem)
{
ASSERT(nItem >= 0);
ASSERT(nItem < GetItemCount());
if ((nItem < 0) || nItem >= GetItemCount())
return _T("");
ASSERT(nSubItem >= 0);
ASSERT(nSubItem < GetColumns());
if ((nSubItem < 0) || nSubItem >= GetColumns())
return _T("");
CString str;
str = _T("");
str = GetItemText(nItem, nSubItem);
return str;
}
///////////////////////////////////////////////////////////////////////////////
// SetCurSel
BOOL CXListCtrl::SetCurSel(int nItem, BOOL bEnsureVisible /*= FALSE*/)
{
BOOL bRet = SetItemState(nItem, LVIS_FOCUSED | LVIS_SELECTED,
LVIS_FOCUSED | LVIS_SELECTED);
//+++
if (bEnsureVisible)
EnsureVisible(nItem, FALSE);
return bRet;
}
///////////////////////////////////////////////////////////////////////////////
// GetCurSel - returns selected item number, or -1 if no item selected
//
// Note: for single-selection lists only
//
int CXListCtrl::GetCurSel()
{
POSITION pos = GetFirstSelectedItemPosition();
int nSelectedItem = -1;
if (pos != NULL)
nSelectedItem = GetNextSelectedItem(pos);
return nSelectedItem;
}
///////////////////////////////////////////////////////////////////////////////
// UpdateSubItem
void CXListCtrl::UpdateSubItem(int nItem, int nSubItem)
{
ASSERT(nItem >= 0);
ASSERT(nItem < GetItemCount());
if ((nItem < 0) || nItem >= GetItemCount())
return;
ASSERT(nSubItem >= 0);
ASSERT(nSubItem < GetColumns());
if ((nSubItem < 0) || nSubItem >= GetColumns())
return;
CRect rect;
if (nSubItem == -1)
{
GetItemRect(nItem, &rect, LVIR_BOUNDS);
}
else
{
GetSubItemRect(nItem, nSubItem, LVIR_BOUNDS, rect);
}
rect.InflateRect(2, 2);
InvalidateRect(&rect);
UpdateWindow();
}
///////////////////////////////////////////////////////////////////////////////
// GetColumns
int CXListCtrl::GetColumns()
{
return GetHeaderCtrl()->GetItemCount();
}
///////////////////////////////////////////////////////////////////////////////
// GetItemData
//
// The GetItemData and SetItemData functions allow for app-specific data
// to be stored, by using an extra field in the XLISTCTRLDATA struct.
//
DWORD CXListCtrl::GetItemData(int nItem)
{
ASSERT(nItem >= 0);
ASSERT(nItem < GetItemCount());
if ((nItem < 0) || nItem >= GetItemCount())
return 0;
XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) CListCtrl::GetItemData(nItem);
if (!pXLCD)
{
return 0;
}
return pXLCD->dwItemData;
}
///////////////////////////////////////////////////////////////////////////////
// SetItemData
BOOL CXListCtrl::SetItemData(int nItem, DWORD dwData)
{
ASSERT(nItem >= 0);
ASSERT(nItem < GetItemCount());
if ((nItem < 0) || nItem >= GetItemCount())
return FALSE;
XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) CListCtrl::GetItemData(nItem);
if (!pXLCD)
{
return FALSE;
}
pXLCD->dwItemData = dwData;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// GetHeaderCheckedState
//
// The GetHeaderCheckedState and SetHeaderCheckedState may be used to toggle
// the checkbox in a column header.
// 0 = no checkbox
// 1 = unchecked
// 2 = checked
//
int CXListCtrl::GetHeaderCheckedState(int nSubItem)
{
ASSERT(nSubItem >= 0);
ASSERT(nSubItem < GetColumns());
if ((nSubItem < 0) || nSubItem >= GetColumns())
return -1;
HDITEM hditem;
// use the image index (0 or 1) to indicate the checked status
hditem.mask = HDI_IMAGE;
m_HeaderCtrl.GetItem(nSubItem, &hditem);
return hditem.iImage;
}
///////////////////////////////////////////////////////////////////////////////
// SetHeaderCheckedState
BOOL CXListCtrl::SetHeaderCheckedState(int nSubItem, int nCheckedState)
{
ASSERT(nSubItem >= 0);
ASSERT(nSubItem < GetColumns());
if ((nSubItem < 0) || nSubItem >= GetColumns())
return FALSE;
ASSERT(nCheckedState == 0 || nCheckedState == 1 || nCheckedState == 2);
HDITEM hditem;
hditem.mask = HDI_IMAGE;
hditem.iImage = nCheckedState;
m_HeaderCtrl.SetItem(nSubItem, &hditem);
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// OnColumnClick
BOOL CXListCtrl::OnColumnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
// XLISTCTRL_TRACE(_T("in CXListCtrl::OnColumnClick\n"));
NMLISTVIEW* pnmlv = (NMLISTVIEW*)pNMHDR;
int nSubItem = pnmlv->iSubItem;
int nCheckedState = GetHeaderCheckedState(nSubItem);
// 0 = no checkbox
if (nCheckedState != XHEADERCTRL_NO_IMAGE)
{
nCheckedState = (nCheckedState == 1) ? 2 : 1;
SetHeaderCheckedState(nSubItem, nCheckedState);
m_HeaderCtrl.UpdateWindow();
for (int nItem = 0; nItem < GetItemCount(); nItem++)
{
XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) CListCtrl::GetItemData(nItem);
if (!pXLCD)
{
continue;
}
if (pXLCD[nSubItem].nCheckedState != -1)
{
pXLCD[nSubItem].nCheckedState = nCheckedState - 1;
pXLCD[nSubItem].bModified = TRUE;
m_bListModified = TRUE;
UpdateSubItem(nItem, nSubItem);
}
}
}
*pResult = 0;
return FALSE; // return FALSE to send message to parent also -
// NOTE: MSDN documentation is incorrect
}
///////////////////////////////////////////////////////////////////////////////
// CountCheckedItems
int CXListCtrl::CountCheckedItems(int nSubItem)
{
ASSERT(nSubItem >= 0);
ASSERT(nSubItem < GetColumns());
if ((nSubItem < 0) || nSubItem >= GetColumns())
return 0;
int nCount = 0;
for (int nItem = 0; nItem < GetItemCount(); nItem++)
{
XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) CListCtrl::GetItemData(nItem);
if (!pXLCD)
{
continue;
}
if (pXLCD[nSubItem].nCheckedState == 1)
nCount++;
}
return nCount;
}
///////////////////////////////////////////////////////////////////////////////
// GetColors
void CXListCtrl::GetColors()
{
m_cr3DFace = ::GetSysColor(COLOR_3DFACE);
m_cr3DHighLight = ::GetSysColor(COLOR_3DHIGHLIGHT);
m_cr3DShadow = ::GetSysColor(COLOR_3DSHADOW);
m_crActiveCaption = ::GetSysColor(COLOR_ACTIVECAPTION);
m_crBtnFace = ::GetSysColor(COLOR_BTNFACE);
m_crBtnShadow = ::GetSysColor(COLOR_BTNSHADOW);
m_crBtnText = ::GetSysColor(COLOR_BTNTEXT);
m_crGrayText = ::GetSysColor(COLOR_GRAYTEXT);
m_crHighLight = ::GetSysColor(COLOR_HIGHLIGHT);
m_crHighLightText = ::GetSysColor(COLOR_HIGHLIGHTTEXT);
m_crInactiveCaption = ::GetSysColor(COLOR_INACTIVECAPTION);
m_crInactiveCaptionText = ::GetSysColor(COLOR_INACTIVECAPTIONTEXT);
m_crWindow = ::GetSysColor(COLOR_WINDOW);
m_crWindowText = ::GetSysColor(COLOR_WINDOWTEXT);
}
///////////////////////////////////////////////////////////////////////////////
// OnSysColorChange
void CXListCtrl::OnSysColorChange()
{
// XLISTCTRL_TRACE(_T("in CXListCtrl::OnSysColorChange\n"));
CListCtrl::OnSysColorChange();
GetColors();
}
#ifndef DO_NOT_INCLUDE_XCOMBOLIST
///////////////////////////////////////////////////////////////////////////////
// OnTimer
//
// Timer usage:
// 1 - Unlock window updates - used to avoid flashing after combo is created
// used to check if combo button needs to be unpressed,set in
// OnLButtonDown (when combo button is clicked)
// 2 - used to close combo listbox, set in OnComboEscape (user hits Escape
// or listbox loses focus)
// 3 - used to get combo listbox selection, then close combo listbox,
// set in OnComboReturn and OnComboLButtonUp (user hits Enter
// or clicks on item in listbox)
// 4 - used to get combo listbox selection, set in OnComboKeydown (for
// example, user hits arrow key in listbox)
//
void CXListCtrl::OnTimer(UINT nIDEvent)
{
if (nIDEvent == 1) // timer set when combo is created
{
KillTimer(nIDEvent);
UnlockWindowUpdate();
}
else if (nIDEvent == 2) // close combo listbox
{
KillTimer(nIDEvent);
// XLISTCTRL_TRACE(_T("timer 2 ~~~~~\n"));
if (m_pCombo)
{
UpdateSubItem(m_nComboItem, m_nComboSubItem);
m_pCombo->DestroyWindow();
delete m_pCombo;
}
m_pCombo = NULL;
}
else if (nIDEvent == 3) // get combo listbox selection, then close combo listbox
{
KillTimer(nIDEvent);
// XLISTCTRL_TRACE(_T("timer 3 ~~~~~\n"));
if (m_pCombo)
{
CString str;
int i = m_pCombo->GetCurSel();
if (i != LB_ERR)
{
m_pCombo->GetLBText(i, str);
if ((m_nComboItem >= 0 && m_nComboItem < GetItemCount()) &&
(m_nComboSubItem >= 0 && m_nComboSubItem < GetColumns()))
{
SetItemText(m_nComboItem, m_nComboSubItem, str);
UpdateSubItem(m_nComboItem, m_nComboSubItem);
if (str != m_strInitialString)
{
// string is not the same, mark item as modified
XLISTCTRLDATA *pXLCD =
(XLISTCTRLDATA *) CListCtrl::GetItemData(m_nComboItem);
if (pXLCD)
{
pXLCD[m_nComboSubItem].bModified = TRUE;
m_bListModified = TRUE;
}
}
CWnd *pWnd = GetParent();
if (!pWnd)
pWnd = GetOwner();
if (pWnd && ::IsWindow(pWnd->m_hWnd))
pWnd->SendMessage(WM_XLISTCTRL_COMBO_SELECTION,
m_nComboItem, m_nComboSubItem);
}
}
m_pCombo->DestroyWindow();
delete m_pCombo;
}
m_pCombo = NULL;
}
else if (nIDEvent == 4) // get combo listbox selection
{
KillTimer(nIDEvent);
// XLISTCTRL_TRACE(_T("timer 4 ~~~~~\n"));
if (m_pCombo)
{
CString str;
int i = m_pCombo->GetCurSel();
if (i != LB_ERR)
{
m_pCombo->GetLBText(i, str);
if ((m_nComboItem >= 0 && m_nComboItem < GetItemCount()) &&
(m_nComboSubItem >= 0 && m_nComboSubItem < GetColumns()))
{
SetItemText(m_nComboItem, m_nComboSubItem, str);
UpdateSubItem(m_nComboItem, m_nComboSubItem);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -