user32: Add the tests for LB_DELETESTRING, make them pass under Wine.

Dmitry Timoshkov dmitry at codeweavers.com
Tue Apr 28 22:55:13 CDT 2009


This is a fix for the bug 18215.
---
 dlls/user32/listbox.c   |   25 +++++++++++++++++--------
 dlls/user32/tests/msg.c |   40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+), 8 deletions(-)

diff --git a/dlls/user32/listbox.c b/dlls/user32/listbox.c
index f7231f9..eaa805b 100644
--- a/dlls/user32/listbox.c
+++ b/dlls/user32/listbox.c
@@ -1684,12 +1684,19 @@ static LRESULT LISTBOX_InsertString( LB_DESCR *descr, INT index, LPCWSTR str )
  */
 static void LISTBOX_DeleteItem( LB_DESCR *descr, INT index )
 {
+    /* save the item data before it gets freed by LB_RESETCONTENT */
+    ULONG_PTR item_data = descr->items[index].data;
+    LPWSTR item_str = descr->items[index].str;
+
+    if (!descr->nb_items)
+        SendMessageW( descr->self, LB_RESETCONTENT, 0, 0 );
+
     /* Note: Win 3.1 only sends DELETEITEM on owner-draw items,
      *       while Win95 sends it for all items with user data.
      *       It's probably better to send it too often than not
      *       often enough, so this is what we do here.
      */
-    if (IS_OWNERDRAW(descr) || descr->items[index].data)
+    if (IS_OWNERDRAW(descr) || item_data)
     {
         DELETEITEMSTRUCT dis;
         UINT id = (UINT)GetWindowLongPtrW( descr->self, GWLP_ID );
@@ -1698,11 +1705,11 @@ static void LISTBOX_DeleteItem( LB_DESCR *descr, INT index )
         dis.CtlID    = id;
         dis.itemID   = index;
         dis.hwndItem = descr->self;
-        dis.itemData = descr->items[index].data;
+        dis.itemData = item_data;
         SendMessageW( descr->owner, WM_DELETEITEM, id, (LPARAM)&dis );
     }
     if (HAS_STRINGS(descr))
-        HeapFree( GetProcessHeap(), 0, descr->items[index].str );
+        HeapFree( GetProcessHeap(), 0, item_str );
 }
 
 
@@ -1718,18 +1725,20 @@ static LRESULT LISTBOX_RemoveItem( LB_DESCR *descr, INT index )
 
     if ((index < 0) || (index >= descr->nb_items)) return LB_ERR;
 
+    descr->nb_items--;
+    LISTBOX_DeleteItem( descr, index );
+
+    if (!descr->nb_items) return LB_OKAY;
+
     /* We need to invalidate the original rect instead of the updated one. */
     LISTBOX_InvalidateItems( descr, index );
 
-    LISTBOX_DeleteItem( descr, index );
-
     /* Remove the item */
 
     item = &descr->items[index];
-    if (index < descr->nb_items-1)
+    if (index < descr->nb_items)
         RtlMoveMemory( item, item + 1,
-                       (descr->nb_items - index - 1) * sizeof(LB_ITEMDATA) );
-    descr->nb_items--;
+                       (descr->nb_items - index) * sizeof(LB_ITEMDATA) );
     if (descr->anchor_item == descr->nb_items) descr->anchor_item--;
 
     /* Shrink the item array if possible */
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index f698b7f..2445f82 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -11017,6 +11017,19 @@ static const struct message wm_lb_click_0[] =
     { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_LISTBOX, LBN_SELCHANGE) },
     { 0 }
 };
+static const struct message wm_lb_deletestring[] =
+{
+    { LB_DELETESTRING, sent|wparam|lparam, 0, 0 },
+    { WM_DELETEITEM, sent|wparam|parent, ID_LISTBOX, 0 },
+    { 0 }
+};
+static const struct message wm_lb_deletestring_reset[] =
+{
+    { LB_DELETESTRING, sent|wparam|lparam, 0, 0 },
+    { LB_RESETCONTENT, sent|wparam|lparam|defwinproc, 0, 0 },
+    { WM_DELETEITEM, sent|wparam|parent, ID_LISTBOX, 0 },
+    { 0 }
+};
 
 #define check_lb_state(a1, a2, a3, a4, a5) check_lb_state_dbg(a1, a2, a3, a4, a5, __LINE__)
 
@@ -11127,6 +11140,33 @@ static void test_listbox_messages(void)
     check_lb_state(listbox, 3, 0, 0, 0);
     flush_sequence();
 
+    trace("deleting item 0\n");
+    ret = SendMessage(listbox, LB_DELETESTRING, 0, 0);
+    ok(ret == 2, "expected 2, got %ld\n", ret);
+    ok_sequence(wm_lb_deletestring, "LB_DELETESTRING 0", FALSE );
+    check_lb_state(listbox, 2, -1, 0, 0);
+    flush_sequence();
+
+    trace("deleting item 0\n");
+    ret = SendMessage(listbox, LB_DELETESTRING, 0, 0);
+    ok(ret == 1, "expected 1, got %ld\n", ret);
+    ok_sequence(wm_lb_deletestring, "LB_DELETESTRING 0", FALSE );
+    check_lb_state(listbox, 1, -1, 0, 0);
+    flush_sequence();
+
+    trace("deleting item 0\n");
+    ret = SendMessage(listbox, LB_DELETESTRING, 0, 0);
+    ok(ret == 0, "expected 0, got %ld\n", ret);
+    ok_sequence(wm_lb_deletestring_reset, "LB_DELETESTRING 0", FALSE );
+    check_lb_state(listbox, 0, -1, 0, 0);
+    flush_sequence();
+
+    trace("deleting item 0\n");
+    ret = SendMessage(listbox, LB_DELETESTRING, 0, 0);
+    ok(ret == LB_ERR, "expected LB_ERR, got %ld\n", ret);
+    check_lb_state(listbox, 0, -1, 0, 0);
+    flush_sequence();
+
     log_all_parent_messages--;
 
     DestroyWindow(listbox);
-- 
1.6.2.2




More information about the wine-patches mailing list