Nikolay Sivov : comctl32/listview: Fix item search with keyboard input.

Alexandre Julliard julliard at winehq.org
Wed Jan 30 13:43:22 CST 2013


Module: wine
Branch: master
Commit: 8f87fc5b39c83d59da5f5a2f1b482304f401719b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=8f87fc5b39c83d59da5f5a2f1b482304f401719b

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Wed Jan 30 12:14:53 2013 +0400

comctl32/listview: Fix item search with keyboard input.

---

 dlls/comctl32/listview.c |   26 +++++++++++++++++---------
 1 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c
index c16a619..8031d37 100644
--- a/dlls/comctl32/listview.c
+++ b/dlls/comctl32/listview.c
@@ -1838,9 +1838,9 @@ static inline INT LISTVIEW_GetCountPerColumn(const LISTVIEW_INFO *infoPtr)
 static INT LISTVIEW_ProcessLetterKeys(LISTVIEW_INFO *infoPtr, WPARAM charCode, LPARAM keyData)
 {
     WCHAR buffer[MAX_PATH];
-    INT endidx, startidx;
     DWORD prevTime;
     LVITEMW item;
+    int startidx;
     INT nItem;
     INT diff;
 
@@ -1880,15 +1880,16 @@ static INT LISTVIEW_ProcessLetterKeys(LISTVIEW_INFO *infoPtr, WPARAM charCode, L
         infoPtr->nSearchParamLength = 1;
     }
 
-    /* and search from the current position */
-    nItem = -1;
-    endidx = infoPtr->nItemCount;
-
     /* should start from next after focused item, so next item that matches
        will be selected, if there isn't any and focused matches it will be selected
        on second search stage from beginning of the list */
     if (infoPtr->nFocusedItem >= 0 && infoPtr->nItemCount > 1)
-        startidx = infoPtr->nFocusedItem + 1;
+    {
+        /* with some accumulated search data available start with current focus, otherwise
+           it's excluded from search */
+        startidx = infoPtr->nSearchParamLength > 1 ? infoPtr->nFocusedItem : infoPtr->nFocusedItem + 1;
+        if (startidx == infoPtr->nItemCount) startidx = 0;
+    }
     else
         startidx = 0;
 
@@ -1908,7 +1909,11 @@ static INT LISTVIEW_ProcessLetterKeys(LISTVIEW_INFO *infoPtr, WPARAM charCode, L
     }
     else
     {
-        INT i = startidx;
+        int i = startidx, endidx;
+
+        /* and search from the current position */
+        nItem = -1;
+        endidx = infoPtr->nItemCount;
 
         /* first search in [startidx, endidx), on failure continue in [0, startidx) */
         while (1)
@@ -1930,12 +1935,15 @@ static INT LISTVIEW_ProcessLetterKeys(LISTVIEW_INFO *infoPtr, WPARAM charCode, L
                 item.cchTextMax = MAX_PATH;
                 if (!LISTVIEW_GetItemW(infoPtr, &item)) return 0;
 
-                if (lstrncmpiW(item.pszText, infoPtr->szSearchParam, infoPtr->nSearchParamLength) == 0)
+                if (!lstrncmpiW(item.pszText, infoPtr->szSearchParam, infoPtr->nSearchParamLength))
                 {
                     nItem = i;
                     break;
                 }
-                else if (nItem == -1 && lstrncmpiW(item.pszText, infoPtr->szSearchParam, 1) == 0)
+                /* this is used to find first char match when search string is not available yet,
+                   otherwise every WM_CHAR will search to next item by first char, ignoring that we're
+                   already waiting for user to complete a string */
+                else if (nItem == -1 && infoPtr->nSearchParamLength == 1 && !lstrncmpiW(item.pszText, infoPtr->szSearchParam, 1))
                 {
                     /* this would work but we must keep looking for a longer match */
                     nItem = i;




More information about the wine-cvs mailing list