 |
列表视的回调函数有用于显示文本的和排序的(QA001052 "ListCtrl排序时如何使用回调函数")。如果设置了lV_ITEM中的文本项为LPSTR_TEXTYCALLBACK,那么在ListView不保存文本数据,而是在显示时发LVN_GETDISPINFO消息给你,由你在这时填充文本数据。这样做主要是对于数据量特别大的时候,如果一上来就填充ListView,时间很长而且浪费内存。而采用这种方法后,只有当要显示某个记录时,你才需要提供数据,速度快而且系统资源占用少。下面是一个大致的例子:
// m_pList is of type CListCtrl*
BEGIN_MESSAGE_MAP(CTestView, CView)
ON_NOTIFY (LVN_GETDISPINFO, IDC_LIST, OnGetDispInfo)
END_MESSAGE_MAP()
int CTestView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
// create CListCtrl and columns
...
// insert item; text will be set in LVN_GETDISPINFO
m_pList->InsertItem (iIndex, LPSTR_TEXTCALLBACK);
...
}
void CTestView::OnGetDispInfo (NMHDR* pnmhdr, LRESULT* pResult)
{
LV_DISPINFO* pdi = (LV_DISPINFO *) pnmhdr;
// set text for column #1
if (0 == pdi->item.iSubItem)
pdi->item.pszText = "1st Column Data";
// set text for column #2
else if (1 == pdi->item.iSubItem)
pdi->item.pszText = "2nd Column Data";
// set text for column #3
else if (2 == pdi->item.iSubItem)
pdi->item.pszText = "3rd Column Data";
}
louyumei问:
有个问题我一直看不明白想请教你一下,你能在百忙之中抽点时间看看吗?我是一个VC 的初学者看了一段程序如下:
LVITEM lvI;
lvI.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE; //LVIF_PARAM使用来排序的
lvI.state = 0;
int nCount = m_GtHomeArrayCountry .GetSize();
for(int i=0;i<nCount;i++)
{
ConfGtHomeRecord rd = m_GtHomeArrayCountry[i];
lvI.iItem = i;
lvI.iSubItem = 0;
lvI.lParam = (LPARAM) &rd;
lvI.pszText = LPSTR_TEXTCALLBACK; //这两句不明白
m_listCtrl.InsertItem(&lvI);
}//end for
其中 ConfGtHomeRecord是一个结构定义如下:
typedef struct {
short codePlan;
char gtParty[GT_LEN+1]; /* GT */
int homeId;
short flag;
} ConfGtHomeRecord
其中m_listCtrl是CListCtrl m_listCtrl;定义的
其中m_GtHomeArrayCountry是如下定义的:
typedef CArray ConfGtHomeArray;
ConfGtHomeArray m_GtHomeArrayCountry;
不明白的地方是下面:
lvI.state = 0;这是什么意思呀为什么要等于0呀?
lvI.pszText = LPSTR_TEXTCALLBACK这句也不明白。
lvI.lParam = (LPARAM) &rd;这句也不明白,为什么要把rd 的地址赋值给lvI.lParam
我查了好多资料一直也不明白。
答:lvI.state是用来指定一些特殊效果的,如是否被选中的等。由于这段程序没有使用什么特殊效果,所以赋0也没有什么特别的。
lvI.pszText = LPSTR_TEXTCALLBACK的基本含义在上面已经说过了,只是补充一下lvI.lParam的用法。把rd的地址赋值给lvI.lParam,是为了使数组中的成员和CListCtrl中的对应项关联起来。当系统调用OnGetDispInfo函数时,你可以用下面的方法获得和当前要显示的项对应的ConfGtHomeRecord结构变量:
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
ConfGtHomeRecord* pAppItem = (ConfGtHomeRecord*)pDispInfo->item.lParam;
至于获得了这个指针后要做什么,就看你的程序的OnGetDispInfo函数就可以了。
此问题由李海回答。
附加关键字:编程, 源程序, programming, source code, C/C++, MFC, C++ Builder, Borland C++, Turbo C, C, BCB, Windows 9x控件, listview, treeview, monthview, progress bar。
|