虚拟 Listview 控件的(主)缓冲区中应该有多少行?
我将纯“c”中的应用程序与 Win32 API 联系在一起。有一个到数据库的 ODBC 连接,它将检索项目(实际上是行)。
MSDN 示例代码暗示末端缓存有一个固定大小的 30 缓冲区(这几乎肯定不是最佳的)。我认为最终缓存和主缓存应该是相同的大小。
我的想法是缓冲区应该超过列表视图一次可以显示的最大项目数。我想这可以在每次调整 Listivew 大小时重新计算?
或者,使用较大的固定值是否更好。如果是这样,那价值是多少?
LVN_ODCACHEHINT通知消息将让您知道它将询问多少项目。这可以帮助您确定缓存的大小。
使用 ListView_ApproximateViewRect(或 LVM_APPROXIMATEVIEWRECT 消息)获取视图矩形高度。
使用 ListView_GetItemRect(或 LVM_GETITEMRECT 消息)获取项目的高度。
将视图矩形高度除以项目的高度,以获得可以适合您的视图的项目数。对每个大小事件执行此计算。
然后相应地创建缓冲区。
@Brian R. Bondy Thanks for the explicit help for how to do get the number of items. In fact I was all ready working my way to understanding that it could be done (for list or report view) with ListView_GetCountPerPage, and I would use you way to get it for for the others, though I don't need the ListView_ApproximateViewRect since I will all ready know the new size of the ListView.
@Lars Truijens I am already using the LVN_ODCACHEHINT and had though about using that to set the buffer size, however I need to read to the end of the SQL data to find the last item to get the number of rows returned from ODBC. Since that would be the best time to fill the 'end cache' I think I have to set up the number of items (and therefore fill the buffer) before we get a call to LVN_ODCACHEHIN.
I guess my real question is one of optimization for which I think Brian hinted at the answer. The amount of overhead in trashing your buffer and reallocating memory is smaller than the overhead of going out to the network and doing an ODBC read, some make the buffer fairly small and change it often rather.
Is this right?
I have done a little more playing around, and it seems that think that LVN_ODCACHEHINT generally fills the main buffer correctly, and only misses if a row (in report mode) is partially visible.
So I think the answer for the size of the cache is: The total number of displayed items, plus one row of displayed items (since in the icons views you have multiple items per row).
You would then re-read the cache with each WM_SIZE and LVN_ODCACHEHINT if either had a different begin and end item number.
The answer would seem to be: (Or a random collection of notes as I fiddle around with ideas)
As a general answer for buffers: Start with some amount, in this case a screen full (I add an extra row in case the next is partially uncovered), and then every time the screen is scrolled, double the buffer size (up to the point before you run out of memory).
Which would seem to be wrong. As it turns out, most ways of loading data are all ready buffered. ODBC calls of File I/O. Pretty much anything that isn't that I can think off is either in memory or is recalculated on the fly. This means the answer really is: take the values provided in LVN_ODCACHEHINT (and add 1 either side - this just seems to work faster if you don't have an integral height).