comctl32/listview: Properly update selection mark on item state change

Nikolay Sivov nsivov at codeweavers.com
Mon Jun 11 03:56:34 CDT 2012


For http://bugs.winehq.org/show_bug.cgi?id=29973
-------------- next part --------------
>From 21b9cff8f215c4259bcdce7bda82bef053e1a75b Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov at codeweavers.com>
Date: Sat, 9 Jun 2012 12:15:16 +0400
Subject: [PATCH 1/5] Properly update selection mark on item state change

---
 dlls/comctl32/listview.c       |    6 ++-
 dlls/comctl32/tests/listview.c |  126 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 130 insertions(+), 2 deletions(-)

diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c
index 7111560..27b2fd0 100644
--- a/dlls/comctl32/listview.c
+++ b/dlls/comctl32/listview.c
@@ -6,7 +6,7 @@
  * Copyright 2000 Jason Mawdsley
  * Copyright 2001 CodeWeavers Inc.
  * Copyright 2002 Dimitrie O. Paun
- * Copyright 2009-2011 Nikolay Sivov
+ * Copyright 2009-2012 Nikolay Sivov
  * Copyright 2009 Owen Rudge for CodeWeavers
  *
  * This library is free software; you can redistribute it and/or
@@ -4276,6 +4276,10 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL
 	{
 	    if (lpLVItem->state & LVIS_FOCUSED)
 	    {
+		/* update selection mark */
+		if (infoPtr->nFocusedItem == -1 && infoPtr->nSelectionMark == -1)
+		    infoPtr->nSelectionMark = lpLVItem->iItem;
+
 		if (infoPtr->nFocusedItem != -1)
 		{
 		    /* remove current focus */
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c
index b96e85f..255ef50 100644
--- a/dlls/comctl32/tests/listview.c
+++ b/dlls/comctl32/tests/listview.c
@@ -2090,7 +2090,6 @@ static void test_multiselect(void)
         { "using VK_HOME", -1, VK_HOME, 1, -1 }
     };
 
-
     hwnd = create_listview_control(LVS_REPORT);
 
     for (i=0;i<items;i++) {
@@ -2237,6 +2236,131 @@ static void test_multiselect(void)
     r = ListView_GetSelectedCount(hwnd);
     expect(0, r);
 
+    /* 1. selection mark is update when new focused item is set */
+    style = GetWindowLongPtrA(hwnd, GWL_STYLE);
+    SetWindowLongPtrA(hwnd, GWL_STYLE, style & ~LVS_SINGLESEL);
+
+    r = SendMessage(hwnd, LVM_SETSELECTIONMARK, 0, -1);
+    expect(-1, r);
+
+    item.stateMask = LVIS_FOCUSED;
+    item.state     = LVIS_FOCUSED;
+    r = SendMessage(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
+    expect(TRUE, r);
+
+    r = SendMessage(hwnd, LVM_GETSELECTIONMARK, 0, 0);
+    expect(0, r);
+
+    /* it's not updated if already set */
+    item.stateMask = LVIS_FOCUSED;
+    item.state     = LVIS_FOCUSED;
+    r = SendMessage(hwnd, LVM_SETITEMSTATE, 1, (LPARAM)&item);
+    expect(TRUE, r);
+
+    r = SendMessage(hwnd, LVM_GETSELECTIONMARK, 0, 0);
+    expect(0, r);
+
+    r = SendMessage(hwnd, LVM_SETSELECTIONMARK, 0, -1);
+    expect(0, r);
+
+    item.stateMask = LVIS_FOCUSED;
+    item.state     = LVIS_FOCUSED;
+    r = SendMessage(hwnd, LVM_SETITEMSTATE, 1, (LPARAM)&item);
+    expect(TRUE, r);
+
+    r = SendMessage(hwnd, LVM_GETSELECTIONMARK, 0, 0);
+    expect(-1, r);
+
+    /* need to reset focused item first */
+    item.stateMask = LVIS_FOCUSED;
+    item.state     = 0;
+    r = SendMessage(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
+    expect(TRUE, r);
+
+    item.stateMask = LVIS_FOCUSED;
+    item.state     = LVIS_FOCUSED;
+    r = SendMessage(hwnd, LVM_SETITEMSTATE, 2, (LPARAM)&item);
+    expect(TRUE, r);
+
+    r = SendMessage(hwnd, LVM_GETSELECTIONMARK, 0, 0);
+    expect(2, r);
+
+    item.stateMask = LVIS_FOCUSED;
+    item.state     = 0;
+    r = SendMessage(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
+    expect(TRUE, r);
+
+    r = SendMessage(hwnd, LVM_GETSELECTIONMARK, 0, 0);
+    expect(2, r);
+
+    /* 2. same tests, with LVM_SETITEM */
+    style = GetWindowLongPtrA(hwnd, GWL_STYLE);
+    SetWindowLongPtrA(hwnd, GWL_STYLE, style & ~LVS_SINGLESEL);
+
+    r = SendMessage(hwnd, LVM_SETSELECTIONMARK, 0, -1);
+    expect(2, r);
+
+    item.stateMask = LVIS_FOCUSED;
+    item.state     = LVIS_FOCUSED;
+    item.mask      = LVIF_STATE;
+    item.iItem = item.iSubItem = 0;
+    r = SendMessage(hwnd, LVM_SETITEMA, 0, (LPARAM)&item);
+    expect(TRUE, r);
+
+    r = SendMessage(hwnd, LVM_GETSELECTIONMARK, 0, 0);
+    expect(0, r);
+
+    /* it's not updated if already set */
+    item.stateMask = LVIS_FOCUSED;
+    item.state     = LVIS_FOCUSED;
+    item.mask      = LVIF_STATE;
+    item.iItem     = 1;
+    item.iSubItem  = 0;
+    r = SendMessage(hwnd, LVM_SETITEMA, 0, (LPARAM)&item);
+    expect(TRUE, r);
+
+    r = SendMessage(hwnd, LVM_GETSELECTIONMARK, 0, 0);
+    expect(0, r);
+
+    r = SendMessage(hwnd, LVM_SETSELECTIONMARK, 0, -1);
+    expect(0, r);
+
+    item.stateMask = LVIS_FOCUSED;
+    item.state     = LVIS_FOCUSED;
+    item.mask      = LVIF_STATE;
+    item.iItem     = 1;
+    item.iSubItem  = 0;
+    r = SendMessage(hwnd, LVM_SETITEMA, 0, (LPARAM)&item);
+    expect(TRUE, r);
+
+    r = SendMessage(hwnd, LVM_GETSELECTIONMARK, 0, 0);
+    expect(-1, r);
+
+    /* need to reset focused item first */
+    item.stateMask = LVIS_FOCUSED;
+    item.state     = 0;
+    r = SendMessage(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
+    expect(TRUE, r);
+
+    item.stateMask = LVIS_FOCUSED;
+    item.state     = LVIS_FOCUSED;
+    item.mask      = LVIF_STATE;
+    item.iItem     = 2;
+    item.iSubItem  = 0;
+    r = SendMessage(hwnd, LVM_SETITEMA, 0, (LPARAM)&item);
+    expect(TRUE, r);
+
+    r = SendMessage(hwnd, LVM_GETSELECTIONMARK, 0, 0);
+    expect(2, r);
+
+    item.stateMask = LVIS_FOCUSED;
+    item.state     = 0;
+    r = SendMessage(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
+    expect(TRUE, r);
+
+    r = SendMessage(hwnd, LVM_GETSELECTIONMARK, 0, 0);
+    expect(2, r);
+
     DestroyWindow(hwnd);
 }
 
-- 
1.5.6.5



More information about the wine-patches mailing list