user32: The hiword of the return value from LB_ITEMFROMPOINT should be a hittest on the item that's returned and not a hittest on the client area as MSDN states.

Huw Davies huw at codeweavers.com
Fri Oct 27 10:41:45 CDT 2006


This is a multi-part message in MIME format.
--------------1.4.2.3
Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit

---
Sorry, please use this one instead.  Forgot to update my tree.

 dlls/user/listbox.c       |   38 ++++++++++++++++++-----
 dlls/user/tests/listbox.c |   74 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 104 insertions(+), 8 deletions(-)
--------------1.4.2.3
Content-Type: text/x-patch;
 name="d9e0b62e79c5f67a377b6ffba21f58e68595bff9.diff"
Content-Transfer-Encoding: 8bit
Content-Disposition: inline;
 filename="d9e0b62e79c5f67a377b6ffba21f58e68595bff9.diff"

diff --git a/dlls/user/listbox.c b/dlls/user/listbox.c
index ae9a8e3..59c4f29 100644
--- a/dlls/user/listbox.c
+++ b/dlls/user/listbox.c
@@ -2731,16 +2731,38 @@ static LRESULT WINAPI ListBoxWndProc_com
         {
             POINT pt;
             RECT rect;
+            int index;
+            BOOL hit = TRUE;
 
-	    pt.x = (short)LOWORD(lParam);
-	    pt.y = (short)HIWORD(lParam);
-	    rect.left = 0;
-	    rect.top = 0;
-	    rect.right = descr->width;
-	    rect.bottom = descr->height;
+            /* The hiword of the return value is not a client area
+               hittest as suggested by MSDN, but rather a hittest on
+               the returned listbox item. */
 
-            return MAKELONG( LISTBOX_GetItemFromPoint(descr, pt.x, pt.y),
-                             !PtInRect( &rect, pt ) );
+            if(descr->nb_items == 0)
+                return 0x1ffff;      /* win9x returns 0x10000, we copy winnt */
+
+            pt.x = (short)LOWORD(lParam);
+            pt.y = (short)HIWORD(lParam);
+
+            SetRect(&rect, 0, 0, descr->width, descr->height);
+
+            if(!PtInRect(&rect, pt))
+            {
+                pt.x = min(pt.x, rect.right - 1);
+                pt.x = max(pt.x, 0);
+                pt.y = min(pt.y, rect.bottom - 1);
+                pt.y = max(pt.y, 0);
+                hit = FALSE;
+            }
+
+            index = LISTBOX_GetItemFromPoint(descr, pt.x, pt.y);
+
+            if(index == -1)
+            {
+                index = descr->nb_items - 1;
+                hit = FALSE;
+            }
+            return MAKELONG(index, hit ? 0 : 1);
         }
 
     case LB_SETCARETINDEX16:
diff --git a/dlls/user/tests/listbox.c b/dlls/user/tests/listbox.c
index 7bbec60..435dc91 100644
--- a/dlls/user/tests/listbox.c
+++ b/dlls/user/tests/listbox.c
@@ -429,6 +429,79 @@ static void test_listbox_height(void)
     DestroyWindow( hList );
 }
 
+static void test_itemfrompoint(void)
+{
+    HWND hList = CreateWindow( "ListBox", "list test", 0,
+                               1, 1, 600, 100, NULL, NULL, NULL, NULL );
+    LONG r, id;
+    RECT rc;
+
+    /* For an empty listbox win2k returns 0x1ffff, win98 returns 0x10000 */
+    r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
+    ok( r == 0x1ffff || r == 0x10000, "ret %x\n", r );
+
+    r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( 700, 30 ));
+    ok( r == 0x1ffff || r == 0x10000, "ret %x\n", r );
+
+    r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( 30, 300 ));
+    ok( r == 0x1ffff || r == 0x10000, "ret %x\n", r );
+
+    id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi");
+    ok( id == 0, "item id wrong\n");
+    id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi1");
+    ok( id == 1, "item id wrong\n");
+
+    r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
+    ok( r == 0x1, "ret %x\n", r );
+
+    r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 37 ));
+    ok( r == 0x10001, "ret %x\n", r );
+
+
+
+    id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi2");
+    ok( id == 2, "item id wrong\n");
+    id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi3");
+    ok( id == 3, "item id wrong\n");
+    id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi4");
+    ok( id == 4, "item id wrong\n");
+    id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi5");
+    ok( id == 5, "item id wrong\n");
+    id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi6");
+    ok( id == 6, "item id wrong\n");
+    id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi7");
+    ok( id == 7, "item id wrong\n");
+
+    /* Set the listbox up so that id 1 is at the top, this leaves 5
+       partially visible at the bottom and 6, 7 are invisible */
+
+    SendMessage( hList, LB_SETTOPINDEX, 1, 0);
+    r = SendMessage( hList, LB_GETTOPINDEX, 0, 0);
+    ok( r == 1, "top %d\n", r);
+
+    r = SendMessage( hList, LB_GETITEMRECT, 5, (LPARAM)&rc);
+    ok( r == 1, "ret %x\n", r);
+    r = SendMessage( hList, LB_GETITEMRECT, 6, (LPARAM)&rc);
+    ok( r == 0, "ret %x\n", r);
+
+    r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(/* x */ 10, /* y */ 10) );
+    ok( r == 1, "ret %x\n", r);
+
+    r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(1000, 10) );
+    ok( r == 0x10001, "ret %x\n", r );
+
+    r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, -10) );
+    ok( r == 0x10001, "ret %x\n", r );
+
+    r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, 100) );
+    ok( r == 0x10005, "item %x\n", r );
+
+    r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, 200) );
+    ok( r == 0x10005, "item %x\n", r );
+
+    DestroyWindow( hList );
+}
+
 START_TEST(listbox)
 {
   const struct listbox_test SS =
@@ -503,4 +576,5 @@ START_TEST(listbox)
   test_ownerdraw();
   test_selection();
   test_listbox_height();
+  test_itemfrompoint();
 }

--------------1.4.2.3--





More information about the wine-patches mailing list