comctl32: Fix LVM_GETITEM/LVIF_STATE so it only returns the bits it
[wine] / dlls / comctl32 / tests / listview.c
1 /*
2  * ListView tests
3  *
4  * Copyright 2006 Mike McCormack for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <stdio.h>
22 #include <windows.h>
23 #include <commctrl.h>
24
25 #include "wine/test.h"
26
27 static void test_images(void)
28 {
29     HWND hwnd, hwndparent = 0;
30     DWORD r;
31     LVITEM item;
32     HIMAGELIST himl;
33     HBITMAP hbmp;
34     RECT r1, r2;
35     static CHAR hello[] = "hello";
36
37     himl = ImageList_Create(40, 40, 0, 4, 4);
38     ok(himl != NULL, "failed to create imagelist\n");
39
40     hbmp = CreateBitmap(40, 40, 1, 1, NULL);
41     ok(hbmp != NULL, "failed to create bitmap\n");
42
43     r = ImageList_Add(himl, hbmp, 0);
44     ok(r == 0, "should be zero\n");
45
46     hwnd = CreateWindowEx(0, "SysListView32", "foo", LVS_OWNERDRAWFIXED, 
47                 10, 10, 100, 200, hwndparent, NULL, NULL, NULL);
48     ok(hwnd != NULL, "failed to create listview window\n");
49
50     r = SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, 0x940);
51     ok(r == 0, "should return zero\n");
52
53     r = SendMessage(hwnd, LVM_SETIMAGELIST, 0, (LPARAM)himl);
54     ok(r == 0, "should return zero\n");
55
56     r = SendMessage(hwnd, LVM_SETICONSPACING, 0, MAKELONG(100,50));
57     /* returns dimensions */
58
59     r = SendMessage(hwnd, LVM_GETITEMCOUNT, 0, 0);
60     ok(r == 0, "should be zero items\n");
61
62     item.mask = LVIF_IMAGE | LVIF_TEXT;
63     item.iItem = 0;
64     item.iSubItem = 1;
65     item.iImage = 0;
66     r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item);
67     ok(r == -1, "should fail\n");
68
69     item.iSubItem = 0;
70     item.pszText = hello;
71     r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item);
72     ok(r == 0, "should not fail\n");
73
74     memset(&r1, 0, sizeof r1);
75     r1.left = LVIR_ICON;
76     r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM) &r1);
77
78     r = SendMessage(hwnd, LVM_DELETEALLITEMS, 0, 0);
79     ok(r == TRUE, "should not fail\n");
80
81     item.iSubItem = 0;
82     item.pszText = hello;
83     r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item);
84     ok(r == 0, "should not fail\n");
85
86     memset(&r2, 0, sizeof r2);
87     r2.left = LVIR_ICON;
88     r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM) &r2);
89
90     ok(!memcmp(&r1, &r2, sizeof r1), "rectangle should be the same\n");
91
92     DestroyWindow(hwnd);
93 }
94
95 static void test_checkboxes(void)
96 {
97     HWND hwnd, hwndparent = 0;
98     LVITEMA item;
99     DWORD r;
100     static CHAR text[]  = "Text",
101                 text2[] = "Text2",
102                 text3[] = "Text3";
103
104     hwnd = CreateWindowEx(0, "SysListView32", "foo", LVS_REPORT, 
105                 10, 10, 100, 200, hwndparent, NULL, NULL, NULL);
106     ok(hwnd != NULL, "failed to create listview window\n");
107
108     /* first without LVS_EX_CHECKBOXES set and an item and check that state is preserved */
109     item.mask = LVIF_TEXT | LVIF_STATE;
110     item.stateMask = 0xffff;
111     item.state = 0xfccc;
112     item.iItem = 0;
113     item.iSubItem = 0;
114     item.pszText = text;
115     r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
116     ok(r == 0, "ret %ld\n", r);
117
118     item.iItem = 0;
119     item.mask = LVIF_STATE;
120     item.stateMask = 0xffff;
121     r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
122     ok(item.state == 0xfccc, "state %x\n", item.state);
123
124     /* Don't set LVIF_STATE */
125     item.mask = LVIF_TEXT;
126     item.stateMask = 0xffff;
127     item.state = 0xfccc;
128     item.iItem = 1;
129     item.iSubItem = 0;
130     item.pszText = text;
131     r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
132     ok(r == 1, "ret %ld\n", r);
133
134     item.iItem = 1;
135     item.mask = LVIF_STATE;
136     item.stateMask = 0xffff;
137     r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
138     ok(item.state == 0, "state %x\n", item.state);
139
140     r = SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_CHECKBOXES, LVS_EX_CHECKBOXES);
141     ok(r == 0, "should return zero\n");
142
143     /* Having turned on checkboxes, check that all existing items are set to 0x1000 (unchecked) */
144     item.iItem = 0;
145     item.mask = LVIF_STATE;
146     item.stateMask = 0xffff;
147     r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
148     ok(item.state == 0x1ccc, "state %x\n", item.state);
149
150     /* Now add an item without specifying a state and check that its state goes to 0x1000 */
151     item.iItem = 2;
152     item.mask = LVIF_TEXT;
153     item.state = 0;
154     item.pszText = text2;
155     r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
156     ok(r == 2, "ret %ld\n", r);
157
158     item.iItem = 2;
159     item.mask = LVIF_STATE;
160     item.stateMask = 0xffff;
161     r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
162     ok(item.state == 0x1000, "state %x\n", item.state);
163
164     /* Add a further item this time specifying a state and still its state goes to 0x1000 */
165     item.iItem = 3;
166     item.mask = LVIF_TEXT | LVIF_STATE;
167     item.stateMask = 0xffff;
168     item.state = 0x2aaa;
169     item.pszText = text3;
170     r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
171     ok(r == 3, "ret %ld\n", r);
172
173     item.iItem = 3;
174     item.mask = LVIF_STATE;
175     item.stateMask = 0xffff;
176     r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
177     ok(item.state == 0x1aaa, "state %x\n", item.state);
178
179     /* Set an item's state to checked */
180     item.iItem = 3;
181     item.mask = LVIF_STATE;
182     item.stateMask = 0xf000;
183     item.state = 0x2000;
184     r = SendMessage(hwnd, LVM_SETITEMA, 0, (LPARAM) &item);
185
186     item.iItem = 3;
187     item.mask = LVIF_STATE;
188     item.stateMask = 0xffff;
189     r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
190     ok(item.state == 0x2aaa, "state %x\n", item.state);
191
192     /* Check that only the bits we asked for are returned,
193      * and that all the others are set to zero
194      */
195     item.iItem = 3;
196     item.mask = LVIF_STATE;
197     item.stateMask = 0xf000;
198     item.state = 0xffff;
199     r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
200     ok(item.state == 0x2000, "state %x\n", item.state);
201
202     /* Set the style again and check that doesn't change an item's state */
203     r = SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_CHECKBOXES, LVS_EX_CHECKBOXES);
204     ok(r == LVS_EX_CHECKBOXES, "ret %lx\n", r);
205
206     item.iItem = 3;
207     item.mask = LVIF_STATE;
208     item.stateMask = 0xffff;
209     r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
210     ok(item.state == 0x2aaa, "state %x\n", item.state);
211
212     /* Unsetting the checkbox extended style doesn't change an item's state */
213     r = SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_CHECKBOXES, 0);
214     ok(r == LVS_EX_CHECKBOXES, "ret %lx\n", r);
215
216     item.iItem = 3;
217     item.mask = LVIF_STATE;
218     item.stateMask = 0xffff;
219     r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
220     ok(item.state == 0x2aaa, "state %x\n", item.state);
221
222     /* Now setting the style again will change an item's state */
223     r = SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_CHECKBOXES, LVS_EX_CHECKBOXES);
224     ok(r == 0, "ret %lx\n", r);
225
226     item.iItem = 3;
227     item.mask = LVIF_STATE;
228     item.stateMask = 0xffff;
229     r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
230     ok(item.state == 0x1aaa, "state %x\n", item.state);
231
232     DestroyWindow(hwnd);
233 }
234
235 START_TEST(listview)
236 {
237     INITCOMMONCONTROLSEX icc;
238
239     icc.dwICC = 0;
240     icc.dwSize = sizeof icc;
241     InitCommonControlsEx(&icc);
242
243     test_images();
244     test_checkboxes();
245 }