comctl32: listview: Fix getting user params and subitems

Frank Richter frank.richter at gmail.com
Fri Dec 29 12:19:36 CST 2006


When querying a listview subitem for the user param, the main item's
user param is returned. Also, when a subitem is custom-drawn, the main
item's user param is passed along.

-------------- next part --------------
>From 187b7b100cdb9e0c5dcb3fef2618500e4c40647e Mon Sep 17 00:00:00 2001
From: Frank Richter frank.richter at gmail.com <frank.richter at gmail.com>
Date: Fri, 29 Dec 2006 19:15:09 +0100
Subject: [PATCH] comctl32: listview: Fix getting user params and subitems

---
 dlls/comctl32/listview.c       |   10 ++---
 dlls/comctl32/tests/listview.c |   85 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 5 deletions(-)

diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c
index e7df207..55b12f3 100644
--- a/dlls/comctl32/listview.c
+++ b/dlls/comctl32/listview.c
@@ -3710,8 +3710,8 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_I
     TRACE("(hdc=%p, nItem=%d, nSubItem=%d, pos=%s)\n", hdc, nItem, nSubItem, wine_dbgstr_point(&pos));
 
     /* get information needed for drawing the item */
-    lvItem.mask = LVIF_TEXT | LVIF_IMAGE;
-    if (nSubItem == 0) lvItem.mask |= LVIF_STATE | LVIF_PARAM;
+    lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
+    if (nSubItem == 0) lvItem.mask |= LVIF_STATE;
     if (uView == LVS_REPORT) lvItem.mask |= LVIF_INDENT;
     lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED | LVIS_STATEIMAGEMASK;
     lvItem.iItem = nItem;
@@ -5348,9 +5348,6 @@ static BOOL LISTVIEW_GetItemT(LISTVIEW_I
 	else textcpynT(lpLVItem->pszText, isW, pItemHdr->pszText, TRUE, lpLVItem->cchTextMax);
     }
 
-    /* if this is a subitem, we're done */
-    if (isubitem) return TRUE;
-  
     /* Next is the lParam field */
     if (dispInfo.item.mask & LVIF_PARAM)
     {
@@ -5361,6 +5358,9 @@ static BOOL LISTVIEW_GetItemT(LISTVIEW_I
     else if (lpLVItem->mask & LVIF_PARAM)
 	lpLVItem->lParam = lpItem->lParam;
 
+    /* if this is a subitem, we're done */
+    if (isubitem) return TRUE;
+  
     /* ... the state field (this one is different due to uCallbackmask) */
     if (lpLVItem->mask & LVIF_STATE) 
     {
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c
index 2bfca02..1fbf739 100644
--- a/dlls/comctl32/tests/listview.c
+++ b/dlls/comctl32/tests/listview.c
@@ -63,6 +63,7 @@ static void test_images(void)
     item.iItem = 0;
     item.iSubItem = 1;
     item.iImage = 0;
+    item.pszText = 0;
     r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item);
     ok(r == -1, "should fail\n");
 
@@ -232,6 +233,89 @@ static void test_checkboxes(void)
     DestroyWindow(hwnd);
 }
 
+static void test_items(void)
+{
+    const LPARAM lparamTest = 0x42;
+    HWND hwnd, hwndparent = 0;
+    LVITEMA item;
+    LVCOLUMNA column;
+    DWORD r;
+    static CHAR text[]  = "Text";
+
+    hwnd = CreateWindowEx(0, "SysListView32", "foo", LVS_REPORT, 
+                10, 10, 100, 200, hwndparent, NULL, NULL, NULL);
+    ok(hwnd != NULL, "failed to create listview window\n");
+    
+    /* 
+     * Test setting/getting item params
+     */
+    
+    /* Set up two columns */
+    column.mask = LVCF_SUBITEM;
+    column.iSubItem = 0;
+    r = SendMessage(hwnd, LVM_INSERTCOLUMNA, 0, (LPARAM)&column);
+    ok(r == 0, "ret %d\n", r);
+    column.iSubItem = 1;
+    r = SendMessage(hwnd, LVM_INSERTCOLUMNA, 1, (LPARAM)&column);
+    ok(r == 1, "ret %d\n", r);
+
+    /* Insert an item with just a param */
+    memset (&item, 0xaa, sizeof (item));
+    item.mask = LVIF_PARAM;
+    item.iItem = 0;
+    item.iSubItem = 0;
+    item.lParam = lparamTest;
+    r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
+    ok(r == 0, "ret %d\n", r);
+
+    /* Test getting of the param */
+    memset (&item, 0xaa, sizeof (item));
+    item.mask = LVIF_PARAM;
+    item.iItem = 0;
+    item.iSubItem = 0;
+    r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
+    ok(r != 0, "ret %d\n", r);
+    ok(item.lParam == lparamTest, "got lParam %lx, expected %lx\n", item.lParam, lparamTest);
+    
+    /* Set up a subitem */
+    memset (&item, 0xaa, sizeof (item));
+    item.mask = LVIF_TEXT;
+    item.iItem = 0;
+    item.iSubItem = 1;
+    item.pszText = text;
+    r = SendMessage(hwnd, LVM_SETITEMA, 0, (LPARAM) &item);
+    ok(r != 0, "ret %d\n", r);
+    
+    /* Query param from subitem: returns main item param */
+    memset (&item, 0xaa, sizeof (item));
+    item.mask = LVIF_PARAM;
+    item.iItem = 0;
+    item.iSubItem = 1;
+    r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
+    ok(r != 0, "ret %d\n", r);
+    ok(item.lParam == lparamTest, "got lParam %lx, expected %lx\n", item.lParam, lparamTest);
+
+    /* Set up param on first subitem: no effect */
+    memset (&item, 0xaa, sizeof (item));
+    item.mask = LVIF_PARAM;
+    item.iItem = 0;
+    item.iSubItem = 1;
+    item.lParam = lparamTest+1;
+    r = SendMessage(hwnd, LVM_SETITEMA, 0, (LPARAM) &item);
+    ok(r == 0, "ret %d\n", r);
+    
+    /* Query param from subitem again: should still return main item param */
+    memset (&item, 0xaa, sizeof (item));
+    item.mask = LVIF_PARAM;
+    item.iItem = 0;
+    item.iSubItem = 1;
+    r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
+    ok(r != 0, "ret %d\n", r);
+    ok(item.lParam == lparamTest, "got lParam %lx, expected %lx\n", item.lParam, lparamTest);
+
+    DestroyWindow(hwnd);
+}
+
 START_TEST(listview)
 {
     INITCOMMONCONTROLSEX icc;
@@ -242,4 +326,5 @@ START_TEST(listview)
 
     test_images();
     test_checkboxes();
+    test_items();
 }
-- 
1.4.2.4



More information about the wine-patches mailing list