我需要处理用户可见的 ListView(在报告模式下)中的所有项目。在调试时,我尝试了这个:
int item;
HWND hlist;
for( item = ListView_GetNextItem( hlist, -1, LVNI_VISIBLEONLY );
item >= 0;
item = ListView_GetNextItem( hlist, item, LVNI_VISIBLEONLY ) )
{
if( ListView_IsItemVisible( hlist, item ) )
{
OutputDebugString("DEBUG: Found a visible item!\n");
}
}
根据文档,GetNextItem 循环应该提供所有可见的项目(在 Vista 或更高版本中,我在 Win7 上)。但是,我的调试显示它实际上提供了 ListView 中的所有项目。
所以我添加了 IsItemVisible 的冗余测试,记录在指定项目为 VISIBLE 时返回 TRUE。不幸的是,对于在 for() 循环中找到的每个项目,它都会返回 FALSE。
显然,我在这里遗漏了一些关键的东西(而且可能很明显),但我完全不知道它可能是什么。哦,FWIW 我正在 Windows 7 Professional x64 下测试,我的构建目标是 WINVER 0x0601(_WIN32_WINNT 也是 0x0601)。
有什么我想念的想法吗?
[更新]
我找到了一种解决方法(见下文),但我仍然很想知道为什么与可见相关的功能都不起作用(对我来说)。
对于任何有兴趣的人,以下是我解决此问题的方法:
LVITEM lvi;
HWND hlist = GetDlgItem( hwnd, LST_ALARMS );
int item;
RECT rcList;
RECT rcItem;
RECT rcHead;
GetClientRect( hlist, &rcList );
// Remove the header space from the visible item area
GetClientRect( ListView_GetHeader(hlist), &rcHead );
rcList.top += (rcHead.bottom - rcHead.top);
memset( &lvi, 0, sizeof(lvi) );
for( item = ListView_GetNextItem( hlist, -1, LVNI_ALL );
item >= 0;
item = ListView_GetNextItem( hlist, item, LVNI_ALL ) )
{
if( ListView_GetItemRect( hlist, item, &rcItem, LVIR_BOUNDS )
&& (rcList.top <= rcItem.top)
&& (rcItem.bottom <= rcList.bottom) )
{ // This item is COMPLETELY visible
// -- partially visible items are NOT included.
lvi.mask = LVIF_PARAM;
lvi.iItem = item;
ListView_GetItem( hlist, &lvi );
// do stuff with item
}
}
这与我希望本消息开头的内容完全一样。我更喜欢可见性函数的更易读性,但由于我需要它来实际工作,所以我无法比较矩形。