📄 xlistctrl.cpp
字号:
CListCtrl::OnTimer(nIDEvent);
}
///////////////////////////////////////////////////////////////////////////////
// OnComboEscape
LRESULT CXListCtrl::OnComboEscape(WPARAM, LPARAM)
{
// XLISTCTRL_TRACE(_T("in CXListCtrl::OnComboEscape\n"));
SetTimer(2, 50, NULL);
//UpdateSubItem(m_nComboItem, m_nComboSubItem);
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// OnComboReturn
LRESULT CXListCtrl::OnComboComplete(WPARAM, LPARAM)
{
// XLISTCTRL_TRACE(_T("in CXListCtrl::OnComboComplete\n"));
SetTimer(3, 50, NULL);
return 0;
}
#endif // #ifndef DO_NOT_INCLUDE_XCOMBOLIST
#ifndef NO_XLISTCTRL_TOOL_TIPS
///////////////////////////////////////////////////////////////////////////////
// OnToolHitTest
int CXListCtrl::OnToolHitTest(CPoint point, TOOLINFO * pTI) const
{
LVHITTESTINFO lvhitTestInfo;
lvhitTestInfo.pt = point;
int nItem = ListView_SubItemHitTest(this->m_hWnd, &lvhitTestInfo);
int nSubItem = lvhitTestInfo.iSubItem;
//XLISTCTRL_TRACE(_T("in CToolTipListCtrl::OnToolHitTest: %d,%d\n"), nItem, nSubItem);
UINT nFlags = lvhitTestInfo.flags;
// nFlags is 0 if the SubItemHitTest fails
// Therefore, 0 & <anything> will equal false
if (nFlags & LVHT_ONITEMLABEL)
{
// If it did fall on a list item,
// and it was also hit one of the
// item specific subitems we wish to show tool tips for
// get the client (area occupied by this control
RECT rcClient;
GetClientRect(&rcClient);
// fill in the TOOLINFO structure
pTI->hwnd = m_hWnd;
pTI->uId = (UINT) (nItem * 1000 + nSubItem + 1);
pTI->lpszText = LPSTR_TEXTCALLBACK;
pTI->rect = rcClient;
return pTI->uId; // By returning a unique value per listItem,
// we ensure that when the mouse moves over another
// list item, the tooltip will change
}
else
{
//Otherwise, we aren't interested, so let the message propagate
return -1;
}
}
///////////////////////////////////////////////////////////////////////////////
// OnToolTipText
BOOL CXListCtrl::OnToolTipText(UINT /*id*/, NMHDR * pNMHDR, LRESULT * pResult)
{
UINT nID = pNMHDR->idFrom;
//XLISTCTRL_TRACE(_T("in CXListCtrl::OnToolTipText: id=%d\n"), nID);
// check if this is the automatic tooltip of the control
if (nID == 0)
return TRUE; // do not allow display of automatic tooltip,
// or our tooltip will disappear
// handle both ANSI and UNICODE versions of the message
TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
*pResult = 0;
// get the mouse position
const MSG* pMessage;
pMessage = GetCurrentMessage();
ASSERT(pMessage);
CPoint pt;
pt = pMessage->pt; // get the point from the message
ScreenToClient(&pt); // convert the point's coords to be relative to this control
// see if the point falls onto a list item
LVHITTESTINFO lvhitTestInfo;
lvhitTestInfo.pt = pt;
int nItem = SubItemHitTest(&lvhitTestInfo);
int nSubItem = lvhitTestInfo.iSubItem;
UINT nFlags = lvhitTestInfo.flags;
// nFlags is 0 if the SubItemHitTest fails
// Therefore, 0 & <anything> will equal false
if (nFlags & LVHT_ONITEMLABEL)
{
// If it did fall on a list item,
// and it was also hit one of the
// item specific subitems we wish to show tooltips for
CString strToolTip;
strToolTip = _T("");
XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) CListCtrl::GetItemData(nItem);
if (pXLCD)
{
strToolTip = pXLCD[nSubItem].strToolTip;
}
if (!strToolTip.IsEmpty())
{
// If there was a CString associated with the list item,
// copy it's text (up to 80 characters worth, limitation
// of the TOOLTIPTEXT structure) into the TOOLTIPTEXT
// structure's szText member
#ifndef _UNICODE
if (pNMHDR->code == TTN_NEEDTEXTA)
lstrcpyn(pTTTA->szText, strToolTip, 80);
else
_mbstowcsz(pTTTW->szText, strToolTip, 80);
#else
if (pNMHDR->code == TTN_NEEDTEXTA)
_wcstombsz(pTTTA->szText, strToolTip, 80);
else
lstrcpyn(pTTTW->szText, strToolTip, 80);
#endif
return FALSE; // we found a tool tip,
}
}
return FALSE; // we didn't handle the message, let the
// framework continue propagating the message
}
///////////////////////////////////////////////////////////////////////////////
// SetItemToolTipText
BOOL CXListCtrl::SetItemToolTipText(int nItem, int nSubItem, LPCTSTR lpszToolTipText)
{
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;
XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) CListCtrl::GetItemData(nItem);
if (!pXLCD)
{
return FALSE;
}
pXLCD[nSubItem].strToolTip = lpszToolTipText;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// GetItemToolTipText
CString CXListCtrl::GetItemToolTipText(int nItem, int nSubItem)
{
CString strToolTip;
strToolTip = _T("");
ASSERT(nItem >= 0);
ASSERT(nItem < GetItemCount());
if ((nItem < 0) || nItem >= GetItemCount())
return strToolTip;
ASSERT(nSubItem >= 0);
ASSERT(nSubItem < GetColumns());
if ((nSubItem < 0) || nSubItem >= GetColumns())
return strToolTip;
XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) CListCtrl::GetItemData(nItem);
if (pXLCD)
{
strToolTip = pXLCD[nSubItem].strToolTip;
}
return strToolTip;
}
///////////////////////////////////////////////////////////////////////////////
// DeleteAllToolTips
void CXListCtrl::DeleteAllToolTips()
{
int nRow = GetItemCount();
int nCol = GetColumns();
for (int nItem = 0; nItem < nRow; nItem++)
{
XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) CListCtrl::GetItemData(nItem);
if (pXLCD)
for (int nSubItem = 0; nSubItem < nCol; nSubItem++)
pXLCD[nSubItem].strToolTip = _T("");
}
}
#endif
#ifndef DO_NOT_INCLUDE_XCOMBOLIST
///////////////////////////////////////////////////////////////////////////////
// DrawComboBox
void CXListCtrl::DrawComboBox(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;
// Make sure that nSubItem is valid
ASSERT(GetColumnWidth(nSubItem) >= 5);
if (GetColumnWidth(nSubItem) < 5)
return;
XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) CListCtrl::GetItemData(nItem);
if (!pXLCD)
{
ASSERT(FALSE);
return;
}
if (!pXLCD[0].bEnabled)
return;
#ifdef _DEBUG
DWORD dwExStyle = GetExtendedStyle();
if ((dwExStyle & LVS_EX_FULLROWSELECT) == 0)
{
// XLISTCTRL_TRACE(_T("XListCtrl: combo boxes require LVS_EX_FULLROWSELECT style\n"));
ASSERT(FALSE);
}
#endif
// Get the column offset
int offset = 0;
for (int i = 0; i < nSubItem; i++)
offset += GetColumnWidth(i);
CRect rect;
GetSubItemRect(nItem, nSubItem, LVIR_BOUNDS, rect);
CRect rectClient;
GetClientRect(&rectClient);
m_pCombo = new CXCombo(this);
ASSERT(m_pCombo);
if (m_pCombo)
{
m_nComboItem = nItem;
m_nComboSubItem = nSubItem;
rect.top -= 1;
m_rectComboList = rect;
ClientToScreen(&m_rectComboList);
m_rectComboList.left += 1;
DWORD dwStyle = CBS_DROPDOWNLIST | WS_POPUP | WS_VISIBLE ;
BOOL bSuccess = m_pCombo->CreateEx(WS_EX_CONTROLPARENT,
ADVCOMBOBOXCTRL_CLASSNAME,
_T(""),
dwStyle,
m_rectComboList,
this,
0,
NULL);
if (bSuccess)
{
LockWindowUpdate();
//if (pXLCD[nSubItem].psa)//ori code
if (pXLCD[nSubItem].sa.GetSize()>0)//add by kuan
{
// add strings to combo
CString s = _T("");
try
{
/*//ori code
for (int i = 0; i < pXLCD[nSubItem].psa->GetSize(); i++)
{
s = pXLCD[nSubItem].psa->GetAt(i);
if (!s.IsEmpty())
m_pCombo->AddString(s);
}
*/
//...........................add by kuan
for (int i = 0; i < pXLCD[nSubItem].sa.GetSize(); i++)
{
s = pXLCD[nSubItem].sa.GetAt(i);
if (!s.IsEmpty())
m_pCombo->AddString(s);
}
//......................................
}
catch(...)
{
TRACE(_T("ERROR - exception in CXListCtrl::DrawComboBox\n"));
TRACE(_T("==> Attempting to access psa pointer; string array must be a class\n"));
TRACE(_T("==> variable, a global variable, or allocated on the heap.\n"));
}
}
m_pCombo->SetDefaultVisibleItems(pXLCD[nSubItem].nComboListHeight);
int index = 0;
CString str = _T("");
// Note that strings in combo are sorted in CXListCtrl::SetComboBox()
if (pXLCD[nSubItem].psa)
{
try
{
if ((pXLCD[nSubItem].nInitialComboSel >= 0) &&
(m_pCombo->GetCount() > pXLCD[nSubItem].nInitialComboSel))
{
index = pXLCD[nSubItem].nInitialComboSel;
m_pCombo->GetLBText(index, str);
// XLISTCTRL_TRACE(_T("nInitialComboSel=%d str=<%s>\n"), index, str);
SetItemText(nItem, nSubItem, str);
pXLCD[nSubItem].nInitialComboSel = -1; // default after first time
}
}
catch(...)
{
TRACE(_T("ERROR - exception in CXListCtrl::DrawComboBox\n"));
TRACE(_T("==> Attempting to access psa pointer; string array must be a class\n"));
TRACE(_T("==> variable, a global variable, or allocated on the heap.\n"));
}
}
if (str.IsEmpty())
str = GetItemText(nItem, nSubItem);
if (str.IsEmpty())
{
// str is empty, try to get from first listbox string
if (m_pCombo->GetCount() > 0)
{
m_pCombo->GetLBText(0, str);
index = 0;
}
SetItemText(nItem, nSubItem, str);
}
else
{
// set listbox selection from subitem text
index = m_pCombo->FindStringExact(-1, str);
// XLISTCTRL_TRACE(_T("FindStringExact returned %d\n"), index);
if (index == LB_ERR)
index = 0;
}
m_pCombo->SetCurSel(index);
m_pCombo->GetLBText(index, m_strInitialString);
SetTimer(1, 50, NULL);
}
m_pCombo->Invalidate();
m_pCombo->RedrawWindow();
m_pCombo->BringWindowToTop();
}
}
#endif
///////////////////////////////////////////////////////////////////////////////
// DrawEdit - Start edit of a sub item label
// nItem - The row index of the item to edit
// nSubItem - The column of the sub item.
void CXListCtrl::DrawEdit(int nItem, int nSubItem)
{
// XLISTCTRL_TRACE(_T("in CXListCtrl::DrawEdit\n"));
ASSERT(nItem >= 0);
ASSERT(nItem < GetItemCount());
if ((nItem < 0) || nItem >= GetItemCount())
return;
ASSERT(nSubItem >= 0);
ASSERT(nSubItem < GetColumns());
if ((nSubItem < 0) || nSubItem >= GetColumns())
return;
// Make sure that nSubItem is valid
ASSERT(GetColumnWidth(nSubItem) >= 5);
if (GetColumnWidth(nSubItem) < 5)
return;
XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) CListCtrl::GetItemData(nItem);
if (!pXLCD)
{
ASSERT(FALSE);
return;
}
if (!pXLCD[0].bEnabled)
return;
#ifdef _DEBUG
DWORD dwExStyle = GetExtendedStyle();
if ((dwExStyle & LVS_EX_FULLROWSELECT) == 0)
{
// XLISTCTRL_TRACE(_T("XListCtrl: edit boxes require LVS_EX_FULLROWSELECT style\n"));
ASSERT(FALSE);
}
#endif
// make sure that the item is visible
if (!EnsureVisible(nItem, TRUE))
return;
// get the column offset
int offset = 0;
for (int i = 0; i < nSubItem; i++)
offset += GetColumnWidth(i);
CRect rect;
GetItemRect(nItem, &rect, LVIR_BOUNDS);
// now scroll if we need to expose the column
CRect rectClient;
GetClientRect(&rectClient);
if (offset + rect.left < 0 || offset + rect.left > rectClient.right)
{
CSize size;
size.cx = offset + rect.left;
size.cy = 0;
Scroll(size);
rect.left -= size.cx;
}
// Get Column alignment
LV_COLUMN lvcol;
lvcol.mask = LVCF_FMT;
GetColumn(nSubItem, &lvcol);
DWORD dwStyle = 0;
if ((lvcol.fmt & LVCFMT_JUSTIFYMASK) == LVCFMT_LEFT)
dwStyle = ES_LEFT;
else if ((lvcol.fmt & LVCFMT_JUSTIFYMASK) == LVCFMT_RIGHT)
dwStyle = ES_RIGHT;
else dwStyle = ES_CENTER;
dwStyle |= WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_LEFT /*| WS_BORDER*/ ;
//rect.top -= 2;
rect.bottom += 1;
rect.left += offset + 2;
rect.right = rect.left + GetColumnWidth(nSubItem) - 4;
if (rect.right > rectClient.right)
rect.right = rectClient.right;
m_strInitialString = GetItemText(nItem, nSubItem);
/**************************add by kuan************************////
if (NULL !=m_pEdit)
{
m_pEdit->DestroyWindow();
delete m_pEdit;
m_pEdit=NULL;
}
/*************************************************************///
ASSERT(m_pEdit == NULL);
m_pEdit = new CXEdit(this, m_strInitialString);
if (m_pEdit)
{
BOOL bSuccess = m_pEdit->Create(dwStyle, rect, this, 99);
m_nEditItem = nItem;
m_nEditSubItem = nSubItem;
if (bSuccess)
{
m_pEdit->SetFocus();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -