因为列表框里需要显示的数据多达10万条或者几十万,我不得不用虚拟列表视。虚拟列表视CListView中列表框风格必须为LVS_OWNERDATA。虚拟列表中数据的填充已经实现,已经达到填充数据所花时间与记录数无关的目的。
现在的问题是,我需要在列表框里实现查找功能,很明显我不能用遍历每行的方式。列表框里每行有5列,我怎么根据其中某项可能的值快速定位出某行?
我知道若风格不为LVS_OWNERDATA,在一个普通列表框里根据第一列(仅限于第一列)的值查找是可以的。例如:
LVFINDINFO info;
info.psz="109";//第一列目标值
info.flags=LVFI_PARTIAL|LVFI_STRING;
int nIndex=GetListCtrl().FindItem(&info);//可以正确得到第一列为"109"的行号
但这里风格不为LVS_OWNERDATA才行,并且只能根据第一列的值查!
是不是需要用到诸如:
LVITEM lparam;
lparam.iSubItem=4;
lparam.mask=LVIF_TEXT;
sprintf(lparam.pszText,strTime);info.flags=LVFI_PARAM;
info.lParam=lparam;//?这句类型不匹配报错
请高手赐教!分不够只管说。
现在的问题是,我需要在列表框里实现查找功能,很明显我不能用遍历每行的方式。列表框里每行有5列,我怎么根据其中某项可能的值快速定位出某行?
我知道若风格不为LVS_OWNERDATA,在一个普通列表框里根据第一列(仅限于第一列)的值查找是可以的。例如:
LVFINDINFO info;
info.psz="109";//第一列目标值
info.flags=LVFI_PARTIAL|LVFI_STRING;
int nIndex=GetListCtrl().FindItem(&info);//可以正确得到第一列为"109"的行号
但这里风格不为LVS_OWNERDATA才行,并且只能根据第一列的值查!
是不是需要用到诸如:
LVITEM lparam;
lparam.iSubItem=4;
lparam.mask=LVIF_TEXT;
sprintf(lparam.pszText,strTime);info.flags=LVFI_PARAM;
info.lParam=lparam;//?这句类型不匹配报错
请高手赐教!分不够只管说。
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
LV_ITEM* pItem= &(pDispInfo)->item;int iItemIndx= pItem->iItem;if (pItem->mask & LVIF_TEXT) //valid text buffer?
{
switch(pItem->iSubItem){
case 0: //fill in main text
lstrcpy(pItem->pszText,
m_Items[iItemIndx].m_strItemText);
break;
case 1: //fill in sub item 1 text
lstrcpy(pItem->pszText,
m_Items[iItemIndx].m_strSubItem1Text);
break;
case 2: //fill in sub item 2 text
lstrcpy(pItem->pszText,
m_Items[iItemIndx].m_strSubItem2Text);
break;
}
}if pItem->mask & LVIF_IMAGE) //valid image?
pItem->iImage=
m_Items[iItemIndx].m_iImageIndex;里面的iItemIndx就是虚表行号(从0开始)。明白了这个处理函数,就明白如何查找某项数据了。
这部分代码我程序里有啊,看了你的回帖我还是不知道怎么实现,您就明说吧!我的这部分代码为:
void CTableView::OnGetdispinfo(NMHDR* pNMHDR, LRESULT* pResult)
{
int iIndexs[]=
{
0,4,1,2,3
}; LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
TCHAR szValue[MAX_PATH];
VARIANT varValue;
long index = pDispInfo->item.iItem;
long subItem = pDispInfo->item.iSubItem;
FieldsPtr pFields = m_pRst->Fields;
FieldPtr pField=NULL;
if(pDispInfo->item.mask & LVIF_TEXT)
{
CString strVal;
try
{
m_pRst->PutAbsolutePosition((enum PositionEnum)(index+1));
}
catch(_com_error &e)
{
_bstr_t bstr=e.Description();
return;
} try
{
varValue=pFields->Item[short(iIndexs[subItem])]->GetValue();
strVal=theApp.Format(varValue);
sprintf(szValue,strVal);
}
catch(_com_error &e)
{
_bstr_t bstr=e.Description();
return;
}
lstrcpyn(pDispInfo->item.pszText, szValue, pDispInfo->item.cchTextMax);//set item text
} *pResult = 0;
}
CTableView由CListView继承来。m_Items是啥,我用下列代码:
LPSTR df=GetListCtrl().m_Items[0].pszText;
时怎么出现错误:
'm_Items' : is not a member of 'CListCtrl'
'm_Items' 不是CListCtrl的成员变量。
究竟怎么实现快速查找?
比如现在的虚表可以显示100万行数据,有3列。当拖动垂直滚动条到某个位置时,需要显示第1000列到1100列的数据,就会产生1001条LVN_GETDISPINFO通知。OnGetdispinfo()解析第一条通知,通过pItem->iItem知道现在要显示第1000行的数据,它的第0列文字是m_Items[iItemIndx].m_strItemText,第1列文字是m_Items[iItemIndx].m_strSubItem1Text,第2列文字是m_Items[iItemIndx].m_strSubItem2Text。如果虚表没有图片,就不用考虑pItem->mask & LVIF_IMAGE了。后面的1000条通知同样处理。
快速查找就是针对结构数组m_Items[]的。
以上假定list control是report样式。
不知道我说的对不对?
马上要结贴了,分看来全都是你的了。
//建立索引
pRs->Fields->GetItem("field4")->Properties->GetItem("Optimize")->PutValue("True");
//开始查询
HRESULT hr=pRs->Find("field4= xxx",0,adSearchForward,"");
if(hr==S_OK)
{
_variant_t var=pRs->Book;//得到标签
int iRow=int(var.dblVal);//返回记录集的行号也就是列表框的行号!
}