comctl32/listview: fix icon spacing calculation [try 2]
Daniel Jelinski
djelinski1 at gmail.com
Mon Jan 14 14:53:20 CST 2013
-------------- next part --------------
From fb1fa3e98ce8405ff30a228caa4441f8a94bbe74 Mon Sep 17 00:00:00 2001
From: Daniel Jelinski <djelinski1 at gmail.com>
Date: Sun, 13 Jan 2013 13:25:17 +0100
Subject: comctl32/listview: fix icon spacing calculation
Try 2: use INT for parameter (fixes 64 bit test), added checking if upper
32 bits of icon spacing are preserved. I didn't perform 64bit tests on wine,
so some todo_wine may be missing.
based on patch by Nikolay Sivov; should fix bug 17380 (overlapping icons
in listview Icon view)
---
dlls/comctl32/listview.c | 49 ++++++++---------
dlls/comctl32/tests/listview.c | 111 +++++++++++++++++++++++++++++++---------
2 files changed, 110 insertions(+), 50 deletions(-)
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c
index bb6d1b2..01d7c2a 100644
--- a/dlls/comctl32/listview.c
+++ b/dlls/comctl32/listview.c
@@ -8,6 +8,7 @@
* Copyright 2002 Dimitrie O. Paun
* Copyright 2009-2013 Nikolay Sivov
* Copyright 2009 Owen Rudge for CodeWeavers
+ * Copyright 2012-2013 Daniel Jelinski
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -8574,33 +8575,27 @@ static DWORD LISTVIEW_SetIconSpacing(LISTVIEW_INFO *infoPtr, INT cx, INT cy)
DWORD oldspacing = MAKELONG(infoPtr->iconSpacing.cx, infoPtr->iconSpacing.cy);
TRACE("requested=(%d,%d)\n", cx, cy);
-
+
/* this is supported only for LVS_ICON style */
if (infoPtr->uView != LV_VIEW_ICON) return oldspacing;
-
- /* set to defaults, if instructed to */
- if (cx == -1) cx = GetSystemMetrics(SM_CXICONSPACING);
- if (cy == -1) cy = GetSystemMetrics(SM_CYICONSPACING);
- /* if 0 then compute width
- * FIXME: computed cx and cy is not matching native behaviour */
- if (cx == 0) {
- cx = GetSystemMetrics(SM_CXICONSPACING);
- if (infoPtr->iconSize.cx + ICON_LR_PADDING > cx)
- cx = infoPtr->iconSize.cx + ICON_LR_PADDING;
+ /* set to defaults, if instructed to */
+ if (cx == -1 && cy == -1)
+ {
+ infoPtr->iconSpacing.cx = GetSystemMetrics(SM_CXICONSPACING) - GetSystemMetrics(SM_CXICON) + infoPtr->iconSize.cx;
+ infoPtr->iconSpacing.cy = GetSystemMetrics(SM_CYICONSPACING) - GetSystemMetrics(SM_CYICON) + infoPtr->iconSize.cy;
}
+ else
+ {
+ if (cx != 0)
+ infoPtr->iconSpacing.cx = cx;
- /* if 0 then compute height */
- if (cy == 0)
- cy = infoPtr->iconSize.cy + 2 * infoPtr->ntmHeight +
- ICON_BOTTOM_PADDING + ICON_TOP_PADDING + LABEL_VERT_PADDING;
-
-
- infoPtr->iconSpacing.cx = cx;
- infoPtr->iconSpacing.cy = cy;
+ if (cy != 0)
+ infoPtr->iconSpacing.cy = cy;
+ }
TRACE("old=(%d,%d), new=(%d,%d), iconSize=(%d,%d), ntmH=%d\n",
- LOWORD(oldspacing), HIWORD(oldspacing), cx, cy,
+ LOWORD(oldspacing), HIWORD(oldspacing), infoPtr->iconSpacing.cx, infoPtr->iconSpacing.cy,
infoPtr->iconSize.cx, infoPtr->iconSize.cy,
infoPtr->ntmHeight);
@@ -8652,7 +8647,7 @@ static HIMAGELIST LISTVIEW_SetImageList(LISTVIEW_INFO *infoPtr, INT nType, HIMAG
himlOld = infoPtr->himlNormal;
infoPtr->himlNormal = himl;
if (infoPtr->uView == LV_VIEW_ICON) set_icon_size(&infoPtr->iconSize, himl, FALSE);
- LISTVIEW_SetIconSpacing(infoPtr, 0, 0);
+ LISTVIEW_SetIconSpacing(infoPtr, -1, -1);
break;
case LVSIL_SMALL:
@@ -9076,7 +9071,7 @@ static INT LISTVIEW_SetView(LISTVIEW_INFO *infoPtr, DWORD nView)
{
TRACE("icon old size=(%d,%d), new size=(%d,%d)\n",
oldIconSize.cx, oldIconSize.cy, infoPtr->iconSize.cx, infoPtr->iconSize.cy);
- LISTVIEW_SetIconSpacing(infoPtr, 0, 0);
+ LISTVIEW_SetIconSpacing(infoPtr, -1, -1);
}
LISTVIEW_Arrange(infoPtr, LVA_DEFAULT);
break;
@@ -9375,8 +9370,8 @@ static LRESULT LISTVIEW_NCCreate(HWND hwnd, const CREATESTRUCTW *lpcs)
infoPtr->bRedraw = TRUE;
infoPtr->bNoItemMetrics = TRUE;
infoPtr->bDoChangeNotify = TRUE;
- infoPtr->iconSpacing.cx = GetSystemMetrics(SM_CXICONSPACING);
- infoPtr->iconSpacing.cy = GetSystemMetrics(SM_CYICONSPACING);
+ infoPtr->iconSpacing.cx = GetSystemMetrics(SM_CXICONSPACING) - GetSystemMetrics(SM_CXICON);
+ infoPtr->iconSpacing.cy = GetSystemMetrics(SM_CYICONSPACING) - GetSystemMetrics(SM_CYICON);
infoPtr->nEditLabelItem = -1;
infoPtr->nLButtonDownItem = -1;
infoPtr->dwHoverTime = HOVER_DEFAULT; /* default system hover time */
@@ -10998,7 +10993,7 @@ static INT LISTVIEW_StyleChanged(LISTVIEW_INFO *infoPtr, WPARAM wStyleType,
{
TRACE("icon old size=(%d,%d), new size=(%d,%d)\n",
oldIconSize.cx, oldIconSize.cy, infoPtr->iconSize.cx, infoPtr->iconSize.cy);
- LISTVIEW_SetIconSpacing(infoPtr, 0, 0);
+ LISTVIEW_SetIconSpacing(infoPtr, -1, -1);
}
}
else if (uNewView == LVS_REPORT)
@@ -11432,7 +11427,9 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return LISTVIEW_SetHoverTime(infoPtr, (DWORD)lParam);
case LVM_SETICONSPACING:
- return LISTVIEW_SetIconSpacing(infoPtr, (short)LOWORD(lParam), (short)HIWORD(lParam));
+ if(lParam == -1)
+ return LISTVIEW_SetIconSpacing(infoPtr, -1, -1);
+ return LISTVIEW_SetIconSpacing(infoPtr, LOWORD(lParam), HIWORD(lParam));
case LVM_SETIMAGELIST:
return (LRESULT)LISTVIEW_SetImageList(infoPtr, (INT)wParam, (HIMAGELIST)lParam);
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c
index cff6e92..efa514d 100644
--- a/dlls/comctl32/tests/listview.c
+++ b/dlls/comctl32/tests/listview.c
@@ -4588,10 +4588,11 @@ static void test_getitemspacing(void)
{
HWND hwnd;
DWORD ret;
+#ifdef _WIN64
+ LPARAM ret2;
+#endif
INT cx, cy;
- HIMAGELIST himl;
- HBITMAP hbmp;
- LVITEMA itema;
+ HIMAGELIST himl40, himl80;
cx = GetSystemMetrics(SM_CXICONSPACING) - GetSystemMetrics(SM_CXICON);
cy = GetSystemMetrics(SM_CYICONSPACING) - GetSystemMetrics(SM_CYICON);
@@ -4599,56 +4600,118 @@ static void test_getitemspacing(void)
/* LVS_ICON */
hwnd = create_listview_control(LVS_ICON);
ret = SendMessage(hwnd, LVM_GETITEMSPACING, FALSE, 0);
-todo_wine {
expect(cx, LOWORD(ret));
expect(cy, HIWORD(ret));
-}
+
/* now try with icons */
- himl = ImageList_Create(40, 40, 0, 4, 4);
- ok(himl != NULL, "failed to create imagelist\n");
- hbmp = CreateBitmap(40, 40, 1, 1, NULL);
- ok(hbmp != NULL, "failed to create bitmap\n");
- ret = ImageList_Add(himl, hbmp, 0);
- expect(0, ret);
- ret = SendMessage(hwnd, LVM_SETIMAGELIST, 0, (LPARAM)himl);
+ himl40 = ImageList_Create(40, 40, 0, 4, 4);
+ ok(himl40 != NULL, "failed to create imagelist\n");
+ ret = SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)himl40);
expect(0, ret);
- itema.mask = LVIF_IMAGE;
- itema.iImage = 0;
- itema.iItem = 0;
- itema.iSubItem = 0;
- ret = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM)&itema);
- expect(0, ret);
ret = SendMessage(hwnd, LVM_GETITEMSPACING, FALSE, 0);
-todo_wine {
/* spacing + icon size returned */
expect(cx + 40, LOWORD(ret));
expect(cy + 40, HIWORD(ret));
+
+ /* try changing icon size */
+ himl80 = ImageList_Create(80, 80, 0, 4, 4);
+ ok(himl80 != NULL, "failed to create imagelist\n");
+ SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)himl80);
+
+ ret = SendMessage(hwnd, LVM_GETITEMSPACING, FALSE, 0);
+ /* spacing + icon size returned */
+ expect(cx + 80, LOWORD(ret));
+ expect(cy + 80, HIWORD(ret));
+
+ /* set own icon spacing */
+ ret = SendMessage(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(100, 100));
+ expect(cx + 80, LOWORD(ret));
+ expect(cy + 80, HIWORD(ret));
+
+ ret = SendMessage(hwnd, LVM_GETITEMSPACING, FALSE, 0);
+ /* set size returned */
+ expect(100, LOWORD(ret));
+ expect(100, HIWORD(ret));
+
+ /* now change image list - icon spacing should be unaffected */
+ SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)himl40);
+
+ ret = SendMessage(hwnd, LVM_GETITEMSPACING, FALSE, 0);
+ /* set size returned */
+todo_wine {
+ expect(100, LOWORD(ret));
+ expect(100, HIWORD(ret));
}
+ /* spacing = 0 - keep previous value */
+ ret = SendMessage(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(0, -1));
+todo_wine {
+ expect(100, LOWORD(ret));
+ expect(100, HIWORD(ret));
+}
+ ret = SendMessage(hwnd, LVM_GETITEMSPACING, FALSE, 0);
+todo_wine
+ expect(100, LOWORD(ret));
+ expect(0xFFFF, HIWORD(ret));
+
+ /* LPARAM = -1 - restore default processing */
+ ret = SendMessage(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(-1,-1));
+todo_wine
+ expect(100, LOWORD(ret));
+ expect(0xFFFF, HIWORD(ret));
+
+ /* NOTE: -1 is not the same as MAKELPARAM(-1,-1) in 64bit listview */
+#ifdef _WIN64
+ ret = SendMessage(hwnd, LVM_SETICONSPACING, 0, 0xBAADF00DDEADBEEFLL);
+ expect(0xFFFF, LOWORD(ret));
+ expect(0xFFFF, HIWORD(ret));
+ ret2 = SendMessage(hwnd, LVM_GETITEMSPACING, FALSE, 0);
+ ok((LONG)0xDEADBEEF == ret2, "Expected FFFFFFFFDEADBEEF, got %p\n", (void*)ret2);
+ ret2 = SendMessage(hwnd, LVM_SETICONSPACING, 0, -1);
+ ok(0xDEADBEEF == ret2, "Expected 00000000DEADBEEF, got %p\n", (void*)ret2);
+#endif
+ ret = SendMessage(hwnd, LVM_GETITEMSPACING, FALSE, 0);
+ /* spacing + icon size returned */
+ expect(cx + 40, LOWORD(ret));
+ expect(cy + 40, HIWORD(ret));
+
+ SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_NORMAL, 0);
+ ImageList_Destroy(himl80);
DestroyWindow(hwnd);
/* LVS_SMALLICON */
hwnd = create_listview_control(LVS_SMALLICON);
ret = SendMessage(hwnd, LVM_GETITEMSPACING, FALSE, 0);
-todo_wine {
expect(cx, LOWORD(ret));
expect(cy, HIWORD(ret));
+
+ /* spacing does not depend on selected view type */
+ ret = SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)himl40);
+ expect(0, ret);
+
+ ret = SendMessage(hwnd, LVM_GETITEMSPACING, FALSE, 0);
+ /* spacing + icon size returned */
+todo_wine {
+ expect(cx + 40, LOWORD(ret));
+ expect(cy + 40, HIWORD(ret));
}
+ SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_NORMAL, 0);
+ ImageList_Destroy(himl40);
DestroyWindow(hwnd);
/* LVS_REPORT */
hwnd = create_listview_control(LVS_REPORT);
ret = SendMessage(hwnd, LVM_GETITEMSPACING, FALSE, 0);
-todo_wine {
+
expect(cx, LOWORD(ret));
expect(cy, HIWORD(ret));
-}
+
DestroyWindow(hwnd);
/* LVS_LIST */
hwnd = create_listview_control(LVS_LIST);
ret = SendMessage(hwnd, LVM_GETITEMSPACING, FALSE, 0);
-todo_wine {
+
expect(cx, LOWORD(ret));
expect(cy, HIWORD(ret));
-}
+
DestroyWindow(hwnd);
}
--
1.7.5.4
More information about the wine-patches
mailing list