virtual list control scrolling is painfully slow
So you create a LVS_OWNERDATA
(virtual) list-view control and set its style to LVS_REPORT
. Btw, isn't a rectangle of (0,0,20,20) too small? But I see you are using the same coordinates for other controls as well, so I guess you re-arrange them later (code not shown here).
The function processing the LVN_GETDISPINFO
notification must be declared in your class's message-map, to associate the function to the message:
BEGIN_MESSAGE_MAP(CAlbumView, ...)
.
.
ON_NOTIFY(LVN_GETDISPINFO, IDC_LISTCTRL, &CAlbumView::OnLvnGetdispinfoListCtlr)
END_MESSAGE_MAP()
This is what wizard-generated code would look like, if you didn't subclass from CMFCListControl
and instead simply used CMFCListControl
as is. But you create the control yourself, so please disregard this remark if you have correctly made the aforementioned declaration in the child class's message-map and you found that the function is actually called (debug or trace).
I think the reason why your code doesn't work is because you copy the items' texts to a buffer supposedly pointed by the pszText
instead of setting the pszText
pointer. Here is a excerpt from the documentation about the LV_ITEM structure:
pszText
If the structure specifies item attributes, pszText is a pointer to a null-terminated string containing the item text. When responding to an LVN_GETDISPINFO notification, be sure that this pointer remains valid until after the next notification has been received.
Also:cchTextMax
This member is only used when the structure receives item attributes. ... It is read-only during LVN_GETDISPINFO and other LVN_ notifications.
And the example in the LVN_GETDISPINFO documentation does exactly this.
So, your code could be changed as shown below:
void CAlbumListCtrl::OnLvnGetdispinfo(NMHDR *pNMHDR, LRESULT *pResult)
{
NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
LVITEM &Item = (pDispInfo)->item;
CString csTemp;
static TCHAR _szItemId[20]; // Persistent buffer
ASSERT(m_pLibrary);
if (!m_pLibrary)
AfxThrowMemoryException();
const CImageEntry *pEntry = m_pLibrary->GetImageEntryAt((size_t)Item.iItem);
if (Item.mask & LVIF_TEXT) //Item/subItem text
{
switch (Item.iSubItem)
{
case 0: //fill in ID
csTemp.Format(_T("%ld"), pEntry->GetItemId());
_tcscpy_s(_szItemId, csTemp);
Item.pszText = _szItemId;
break;
case 1: //fill in sub item 1 text
Item.pszText = pEntry->GetItemName().c_str();
break;
case 2: //fill in sub item 2 text
Item.pszText = pEntry->GetPathName().c_str();
break;
case 3: //fill in sub item 3 text
Item.pszText = m_pLibrary->GetImageEntryType(pEntry).c_str();
break;
default:
break;
}
}
*pResult = 0;
}
Notes:
- I only modified this code in a text editor, it's not actually tested. It may need some minor fixes to even compile.
- The
InsertItem()
andDeleteAllItems()
calls (along with that browsing of the list) must be removed, as the control does not really store any content, instead it requests the data of the items being displayed, through the LVN_GETDISPINFO message (referenced by the item's index -iItem
).