http://bugs.winehq.org/show_bug.cgi?id=12701
--- Comment #9 from Igor Tarasov tarasov.igor@gmail.com 2009-01-31 10:34:49 --- Created an attachment (id=19125) --> (http://bugs.winehq.org/attachment.cgi?id=19125) test patch
I think I've discovered all the bugs:
1. Wrong filtering and case-senisveness:
I've found out that ours listview calls LVM_FINDITEMW and in listview.c:5145 we see this:
if (lpFindInfo->flags & LVFI_PARTIAL) { if (strstrW(lvItem.pszText, lpFindInfo->psz) == NULL) continue; } else { if (lstrcmpW(lvItem.pszText, lpFindInfo->psz) != 0) continue; }
Well, both of these calls (strstrW and lstrcmpW) are case-sensitive. While MSDN states that search is supposed to be case-insensitive: http://msdn.microsoft.com/en-us/library/bb774745(VS.85).aspx
Here are the roots of the first part of this bug. Second part of our bug is about searching not items starting with, but items containing text. LVFI_PARTIAL means that we should look not for items containing text, but for items starting with it.
Here is my version (attached as patch):
if (lpFindInfo->flags & LVFI_PARTIAL) { const WCHAR *str1 = lvItem.pszText; const WCHAR *str2 = lpFindInfo->psz;
if (*str2) { while (*str2 && *str1) { if (tolowerW(*str1) != tolowerW(*str2)) break; str1++; str2++; } if (*str2) continue; } } else { if (lstrcmpiW(lvItem.pszText, lpFindInfo->psz) != 0) continue; }
This works as expected, though I am not sure as if this is the best (and fastest) way to do this.
2. Selection works slow. For every item in our listview during the search LISTVIEW_GetItemT is being called (which is quite heavy for such big cycle). This function, on it's part, sends LVN_GETDISPINFOW notification (line 5487). So, several thousands of notifications take some time ;) Notice the comment at line 5472:
/* apparently, we should not callback for lParam in LVS_OWNERDATA */
Debug lines show that the fields we need (pszText) are available BEFORE sending that message. Maybe, this could be avoided or worked out?
3. Slowdown when closing listview window. Slow place is function LISTVIEW_DeleteAllItems. MSDN states: LVM_DELETEALLITEMS Sets the item count to zero and clears all internal selection variables, but it does not actually delete any items. It makes a notification callback. http://msdn.microsoft.com/en-us/library/bb774735(VS.85).aspx
However, code on line 4512 does a lot more than required (also sending notifications for each listview item). As good as I understand only 1 notification is required. And deletion could be done via ranges_destroy.