[4/5] comctl32/listview: Switching to/from LVS_OWNERDATA isn't allowed after creation (resent)
Nikolay Sivov
bunglehead at gmail.com
Mon Apr 20 02:55:03 CDT 2009
When trying to set LVS_OWNERDATA after creation this style is blocked
by WM_STYLECHANGING handler and doesn't pass to WM_STYLECHANGED,
if a control was created with LVS_OWNERDATA it passes to WM_STYLECHANGED.
Trying to reset LVS_OWNERDATA - new style got it at WM_STYLECHANGED point.
This behaviour could be verified using traces added since style fields are
passed through pointers and not logged in tests.
Changelog:
- block switching LVS_OWNERDATA after ListView creation
- add some traces for WM_STYLECHANG[ED,ING] in tests
- add some tests for this feature
>From fdcdb2fb20a86dc87f52757fc58ce90e1f1118e5 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <bunglehead at gmail.com>
Date: Mon, 20 Apr 2009 02:57:13 -0400
Subject: Switching to/from LVS_OWNERDATA isn't allowed after creation
---
dlls/comctl32/listview.c | 34 +++++++++++++++-
dlls/comctl32/tests/listview.c | 86 +++++++++++++++++++++++++++++++++++----
2 files changed, 110 insertions(+), 10 deletions(-)
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c
index d4fdaa6..d249cff 100644
--- a/dlls/comctl32/listview.c
+++ b/dlls/comctl32/listview.c
@@ -9566,7 +9566,6 @@ static INT LISTVIEW_StyleChanged(LISTVIEW_INFO *infoPtr, WPARAM wStyleType,
if (wStyleType != GWL_STYLE) return 0;
/* FIXME: if LVS_NOSORTHEADER changed, update header */
- /* what if LVS_OWNERDATA changed? */
/* or LVS_SINGLESEL */
/* or LVS_SORT{AS,DES}CENDING */
@@ -9660,6 +9659,36 @@ static INT LISTVIEW_StyleChanged(LISTVIEW_INFO *infoPtr, WPARAM wStyleType,
/***
* DESCRIPTION:
+ * Processes WM_STYLECHANGING messages.
+ *
+ * PARAMETER(S):
+ * [I] infoPtr : valid pointer to the listview structure
+ * [I] wStyleType : window style type (normal or extended)
+ * [I0] lpss : window style information
+ *
+ * RETURN:
+ * Zero
+ */
+static INT LISTVIEW_StyleChanging(LISTVIEW_INFO *infoPtr, WPARAM wStyleType,
+ STYLESTRUCT *lpss)
+{
+ TRACE("(styletype=%lx, styleOld=0x%08x, styleNew=0x%08x)\n",
+ wStyleType, lpss->styleOld, lpss->styleNew);
+
+ /* don't forward LVS_OWNERDATA only if not already set to */
+ if ((lpss->styleNew ^ lpss->styleOld) & LVS_OWNERDATA)
+ {
+ if (lpss->styleOld & LVS_OWNERDATA)
+ lpss->styleNew |= LVS_OWNERDATA;
+ else
+ lpss->styleNew &= ~LVS_OWNERDATA;
+ }
+
+ return 0;
+}
+
+/***
+ * DESCRIPTION:
* Processes WM_SHOWWINDOW messages.
*
* PARAMETER(S):
@@ -10160,6 +10189,9 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_STYLECHANGED:
return LISTVIEW_StyleChanged(infoPtr, wParam, (LPSTYLESTRUCT)lParam);
+ case WM_STYLECHANGING:
+ return LISTVIEW_StyleChanging(infoPtr, wParam, (LPSTYLESTRUCT)lParam);
+
case WM_SYSCOLORCHANGE:
COMCTL32_RefreshSysColors();
return 0;
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c
index d08ca2f..5aa2f52 100644
--- a/dlls/comctl32/tests/listview.c
+++ b/dlls/comctl32/tests/listview.c
@@ -146,6 +146,12 @@ static const struct message listview_itempos_seq[] = {
{ 0 }
};
+static const struct message listview_ownerdata_switchto_seq[] = {
+ { WM_STYLECHANGING, sent },
+ { WM_STYLECHANGED, sent },
+ { 0 }
+};
+
struct subclass_info
{
WNDPROC oldproc;
@@ -223,6 +229,14 @@ static LRESULT WINAPI listview_subclass_proc(HWND hwnd, UINT message, WPARAM wPa
trace("listview: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam);
+ /* some debug output for style changing */
+ if ((message == WM_STYLECHANGING ||
+ message == WM_STYLECHANGED) && lParam)
+ {
+ STYLESTRUCT *style = (STYLESTRUCT*)lParam;
+ trace("\told style: 0x%08x, new style: 0x%08x\n", style->styleOld, style->styleNew);
+ }
+
msg.message = message;
msg.flags = sent|wparam|lparam;
if (defwndproc_counter) msg.flags |= defwinproc;
@@ -237,7 +251,7 @@ static LRESULT WINAPI listview_subclass_proc(HWND hwnd, UINT message, WPARAM wPa
return ret;
}
-static HWND create_listview_control(void)
+static HWND create_listview_control(DWORD style)
{
struct subclass_info *info;
HWND hwnd;
@@ -249,7 +263,7 @@ static HWND create_listview_control(void)
GetClientRect(hwndparent, &rect);
hwnd = CreateWindowExA(0, WC_LISTVIEW, "foo",
- WS_CHILD | WS_BORDER | WS_VISIBLE | LVS_REPORT,
+ WS_CHILD | WS_BORDER | WS_VISIBLE | LVS_REPORT | style,
0, 0, rect.right, rect.bottom,
hwndparent, NULL, GetModuleHandleA(NULL), NULL);
ok(hwnd != NULL, "gle=%d\n", GetLastError());
@@ -957,7 +971,7 @@ static void test_redraw(void)
{
HWND hwnd, hwndheader;
- hwnd = create_listview_control();
+ hwnd = create_listview_control(0);
hwndheader = subclass_header(hwnd);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
@@ -1009,7 +1023,7 @@ static void test_customdraw(void)
HWND hwnd;
WNDPROC oldwndproc;
- hwnd = create_listview_control();
+ hwnd = create_listview_control(0);
insert_column(hwnd, 0);
insert_column(hwnd, 1);
@@ -1081,7 +1095,7 @@ static void test_color(void)
COLORREF color;
COLORREF colors[4] = {RGB(0,0,0), RGB(100,50,200), CLR_NONE, RGB(255,255,255)};
- hwnd = create_listview_control();
+ hwnd = create_listview_control(0);
ok(hwnd != NULL, "failed to create a listview window\n");
flush_sequences(sequences, NUM_MSG_SEQUENCES);
@@ -1127,7 +1141,7 @@ static void test_item_count(void)
static CHAR item1text[] = "item1";
static CHAR item2text[] = "item2";
- hwnd = create_listview_control();
+ hwnd = create_listview_control(0);
ok(hwnd != NULL, "failed to create a listview window\n");
flush_sequences(sequences, NUM_MSG_SEQUENCES);
@@ -1346,7 +1360,7 @@ static void test_multiselect(void)
};
- hwnd = create_listview_control();
+ hwnd = create_listview_control(0);
for (i=0;i<items;i++) {
insert_item(hwnd, 0);
@@ -1403,7 +1417,7 @@ static void test_subitem_rect(void)
RECT rect;
/* test LVM_GETSUBITEMRECT for header */
- hwnd = create_listview_control();
+ hwnd = create_listview_control(0);
ok(hwnd != NULL, "failed to create a listview window\n");
/* add some columns */
memset(&col, 0, sizeof(LVCOLUMN));
@@ -1464,7 +1478,7 @@ static void test_sorting(void)
LVITEMA item = {0};
DWORD r;
- hwnd = create_listview_control();
+ hwnd = create_listview_control(0);
ok(hwnd != NULL, "failed to create a listview window\n");
/* insert some items */
@@ -1514,6 +1528,59 @@ static void test_sorting(void)
DestroyWindow(hwnd);
}
+static void test_ownerdata(void)
+{
+ HWND hwnd;
+ LONG_PTR style, ret;
+
+ /* it isn't possible to set LVS_OWNERDATA after creation */
+ hwnd = create_listview_control(0);
+ ok(hwnd != NULL, "failed to create a listview window\n");
+ style = GetWindowLongPtrA(hwnd, GWL_STYLE);
+ ok(!(style & LVS_OWNERDATA) && style, "LVS_OWNERDATA isn't expected\n");
+
+ flush_sequences(sequences, NUM_MSG_SEQUENCES);
+
+ ret = SetWindowLongPtrA(hwnd, GWL_STYLE, style | LVS_OWNERDATA);
+ ok(ret == style, "Expected set GWL_STYLE to succeed\n");
+ ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_ownerdata_switchto_seq,
+ "try to switch to LVS_OWNERDATA seq", FALSE);
+
+ style = GetWindowLongPtrA(hwnd, GWL_STYLE);
+ ok(!(style & LVS_OWNERDATA), "LVS_OWNERDATA isn't expected\n");
+ DestroyWindow(hwnd);
+
+ /* try to set LVS_OWNERDATA after creation just having it */
+ hwnd = create_listview_control(LVS_OWNERDATA);
+ ok(hwnd != NULL, "failed to create a listview window\n");
+ style = GetWindowLongPtrA(hwnd, GWL_STYLE);
+ ok(style & LVS_OWNERDATA, "LVS_OWNERDATA is expected\n");
+
+ flush_sequences(sequences, NUM_MSG_SEQUENCES);
+
+ ret = SetWindowLongPtrA(hwnd, GWL_STYLE, style | LVS_OWNERDATA);
+ ok(ret == style, "Expected set GWL_STYLE to succeed\n");
+ ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_ownerdata_switchto_seq,
+ "try to switch to LVS_OWNERDATA seq", FALSE);
+ DestroyWindow(hwnd);
+
+ /* try to remove LVS_OWNERDATA after creation just having it */
+ hwnd = create_listview_control(LVS_OWNERDATA);
+ ok(hwnd != NULL, "failed to create a listview window\n");
+ style = GetWindowLongPtrA(hwnd, GWL_STYLE);
+ ok(style & LVS_OWNERDATA, "LVS_OWNERDATA is expected\n");
+
+ flush_sequences(sequences, NUM_MSG_SEQUENCES);
+
+ ret = SetWindowLongPtrA(hwnd, GWL_STYLE, style & ~LVS_OWNERDATA);
+ ok(ret == style, "Expected set GWL_STYLE to succeed\n");
+ ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_ownerdata_switchto_seq,
+ "try to switch to LVS_OWNERDATA seq", FALSE);
+ style = GetWindowLongPtrA(hwnd, GWL_STYLE);
+ ok(style & LVS_OWNERDATA, "LVS_OWNERDATA is expected\n");
+ DestroyWindow(hwnd);
+}
+
START_TEST(listview)
{
HMODULE hComctl32;
@@ -1553,4 +1620,5 @@ START_TEST(listview)
test_multiselect();
test_subitem_rect();
test_sorting();
+ test_ownerdata();
}
--
1.5.6.5
More information about the wine-patches
mailing list