ユーザーに表示される 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 ループは、VISIBLE であるすべてのアイテムを提供する必要があります (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
}
}
これは、このメッセージの冒頭で期待したとおりに機能しています。私は可視性関数の読みやすさを望んでいますが、実際に機能させる必要があるため、四角形の比較に行き詰まっています。