1 /*
2  * ListView tests
3  *
4  * Copyright 2006 Mike McCormack for CodeWeavers
5  * Copyright 2007 George Gov
6  * Copyright 2009-2014 Nikolay Sivov
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22 
23 #include "precomp.h"
24 
25 enum seq_index {
26     PARENT_SEQ_INDEX,
27     PARENT_FULL_SEQ_INDEX,
28     PARENT_CD_SEQ_INDEX,
29     LISTVIEW_SEQ_INDEX,
30     EDITBOX_SEQ_INDEX,
31     COMBINED_SEQ_INDEX,
32     NUM_MSG_SEQUENCES
33 };
34 
35 #define LISTVIEW_ID 0
36 #define HEADER_ID   1
37 
38 #define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
39 #define expect2(expected1, expected2, got1, got2) ok(expected1 == got1 && expected2 == got2, \
40        "expected (%d,%d), got (%d,%d)\n", expected1, expected2, got1, got2)
41 
42 static const WCHAR testparentclassW[] =
43     {'L','i','s','t','v','i','e','w',' ','t','e','s','t',' ','p','a','r','e','n','t','W', 0};
44 
45 static HWND hwndparent, hwndparentW;
46 /* prevents edit box creation, LVN_BEGINLABELEDIT return value */
47 static BOOL blockEdit;
48 /* return nonzero on NM_HOVER */
49 static BOOL g_block_hover;
50 /* notification data for LVN_ITEMCHANGED */
51 static NMLISTVIEW g_nmlistview;
52 /* notification data for LVN_ITEMCHANGING */
53 static NMLISTVIEW g_nmlistview_changing;
54 /* format reported to control:
55    -1 falls to defproc, anything else returned */
56 static INT notifyFormat;
57 /* indicates we're running < 5.80 version */
58 static BOOL g_is_below_5;
59 /* item data passed to LVN_GETDISPINFOA */
60 static LVITEMA g_itema;
61 /* alter notification code A->W */
62 static BOOL g_disp_A_to_W;
63 /* dispinfo data sent with LVN_LVN_ENDLABELEDIT */
64 static NMLVDISPINFOA g_editbox_disp_info;
65 /* when this is set focus will be tested on LVN_DELETEITEM */
66 static BOOL g_focus_test_LVN_DELETEITEM;
67 
68 static HWND subclass_editbox(HWND hwndListview);
69 
70 static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
71 
72 static const struct message create_ownerdrawfixed_parent_seq[] = {
73     { WM_NOTIFYFORMAT, sent },
74     { WM_QUERYUISTATE, sent|optional }, /* Win2K and higher */
75     { WM_MEASUREITEM, sent },
76     { WM_PARENTNOTIFY, sent },
77     { 0 }
78 };
79 
80 static const struct message redraw_listview_seq[] = {
81     { WM_PAINT,      sent|id,            0, 0, LISTVIEW_ID },
82     { WM_PAINT,      sent|id,            0, 0, HEADER_ID },
83     { WM_NCPAINT,    sent|id|defwinproc, 0, 0, HEADER_ID },
84     { WM_ERASEBKGND, sent|id|defwinproc|optional, 0, 0, HEADER_ID },
85     { WM_NOTIFY,     sent|id|defwinproc, 0, 0, LISTVIEW_ID },
86     { WM_NCPAINT,    sent|id|defwinproc, 0, 0, LISTVIEW_ID },
87     { WM_ERASEBKGND, sent|id|defwinproc|optional, 0, 0, LISTVIEW_ID },
88     { 0 }
89 };
90 
91 static const struct message listview_icon_spacing_seq[] = {
92     { LVM_SETICONSPACING, sent|lparam, 0, MAKELPARAM(20, 30) },
93     { LVM_SETICONSPACING, sent|lparam, 0, MAKELPARAM(25, 35) },
94     { LVM_SETICONSPACING, sent|lparam, 0, MAKELPARAM(-1, -1) },
95     { 0 }
96 };
97 
98 static const struct message listview_color_seq[] = {
99     { LVM_SETBKCOLOR,     sent|lparam, 0, RGB(0,0,0) },
100     { LVM_GETBKCOLOR,     sent },
101     { LVM_SETTEXTCOLOR,   sent|lparam, 0, RGB(0,0,0) },
102     { LVM_GETTEXTCOLOR,   sent },
103     { LVM_SETTEXTBKCOLOR, sent|lparam, 0, RGB(0,0,0) },
104     { LVM_GETTEXTBKCOLOR, sent },
105 
106     { LVM_SETBKCOLOR,     sent|lparam, 0, RGB(100,50,200) },
107     { LVM_GETBKCOLOR,     sent },
108     { LVM_SETTEXTCOLOR,   sent|lparam, 0, RGB(100,50,200) },
109     { LVM_GETTEXTCOLOR,   sent },
110     { LVM_SETTEXTBKCOLOR, sent|lparam, 0, RGB(100,50,200) },
111     { LVM_GETTEXTBKCOLOR, sent },
112 
113     { LVM_SETBKCOLOR,     sent|lparam, 0, CLR_NONE },
114     { LVM_GETBKCOLOR,     sent },
115     { LVM_SETTEXTCOLOR,   sent|lparam, 0, CLR_NONE },
116     { LVM_GETTEXTCOLOR,   sent },
117     { LVM_SETTEXTBKCOLOR, sent|lparam, 0, CLR_NONE },
118     { LVM_GETTEXTBKCOLOR, sent },
119 
120     { LVM_SETBKCOLOR,     sent|lparam, 0, RGB(255,255,255) },
121     { LVM_GETBKCOLOR,     sent },
122     { LVM_SETTEXTCOLOR,   sent|lparam, 0, RGB(255,255,255) },
123     { LVM_GETTEXTCOLOR,   sent },
124     { LVM_SETTEXTBKCOLOR, sent|lparam, 0, RGB(255,255,255) },
125     { LVM_GETTEXTBKCOLOR, sent },
126     { 0 }
127 };
128 
129 static const struct message listview_item_count_seq[] = {
130     { LVM_GETITEMCOUNT,   sent },
131     { LVM_INSERTITEMA,    sent },
132     { LVM_INSERTITEMA,    sent },
133     { LVM_INSERTITEMA,    sent },
134     { LVM_GETITEMCOUNT,   sent },
135     { LVM_DELETEITEM,     sent|wparam, 2 },
136     { WM_NCPAINT,         sent|optional },
137     { WM_ERASEBKGND,      sent|optional },
138     { LVM_GETITEMCOUNT,   sent },
139     { LVM_DELETEALLITEMS, sent },
140     { LVM_GETITEMCOUNT,   sent },
141     { LVM_INSERTITEMA,    sent },
142     { LVM_INSERTITEMA,    sent },
143     { LVM_GETITEMCOUNT,   sent },
144     { LVM_INSERTITEMA,    sent },
145     { LVM_GETITEMCOUNT,   sent },
146     { 0 }
147 };
148 
149 static const struct message listview_itempos_seq[] = {
150     { LVM_INSERTITEMA,     sent },
151     { LVM_INSERTITEMA,     sent },
152     { LVM_INSERTITEMA,     sent },
153     { LVM_SETITEMPOSITION, sent|wparam|lparam, 1, MAKELPARAM(10,5) },
154     { WM_NCPAINT,          sent|optional },
155     { WM_ERASEBKGND,       sent|optional },
156     { LVM_GETITEMPOSITION, sent|wparam,        1 },
157     { LVM_SETITEMPOSITION, sent|wparam|lparam, 2, MAKELPARAM(0,0) },
158     { LVM_GETITEMPOSITION, sent|wparam,        2 },
159     { LVM_SETITEMPOSITION, sent|wparam|lparam, 0, MAKELPARAM(20,20) },
160     { LVM_GETITEMPOSITION, sent|wparam,        0 },
161     { 0 }
162 };
163 
164 static const struct message listview_ownerdata_switchto_seq[] = {
165     { WM_STYLECHANGING,    sent },
166     { WM_STYLECHANGED,     sent },
167     { 0 }
168 };
169 
170 static const struct message listview_getorderarray_seq[] = {
171     { LVM_GETCOLUMNORDERARRAY, sent|id|wparam, 2, 0, LISTVIEW_ID },
172     { HDM_GETORDERARRAY,       sent|id|wparam, 2, 0, HEADER_ID },
173     { LVM_GETCOLUMNORDERARRAY, sent|id|wparam, 0, 0, LISTVIEW_ID },
174     { HDM_GETORDERARRAY,       sent|id|wparam, 0, 0, HEADER_ID },
175     { 0 }
176 };
177 
178 static const struct message listview_setorderarray_seq[] = {
179     { LVM_SETCOLUMNORDERARRAY, sent|id|wparam, 2, 0, LISTVIEW_ID },
180     { HDM_SETORDERARRAY,       sent|id|wparam, 2, 0, HEADER_ID },
181     { LVM_SETCOLUMNORDERARRAY, sent|id|wparam, 0, 0, LISTVIEW_ID },
182     { HDM_SETORDERARRAY,       sent|id|wparam, 0, 0, HEADER_ID },
183     { 0 }
184 };
185 
186 static const struct message empty_seq[] = {
187     { 0 }
188 };
189 
190 static const struct message parent_focus_change_ownerdata_seq[] = {
191     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
192     { WM_NOTIFY, sent|id, 0, 0, LVN_GETDISPINFOA },
193     { 0 }
194 };
195 
196 static const struct message forward_erasebkgnd_parent_seq[] = {
197     { WM_ERASEBKGND, sent },
198     { 0 }
199 };
200 
201 static const struct message ownerdata_select_focus_parent_seq[] = {
202     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
203     { WM_NOTIFY, sent|id, 0, 0, LVN_GETDISPINFOA },
204     { WM_NOTIFY, sent|id|optional, 0, 0, LVN_GETDISPINFOA }, /* version 4.7x */
205     { 0 }
206 };
207 
208 static const struct message ownerdata_setstate_all_parent_seq[] = {
209     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
210     { 0 }
211 };
212 
213 static const struct message ownerdata_defocus_all_parent_seq[] = {
214     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
215     { WM_NOTIFY, sent|id, 0, 0, LVN_GETDISPINFOA },
216     { WM_NOTIFY, sent|id|optional, 0, 0, LVN_GETDISPINFOA },
217     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
218     { 0 }
219 };
220 
221 static const struct message ownerdata_deselect_all_parent_seq[] = {
222     { WM_NOTIFY, sent|id, 0, 0, LVN_ODCACHEHINT },
223     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
224     { 0 }
225 };
226 
227 static const struct message change_all_parent_seq[] = {
228     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
229     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
230 
231     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
232     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
233 
234     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
235     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
236 
237     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
238     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
239 
240     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
241     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
242     { 0 }
243 };
244 
245 static const struct message changing_all_parent_seq[] = {
246     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
247     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
248     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
249     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
250     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
251     { 0 }
252 };
253 
254 static const struct message textcallback_set_again_parent_seq[] = {
255     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
256     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED  },
257     { 0 }
258 };
259 
260 static const struct message single_getdispinfo_parent_seq[] = {
261     { WM_NOTIFY, sent|id, 0, 0, LVN_GETDISPINFOA },
262     { 0 }
263 };
264 
265 static const struct message getitemposition_seq1[] = {
266     { LVM_GETITEMPOSITION, sent|id, 0, 0, LISTVIEW_ID },
267     { 0 }
268 };
269 
270 static const struct message getitemposition_seq2[] = {
271     { LVM_GETITEMPOSITION, sent|id, 0, 0, LISTVIEW_ID },
272     { HDM_GETITEMRECT, sent|id, 0, 0, HEADER_ID },
273     { 0 }
274 };
275 
276 static const struct message getsubitemrect_seq[] = {
277     { LVM_GETSUBITEMRECT, sent|id|wparam, -1, 0, LISTVIEW_ID },
278     { HDM_GETITEMRECT, sent|id, 0, 0, HEADER_ID },
279     { LVM_GETSUBITEMRECT, sent|id|wparam, 0, 0, LISTVIEW_ID },
280     { HDM_GETITEMRECT, sent|id, 0, 0, HEADER_ID },
281     { LVM_GETSUBITEMRECT, sent|id|wparam, -10, 0, LISTVIEW_ID },
282     { HDM_GETITEMRECT, sent|id, 0, 0, HEADER_ID },
283     { LVM_GETSUBITEMRECT, sent|id|wparam, 20, 0, LISTVIEW_ID },
284     { HDM_GETITEMRECT, sent|id, 0, 0, HEADER_ID },
285     { 0 }
286 };
287 
288 static const struct message editbox_create_pos[] = {
289     /* sequence sent after LVN_BEGINLABELEDIT */
290     /* next two are 4.7x specific */
291     { WM_WINDOWPOSCHANGING, sent },
292     { WM_WINDOWPOSCHANGED, sent|optional },
293 
294     { WM_WINDOWPOSCHANGING, sent|optional },
295     { WM_NCCALCSIZE, sent },
296     { WM_WINDOWPOSCHANGED, sent },
297     { WM_MOVE, sent|defwinproc },
298     { WM_SIZE, sent|defwinproc },
299     /* the rest is todo, skipped in 4.7x */
300     { WM_WINDOWPOSCHANGING, sent|optional },
301     { WM_WINDOWPOSCHANGED, sent|optional },
302     { 0 }
303 };
304 
305 static const struct message scroll_parent_seq[] = {
306     { WM_NOTIFY, sent|id, 0, 0, LVN_BEGINSCROLL },
307     { WM_NOTIFY, sent|id, 0, 0, LVN_ENDSCROLL },
308     { 0 }
309 };
310 
311 static const struct message setredraw_seq[] = {
312     { WM_SETREDRAW, sent|id|wparam, FALSE, 0, LISTVIEW_ID },
313     { 0 }
314 };
315 
316 static const struct message lvs_ex_transparentbkgnd_seq[] = {
317     { WM_PRINTCLIENT, sent|lparam, 0, PRF_ERASEBKGND },
318     { 0 }
319 };
320 
321 static const struct message edit_end_nochange[] = {
322     { WM_NOTIFY, sent|id, 0, 0, LVN_ENDLABELEDITA },
323     { WM_NOTIFY, sent|id, 0, 0, NM_CUSTOMDRAW },     /* todo */
324     { WM_NOTIFY, sent|id, 0, 0, NM_SETFOCUS },
325     { 0 }
326 };
327 
328 static const struct message hover_parent[] = {
329     { WM_GETDLGCODE, sent }, /* todo_wine */
330     { WM_NOTIFY, sent|id, 0, 0, NM_HOVER },
331     { 0 }
332 };
333 
334 static const struct message listview_destroy[] = {
335     { 0x0090, sent|optional }, /* Vista */
336     { WM_PARENTNOTIFY, sent },
337     { WM_SHOWWINDOW, sent },
338     { WM_WINDOWPOSCHANGING, sent },
339     { WM_WINDOWPOSCHANGED, sent|optional },
340     { WM_DESTROY, sent },
341     { WM_NOTIFY, sent|id, 0, 0, LVN_DELETEALLITEMS },
342     { WM_NCDESTROY, sent },
343     { 0 }
344 };
345 
346 static const struct message listview_ownerdata_destroy[] = {
347     { 0x0090, sent|optional }, /* Vista */
348     { WM_PARENTNOTIFY, sent },
349     { WM_SHOWWINDOW, sent },
350     { WM_WINDOWPOSCHANGING, sent },
351     { WM_WINDOWPOSCHANGED, sent|optional },
352     { WM_DESTROY, sent },
353     { WM_NCDESTROY, sent },
354     { 0 }
355 };
356 
357 static const struct message listview_ownerdata_deleteall[] = {
358     { LVM_DELETEALLITEMS, sent },
359     { WM_NOTIFY, sent|id, 0, 0, LVN_DELETEALLITEMS },
360     { 0 }
361 };
362 
363 static const struct message listview_header_changed_seq[] = {
364     { LVM_SETCOLUMNA, sent },
365     { WM_NOTIFY, sent|id|defwinproc, 0, 0, LISTVIEW_ID },
366     { WM_NOTIFY, sent|id|defwinproc, 0, 0, LISTVIEW_ID },
367     { 0 }
368 };
369 
370 static const struct message parent_header_click_seq[] = {
371     { WM_NOTIFY, sent|id, 0, 0, LVN_COLUMNCLICK },
372     { WM_NOTIFY, sent|id, 0, 0, HDN_ITEMCLICKA },
373     { 0 }
374 };
375 
376 static const struct message parent_header_divider_dclick_seq[] = {
377     { WM_NOTIFY, sent|id, 0, 0, HDN_ITEMCHANGINGA },
378     { WM_NOTIFY, sent|id, 0, 0, NM_CUSTOMDRAW },
379     { WM_NOTIFY, sent|id, 0, 0, NM_CUSTOMDRAW },
380     { WM_NOTIFY, sent|id, 0, 0, HDN_ITEMCHANGEDA },
381     { WM_NOTIFY, sent|id, 0, 0, HDN_DIVIDERDBLCLICKA },
382     { 0 }
383 };
384 
385 static const struct message listview_set_imagelist[] = {
386     { LVM_SETIMAGELIST, sent|id, 0, 0, LISTVIEW_ID },
387     { 0 }
388 };
389 
390 static const struct message listview_header_set_imagelist[] = {
391     { LVM_SETIMAGELIST, sent|id, 0, 0, LISTVIEW_ID },
392     { HDM_SETIMAGELIST, sent|id, 0, 0, HEADER_ID },
393     { 0 }
394 };
395 
396 static const struct message parent_insert_focused_seq[] = {
397     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
398     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
399     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
400     { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
401     { WM_NOTIFY, sent|id, 0, 0, LVN_INSERTITEM },
402     { 0 }
403 };
404 
405 static const struct message parent_report_cd_seq[] = {
406     { WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_PREPAINT },
407     { WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_ITEMPREPAINT },
408     { WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_ITEMPREPAINT|CDDS_SUBITEM },
409     { WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_ITEMPOSTPAINT|CDDS_SUBITEM },
410     { WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_ITEMPREPAINT|CDDS_SUBITEM },
411     { WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_ITEMPOSTPAINT|CDDS_SUBITEM },
412     { WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_ITEMPOSTPAINT },
413     { WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_POSTPAINT },
414     { 0 }
415 };
416 
417 static const struct message parent_list_cd_seq[] = {
418     { WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_PREPAINT },
419     { WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_ITEMPREPAINT },
420     { WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_ITEMPOSTPAINT },
421     { WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_POSTPAINT },
422     { 0 }
423 };
424 
425 static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
426 {
427     static LONG defwndproc_counter = 0;
428     LRESULT ret;
429     struct message msg;
430 
431     msg.message = message;
432     msg.flags = sent|wparam|lparam;
433     if (defwndproc_counter) msg.flags |= defwinproc;
434     msg.wParam = wParam;
435     msg.lParam = lParam;
436     if (message == WM_NOTIFY && lParam) msg.id = ((NMHDR*)lParam)->code;
437 
438     /* log system messages, except for painting */
439     if (message < WM_USER &&
440         message != WM_PAINT &&
441         message != WM_ERASEBKGND &&
442         message != WM_NCPAINT &&
443         message != WM_NCHITTEST &&
444         message != WM_GETTEXT &&
445         message != WM_GETICON &&
446         message != WM_DEVICECHANGE)
447     {
448         add_message(sequences, PARENT_SEQ_INDEX, &msg);
449         add_message(sequences, COMBINED_SEQ_INDEX, &msg);
450     }
451     add_message(sequences, PARENT_FULL_SEQ_INDEX, &msg);
452 
453     switch (message)
454     {
455       case WM_NOTIFY:
456       {
457           switch (((NMHDR*)lParam)->code)
458           {
459           case LVN_BEGINLABELEDITA:
460           {
461               HWND edit = NULL;
462 
463               /* subclass edit box */
464               if (!blockEdit)
465                   edit = subclass_editbox(((NMHDR*)lParam)->hwndFrom);
466 
467               if (edit)
468               {
469                   INT len = SendMessageA(edit, EM_GETLIMITTEXT, 0, 0);
470                   ok(len == 259 || broken(len == 260) /* includes NULL in NT4 */,
471                       "text limit %d, expected 259\n", len);
472               }
473 
474               return blockEdit;
475           }
476           case LVN_ENDLABELEDITA:
477               {
478               HWND edit;
479 
480               /* always accept new item text */
481               NMLVDISPINFOA *di = (NMLVDISPINFOA*)lParam;
482               g_editbox_disp_info = *di;
483               trace("LVN_ENDLABELEDIT: text=%s\n", di->item.pszText ? di->item.pszText : "(null)");
484 
485               /* edit control still available from this notification */
486               edit = (HWND)SendMessageA(((NMHDR*)lParam)->hwndFrom, LVM_GETEDITCONTROL, 0, 0);
487               ok(IsWindow(edit), "expected valid edit control handle\n");
488               ok((GetWindowLongA(edit, GWL_STYLE) & ES_MULTILINE) == 0, "edit is multiline\n");
489 
490               return TRUE;
491               }
492           case LVN_BEGINSCROLL:
493           case LVN_ENDSCROLL:
494               {
495               NMLVSCROLL *pScroll = (NMLVSCROLL*)lParam;
496 
497               trace("LVN_%sSCROLL: (%d,%d)\n", pScroll->hdr.code == LVN_BEGINSCROLL ?
498                                                "BEGIN" : "END", pScroll->dx, pScroll->dy);
499               }
500               break;
501           case LVN_ITEMCHANGING:
502               {
503                   NMLISTVIEW *nmlv = (NMLISTVIEW*)lParam;
504                   g_nmlistview_changing = *nmlv;
505               }
506               break;
507           case LVN_ITEMCHANGED:
508               {
509                   NMLISTVIEW *nmlv = (NMLISTVIEW*)lParam;
510                   g_nmlistview = *nmlv;
511               }
512               break;
513           case LVN_GETDISPINFOA:
514               {
515                   NMLVDISPINFOA *dispinfo = (NMLVDISPINFOA*)lParam;
516                   g_itema = dispinfo->item;
517 
518                   if (g_disp_A_to_W && (dispinfo->item.mask & LVIF_TEXT))
519                   {
520                       static const WCHAR testW[] = {'T','E','S','T',0};
521                       dispinfo->hdr.code = LVN_GETDISPINFOW;
522                       memcpy(dispinfo->item.pszText, testW, sizeof(testW));
523                   }
524 
525                   /* test control buffer size for text, 10 used to mask cases when control
526                      is using caller buffer to process LVM_GETITEM for example */
527                   if (dispinfo->item.mask & LVIF_TEXT && dispinfo->item.cchTextMax > 10)
528                       ok(dispinfo->item.cchTextMax == 260 ||
529                          broken(dispinfo->item.cchTextMax == 264) /* NT4 reports aligned size */,
530                       "buffer size %d\n", dispinfo->item.cchTextMax);
531               }
532               break;
533           case LVN_DELETEITEM:
534               if (g_focus_test_LVN_DELETEITEM)
535               {
536                   NMLISTVIEW *nmlv = (NMLISTVIEW*)lParam;
537                   UINT state;
538 
539                   state = SendMessageA(((NMHDR*)lParam)->hwndFrom, LVM_GETITEMSTATE, nmlv->iItem, LVIS_FOCUSED);
540                   ok(state == 0, "got state %x\n", state);
541               }
542               break;
543           case NM_HOVER:
544               if (g_block_hover) return 1;
545               break;
546           }
547           break;
548       }
549       case WM_NOTIFYFORMAT:
550       {
551           /* force to return format */
552           if (lParam == NF_QUERY && notifyFormat != -1) return notifyFormat;
553           break;
554       }
555     }
556 
557     defwndproc_counter++;
558     if (IsWindowUnicode(hwnd))
559         ret = DefWindowProcW(hwnd, message, wParam, lParam);
560     else
561         ret = DefWindowProcA(hwnd, message, wParam, lParam);
562     defwndproc_counter--;
563 
564     return ret;
565 }
566 
567 static BOOL register_parent_wnd_class(BOOL Unicode)
568 {
569     WNDCLASSA clsA;
570     WNDCLASSW clsW;
571 
572     if (Unicode)
573     {
574         clsW.style = 0;
575         clsW.lpfnWndProc = parent_wnd_proc;
576         clsW.cbClsExtra = 0;
577         clsW.cbWndExtra = 0;
578         clsW.hInstance = GetModuleHandleW(NULL);
579         clsW.hIcon = 0;
580         clsW.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
581         clsW.hbrBackground = GetStockObject(WHITE_BRUSH);
582         clsW.lpszMenuName = NULL;
583         clsW.lpszClassName = testparentclassW;
584     }
585     else
586     {
587         clsA.style = 0;
588         clsA.lpfnWndProc = parent_wnd_proc;
589         clsA.cbClsExtra = 0;
590         clsA.cbWndExtra = 0;
591         clsA.hInstance = GetModuleHandleA(NULL);
592         clsA.hIcon = 0;
593         clsA.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
594         clsA.hbrBackground = GetStockObject(WHITE_BRUSH);
595         clsA.lpszMenuName = NULL;
596         clsA.lpszClassName = "Listview test parent class";
597     }
598 
599     return Unicode ? RegisterClassW(&clsW) : RegisterClassA(&clsA);
600 }
601 
602 static HWND create_parent_window(BOOL Unicode)
603 {
604     static const WCHAR nameW[] = {'t','e','s','t','p','a','r','e','n','t','n','a','m','e','W',0};
605     HWND hwnd;
606 
607     if (!register_parent_wnd_class(Unicode))
608         return NULL;
609 
610     blockEdit = FALSE;
611     notifyFormat = -1;
612 
613     if (Unicode)
614         hwnd = CreateWindowExW(0, testparentclassW, nameW,
615                                WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
616                                WS_MAXIMIZEBOX | WS_VISIBLE,
617                                0, 0, 100, 100,
618                                GetDesktopWindow(), NULL, GetModuleHandleW(NULL), NULL);
619     else
620         hwnd = CreateWindowExA(0, "Listview test parent class",
621                                "Listview test parent window",
622                                WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
623                                WS_MAXIMIZEBOX | WS_VISIBLE,
624                                0, 0, 100, 100,
625                                GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL);
626     SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE );
627     return hwnd;
628 }
629 
630 static LRESULT WINAPI listview_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
631 {
632     WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
633     static LONG defwndproc_counter = 0;
634     LRESULT ret;
635     struct message msg;
636 
637     msg.message = message;
638     msg.flags = sent|wparam|lparam;
639     if (defwndproc_counter) msg.flags |= defwinproc;
640     msg.wParam = wParam;
641     msg.lParam = lParam;
642     msg.id = LISTVIEW_ID;
643     add_message(sequences, LISTVIEW_SEQ_INDEX, &msg);
644     add_message(sequences, COMBINED_SEQ_INDEX, &msg);
645 
646     defwndproc_counter++;
647     ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
648     defwndproc_counter--;
649     return ret;
650 }
651 
652 static HWND create_listview_control(DWORD style)
653 {
654     WNDPROC oldproc;
655     HWND hwnd;
656     RECT rect;
657 
658     GetClientRect(hwndparent, &rect);
659     hwnd = CreateWindowExA(0, WC_LISTVIEWA, "foo",
660                            WS_CHILD | WS_BORDER | WS_VISIBLE | style,
661                            0, 0, rect.right, rect.bottom,
662                            hwndparent, NULL, GetModuleHandleA(NULL), NULL);
663     ok(hwnd != NULL, "gle=%d\n", GetLastError());
664 
665     if (!hwnd) return NULL;
666 
667     oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC,
668                                         (LONG_PTR)listview_subclass_proc);
669     SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc);
670 
671     return hwnd;
672 }
673 
674 /* unicode listview window with specified parent */
675 static HWND create_listview_controlW(DWORD style, HWND parent)
676 {
677     WNDPROC oldproc;
678     HWND hwnd;
679     RECT rect;
680     static const WCHAR nameW[] = {'f','o','o',0};
681 
682     GetClientRect(parent, &rect);
683     hwnd = CreateWindowExW(0, WC_LISTVIEWW, nameW,
684                            WS_CHILD | WS_BORDER | WS_VISIBLE | style,
685                            0, 0, rect.right, rect.bottom,
686                            parent, NULL, GetModuleHandleW(NULL), NULL);
687     ok(hwnd != NULL, "gle=%d\n", GetLastError());
688 
689     if (!hwnd) return NULL;
690 
691     oldproc = (WNDPROC)SetWindowLongPtrW(hwnd, GWLP_WNDPROC,
692                                         (LONG_PTR)listview_subclass_proc);
693     SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc);
694 
695     return hwnd;
696 }
697 
698 static LRESULT WINAPI header_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
699 {
700     WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
701     static LONG defwndproc_counter = 0;
702     struct message msg = { 0 };
703     LRESULT ret;
704 
705     msg.message = message;
706     msg.flags = sent|wparam|lparam;
707     if (defwndproc_counter) msg.flags |= defwinproc;
708     msg.wParam = wParam;
709     msg.lParam = lParam;
710     msg.id = HEADER_ID;
711     add_message(sequences, LISTVIEW_SEQ_INDEX, &msg);
712 
713     defwndproc_counter++;
714     ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
715     defwndproc_counter--;
716     return ret;
717 }
718 
719 static HWND subclass_header(HWND hwndListview)
720 {
721     WNDPROC oldproc;
722     HWND hwnd;
723 
724     hwnd = (HWND)SendMessageA(hwndListview, LVM_GETHEADER, 0, 0);
725     oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC,
726                                          (LONG_PTR)header_subclass_proc);
727     SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc);
728 
729     return hwnd;
730 }
731 
732 static LRESULT WINAPI editbox_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
733 {
734     WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
735     static LONG defwndproc_counter = 0;
736     struct message msg = { 0 };
737     LRESULT ret;
738 
739     msg.message = message;
740     msg.flags = sent|wparam|lparam;
741     if (defwndproc_counter) msg.flags |= defwinproc;
742     msg.wParam = wParam;
743     msg.lParam = lParam;
744 
745     /* all we need is sizing */
746     if (message == WM_WINDOWPOSCHANGING ||
747         message == WM_NCCALCSIZE ||
748         message == WM_WINDOWPOSCHANGED ||
749         message == WM_MOVE ||
750         message == WM_SIZE)
751     {
752         add_message(sequences, EDITBOX_SEQ_INDEX, &msg);
753     }
754 
755     defwndproc_counter++;
756     ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
757     defwndproc_counter--;
758     return ret;
759 }
760 
761 static HWND subclass_editbox(HWND hwndListview)
762 {
763     WNDPROC oldproc;
764     HWND hwnd;
765 
766     hwnd = (HWND)SendMessageA(hwndListview, LVM_GETEDITCONTROL, 0, 0);
767     oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC,
768                                          (LONG_PTR)editbox_subclass_proc);
769     SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc);
770 
771     return hwnd;
772 }
773 
774 /* Performs a single LVM_HITTEST test */
775 static void test_lvm_hittest_(HWND hwnd, INT x, INT y, INT item, UINT flags, UINT broken_flags,
776                               BOOL todo_item, BOOL todo_flags, int line)
777 {
778     LVHITTESTINFO lpht;
779     INT ret;
780 
781     lpht.pt.x = x;
782     lpht.pt.y = y;
783     lpht.iSubItem = 10;
784 
785     ret = SendMessageA(hwnd, LVM_HITTEST, 0, (LPARAM)&lpht);
786 
787     todo_wine_if(todo_item)
788     {
789         ok_(__FILE__, line)(ret == item, "Expected %d retval, got %d\n", item, ret);
790         ok_(__FILE__, line)(lpht.iItem == item, "Expected %d item, got %d\n", item, lpht.iItem);
791         ok_(__FILE__, line)(lpht.iSubItem == 10, "Expected subitem not overwrited\n");
792     }
793 
794     if (todo_flags)
795     {
796         todo_wine
797             ok_(__FILE__, line)(lpht.flags == flags, "Expected flags 0x%x, got 0x%x\n", flags, lpht.flags);
798     }
799     else if (broken_flags)
800         ok_(__FILE__, line)(lpht.flags == flags || broken(lpht.flags == broken_flags),
801                             "Expected flags %x, got %x\n", flags, lpht.flags);
802     else
803         ok_(__FILE__, line)(lpht.flags == flags, "Expected flags 0x%x, got 0x%x\n", flags, lpht.flags);
804 }
805 
806 #define test_lvm_hittest(a,b,c,d,e,f,g,h) test_lvm_hittest_(a,b,c,d,e,f,g,h,__LINE__)
807 
808 /* Performs a single LVM_SUBITEMHITTEST test */
809 static void test_lvm_subitemhittest_(HWND hwnd, INT x, INT y, INT item, INT subitem, UINT flags,
810                                      BOOL todo_item, BOOL todo_subitem, BOOL todo_flags, int line)
811 {
812     LVHITTESTINFO lpht;
813     INT ret;
814 
815     lpht.pt.x = x;
816     lpht.pt.y = y;
817 
818     ret = SendMessageA(hwnd, LVM_SUBITEMHITTEST, 0, (LPARAM)&lpht);
819 
820     todo_wine_if(todo_item)
821     {
822         ok_(__FILE__, line)(ret == item, "Expected %d retval, got %d\n", item, ret);
823         ok_(__FILE__, line)(lpht.iItem == item, "Expected %d item, got %d\n", item, lpht.iItem);
824     }
825 
826     todo_wine_if(todo_subitem)
827         ok_(__FILE__, line)(lpht.iSubItem == subitem, "Expected subitem %d, got %d\n", subitem, lpht.iSubItem);
828 
829     todo_wine_if(todo_flags)
830         ok_(__FILE__, line)(lpht.flags == flags, "Expected flags 0x%x, got 0x%x\n", flags, lpht.flags);
831 }
832 
833 #define test_lvm_subitemhittest(a,b,c,d,e,f,g,h,i) test_lvm_subitemhittest_(a,b,c,d,e,f,g,h,i,__LINE__)
834 
835 static void test_images(void)
836 {
837     HWND hwnd;
838     INT r;
839     LVITEMA item;
840     HIMAGELIST himl;
841     HBITMAP hbmp;
842     RECT r1, r2;
843     static CHAR hello[] = "hello";
844 
845     himl = ImageList_Create(40, 40, 0, 4, 4);
846     ok(himl != NULL, "failed to create imagelist\n");
847 
848     hbmp = CreateBitmap(40, 40, 1, 1, NULL);
849     ok(hbmp != NULL, "failed to create bitmap\n");
850 
851     r = ImageList_Add(himl, hbmp, 0);
852     ok(r == 0, "should be zero\n");
853 
854     hwnd = CreateWindowExA(0, "SysListView32", "foo", LVS_OWNERDRAWFIXED,
855                 10, 10, 100, 200, hwndparent, NULL, NULL, NULL);
856     ok(hwnd != NULL, "failed to create listview window\n");
857 
858     r = SendMessageA(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
859                     LVS_EX_UNDERLINEHOT | LVS_EX_FLATSB | LVS_EX_ONECLICKACTIVATE);
860 
861     ok(r == 0, "should return zero\n");
862 
863     r = SendMessageA(hwnd, LVM_SETIMAGELIST, 0, (LPARAM)himl);
864     ok(r == 0, "should return zero\n");
865 
866     r = SendMessageA(hwnd, LVM_SETICONSPACING, 0, MAKELONG(100,50));
867     ok(r != 0, "got 0\n");
868 
869     /* returns dimensions */
870 
871     r = SendMessageA(hwnd, LVM_GETITEMCOUNT, 0, 0);
872     ok(r == 0, "should be zero items\n");
873 
874     item.mask = LVIF_IMAGE | LVIF_TEXT;
875     item.iItem = 0;
876     item.iSubItem = 1;
877     item.iImage = 0;
878     item.pszText = 0;
879     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
880     ok(r == -1, "should fail\n");
881 
882     item.iSubItem = 0;
883     item.pszText = hello;
884     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
885     ok(r == 0, "should not fail\n");
886 
887     SetRect(&r1, LVIR_ICON, 0, 0, 0);
888     r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM) &r1);
889     expect(1, r);
890 
891     r = SendMessageA(hwnd, LVM_DELETEALLITEMS, 0, 0);
892     ok(r == TRUE, "should not fail\n");
893 
894     item.iSubItem = 0;
895     item.pszText = hello;
896     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
897     ok(r == 0, "should not fail\n");
898 
899     SetRect(&r2, LVIR_ICON, 0, 0, 0);
900     r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM) &r2);
901     expect(1, r);
902 
903     ok(EqualRect(&r1, &r2), "rectangle should be the same\n");
904 
905     DestroyWindow(hwnd);
906 }
907 
908 static void test_checkboxes(void)
909 {
910     HWND hwnd;
911     LVITEMA item;
912     DWORD r;
913     static CHAR text[]  = "Text",
914                 text2[] = "Text2",
915                 text3[] = "Text3";
916 
917     hwnd = CreateWindowExA(0, "SysListView32", "foo", LVS_REPORT,
918                 10, 10, 100, 200, hwndparent, NULL, NULL, NULL);
919     ok(hwnd != NULL, "failed to create listview window\n");
920 
921     /* first without LVS_EX_CHECKBOXES set and an item and check that state is preserved */
922     item.mask = LVIF_TEXT | LVIF_STATE;
923     item.stateMask = 0xffff;
924     item.state = 0xfccc;
925     item.iItem = 0;
926     item.iSubItem = 0;
927     item.pszText = text;
928     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
929     expect(0, r);
930 
931     item.iItem = 0;
932     item.mask = LVIF_STATE;
933     item.stateMask = 0xffff;
934     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
935     expect(1, r);
936     ok(item.state == 0xfccc, "state %x\n", item.state);
937 
938     /* Don't set LVIF_STATE */
939     item.mask = LVIF_TEXT;
940     item.stateMask = 0xffff;
941     item.state = 0xfccc;
942     item.iItem = 1;
943     item.iSubItem = 0;
944     item.pszText = text;
945     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
946     expect(1, r);
947 
948     item.iItem = 1;
949     item.mask = LVIF_STATE;
950     item.stateMask = 0xffff;
951     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
952     expect(1, r);
953     ok(item.state == 0, "state %x\n", item.state);
954 
955     r = SendMessageA(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_CHECKBOXES, LVS_EX_CHECKBOXES);
956     expect(0, r);
957 
958     /* Having turned on checkboxes, check that all existing items are set to 0x1000 (unchecked) */
959     item.iItem = 0;
960     item.mask = LVIF_STATE;
961     item.stateMask = 0xffff;
962     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
963     expect(1, r);
964     if (item.state != 0x1ccc)
965     {
966         win_skip("LVS_EX_CHECKBOXES style is unavailable. Skipping.\n");
967         DestroyWindow(hwnd);
968         return;
969     }
970 
971     /* Now add an item without specifying a state and check that its state goes to 0x1000 */
972     item.iItem = 2;
973     item.mask = LVIF_TEXT;
974     item.state = 0;
975     item.pszText = text2;
976     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
977     expect(2, r);
978 
979     item.iItem = 2;
980     item.mask = LVIF_STATE;
981     item.stateMask = 0xffff;
982     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
983     expect(1, r);
984     ok(item.state == 0x1000, "state %x\n", item.state);
985 
986     /* Add a further item this time specifying a state and still its state goes to 0x1000 */
987     item.iItem = 3;
988     item.mask = LVIF_TEXT | LVIF_STATE;
989     item.stateMask = 0xffff;
990     item.state = 0x2aaa;
991     item.pszText = text3;
992     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
993     expect(3, r);
994 
995     item.iItem = 3;
996     item.mask = LVIF_STATE;
997     item.stateMask = 0xffff;
998     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
999     expect(1, r);
1000     ok(item.state == 0x1aaa, "state %x\n", item.state);
1001 
1002     /* Set an item's state to checked */
1003     item.iItem = 3;
1004     item.mask = LVIF_STATE;
1005     item.stateMask = 0xf000;
1006     item.state = 0x2000;
1007     r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM) &item);
1008     expect(1, r);
1009 
1010     item.iItem = 3;
1011     item.mask = LVIF_STATE;
1012     item.stateMask = 0xffff;
1013     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1014     expect(1, r);
1015     ok(item.state == 0x2aaa, "state %x\n", item.state);
1016 
1017     /* Check that only the bits we asked for are returned,
1018      * and that all the others are set to zero
1019      */
1020     item.iItem = 3;
1021     item.mask = LVIF_STATE;
1022     item.stateMask = 0xf000;
1023     item.state = 0xffff;
1024     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1025     expect(1, r);
1026     ok(item.state == 0x2000, "state %x\n", item.state);
1027 
1028     /* Set the style again and check that doesn't change an item's state */
1029     r = SendMessageA(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_CHECKBOXES, LVS_EX_CHECKBOXES);
1030     ok(r == LVS_EX_CHECKBOXES, "ret %x\n", r);
1031 
1032     item.iItem = 3;
1033     item.mask = LVIF_STATE;
1034     item.stateMask = 0xffff;
1035     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1036     expect(1, r);
1037     ok(item.state == 0x2aaa, "state %x\n", item.state);
1038 
1039     /* Unsetting the checkbox extended style doesn't change an item's state */
1040     r = SendMessageA(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_CHECKBOXES, 0);
1041     ok(r == LVS_EX_CHECKBOXES, "ret %x\n", r);
1042 
1043     item.iItem = 3;
1044     item.mask = LVIF_STATE;
1045     item.stateMask = 0xffff;
1046     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1047     expect(1, r);
1048     ok(item.state == 0x2aaa, "state %x\n", item.state);
1049 
1050     /* Now setting the style again will change an item's state */
1051     r = SendMessageA(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_CHECKBOXES, LVS_EX_CHECKBOXES);
1052     expect(0, r);
1053 
1054     item.iItem = 3;
1055     item.mask = LVIF_STATE;
1056     item.stateMask = 0xffff;
1057     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1058     expect(1, r);
1059     ok(item.state == 0x1aaa, "state %x\n", item.state);
1060 
1061     /* Toggle checkbox tests (bug 9934) */
1062     memset (&item, 0xcc, sizeof(item));
1063     item.mask = LVIF_STATE;
1064     item.iItem = 3;
1065     item.iSubItem = 0;
1066     item.state = LVIS_FOCUSED;
1067     item.stateMask = LVIS_FOCUSED;
1068     r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM) &item);
1069     expect(1, r);
1070 
1071     item.iItem = 3;
1072     item.mask = LVIF_STATE;
1073     item.stateMask = 0xffff;
1074     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1075     expect(1, r);
1076     ok(item.state == 0x1aab, "state %x\n", item.state);
1077 
1078     r = SendMessageA(hwnd, WM_KEYDOWN, VK_SPACE, 0);
1079     expect(0, r);
1080     r = SendMessageA(hwnd, WM_KEYUP, VK_SPACE, 0);
1081     expect(0, r);
1082 
1083     item.iItem = 3;
1084     item.mask = LVIF_STATE;
1085     item.stateMask = 0xffff;
1086     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1087     expect(1, r);
1088     ok(item.state == 0x2aab, "state %x\n", item.state);
1089 
1090     r = SendMessageA(hwnd, WM_KEYDOWN, VK_SPACE, 0);
1091     expect(0, r);
1092     r = SendMessageA(hwnd, WM_KEYUP, VK_SPACE, 0);
1093     expect(0, r);
1094 
1095     item.iItem = 3;
1096     item.mask = LVIF_STATE;
1097     item.stateMask = 0xffff;
1098     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1099     expect(1, r);
1100     ok(item.state == 0x1aab, "state %x\n", item.state);
1101 
1102     DestroyWindow(hwnd);
1103 }
1104 
1105 static void insert_column(HWND hwnd, int idx)
1106 {
1107     LVCOLUMNA column;
1108     INT rc;
1109 
1110     memset(&column, 0xcc, sizeof(column));
1111     column.mask = LVCF_SUBITEM;
1112     column.iSubItem = idx;
1113 
1114     rc = SendMessageA(hwnd, LVM_INSERTCOLUMNA, idx, (LPARAM)&column);
1115     expect(idx, rc);
1116 }
1117 
1118 static void insert_item(HWND hwnd, int idx)
1119 {
1120     static CHAR text[] = "foo";
1121 
1122     LVITEMA item;
1123     INT rc;
1124 
1125     memset(&item, 0xcc, sizeof (item));
1126     item.mask = LVIF_TEXT;
1127     item.iItem = idx;
1128     item.iSubItem = 0;
1129     item.pszText = text;
1130 
1131     rc = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item);
1132     expect(idx, rc);
1133 }
1134 
1135 static void test_items(void)
1136 {
1137     const LPARAM lparamTest = 0x42;
1138     static CHAR text[] = "Text";
1139     char buffA[5];
1140     HWND hwnd;
1141     LVITEMA item;
1142     DWORD r;
1143 
1144     hwnd = CreateWindowExA(0, "SysListView32", "foo", LVS_REPORT,
1145                 10, 10, 100, 200, hwndparent, NULL, NULL, NULL);
1146     ok(hwnd != NULL, "failed to create listview window\n");
1147 
1148     /*
1149      * Test setting/getting item params
1150      */
1151 
1152     /* Set up two columns */
1153     insert_column(hwnd, 0);
1154     insert_column(hwnd, 1);
1155 
1156     /* LVIS_SELECTED with zero stateMask */
1157     /* set */
1158     memset (&item, 0, sizeof (item));
1159     item.mask = LVIF_STATE;
1160     item.state = LVIS_SELECTED;
1161     item.stateMask = 0;
1162     item.iItem = 0;
1163     item.iSubItem = 0;
1164     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
1165     expect(0, r);
1166     /* get */
1167     memset (&item, 0xcc, sizeof (item));
1168     item.mask = LVIF_STATE;
1169     item.stateMask = LVIS_SELECTED;
1170     item.state = 0;
1171     item.iItem = 0;
1172     item.iSubItem = 0;
1173     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1174     expect(1, r);
1175     ok(item.state & LVIS_SELECTED, "Expected LVIS_SELECTED\n");
1176     r = SendMessageA(hwnd, LVM_DELETEITEM, 0, 0);
1177     ok(r, "got %d\n", r);
1178 
1179     /* LVIS_SELECTED with zero stateMask */
1180     /* set */
1181     memset (&item, 0, sizeof (item));
1182     item.mask = LVIF_STATE;
1183     item.state = LVIS_FOCUSED;
1184     item.stateMask = 0;
1185     item.iItem = 0;
1186     item.iSubItem = 0;
1187     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
1188     expect(0, r);
1189     /* get */
1190     memset (&item, 0xcc, sizeof (item));
1191     item.mask = LVIF_STATE;
1192     item.stateMask = LVIS_FOCUSED;
1193     item.state = 0;
1194     item.iItem = 0;
1195     item.iSubItem = 0;
1196     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1197     expect(1, r);
1198     ok(item.state & LVIS_FOCUSED, "Expected LVIS_FOCUSED\n");
1199     r = SendMessageA(hwnd, LVM_DELETEITEM, 0, 0);
1200     ok(r, "got %d\n", r);
1201 
1202     /* LVIS_CUT with LVIS_FOCUSED stateMask */
1203     /* set */
1204     memset (&item, 0, sizeof (item));
1205     item.mask = LVIF_STATE;
1206     item.state = LVIS_CUT;
1207     item.stateMask = LVIS_FOCUSED;
1208     item.iItem = 0;
1209     item.iSubItem = 0;
1210     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
1211     expect(0, r);
1212     /* get */
1213     memset (&item, 0xcc, sizeof (item));
1214     item.mask = LVIF_STATE;
1215     item.stateMask = LVIS_CUT;
1216     item.state = 0;
1217     item.iItem = 0;
1218     item.iSubItem = 0;
1219     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1220     expect(1, r);
1221     ok(item.state & LVIS_CUT, "Expected LVIS_CUT\n");
1222     r = SendMessageA(hwnd, LVM_DELETEITEM, 0, 0);
1223     ok(r, "got %d\n", r);
1224 
1225     /* Insert an item with just a param */
1226     memset (&item, 0xcc, sizeof (item));
1227     item.mask = LVIF_PARAM;
1228     item.iItem = 0;
1229     item.iSubItem = 0;
1230     item.lParam = lparamTest;
1231     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
1232     expect(0, r);
1233 
1234     /* Test getting of the param */
1235     memset (&item, 0xcc, sizeof (item));
1236     item.mask = LVIF_PARAM;
1237     item.iItem = 0;
1238     item.iSubItem = 0;
1239     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1240     expect(1, r);
1241     ok(item.lParam == lparamTest, "got lParam %lx, expected %lx\n", item.lParam, lparamTest);
1242 
1243     /* Set up a subitem */
1244     memset (&item, 0xcc, sizeof (item));
1245     item.mask = LVIF_TEXT;
1246     item.iItem = 0;
1247     item.iSubItem = 1;
1248     item.pszText = text;
1249     r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM) &item);
1250     expect(1, r);
1251 
1252     item.mask = LVIF_TEXT;
1253     item.iItem = 0;
1254     item.iSubItem = 1;
1255     item.pszText = buffA;
1256     item.cchTextMax = sizeof(buffA);
1257     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1258     expect(1, r);
1259     ok(!memcmp(item.pszText, text, sizeof(text)), "got text %s, expected %s\n", item.pszText, text);
1260 
1261     /* set up with extra flag */
1262     /* 1. reset subitem text */
1263     item.mask = LVIF_TEXT;
1264     item.iItem = 0;
1265     item.iSubItem = 1;
1266     item.pszText = NULL;
1267     r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM) &item);
1268     expect(1, r);
1269 
1270     item.mask = LVIF_TEXT;
1271     item.iItem = 0;
1272     item.iSubItem = 1;
1273     item.pszText = buffA;
1274     buffA[0] = 'a';
1275     item.cchTextMax = sizeof(buffA);
1276     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1277     expect(1, r);
1278     ok(item.pszText[0] == 0, "got %p\n", item.pszText);
1279 
1280     /* 2. set new text with extra flag specified */
1281     item.mask = LVIF_TEXT | LVIF_DI_SETITEM;
1282     item.iItem = 0;
1283     item.iSubItem = 1;
1284     item.pszText = text;
1285     r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM) &item);
1286     ok(r == 1 || broken(r == 0) /* NT4 */, "ret %d\n", r);
1287 
1288     if (r == 1)
1289     {
1290         item.mask = LVIF_TEXT;
1291         item.iItem = 0;
1292         item.iSubItem = 1;
1293         item.pszText = buffA;
1294         buffA[0] = 'a';
1295         item.cchTextMax = sizeof(buffA);
1296         r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1297         expect(1, r);
1298         ok(!memcmp(item.pszText, text, sizeof(text)), "got %s, expected %s\n", item.pszText, text);
1299     }
1300 
1301     /* Query param from subitem: returns main item param */
1302     memset (&item, 0xcc, sizeof (item));
1303     item.mask = LVIF_PARAM;
1304     item.iItem = 0;
1305     item.iSubItem = 1;
1306     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1307     expect(1, r);
1308     ok(item.lParam == lparamTest, "got lParam %lx, expected %lx\n", item.lParam, lparamTest);
1309 
1310     /* Set up param on first subitem: no effect */
1311     memset (&item, 0xcc, sizeof (item));
1312     item.mask = LVIF_PARAM;
1313     item.iItem = 0;
1314     item.iSubItem = 1;
1315     item.lParam = lparamTest+1;
1316     r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM) &item);
1317     expect(0, r);
1318 
1319     /* Query param from subitem again: should still return main item param */
1320     memset (&item, 0xcc, sizeof (item));
1321     item.mask = LVIF_PARAM;
1322     item.iItem = 0;
1323     item.iSubItem = 1;
1324     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1325     expect(1, r);
1326     ok(item.lParam == lparamTest, "got lParam %lx, expected %lx\n", item.lParam, lparamTest);
1327 
1328     /**** Some tests of state highlighting ****/
1329     memset (&item, 0xcc, sizeof (item));
1330     item.mask = LVIF_STATE;
1331     item.iItem = 0;
1332     item.iSubItem = 0;
1333     item.state = LVIS_SELECTED;
1334     item.stateMask = LVIS_SELECTED | LVIS_DROPHILITED;
1335     r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM) &item);
1336     expect(1, r);
1337     item.iSubItem = 1;
1338     item.state = LVIS_DROPHILITED;
1339     r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM) &item);
1340     expect(1, r);
1341 
1342     memset (&item, 0xcc, sizeof (item));
1343     item.mask = LVIF_STATE;
1344     item.iItem = 0;
1345     item.iSubItem = 0;
1346     item.stateMask = -1;
1347     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1348     expect(1, r);
1349     ok(item.state == LVIS_SELECTED, "got state %x, expected %x\n", item.state, LVIS_SELECTED);
1350     item.iSubItem = 1;
1351     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1352     expect(1, r);
1353     todo_wine ok(item.state == LVIS_DROPHILITED, "got state %x, expected %x\n", item.state, LVIS_DROPHILITED);
1354 
1355     /* some notnull but meaningless masks */
1356     memset (&item, 0, sizeof(item));
1357     item.mask = LVIF_NORECOMPUTE;
1358     item.iItem = 0;
1359     item.iSubItem = 0;
1360     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1361     expect(1, r);
1362     memset (&item, 0, sizeof(item));
1363     item.mask = LVIF_DI_SETITEM;
1364     item.iItem = 0;
1365     item.iSubItem = 0;
1366     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
1367     expect(1, r);
1368 
1369     /* set text to callback value already having it */
1370     r = SendMessageA(hwnd, LVM_DELETEALLITEMS, 0, 0);
1371     expect(TRUE, r);
1372     memset (&item, 0, sizeof (item));
1373     item.mask  = LVIF_TEXT;
1374     item.pszText = LPSTR_TEXTCALLBACKA;
1375     item.iItem = 0;
1376     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
1377     expect(0, r);
1378     memset (&item, 0, sizeof (item));
1379 
1380     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1381 
1382     item.pszText = LPSTR_TEXTCALLBACKA;
1383     r = SendMessageA(hwnd, LVM_SETITEMTEXTA, 0 , (LPARAM) &item);
1384     expect(TRUE, r);
1385 
1386     ok_sequence(sequences, PARENT_SEQ_INDEX, textcallback_set_again_parent_seq,
1387                 "check callback text comparison rule", FALSE);
1388 
1389     DestroyWindow(hwnd);
1390 }
1391 
1392 static void test_columns(void)
1393 {
1394     HWND hwnd, header;
1395     LVCOLUMNA column;
1396     LVITEMA item;
1397     INT order[2];
1398     CHAR buff[5];
1399     DWORD rc;
1400 
1401     hwnd = CreateWindowExA(0, "SysListView32", "foo", LVS_LIST,
1402                 10, 10, 100, 200, hwndparent, NULL, NULL, NULL);
1403     ok(hwnd != NULL, "failed to create listview window\n");
1404 
1405     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
1406     ok(header == NULL, "got %p\n", header);
1407 
1408     rc = SendMessageA(hwnd, LVM_GETCOLUMNORDERARRAY, 2, (LPARAM)&order);
1409     ok(rc == 0, "got %d\n", rc);
1410 
1411     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
1412     ok(header == NULL, "got %p\n", header);
1413 
1414     DestroyWindow(hwnd);
1415 
1416     hwnd = CreateWindowExA(0, "SysListView32", "foo", LVS_REPORT,
1417                 10, 10, 100, 200, hwndparent, NULL, NULL, NULL);
1418     ok(hwnd != NULL, "failed to create listview window\n");
1419 
1420     rc = SendMessageA(hwnd, LVM_DELETECOLUMN, -1, 0);
1421     ok(!rc, "got %d\n", rc);
1422 
1423     rc = SendMessageA(hwnd, LVM_DELETECOLUMN, 0, 0);
1424     ok(!rc, "got %d\n", rc);
1425 
1426     /* Add a column with no mask */
1427     memset(&column, 0xcc, sizeof(column));
1428     column.mask = 0;
1429     rc = SendMessageA(hwnd, LVM_INSERTCOLUMNA, 0, (LPARAM)&column);
1430     ok(rc == 0, "Inserting column with no mask failed with %d\n", rc);
1431 
1432     /* Check its width */
1433     rc = SendMessageA(hwnd, LVM_GETCOLUMNWIDTH, 0, 0);
1434     ok(rc == 10, "Inserting column with no mask failed to set width to 10 with %d\n", rc);
1435 
1436     DestroyWindow(hwnd);
1437 
1438     /* LVM_GETCOLUMNORDERARRAY */
1439     hwnd = create_listview_control(LVS_REPORT);
1440     subclass_header(hwnd);
1441 
1442     memset(&column, 0, sizeof(column));
1443     column.mask = LVCF_WIDTH;
1444     column.cx = 100;
1445     rc = SendMessageA(hwnd, LVM_INSERTCOLUMNA, 0, (LPARAM)&column);
1446     expect(0, rc);
1447 
1448     column.cx = 200;
1449     rc = SendMessageA(hwnd, LVM_INSERTCOLUMNA, 1, (LPARAM)&column);
1450     expect(1, rc);
1451 
1452     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1453 
1454     rc = SendMessageA(hwnd, LVM_GETCOLUMNORDERARRAY, 2, (LPARAM)&order);
1455     expect(1, rc);
1456     ok(order[0] == 0, "Expected order 0, got %d\n", order[0]);
1457     ok(order[1] == 1, "Expected order 1, got %d\n", order[1]);
1458 
1459     rc = SendMessageA(hwnd, LVM_GETCOLUMNORDERARRAY, 0, 0);
1460     expect(0, rc);
1461 
1462     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_getorderarray_seq, "get order array", FALSE);
1463 
1464     /* LVM_SETCOLUMNORDERARRAY */
1465     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1466 
1467     order[0] = 0;
1468     order[1] = 1;
1469     rc = SendMessageA(hwnd, LVM_SETCOLUMNORDERARRAY, 2, (LPARAM)&order);
1470     expect(1, rc);
1471 
1472     rc = SendMessageA(hwnd, LVM_SETCOLUMNORDERARRAY, 0, 0);
1473     expect(0, rc);
1474 
1475     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_setorderarray_seq, "set order array", FALSE);
1476 
1477     /* after column added subitem is considered as present */
1478     insert_item(hwnd, 0);
1479 
1480     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1481 
1482     item.pszText = buff;
1483     item.cchTextMax = sizeof(buff);
1484     item.iItem = 0;
1485     item.iSubItem = 1;
1486     item.mask = LVIF_TEXT;
1487     memset(&g_itema, 0, sizeof(g_itema));
1488     rc = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
1489     expect(1, rc);
1490     ok(g_itema.iSubItem == 1, "got %d\n", g_itema.iSubItem);
1491 
1492     ok_sequence(sequences, PARENT_SEQ_INDEX, single_getdispinfo_parent_seq,
1493         "get subitem text after column added", FALSE);
1494 
1495     DestroyWindow(hwnd);
1496 }
1497 
1498 /* test setting imagelist between WM_NCCREATE and WM_CREATE */
1499 static WNDPROC listviewWndProc;
1500 static HIMAGELIST test_create_imagelist;
1501 
1502 static LRESULT CALLBACK create_test_wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1503 {
1504     LRESULT ret;
1505 
1506     if (uMsg == WM_CREATE)
1507     {
1508         CREATESTRUCTA *lpcs = (CREATESTRUCTA*)lParam;
1509         lpcs->style |= LVS_REPORT;
1510     }
1511     ret = CallWindowProcA(listviewWndProc, hwnd, uMsg, wParam, lParam);
1512     if (uMsg == WM_CREATE) SendMessageA(hwnd, LVM_SETIMAGELIST, 0, (LPARAM)test_create_imagelist);
1513     return ret;
1514 }
1515 
1516 static void test_create(void)
1517 {
1518     static const WCHAR testtextW[] = {'t','e','s','t',' ','t','e','x','t',0};
1519     char buff[16];
1520     HWND hList;
1521     HWND hHeader;
1522     LONG_PTR ret;
1523     LONG r;
1524     LVCOLUMNA col;
1525     RECT rect;
1526     WNDCLASSEXA cls;
1527     DWORD style;
1528 
1529     cls.cbSize = sizeof(WNDCLASSEXA);
1530     ok(GetClassInfoExA(GetModuleHandleA(NULL), "SysListView32", &cls), "GetClassInfoEx failed\n");
1531     listviewWndProc = cls.lpfnWndProc;
1532     cls.lpfnWndProc = create_test_wndproc;
1533     cls.lpszClassName = "MyListView32";
1534     ok(RegisterClassExA(&cls), "RegisterClassEx failed\n");
1535 
1536     test_create_imagelist = ImageList_Create(16, 16, 0, 5, 10);
1537     hList = CreateWindowA("MyListView32", "Test", WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, GetModuleHandleA(NULL), 0);
1538     ok((HIMAGELIST)SendMessageA(hList, LVM_GETIMAGELIST, 0, 0) == test_create_imagelist, "Image list not obtained\n");
1539     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1540     ok(IsWindow(hHeader) && IsWindowVisible(hHeader), "Listview not in report mode\n");
1541     ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n");
1542     DestroyWindow(hList);
1543 
1544     /* header isn't created on LVS_ICON and LVS_LIST styles */
1545     hList = CreateWindowA("SysListView32", "Test", WS_VISIBLE, 0, 0, 100, 100, NULL, NULL,
1546                            GetModuleHandleA(NULL), 0);
1547     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1548     ok(!IsWindow(hHeader), "Header shouldn't be created\n");
1549     ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n");
1550     /* insert column */
1551     memset(&col, 0, sizeof(LVCOLUMNA));
1552     col.mask = LVCF_WIDTH;
1553     col.cx = 100;
1554     r = SendMessageA(hList, LVM_INSERTCOLUMNA, 0, (LPARAM)&col);
1555     expect(0, r);
1556     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1557     ok(IsWindow(hHeader), "Header should be created\n");
1558     ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n");
1559     style = GetWindowLongA(hHeader, GWL_STYLE);
1560     ok(!(style & HDS_HIDDEN), "Not expected HDS_HIDDEN\n");
1561     DestroyWindow(hList);
1562 
1563     hList = CreateWindowA("SysListView32", "Test", WS_VISIBLE|LVS_LIST, 0, 0, 100, 100, NULL, NULL,
1564                            GetModuleHandleA(NULL), 0);
1565     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1566     ok(!IsWindow(hHeader), "Header shouldn't be created\n");
1567     ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n");
1568     /* insert column */
1569     memset(&col, 0, sizeof(LVCOLUMNA));
1570     col.mask = LVCF_WIDTH;
1571     col.cx = 100;
1572     r = SendMessageA(hList, LVM_INSERTCOLUMNA, 0, (LPARAM)&col);
1573     expect(0, r);
1574     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1575     ok(IsWindow(hHeader), "Header should be created\n");
1576     ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n");
1577     DestroyWindow(hList);
1578 
1579     /* try to switch LVS_ICON -> LVS_REPORT and back LVS_ICON -> LVS_REPORT */
1580     hList = CreateWindowA("SysListView32", "Test", WS_VISIBLE, 0, 0, 100, 100, NULL, NULL,
1581                            GetModuleHandleA(NULL), 0);
1582     ret = SetWindowLongPtrA(hList, GWL_STYLE, GetWindowLongPtrA(hList, GWL_STYLE) | LVS_REPORT);
1583     ok(ret & WS_VISIBLE, "Style wrong, should have WS_VISIBLE\n");
1584     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1585     ok(IsWindow(hHeader), "Header should be created\n");
1586     ret = SetWindowLongPtrA(hList, GWL_STYLE, GetWindowLongA(hList, GWL_STYLE) & ~LVS_REPORT);
1587     ok((ret & WS_VISIBLE) && (ret & LVS_REPORT), "Style wrong, should have WS_VISIBLE|LVS_REPORT\n");
1588     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1589     ok(IsWindow(hHeader), "Header should be created\n");
1590     ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n");
1591     DestroyWindow(hList);
1592 
1593     /* try to switch LVS_LIST -> LVS_REPORT and back LVS_LIST -> LVS_REPORT */
1594     hList = CreateWindowA("SysListView32", "Test", WS_VISIBLE|LVS_LIST, 0, 0, 100, 100, NULL, NULL,
1595                            GetModuleHandleA(NULL), 0);
1596     ret = SetWindowLongPtrA(hList, GWL_STYLE,
1597                            (GetWindowLongPtrA(hList, GWL_STYLE) & ~LVS_LIST) | LVS_REPORT);
1598     ok(((ret & WS_VISIBLE) && (ret & LVS_LIST)), "Style wrong, should have WS_VISIBLE|LVS_LIST\n");
1599     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1600     ok(IsWindow(hHeader), "Header should be created\n");
1601     ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n");
1602     ret = SetWindowLongPtrA(hList, GWL_STYLE,
1603                            (GetWindowLongPtrA(hList, GWL_STYLE) & ~LVS_REPORT) | LVS_LIST);
1604     ok(((ret & WS_VISIBLE) && (ret & LVS_REPORT)), "Style wrong, should have WS_VISIBLE|LVS_REPORT\n");
1605     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1606     ok(IsWindow(hHeader), "Header should be created\n");
1607     ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n");
1608     DestroyWindow(hList);
1609 
1610     /* LVS_REPORT without WS_VISIBLE */
1611     hList = CreateWindowA("SysListView32", "Test", LVS_REPORT, 0, 0, 100, 100, NULL, NULL,
1612                           GetModuleHandleA(NULL), 0);
1613     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1614     ok(!IsWindow(hHeader), "Header shouldn't be created\n");
1615     ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n");
1616     /* insert column */
1617     memset(&col, 0, sizeof(LVCOLUMNA));
1618     col.mask = LVCF_WIDTH;
1619     col.cx = 100;
1620     r = SendMessageA(hList, LVM_INSERTCOLUMNA, 0, (LPARAM)&col);
1621     expect(0, r);
1622     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1623     ok(IsWindow(hHeader), "Header should be created\n");
1624     ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n");
1625     DestroyWindow(hList);
1626 
1627     /* LVS_REPORT without WS_VISIBLE, try to show it */
1628     hList = CreateWindowA("SysListView32", "Test", LVS_REPORT, 0, 0, 100, 100, NULL, NULL,
1629                           GetModuleHandleA(NULL), 0);
1630     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1631     ok(!IsWindow(hHeader), "Header shouldn't be created\n");
1632     ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n");
1633     ShowWindow(hList, SW_SHOW);
1634     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1635     ok(IsWindow(hHeader), "Header should be created\n");
1636     ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n");
1637     DestroyWindow(hList);
1638 
1639     /* LVS_REPORT with LVS_NOCOLUMNHEADER */
1640     hList = CreateWindowA("SysListView32", "Test", LVS_REPORT|LVS_NOCOLUMNHEADER|WS_VISIBLE,
1641                           0, 0, 100, 100, NULL, NULL, GetModuleHandleA(NULL), 0);
1642     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1643     ok(IsWindow(hHeader), "Header should be created\n");
1644     ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n");
1645     /* HDS_DRAGDROP set by default */
1646     ok(GetWindowLongPtrA(hHeader, GWL_STYLE) & HDS_DRAGDROP, "Expected header to have HDS_DRAGDROP\n");
1647     DestroyWindow(hList);
1648 
1649     /* setting LVS_EX_HEADERDRAGDROP creates header */
1650     hList = CreateWindowA("SysListView32", "Test", LVS_REPORT, 0, 0, 100, 100, NULL, NULL,
1651                           GetModuleHandleA(NULL), 0);
1652     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1653     ok(!IsWindow(hHeader), "Header shouldn't be created\n");
1654     ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n");
1655     SendMessageA(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_HEADERDRAGDROP);
1656     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1657     ok(IsWindow(hHeader) ||
1658        broken(!IsWindow(hHeader)), /* 4.7x common controls */
1659        "Header should be created\n");
1660     ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n");
1661     DestroyWindow(hList);
1662 
1663     /* setting LVS_EX_GRIDLINES creates header */
1664     hList = CreateWindowA("SysListView32", "Test", LVS_REPORT, 0, 0, 100, 100, NULL, NULL,
1665                           GetModuleHandleA(NULL), 0);
1666     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1667     ok(!IsWindow(hHeader), "Header shouldn't be created\n");
1668     ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n");
1669     SendMessageA(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_GRIDLINES);
1670     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1671     ok(IsWindow(hHeader) ||
1672        broken(!IsWindow(hHeader)), /* 4.7x common controls */
1673        "Header should be created\n");
1674     ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n");
1675     DestroyWindow(hList);
1676 
1677     /* setting LVS_EX_FULLROWSELECT creates header */
1678     hList = CreateWindowA("SysListView32", "Test", LVS_REPORT, 0, 0, 100, 100, NULL, NULL,
1679                           GetModuleHandleA(NULL), 0);
1680     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1681     ok(!IsWindow(hHeader), "Header shouldn't be created\n");
1682     ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n");
1683     SendMessageA(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
1684     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1685     ok(IsWindow(hHeader) ||
1686        broken(!IsWindow(hHeader)), /* 4.7x common controls */
1687        "Header should be created\n");
1688     ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n");
1689     DestroyWindow(hList);
1690 
1691     /* not report style accepts LVS_EX_HEADERDRAGDROP too */
1692     hList = create_listview_control(LVS_ICON);
1693     SendMessageA(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_HEADERDRAGDROP);
1694     r = SendMessageA(hList, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
1695     ok(r & LVS_EX_HEADERDRAGDROP, "Expected LVS_EX_HEADERDRAGDROP to be set\n");
1696     DestroyWindow(hList);
1697 
1698     /* requesting header info with LVM_GETSUBITEMRECT doesn't create it */
1699     hList = CreateWindowA("SysListView32", "Test", LVS_REPORT, 0, 0, 100, 100, NULL, NULL,
1700                           GetModuleHandleA(NULL), 0);
1701     ok(!IsWindow(hHeader), "Header shouldn't be created\n");
1702     ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n");
1703 
1704     SetRect(&rect, LVIR_BOUNDS, 1, -10, -10);
1705     r = SendMessageA(hList, LVM_GETSUBITEMRECT, -1, (LPARAM)&rect);
1706     /* right value contains garbage, probably because header columns are not set up */
1707     expect(0, rect.bottom);
1708     expect(1, r);
1709 
1710     hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
1711     ok(!IsWindow(hHeader), "Header shouldn't be created\n");
1712     ok(GetDlgItem(hList, 0) == NULL, "NULL dialog item expected\n");
1713 
1714     DestroyWindow(hList);
1715 
1716     /* WM_MEASUREITEM should be sent when created with LVS_OWNERDRAWFIXED */
1717     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1718     hList = create_listview_control(LVS_OWNERDRAWFIXED | LVS_REPORT);
1719     ok_sequence(sequences, PARENT_SEQ_INDEX, create_ownerdrawfixed_parent_seq,
1720                 "created with LVS_OWNERDRAWFIXED|LVS_REPORT - parent seq", FALSE);
1721     DestroyWindow(hList);
1722 
1723     /* Test that window text is preserved. */
1724     hList = CreateWindowExA(0, WC_LISTVIEWA, "test text", WS_CHILD | WS_BORDER | WS_VISIBLE,
1725         0, 0, 100, 100, hwndparent, NULL, GetModuleHandleA(NULL), NULL);
1726     ok(hList != NULL, "Failed to create ListView window.\n");
1727     *buff = 0;
1728     GetWindowTextA(hList, buff, sizeof(buff));
1729     ok(!strcmp(buff, "test text"), "Unexpected window text %s.\n", buff);
1730     DestroyWindow(hList);
1731 
1732     hList = CreateWindowExW(0, WC_LISTVIEWW, testtextW, WS_CHILD | WS_BORDER | WS_VISIBLE,
1733         0, 0, 100, 100, hwndparent, NULL, GetModuleHandleA(NULL), NULL);
1734     ok(hList != NULL, "Failed to create ListView window.\n");
1735     *buff = 0;
1736     GetWindowTextA(hList, buff, sizeof(buff));
1737     ok(!strcmp(buff, "test text"), "Unexpected window text %s.\n", buff);
1738     DestroyWindow(hList);
1739 }
1740 
1741 static void test_redraw(void)
1742 {
1743     HWND hwnd;
1744     HDC hdc;
1745     BOOL res;
1746     DWORD r;
1747 
1748     hwnd = create_listview_control(LVS_REPORT);
1749     subclass_header(hwnd);
1750 
1751     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1752 
1753     InvalidateRect(hwnd, NULL, TRUE);
1754     UpdateWindow(hwnd);
1755     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, redraw_listview_seq, "redraw listview", FALSE);
1756 
1757     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1758 
1759     /* forward WM_ERASEBKGND to parent on CLR_NONE background color */
1760     /* 1. Without backbuffer */
1761     res = SendMessageA(hwnd, LVM_SETBKCOLOR, 0, CLR_NONE);
1762     expect(TRUE, res);
1763 
1764     hdc = GetWindowDC(hwndparent);
1765 
1766     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1767     r = SendMessageA(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0);
1768     ok(r == 1, "Expected not zero result\n");
1769     ok_sequence(sequences, PARENT_FULL_SEQ_INDEX, forward_erasebkgnd_parent_seq,
1770                 "forward WM_ERASEBKGND on CLR_NONE", FALSE);
1771 
1772     res = SendMessageA(hwnd, LVM_SETBKCOLOR, 0, CLR_DEFAULT);
1773     expect(TRUE, res);
1774 
1775     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1776     r = SendMessageA(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0);
1777     expect(1, r);
1778     ok_sequence(sequences, PARENT_FULL_SEQ_INDEX, empty_seq,
1779                 "don't forward WM_ERASEBKGND on non-CLR_NONE", FALSE);
1780 
1781     /* 2. With backbuffer */
1782     SendMessageA(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_DOUBLEBUFFER,
1783                                                      LVS_EX_DOUBLEBUFFER);
1784     res = SendMessageA(hwnd, LVM_SETBKCOLOR, 0, CLR_NONE);
1785     expect(TRUE, res);
1786 
1787     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1788     r = SendMessageA(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0);
1789     expect(1, r);
1790     ok_sequence(sequences, PARENT_FULL_SEQ_INDEX, forward_erasebkgnd_parent_seq,
1791                 "forward WM_ERASEBKGND on CLR_NONE", FALSE);
1792 
1793     res = SendMessageA(hwnd, LVM_SETBKCOLOR, 0, CLR_DEFAULT);
1794     expect(TRUE, res);
1795 
1796     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1797     r = SendMessageA(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0);
1798     todo_wine expect(1, r);
1799     ok_sequence(sequences, PARENT_FULL_SEQ_INDEX, empty_seq,
1800                 "don't forward WM_ERASEBKGND on non-CLR_NONE", FALSE);
1801 
1802     ReleaseDC(hwndparent, hdc);
1803 
1804     DestroyWindow(hwnd);
1805 }
1806 
1807 static LRESULT WINAPI cd_wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
1808 {
1809     COLORREF clr, c0ffee = RGB(0xc0, 0xff, 0xee);
1810 
1811     if(message == WM_NOTIFY) {
1812         NMHDR *nmhdr = (NMHDR*)lParam;
1813         if(nmhdr->code == NM_CUSTOMDRAW) {
1814             NMLVCUSTOMDRAW *nmlvcd = (NMLVCUSTOMDRAW*)nmhdr;
1815             struct message msg;
1816 
1817             msg.message = message;
1818             msg.flags = sent|wparam|lparam|custdraw;
1819             msg.wParam = wParam;
1820             msg.lParam = lParam;
1821             msg.id = nmhdr->code;
1822             msg.stage = nmlvcd->nmcd.dwDrawStage;
1823             add_message(sequences, PARENT_CD_SEQ_INDEX, &msg);
1824 
1825             switch(nmlvcd->nmcd.dwDrawStage) {
1826             case CDDS_PREPAINT:
1827                 SetBkColor(nmlvcd->nmcd.hdc, c0ffee);
1828                 return CDRF_NOTIFYITEMDRAW|CDRF_NOTIFYPOSTPAINT;
1829             case CDDS_ITEMPREPAINT:
1830                 nmlvcd->clrTextBk = CLR_DEFAULT;
1831                 nmlvcd->clrText = RGB(0, 255, 0);
1832                 return CDRF_NOTIFYSUBITEMDRAW|CDRF_NOTIFYPOSTPAINT;
1833             case CDDS_ITEMPREPAINT | CDDS_SUBITEM:
1834                 clr = GetBkColor(nmlvcd->nmcd.hdc);
1835                 ok(nmlvcd->clrTextBk == CLR_DEFAULT, "got 0x%x\n", nmlvcd->clrTextBk);
1836                 ok(nmlvcd->clrText == RGB(0, 255, 0), "got 0x%x\n", nmlvcd->clrText);
1837                 todo_wine_if(nmlvcd->iSubItem)
1838                     ok(clr == c0ffee, "clr=%.8x\n", clr);
1839                 return CDRF_NOTIFYPOSTPAINT;
1840             case CDDS_ITEMPOSTPAINT | CDDS_SUBITEM:
1841                 clr = GetBkColor(nmlvcd->nmcd.hdc);
1842                 todo_wine ok(clr == c0ffee, "clr=%.8x\n", clr);
1843                 ok(nmlvcd->clrTextBk == CLR_DEFAULT, "got 0x%x\n", nmlvcd->clrTextBk);
1844                 ok(nmlvcd->clrText == RGB(0, 255, 0), "got 0x%x\n", nmlvcd->clrText);
1845                 return CDRF_DODEFAULT;
1846             }
1847             return CDRF_DODEFAULT;
1848         }
1849     }
1850 
1851     return DefWindowProcA(hwnd, message, wParam, lParam);
1852 }
1853 
1854 static void test_customdraw(void)
1855 {
1856     HWND hwnd;
1857     WNDPROC oldwndproc;
1858 
1859     hwnd = create_listview_control(LVS_REPORT);
1860 
1861     insert_column(hwnd, 0);
1862     insert_column(hwnd, 1);
1863     insert_item(hwnd, 0);
1864 
1865     oldwndproc = (WNDPROC)SetWindowLongPtrA(hwndparent, GWLP_WNDPROC,
1866                                            (LONG_PTR)cd_wndproc);
1867 
1868     InvalidateRect(hwnd, NULL, TRUE);
1869     UpdateWindow(hwnd);
1870 
1871     /* message tests */
1872     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1873     InvalidateRect(hwnd, NULL, TRUE);
1874     UpdateWindow(hwnd);
1875     ok_sequence(sequences, PARENT_CD_SEQ_INDEX, parent_report_cd_seq, "parent customdraw, LVS_REPORT", FALSE);
1876 
1877     DestroyWindow(hwnd);
1878 
1879     hwnd = create_listview_control(LVS_LIST);
1880 
1881     insert_column(hwnd, 0);
1882     insert_column(hwnd, 1);
1883     insert_item(hwnd, 0);
1884 
1885     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1886     InvalidateRect(hwnd, NULL, TRUE);
1887     UpdateWindow(hwnd);
1888     ok_sequence(sequences, PARENT_CD_SEQ_INDEX, parent_list_cd_seq, "parent customdraw, LVS_LIST", FALSE);
1889 
1890     SetWindowLongPtrA(hwndparent, GWLP_WNDPROC, (LONG_PTR)oldwndproc);
1891     DestroyWindow(hwnd);
1892 }
1893 
1894 static void test_icon_spacing(void)
1895 {
1896     /* LVM_SETICONSPACING */
1897     /* note: LVM_SETICONSPACING returns the previous icon spacing if successful */
1898 
1899     HWND hwnd;
1900     WORD w, h;
1901     INT r;
1902 
1903     hwnd = create_listview_control(LVS_ICON);
1904     ok(hwnd != NULL, "failed to create a listview window\n");
1905 
1906     r = SendMessageA(hwnd, WM_NOTIFYFORMAT, (WPARAM)hwndparent, NF_REQUERY);
1907     expect(NFR_ANSI, r);
1908 
1909     /* reset the icon spacing to defaults */
1910     SendMessageA(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(-1, -1));
1911 
1912     /* now we can request what the defaults are */
1913     r = SendMessageA(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(-1, -1));
1914     w = LOWORD(r);
1915     h = HIWORD(r);
1916 
1917     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1918 
1919     r = SendMessageA(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(20, 30));
1920     ok(r == MAKELONG(w, h) ||
1921        broken(r == MAKELONG(w, w)), /* win98 */
1922        "Expected %d, got %d\n", MAKELONG(w, h), r);
1923 
1924     r = SendMessageA(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(25, 35));
1925     expect(MAKELONG(20,30), r);
1926 
1927     r = SendMessageA(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(-1,-1));
1928     expect(MAKELONG(25,35), r);
1929 
1930     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_icon_spacing_seq, "test icon spacing seq", FALSE);
1931 
1932     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1933     DestroyWindow(hwnd);
1934 }
1935 
1936 static void test_color(void)
1937 {
1938     RECT rect;
1939     HWND hwnd;
1940     DWORD r;
1941     int i;
1942 
1943     COLORREF color;
1944     COLORREF colors[4] = {RGB(0,0,0), RGB(100,50,200), CLR_NONE, RGB(255,255,255)};
1945 
1946     hwnd = create_listview_control(LVS_REPORT);
1947     ok(hwnd != NULL, "failed to create a listview window\n");
1948 
1949     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1950 
1951     for (i = 0; i < 4; i++)
1952     {
1953         color = colors[i];
1954 
1955         r = SendMessageA(hwnd, LVM_SETBKCOLOR, 0, color);
1956         expect(TRUE, r);
1957         r = SendMessageA(hwnd, LVM_GETBKCOLOR, 0, 0);
1958         expect(color, r);
1959 
1960         r = SendMessageA(hwnd, LVM_SETTEXTCOLOR, 0, color);
1961         expect (TRUE, r);
1962         r = SendMessageA(hwnd, LVM_GETTEXTCOLOR, 0, 0);
1963         expect(color, r);
1964 
1965         r = SendMessageA(hwnd, LVM_SETTEXTBKCOLOR, 0, color);
1966         expect(TRUE, r);
1967         r = SendMessageA(hwnd, LVM_GETTEXTBKCOLOR, 0, 0);
1968         expect(color, r);
1969     }
1970 
1971     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_color_seq, "test color seq", FALSE);
1972     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1973 
1974     /* invalidation test done separately to avoid a message chain mess */
1975     r = ValidateRect(hwnd, NULL);
1976     expect(TRUE, r);
1977     r = SendMessageA(hwnd, LVM_SETBKCOLOR, 0, colors[0]);
1978     expect(TRUE, r);
1979 
1980     rect.right = rect.bottom = 1;
1981     r = GetUpdateRect(hwnd, &rect, TRUE);
1982     todo_wine expect(FALSE, r);
1983     ok(rect.right == 0 && rect.bottom == 0, "got update rectangle\n");
1984 
1985     r = ValidateRect(hwnd, NULL);
1986     expect(TRUE, r);
1987     r = SendMessageA(hwnd, LVM_SETTEXTCOLOR, 0, colors[0]);
1988     expect(TRUE, r);
1989 
1990     rect.right = rect.bottom = 1;
1991     r = GetUpdateRect(hwnd, &rect, TRUE);
1992     todo_wine expect(FALSE, r);
1993     ok(rect.right == 0 && rect.bottom == 0, "got update rectangle\n");
1994 
1995     r = ValidateRect(hwnd, NULL);
1996     expect(TRUE, r);
1997     r = SendMessageA(hwnd, LVM_SETTEXTBKCOLOR, 0, colors[0]);
1998     expect(TRUE, r);
1999 
2000     rect.right = rect.bottom = 1;
2001     r = GetUpdateRect(hwnd, &rect, TRUE);
2002     todo_wine expect(FALSE, r);
2003     ok(rect.right == 0 && rect.bottom == 0, "got update rectangle\n");
2004 
2005     DestroyWindow(hwnd);
2006 }
2007 
2008 static void test_item_count(void)
2009 {
2010     /* LVM_INSERTITEM, LVM_DELETEITEM, LVM_DELETEALLITEMS, LVM_GETITEMCOUNT */
2011 
2012     HWND hwnd;
2013     DWORD r;
2014     HDC hdc;
2015     HFONT hOldFont;
2016     TEXTMETRICA tm;
2017     RECT rect;
2018     INT height;
2019 
2020     LVITEMA item0;
2021     LVITEMA item1;
2022     LVITEMA item2;
2023     static CHAR item0text[] = "item0";
2024     static CHAR item1text[] = "item1";
2025     static CHAR item2text[] = "item2";
2026 
2027     hwnd = create_listview_control(LVS_REPORT);
2028     ok(hwnd != NULL, "failed to create a listview window\n");
2029 
2030     /* resize in dpiaware manner to fit all 3 items added */
2031     hdc = GetDC(0);
2032     hOldFont = SelectObject(hdc, GetStockObject(SYSTEM_FONT));
2033     GetTextMetricsA(hdc, &tm);
2034     /* 2 extra pixels for bounds and header border */
2035     height = tm.tmHeight + 2;
2036     SelectObject(hdc, hOldFont);
2037     ReleaseDC(0, hdc);
2038 
2039     GetWindowRect(hwnd, &rect);
2040     /* 3 items + 1 header + 1 to be sure */
2041     MoveWindow(hwnd, 0, 0, rect.right - rect.left, 5 * height, FALSE);
2042 
2043     flush_sequences(sequences, NUM_MSG_SEQUENCES);
2044 
2045     r = SendMessageA(hwnd, LVM_GETITEMCOUNT, 0, 0);
2046     expect(0, r);
2047 
2048     /* [item0] */
2049     item0.mask = LVIF_TEXT;
2050     item0.iItem = 0;
2051     item0.iSubItem = 0;
2052     item0.pszText = item0text;
2053     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item0);
2054     expect(0, r);
2055 
2056     /* [item0, item1] */
2057     item1.mask = LVIF_TEXT;
2058     item1.iItem = 1;
2059     item1.iSubItem = 0;
2060     item1.pszText = item1text;
2061     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item1);
2062     expect(1, r);
2063 
2064     /* [item0, item1, item2] */
2065     item2.mask = LVIF_TEXT;
2066     item2.iItem = 2;
2067     item2.iSubItem = 0;
2068     item2.pszText = item2text;
2069     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item2);
2070     expect(2, r);
2071 
2072     r = SendMessageA(hwnd, LVM_GETITEMCOUNT, 0, 0);
2073     expect(3, r);
2074 
2075     /* [item0, item1] */
2076     r = SendMessageA(hwnd, LVM_DELETEITEM, 2, 0);
2077     expect(TRUE, r);
2078 
2079     r = SendMessageA(hwnd, LVM_GETITEMCOUNT, 0, 0);
2080     expect(2, r);
2081 
2082     /* [] */
2083     r = SendMessageA(hwnd, LVM_DELETEALLITEMS, 0, 0);
2084     expect(TRUE, r);
2085 
2086     r = SendMessageA(hwnd, LVM_GETITEMCOUNT, 0, 0);
2087     expect(0, r);
2088 
2089     /* [item0] */
2090     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item1);
2091     expect(0, r);
2092 
2093     /* [item0, item1] */
2094     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item1);
2095     expect(1, r);
2096 
2097     r = SendMessageA(hwnd, LVM_GETITEMCOUNT, 0, 0);
2098     expect(2, r);
2099 
2100     /* [item0, item1, item2] */
2101     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item2);
2102     expect(2, r);
2103 
2104     r = SendMessageA(hwnd, LVM_GETITEMCOUNT, 0, 0);
2105     expect(3, r);
2106 
2107     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_item_count_seq, "test item count seq", FALSE);
2108 
2109     flush_sequences(sequences, NUM_MSG_SEQUENCES);
2110     DestroyWindow(hwnd);
2111 }
2112 
2113 static void test_item_position(void)
2114 {
2115     /* LVM_SETITEMPOSITION/LVM_GETITEMPOSITION */
2116 
2117     HWND hwnd;
2118     DWORD r;
2119     POINT position;
2120 
2121     LVITEMA item0;
2122     LVITEMA item1;
2123     LVITEMA item2;
2124     static CHAR item0text[] = "item0";
2125     static CHAR item1text[] = "item1";
2126     static CHAR item2text[] = "item2";
2127 
2128     hwnd = create_listview_control(LVS_ICON);
2129     ok(hwnd != NULL, "failed to create a listview window\n");
2130 
2131     flush_sequences(sequences, NUM_MSG_SEQUENCES);
2132 
2133     /* [item0] */
2134     item0.mask = LVIF_TEXT;
2135     item0.iItem = 0;
2136     item0.iSubItem = 0;
2137     item0.pszText = item0text;
2138     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item0);
2139     expect(0, r);
2140 
2141     /* [item0, item1] */
2142     item1.mask = LVIF_TEXT;
2143     item1.iItem = 1;
2144     item1.iSubItem = 0;
2145     item1.pszText = item1text;
2146     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item1);
2147     expect(1, r);
2148 
2149     /* [item0, item1, item2] */
2150     item2.mask = LVIF_TEXT;
2151     item2.iItem = 2;
2152     item2.iSubItem = 0;
2153     item2.pszText = item2text;
2154     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item2);
2155     expect(2, r);
2156 
2157     r = SendMessageA(hwnd, LVM_SETITEMPOSITION, 1, MAKELPARAM(10,5));
2158     expect(TRUE, r);
2159     r = SendMessageA(hwnd, LVM_GETITEMPOSITION, 1, (LPARAM) &position);
2160     expect(TRUE, r);
2161     expect2(10, 5, position.x, position.y);
2162 
2163     r = SendMessageA(hwnd, LVM_SETITEMPOSITION, 2, MAKELPARAM(0,0));
2164     expect(TRUE, r);
2165     r = SendMessageA(hwnd, LVM_GETITEMPOSITION, 2, (LPARAM) &position);
2166     expect(TRUE, r);
2167     expect2(0, 0, position.x, position.y);
2168 
2169     r = SendMessageA(hwnd, LVM_SETITEMPOSITION, 0, MAKELPARAM(20,20));
2170     expect(TRUE, r);
2171     r = SendMessageA(hwnd, LVM_GETITEMPOSITION, 0, (LPARAM) &position);
2172     expect(TRUE, r);
2173     expect2(20, 20, position.x, position.y);
2174 
2175     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_itempos_seq, "test item position seq", TRUE);
2176 
2177     flush_sequences(sequences, NUM_MSG_SEQUENCES);
2178     DestroyWindow(hwnd);
2179 }
2180 
2181 static void test_getorigin(void)
2182 {
2183     /* LVM_GETORIGIN */
2184 
2185     HWND hwnd;
2186     DWORD r;
2187     POINT position;
2188 
2189     position.x = position.y = 0;
2190 
2191     hwnd = create_listview_control(LVS_ICON);
2192     ok(hwnd != NULL, "failed to create a listview window\n");
2193     flush_sequences(sequences, NUM_MSG_SEQUENCES);
2194 
2195     r = SendMessageA(hwnd, LVM_GETORIGIN, 0, (LPARAM)&position);
2196     expect(TRUE, r);
2197     flush_sequences(sequences, NUM_MSG_SEQUENCES);
2198     DestroyWindow(hwnd);
2199 
2200     hwnd = create_listview_control(LVS_SMALLICON);
2201     ok(hwnd != NULL, "failed to create a listview window\n");
2202     flush_sequences(sequences, NUM_MSG_SEQUENCES);
2203 
2204     r = SendMessageA(hwnd, LVM_GETORIGIN, 0, (LPARAM)&position);
2205     expect(TRUE, r);
2206     flush_sequences(sequences, NUM_MSG_SEQUENCES);
2207     DestroyWindow(hwnd);
2208 
2209     hwnd = create_listview_control(LVS_LIST);
2210     ok(hwnd != NULL, "failed to create a listview window\n");
2211     flush_sequences(sequences, NUM_MSG_SEQUENCES);
2212 
2213     r = SendMessageA(hwnd, LVM_GETORIGIN, 0, (LPARAM)&position);
2214     expect(FALSE, r);
2215     flush_sequences(sequences, NUM_MSG_SEQUENCES);
2216     DestroyWindow(hwnd);
2217 
2218     hwnd = create_listview_control(LVS_REPORT);
2219     ok(hwnd != NULL, "failed to create a listview window\n");
2220     flush_sequences(sequences, NUM_MSG_SEQUENCES);
2221 
2222     r = SendMessageA(hwnd, LVM_GETORIGIN, 0, (LPARAM)&position);
2223     expect(FALSE, r);
2224     flush_sequences(sequences, NUM_MSG_SEQUENCES);
2225     DestroyWindow(hwnd);
2226 }
2227 
2228 static void test_multiselect(void)
2229 {
2230     typedef struct t_select_task
2231     {
2232 	const char *descr;
2233         int initPos;
2234         int loopVK;
2235         int count;
2236 	int result;
2237     } select_task;
2238 
2239     HWND hwnd;
2240     INT r;
2241     int i, j;
2242     static const int items=5;
2243     DWORD item_count;
2244     BYTE kstate[256];
2245     select_task task;
2246     LONG_PTR style;
2247     LVITEMA item;
2248 
2249     static struct t_select_task task_list[] = {
2250         { "using VK_DOWN", 0, VK_DOWN, -1, -1 },
2251         { "using VK_UP", -1, VK_UP, -1, -1 },
2252         { "using VK_END", 0, VK_END, 1, -1 },
2253         { "using VK_HOME", -1, VK_HOME, 1, -1 }
2254     };
2255 
2256     hwnd = create_listview_control(LVS_REPORT);
2257 
2258     for (i = 0; i < items; i++)
2259         insert_item(hwnd, 0);
2260 
2261     item_count = SendMessageA(hwnd, LVM_GETITEMCOUNT, 0, 0);
2262     expect(items, item_count);
2263 
2264     r = SendMessageA(hwnd, LVM_SETSELECTIONMARK, 0, -1);
2265     ok(r == -1, "got %d\n", r);
2266 
2267     r = SendMessageA(hwnd, LVM_SETSELECTIONMARK, 0, 0);
2268     ok(r == -1, "got %d\n", r);
2269 
2270     r = SendMessageA(hwnd, LVM_SETSELECTIONMARK, 0, 0);
2271     ok(r == 0, "got %d\n", r);
2272 
2273     /* out of range index */
2274     r = SendMessageA(hwnd, LVM_SETSELECTIONMARK, 0, items);
2275     ok(r == 0, "got %d\n", r);
2276 
2277     r = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
2278     ok(r == 0, "got %d\n", r);
2279 
2280     r = SendMessageA(hwnd, LVM_SETSELECTIONMARK, 0, -2);
2281     ok(r == 0, "got %d\n", r);
2282 
2283     r = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
2284     ok(r == 0, "got %d\n", r);
2285 
2286     for (i = 0; i < sizeof(task_list)/sizeof(task_list[0]); i++) {
2287         DWORD selected_count;
2288         LVITEMA item;
2289 
2290         task = task_list[i];
2291 
2292 	/* deselect all items */
2293         item.state = 0;
2294         item.stateMask = LVIS_SELECTED;
2295         r = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
2296         ok(r, "got %d\n", r);
2297 	SendMessageA(hwnd, LVM_SETSELECTIONMARK, 0, -1);
2298 
2299 	/* set initial position */
2300         r = SendMessageA(hwnd, LVM_SETSELECTIONMARK, 0, (task.initPos == -1 ? item_count -1 : task.initPos));
2301         ok(r, "got %d\n", r);
2302 
2303         item.state = LVIS_SELECTED;
2304         item.stateMask = LVIS_SELECTED;
2305         r = SendMessageA(hwnd, LVM_SETITEMSTATE, task.initPos == -1 ? item_count-1 : task.initPos, (LPARAM)&item);
2306         ok(r, "got %d\n", r);
2307 
2308 	selected_count = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
2309 	ok(selected_count == 1, "expected 1, got %d\n", selected_count);
2310 
2311 	/* Set SHIFT key pressed */
2312         GetKeyboardState(kstate);
2313         kstate[VK_SHIFT]=0x80;
2314         SetKeyboardState(kstate);
2315 
2316 	for (j=1;j<=(task.count == -1 ? item_count : task.count);j++) {
2317 	    r = SendMessageA(hwnd, WM_KEYDOWN, task.loopVK, 0);
2318 	    expect(0,r);
2319 	    r = SendMessageA(hwnd, WM_KEYUP, task.loopVK, 0);
2320 	    expect(0,r);
2321 	}
2322 
2323 	selected_count = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
2324 
2325 	ok((task.result == -1 ? item_count : task.result) == selected_count,
2326             "Failed multiple selection %s. There should be %d selected items (is %d)\n",
2327             task.descr, item_count, selected_count);
2328 
2329 	/* Set SHIFT key released */
2330 	GetKeyboardState(kstate);
2331         kstate[VK_SHIFT]=0x00;
2332         SetKeyboardState(kstate);
2333     }
2334     DestroyWindow(hwnd);
2335 
2336     /* make multiple selection, then switch to LVS_SINGLESEL */
2337     hwnd = create_listview_control(LVS_REPORT);
2338     for (i=0;i<items;i++) {
2339 	    insert_item(hwnd, 0);
2340     }
2341     item_count = SendMessageA(hwnd, LVM_GETITEMCOUNT, 0, 0);
2342     expect(items,item_count);
2343 
2344     /* try with NULL pointer */
2345     r = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, 0);
2346     expect(FALSE, r);
2347 
2348     /* select all, check notifications */
2349     item.state = 0;
2350     item.stateMask = LVIS_SELECTED;
2351     r = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
2352     ok(r, "got %d\n", r);
2353 
2354     flush_sequences(sequences, NUM_MSG_SEQUENCES);
2355 
2356     item.stateMask = LVIS_SELECTED;
2357     item.state     = LVIS_SELECTED;
2358     r = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
2359     expect(TRUE, r);
2360 
2361     ok_sequence(sequences, PARENT_SEQ_INDEX, change_all_parent_seq,
2362                 "select all notification", FALSE);
2363 
2364     /* select all again (all selected already) */
2365     flush_sequences(sequences, NUM_MSG_SEQUENCES);
2366 
2367     memset(&g_nmlistview_changing, 0xcc, sizeof(g_nmlistview_changing));
2368 
2369     item.stateMask = LVIS_SELECTED;
2370     item.state     = LVIS_SELECTED;
2371     r = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
2372     expect(TRUE, r);
2373 
2374     ok(g_nmlistview_changing.uNewState == LVIS_SELECTED, "got 0x%x\n", g_nmlistview_changing.uNewState);
2375     ok(g_nmlistview_changing.uOldState == LVIS_SELECTED, "got 0x%x\n", g_nmlistview_changing.uOldState);
2376     ok(g_nmlistview_changing.uChanged == LVIF_STATE, "got 0x%x\n", g_nmlistview_changing.uChanged);
2377 
2378     ok_sequence(sequences, PARENT_SEQ_INDEX, changing_all_parent_seq,
2379                 "select all notification 2", FALSE);
2380 
2381     /* deselect all items */
2382     flush_sequences(sequences, NUM_MSG_SEQUENCES);
2383 
2384     item.state = 0;
2385     item.stateMask = LVIS_SELECTED;
2386     r = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
2387     ok(r, "got %d\n", r);
2388 
2389     ok_sequence(sequences, PARENT_SEQ_INDEX, change_all_parent_seq,
2390                 "deselect all notification", FALSE);
2391 
2392     /* deselect all items again */
2393     flush_sequences(sequences, NUM_MSG_SEQUENCES);
2394     item.state = 0;
2395     item.stateMask = LVIS_SELECTED;
2396     SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
2397     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "deselect all notification 2", FALSE);
2398 
2399     /* any non-zero state value does the same */
2400     flush_sequences(sequences, NUM_MSG_SEQUENCES);
2401 
2402     memset(&g_nmlistview_changing, 0xcc, sizeof(g_nmlistview_changing));
2403 
2404     item.stateMask = LVIS_SELECTED;
2405     item.state     = LVIS_CUT;
2406     r = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
2407     expect(TRUE, r);
2408 
2409     ok(g_nmlistview_changing.uNewState == 0, "got 0x%x\n", g_nmlistview_changing.uNewState);
2410     ok(g_nmlistview_changing.uOldState == 0, "got 0x%x\n", g_nmlistview_changing.uOldState);
2411     ok(g_nmlistview_changing.uChanged == LVIF_STATE, "got 0x%x\n", g_nmlistview_changing.uChanged);
2412 
2413     ok_sequence(sequences, PARENT_SEQ_INDEX, changing_all_parent_seq,
2414                 "set state all notification 3", FALSE);
2415 
2416     r = SendMessageA(hwnd, LVM_SETSELECTIONMARK, 0, -1);
2417     ok(r, "got %d\n", r);
2418     for (i = 0; i < 3; i++) {
2419         item.state = LVIS_SELECTED;
2420         item.stateMask = LVIS_SELECTED;
2421         r = SendMessageA(hwnd, LVM_SETITEMSTATE, i, (LPARAM)&item);
2422         ok(r, "got %d\n", r);
2423     }
2424 
2425     r = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
2426     expect(3, r);
2427     r = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
2428     expect(-1, r);
2429 
2430     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
2431     ok(!(style & LVS_SINGLESEL), "LVS_SINGLESEL isn't expected\n");
2432     SetWindowLongPtrA(hwnd, GWL_STYLE, style | LVS_SINGLESEL);
2433     /* check that style is accepted */
2434     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
2435     ok(style & LVS_SINGLESEL, "LVS_SINGLESEL expected\n");
2436 
2437     for (i=0;i<3;i++) {
2438         r = SendMessageA(hwnd, LVM_GETITEMSTATE, i, LVIS_SELECTED);
2439         ok(r & LVIS_SELECTED, "Expected item %d to be selected\n", i);
2440     }
2441     r = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
2442     expect(3, r);
2443     r = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
2444     ok(r == -1, "got %d\n", r);
2445 
2446     /* select one more */
2447     item.state = LVIS_SELECTED;
2448     item.stateMask = LVIS_SELECTED;
2449     r = SendMessageA(hwnd, LVM_SETITEMSTATE, 3, (LPARAM)&item);
2450     ok(r, "got %d\n", r);
2451 
2452     for (i=0;i<3;i++) {
2453         r = SendMessageA(hwnd, LVM_GETITEMSTATE, i, LVIS_SELECTED);
2454         ok(!(r & LVIS_SELECTED), "Expected item %d to be unselected\n", i);
2455     }
2456 
2457     r = SendMessageA(hwnd, LVM_GETITEMSTATE, 3, LVIS_SELECTED);
2458     ok(r & LVIS_SELECTED, "Expected item %d to be selected\n", i);
2459 
2460     r = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
2461     expect(1, r);
2462     r = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
2463     expect(-1, r);
2464 
2465     /* try to select all on LVS_SINGLESEL */
2466     memset(&item, 0, sizeof(item));
2467     item.stateMask = LVIS_SELECTED;
2468     r = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
2469     expect(TRUE, r);
2470     r = SendMessageA(hwnd, LVM_SETSELECTIONMARK, 0, -1);
2471     ok(r == -1, "got %d\n", r);
2472 
2473     item.stateMask = LVIS_SELECTED;
2474     item.state     = LVIS_SELECTED;
2475     r = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
2476     expect(FALSE, r);
2477 
2478     r = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
2479     expect(0, r);
2480     r = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
2481     expect(-1, r);
2482 
2483     /* try to deselect all on LVS_SINGLESEL */
2484     item.stateMask = LVIS_SELECTED;
2485     item.state     = LVIS_SELECTED;
2486     r = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
2487     expect(TRUE, r);
2488 
2489     item.stateMask = LVIS_SELECTED;
2490     item.state     = 0;
2491     r = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
2492     expect(TRUE, r);
2493     r = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
2494     expect(0, r);
2495 
2496     /* 1. selection mark is update when new focused item is set */
2497     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
2498     SetWindowLongPtrA(hwnd, GWL_STYLE, style & ~LVS_SINGLESEL);
2499 
2500     r = SendMessageA(hwnd, LVM_SETSELECTIONMARK, 0, -1);
2501     expect(-1, r);
2502 
2503     item.stateMask = LVIS_FOCUSED;
2504     item.state     = LVIS_FOCUSED;
2505     r = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
2506     expect(TRUE, r);
2507 
2508     r = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
2509     expect(0, r);
2510 
2511     /* it's not updated if already set */
2512     item.stateMask = LVIS_FOCUSED;
2513     item.state     = LVIS_FOCUSED;
2514     r = SendMessageA(hwnd, LVM_SETITEMSTATE, 1, (LPARAM)&item);
2515     expect(TRUE, r);
2516 
2517     r = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
2518     expect(0, r);
2519 
2520     r = SendMessageA(hwnd, LVM_SETSELECTIONMARK, 0, -1);
2521     expect(0, r);
2522 
2523     item.stateMask = LVIS_FOCUSED;
2524     item.state     = LVIS_FOCUSED;
2525     r = SendMessageA(hwnd, LVM_SETITEMSTATE, 1, (LPARAM)&item);
2526     expect(TRUE, r);
2527 
2528     r = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
2529     expect(-1, r);
2530 
2531     /* need to reset focused item first */
2532     item.stateMask = LVIS_FOCUSED;
2533     item.state     = 0;
2534     r = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
2535     expect(TRUE, r);
2536 
2537     item.stateMask = LVIS_FOCUSED;
2538     item.state     = LVIS_FOCUSED;
2539     r = SendMessageA(hwnd, LVM_SETITEMSTATE, 2, (LPARAM)&item);
2540     expect(TRUE, r);
2541 
2542     r = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
2543     expect(2, r);
2544 
2545     item.stateMask = LVIS_FOCUSED;
2546     item.state     = 0;
2547     r = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
2548     expect(TRUE, r);
2549 
2550     r = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
2551     expect(2, r);
2552 
2553     /* 2. same tests, with LVM_SETITEM */
2554     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
2555     SetWindowLongPtrA(hwnd, GWL_STYLE, style & ~LVS_SINGLESEL);
2556 
2557     r = SendMessageA(hwnd, LVM_SETSELECTIONMARK, 0, -1);
2558     expect(2, r);
2559 
2560     item.stateMask = LVIS_FOCUSED;
2561     item.state     = LVIS_FOCUSED;
2562     item.mask      = LVIF_STATE;
2563     item.iItem = item.iSubItem = 0;
2564     r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM)&item);
2565     expect(TRUE, r);
2566 
2567     r = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
2568     expect(0, r);
2569 
2570     /* it's not updated if already set */
2571     item.stateMask = LVIS_FOCUSED;
2572     item.state     = LVIS_FOCUSED;
2573     item.mask      = LVIF_STATE;
2574     item.iItem     = 1;
2575     item.iSubItem  = 0;
2576     r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM)&item);
2577     expect(TRUE, r);
2578 
2579     r = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
2580     expect(0, r);
2581 
2582     r = SendMessageA(hwnd, LVM_SETSELECTIONMARK, 0, -1);
2583     expect(0, r);
2584 
2585     item.stateMask = LVIS_FOCUSED;
2586     item.state     = LVIS_FOCUSED;
2587     item.mask      = LVIF_STATE;
2588     item.iItem     = 1;
2589     item.iSubItem  = 0;
2590     r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM)&item);
2591     expect(TRUE, r);
2592 
2593     r = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
2594     expect(-1, r);
2595 
2596     /* need to reset focused item first */
2597     item.stateMask = LVIS_FOCUSED;
2598     item.state     = 0;
2599     r = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
2600     expect(TRUE, r);
2601 
2602     item.stateMask = LVIS_FOCUSED;
2603     item.state     = LVIS_FOCUSED;
2604     item.mask      = LVIF_STATE;
2605     item.iItem     = 2;
2606     item.iSubItem  = 0;
2607     r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM)&item);
2608     expect(TRUE, r);
2609 
2610     r = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
2611     expect(2, r);
2612 
2613     item.stateMask = LVIS_FOCUSED;
2614     item.state     = 0;
2615     r = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
2616     expect(TRUE, r);
2617 
2618     r = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
2619     expect(2, r);
2620 
2621     DestroyWindow(hwnd);
2622 }
2623 
2624 static void test_subitem_rect(void)
2625 {
2626     HWND hwnd;
2627     DWORD r;
2628     LVCOLUMNA col;
2629     RECT rect, rect2;
2630     INT arr[3];
2631 
2632     /* test LVM_GETSUBITEMRECT for header */
2633     hwnd = create_listview_control(LVS_REPORT);
2634     ok(hwnd != NULL, "failed to create a listview window\n");
2635     /* add some columns */
2636     memset(&col, 0, sizeof(LVCOLUMNA));
2637     col.mask = LVCF_WIDTH;
2638     col.cx = 100;
2639     r = SendMessageA(hwnd, LVM_INSERTCOLUMNA, 0, (LPARAM)&col);
2640     expect(0, r);
2641     col.cx = 150;
2642     r = SendMessageA(hwnd, LVM_INSERTCOLUMNA, 1, (LPARAM)&col);
2643     expect(1, r);
2644     col.cx = 200;
2645     r = SendMessageA(hwnd, LVM_INSERTCOLUMNA, 2, (LPARAM)&col);
2646     expect(2, r);
2647     /* item = -1 means header, subitem index is 1 based */
2648     SetRect(&rect, LVIR_BOUNDS, 0, 0, 0);
2649     r = SendMessageA(hwnd, LVM_GETSUBITEMRECT, -1, (LPARAM)&rect);
2650     expect(0, r);
2651 
2652     SetRect(&rect, LVIR_BOUNDS, 1, 0, 0);
2653     r = SendMessageA(hwnd, LVM_GETSUBITEMRECT, -1, (LPARAM)&rect);
2654     expect(1, r);
2655 
2656     expect(100, rect.left);
2657     expect(250, rect.right);
2658     expect(3, rect.top);
2659 
2660     SetRect(&rect, LVIR_BOUNDS, 2, 0, 0);
2661     r = SendMessageA(hwnd, LVM_GETSUBITEMRECT, -1, (LPARAM)&rect);
2662     expect(1, r);
2663 
2664     expect(250, rect.left);
2665     expect(450, rect.right);
2666     expect(3, rect.top);
2667 
2668     /* item LVS_REPORT padding isn't applied to subitems */
2669     insert_item(hwnd, 0);
2670 
2671     SetRect(&rect, LVIR_BOUNDS, 1, 0, 0);
2672     r = SendMessageA(hwnd, LVM_GETSUBITEMRECT, 0, (LPARAM)&rect);
2673     expect(1, r);
2674     expect(100, rect.left);
2675     expect(250, rect.right);
2676 
2677     SetRect(&rect, LVIR_ICON, 1, 0, 0);
2678     r = SendMessageA(hwnd, LVM_GETSUBITEMRECT, 0, (LPARAM)&rect);
2679     expect(1, r);
2680     /* no icon attached - zero width rectangle, with no left padding */
2681     expect(100, rect.left);
2682     expect(100, rect.right);
2683 
2684     SetRect(&rect, LVIR_LABEL, 1, 0, 0);
2685     r = SendMessageA(hwnd, LVM_GETSUBITEMRECT, 0, (LPARAM)&rect);
2686     expect(1, r);
2687     /* same as full LVIR_BOUNDS */
2688     expect(100, rect.left);
2689     expect(250, rect.right);
2690 
2691     r = SendMessageA(hwnd, LVM_SCROLL, 10, 0);
2692     ok(r, "got %d\n", r);
2693 
2694     SetRect(&rect, LVIR_BOUNDS, 1, 0, 0);
2695     r = SendMessageA(hwnd, LVM_GETSUBITEMRECT, 0, (LPARAM)&rect);
2696     expect(1, r);
2697     expect(90, rect.left);
2698     expect(240, rect.right);
2699 
2700     SendMessageA(hwnd, LVM_SCROLL, -10, 0);
2701 
2702     /* test header interaction */
2703     subclass_header(hwnd);
2704     flush_sequences(sequences, NUM_MSG_SEQUENCES);
2705 
2706     SetRect(&rect, LVIR_BOUNDS, 1, 0, 0);
2707     r = SendMessageA(hwnd, LVM_GETSUBITEMRECT, -1, (LPARAM)&rect);
2708     expect(1, r);
2709 
2710     SetRect(&rect, LVIR_BOUNDS, 1, 0, 0);
2711     r = SendMessageA(hwnd, LVM_GETSUBITEMRECT, 0, (LPARAM)&rect);
2712     expect(1, r);
2713 
2714     SetRect(&rect, LVIR_BOUNDS, 1, 0, 0);
2715     r = SendMessageA(hwnd, LVM_GETSUBITEMRECT, -10, (LPARAM)&rect);
2716     expect(1, r);
2717 
2718     SetRect(&rect, LVIR_BOUNDS, 1, 0, 0);
2719     r = SendMessageA(hwnd, LVM_GETSUBITEMRECT, 20, (LPARAM)&rect);
2720     expect(1, r);
2721 
2722     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, getsubitemrect_seq, "LVM_GETSUBITEMRECT negative index", FALSE);
2723 
2724     DestroyWindow(hwnd);
2725 
2726     /* test subitem rects after re-arranging columns */
2727     hwnd = create_listview_control(LVS_REPORT);
2728     ok(hwnd != NULL, "failed to create a listview window\n");
2729     memset(&col, 0, sizeof(LVCOLUMNA));
2730     col.mask = LVCF_WIDTH;
2731 
2732     col.cx = 100;
2733     r = SendMessageA(hwnd, LVM_INSERTCOLUMNA, 0, (LPARAM)&col);
2734     expect(0, r);
2735 
2736     col.cx = 200;
2737     r = SendMessageA(hwnd, LVM_INSERTCOLUMNA, 1, (LPARAM)&col);
2738     expect(1, r);
2739 
2740     col.cx = 300;
2741     r = SendMessageA(hwnd, LVM_INSERTCOLUMNA, 2, (LPARAM)&col);
2742     expect(2, r);
2743 
2744     insert_item(hwnd, 0);
2745     insert_item(hwnd, 1);
2746 
2747     /* wrong item is refused for main item */
2748     SetRect(&rect, LVIR_BOUNDS, 0, -1, -1);
2749     r = SendMessageA(hwnd, LVM_GETSUBITEMRECT, 2, (LPARAM)&rect);
2750     expect(FALSE, r);
2751 
2752     /* for subitems rectangle is calculated even if there's no item added */
2753     SetRect(&rect, LVIR_BOUNDS, 1, -1, -1);
2754     r = SendMessageA(hwnd, LVM_GETSUBITEMRECT, 1, (LPARAM)&rect);
2755     expect(TRUE, r);
2756 
2757     SetRect(&rect2, LVIR_BOUNDS, 1, -1, -1);
2758     r = SendMessageA(hwnd, LVM_GETSUBITEMRECT, 2, (LPARAM)&rect2);
2759     expect(TRUE, r);
2760     expect(rect.right, rect2.right);
2761     expect(rect.left, rect2.left);
2762     expect(rect.bottom, rect2.top);
2763     ok(rect2.bottom > rect2.top, "expected not zero height\n");
2764 
2765     arr[0] = 1; arr[1] = 0; arr[2] = 2;
2766     r = SendMessageA(hwnd, LVM_SETCOLUMNORDERARRAY, 3, (LPARAM)arr);
2767     expect(TRUE, r);
2768 
2769     SetRect(&rect, LVIR_BOUNDS, 0, -1, -1);
2770     r = SendMessageA(hwnd, LVM_GETSUBITEMRECT, 0, (LPARAM)&rect);
2771     expect(TRUE, r);
2772     expect(0, rect.left);
2773     expect(600, rect.right);
2774 
2775     SetRect(&rect, LVIR_BOUNDS, 1, -1, -1);
2776     r = SendMessageA(hwnd, LVM_GETSUBITEMRECT, 0, (LPARAM)&rect);
2777     expect(TRUE, r);
2778     expect(0, rect.left);
2779     expect(200, rect.right);
2780 
2781     SetRect(&rect2, LVIR_BOUNDS, 1, -1, -1);
2782     r = SendMessageA(hwnd, LVM_GETSUBITEMRECT, 1, (LPARAM)&rect2);
2783     expect(TRUE, r);
2784     expect(0, rect2.left);
2785     expect(200, rect2.right);
2786     /* items are of the same height */
2787     ok(rect2.top > 0, "expected positive item height\n");
2788     expect(rect.bottom, rect2.top);
2789     expect(rect.bottom * 2 - rect.top, rect2.bottom);
2790 
2791     SetRect(&rect, LVIR_BOUNDS, 2, -1, -1);
2792     r = SendMessageA(hwnd, LVM_GETSUBITEMRECT, 0, (LPARAM)&rect);
2793     expect(TRUE, r);
2794     expect(300, rect.left);
2795     expect(600, rect.right);
2796 
2797     DestroyWindow(hwnd);
2798 
2799     /* try it for non LVS_REPORT style */
2800     hwnd = CreateWindowA("SysListView32", "Test", LVS_ICON, 0, 0, 100, 100, NULL, NULL,
2801                          GetModuleHandleA(NULL), 0);
2802     SetRect(&rect, LVIR_BOUNDS, 1, -10, -10);
2803     r = SendMessageA(hwnd, LVM_GETSUBITEMRECT, -1, (LPARAM)&rect);
2804     expect(0, r);
2805     /* rect is unchanged */
2806     expect(0, rect.left);
2807     expect(-10, rect.right);
2808     expect(1, rect.top);
2809     expect(-10, rect.bottom);
2810     DestroyWindow(hwnd);
2811 }
2812 
2813 /* comparison callback for test_sorting */
2814 static INT WINAPI test_CallBackCompare(LPARAM first, LPARAM second, LPARAM lParam)
2815 {
2816     if (first == second) return 0;
2817     return (first > second ? 1 : -1);
2818 }
2819 
2820 static void test_sorting(void)
2821 {
2822     HWND hwnd;
2823     LVITEMA item = {0};
2824     INT r;
2825     LONG_PTR style;
2826     static CHAR names[][5] = {"A", "B", "C", "D", "0"};
2827     CHAR buff[10];
2828 
2829     hwnd = create_listview_control(LVS_REPORT);
2830     ok(hwnd != NULL, "failed to create a listview window\n");
2831 
2832     /* insert some items */
2833     item.mask = LVIF_PARAM | LVIF_STATE;
2834     item.state = LVIS_SELECTED;
2835     item.iItem = 0;
2836     item.iSubItem = 0;
2837     item.lParam = 3;
2838     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
2839     expect(0, r);
2840 
2841     item.mask = LVIF_PARAM;
2842     item.iItem = 1;
2843     item.iSubItem = 0;
2844     item.lParam = 2;
2845     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
2846     expect(1, r);
2847 
2848     item.mask = LVIF_STATE | LVIF_PARAM;
2849     item.state = LVIS_SELECTED;
2850     item.iItem = 2;
2851     item.iSubItem = 0;
2852     item.lParam = 4;
2853     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
2854     expect(2, r);
2855 
2856     r = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
2857     expect(-1, r);
2858 
2859     r = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
2860     expect(2, r);
2861 
2862     r = SendMessageA(hwnd, LVM_SORTITEMS, 0, (LPARAM)test_CallBackCompare);
2863     expect(TRUE, r);
2864 
2865     r = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
2866     expect(2, r);
2867     r = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
2868     expect(-1, r);
2869     r = SendMessageA(hwnd, LVM_GETITEMSTATE, 0, LVIS_SELECTED);
2870     expect(0, r);
2871     r = SendMessageA(hwnd, LVM_GETITEMSTATE, 1, LVIS_SELECTED);
2872     expect(LVIS_SELECTED, r);
2873     r = SendMessageA(hwnd, LVM_GETITEMSTATE, 2, LVIS_SELECTED);
2874     expect(LVIS_SELECTED, r);
2875 
2876     DestroyWindow(hwnd);
2877 
2878     /* switch to LVS_SORTASCENDING when some items added */
2879     hwnd = create_listview_control(LVS_REPORT);
2880     ok(hwnd != NULL, "failed to create a listview window\n");
2881 
2882     item.mask = LVIF_TEXT;
2883     item.iItem = 0;
2884     item.iSubItem = 0;
2885     item.pszText = names[1];
2886     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
2887     expect(0, r);
2888 
2889     item.mask = LVIF_TEXT;
2890     item.iItem = 1;
2891     item.iSubItem = 0;
2892     item.pszText = names[2];
2893     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
2894     expect(1, r);
2895 
2896     item.mask = LVIF_TEXT;
2897     item.iItem = 2;
2898     item.iSubItem = 0;
2899     item.pszText = names[0];
2900     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
2901     expect(2, r);
2902 
2903     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
2904     SetWindowLongPtrA(hwnd, GWL_STYLE, style | LVS_SORTASCENDING);
2905     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
2906     ok(style & LVS_SORTASCENDING, "Expected LVS_SORTASCENDING to be set\n");
2907 
2908     /* no sorting performed when switched to LVS_SORTASCENDING */
2909     item.mask = LVIF_TEXT;
2910     item.iItem = 0;
2911     item.pszText = buff;
2912     item.cchTextMax = sizeof(buff);
2913     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
2914     expect(TRUE, r);
2915     ok(lstrcmpA(buff, names[1]) == 0, "Expected '%s', got '%s'\n", names[1], buff);
2916 
2917     item.iItem = 1;
2918     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
2919     expect(TRUE, r);
2920     ok(lstrcmpA(buff, names[2]) == 0, "Expected '%s', got '%s'\n", names[2], buff);
2921 
2922     item.iItem = 2;
2923     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
2924     expect(TRUE, r);
2925     ok(lstrcmpA(buff, names[0]) == 0, "Expected '%s', got '%s'\n", names[0], buff);
2926 
2927     /* adding new item doesn't resort list */
2928     item.mask = LVIF_TEXT;
2929     item.iItem = 3;
2930     item.iSubItem = 0;
2931     item.pszText = names[3];
2932     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
2933     expect(3, r);
2934 
2935     item.mask = LVIF_TEXT;
2936     item.iItem = 0;
2937     item.pszText = buff;
2938     item.cchTextMax = sizeof(buff);
2939     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
2940     expect(TRUE, r);
2941     ok(lstrcmpA(buff, names[1]) == 0, "Expected '%s', got '%s'\n", names[1], buff);
2942 
2943     item.iItem = 1;
2944     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
2945     expect(TRUE, r);
2946     ok(lstrcmpA(buff, names[2]) == 0, "Expected '%s', got '%s'\n", names[2], buff);
2947 
2948     item.iItem = 2;
2949     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
2950     expect(TRUE, r);
2951     ok(lstrcmpA(buff, names[0]) == 0, "Expected '%s', got '%s'\n", names[0], buff);
2952 
2953     item.iItem = 3;
2954     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
2955     expect(TRUE, r);
2956     ok(lstrcmpA(buff, names[3]) == 0, "Expected '%s', got '%s'\n", names[3], buff);
2957 
2958     /* corner case - item should be placed at first position */
2959     item.mask = LVIF_TEXT;
2960     item.iItem = 4;
2961     item.iSubItem = 0;
2962     item.pszText = names[4];
2963     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
2964     expect(0, r);
2965 
2966     item.iItem = 0;
2967     item.pszText = buff;
2968     item.cchTextMax = sizeof(buff);
2969     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
2970     expect(TRUE, r);
2971     ok(lstrcmpA(buff, names[4]) == 0, "Expected '%s', got '%s'\n", names[4], buff);
2972 
2973     item.iItem = 1;
2974     item.pszText = buff;
2975     item.cchTextMax = sizeof(buff);
2976     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
2977     expect(TRUE, r);
2978     ok(lstrcmpA(buff, names[1]) == 0, "Expected '%s', got '%s'\n", names[1], buff);
2979 
2980     item.iItem = 2;
2981     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
2982     expect(TRUE, r);
2983     ok(lstrcmpA(buff, names[2]) == 0, "Expected '%s', got '%s'\n", names[2], buff);
2984 
2985     item.iItem = 3;
2986     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
2987     expect(TRUE, r);
2988     ok(lstrcmpA(buff, names[0]) == 0, "Expected '%s', got '%s'\n", names[0], buff);
2989 
2990     item.iItem = 4;
2991     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
2992     expect(TRUE, r);
2993     ok(lstrcmpA(buff, names[3]) == 0, "Expected '%s', got '%s'\n", names[3], buff);
2994 
2995     DestroyWindow(hwnd);
2996 }
2997 
2998 static void test_ownerdata(void)
2999 {
3000     static char test_str[] = "test";
3001 
3002     HWND hwnd;
3003     LONG_PTR style, ret;
3004     DWORD res;
3005     LVITEMA item;
3006 
3007     /* it isn't possible to set LVS_OWNERDATA after creation */
3008     if (g_is_below_5)
3009     {
3010         win_skip("set LVS_OWNERDATA after creation leads to crash on < 5.80\n");
3011     }
3012     else
3013     {
3014         hwnd = create_listview_control(LVS_REPORT);
3015         ok(hwnd != NULL, "failed to create a listview window\n");
3016         style = GetWindowLongPtrA(hwnd, GWL_STYLE);
3017         ok(!(style & LVS_OWNERDATA) && style, "LVS_OWNERDATA isn't expected\n");
3018 
3019         flush_sequences(sequences, NUM_MSG_SEQUENCES);
3020 
3021         ret = SetWindowLongPtrA(hwnd, GWL_STYLE, style | LVS_OWNERDATA);
3022         ok(ret == style, "Expected set GWL_STYLE to succeed\n");
3023         ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_ownerdata_switchto_seq,
3024                 "try to switch to LVS_OWNERDATA seq", FALSE);
3025 
3026         style = GetWindowLongPtrA(hwnd, GWL_STYLE);
3027         ok(!(style & LVS_OWNERDATA), "LVS_OWNERDATA isn't expected\n");
3028         DestroyWindow(hwnd);
3029     }
3030 
3031     /* try to set LVS_OWNERDATA after creation just having it */
3032     hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT);
3033     ok(hwnd != NULL, "failed to create a listview window\n");
3034     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
3035     ok(style & LVS_OWNERDATA, "LVS_OWNERDATA is expected\n");
3036 
3037     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3038 
3039     ret = SetWindowLongPtrA(hwnd, GWL_STYLE, style | LVS_OWNERDATA);
3040     ok(ret == style, "Expected set GWL_STYLE to succeed\n");
3041     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_ownerdata_switchto_seq,
3042                 "try to switch to LVS_OWNERDATA seq", FALSE);
3043     DestroyWindow(hwnd);
3044 
3045     /* try to remove LVS_OWNERDATA after creation just having it */
3046     if (g_is_below_5)
3047     {
3048         win_skip("remove LVS_OWNERDATA after creation leads to crash on < 5.80\n");
3049     }
3050     else
3051     {
3052         hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT);
3053         ok(hwnd != NULL, "failed to create a listview window\n");
3054         style = GetWindowLongPtrA(hwnd, GWL_STYLE);
3055         ok(style & LVS_OWNERDATA, "LVS_OWNERDATA is expected\n");
3056 
3057         flush_sequences(sequences, NUM_MSG_SEQUENCES);
3058 
3059         ret = SetWindowLongPtrA(hwnd, GWL_STYLE, style & ~LVS_OWNERDATA);
3060         ok(ret == style, "Expected set GWL_STYLE to succeed\n");
3061         ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_ownerdata_switchto_seq,
3062                 "try to switch to LVS_OWNERDATA seq", FALSE);
3063         style = GetWindowLongPtrA(hwnd, GWL_STYLE);
3064         ok(style & LVS_OWNERDATA, "LVS_OWNERDATA is expected\n");
3065         DestroyWindow(hwnd);
3066     }
3067 
3068     /* try select an item */
3069     hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT);
3070     ok(hwnd != NULL, "failed to create a listview window\n");
3071     res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0);
3072     expect(1, res);
3073     res = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
3074     expect(0, res);
3075     memset(&item, 0, sizeof(item));
3076     item.stateMask = LVIS_SELECTED;
3077     item.state     = LVIS_SELECTED;
3078     res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
3079     expect(TRUE, res);
3080     res = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
3081     expect(1, res);
3082     res = SendMessageA(hwnd, LVM_GETITEMCOUNT, 0, 0);
3083     expect(1, res);
3084     DestroyWindow(hwnd);
3085 
3086     /* LVM_SETITEM and LVM_SETITEMTEXT is unsupported on LVS_OWNERDATA */
3087     hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT);
3088     ok(hwnd != NULL, "failed to create a listview window\n");
3089     res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0);
3090     expect(1, res);
3091     res = SendMessageA(hwnd, LVM_GETITEMCOUNT, 0, 0);
3092     expect(1, res);
3093     memset(&item, 0, sizeof(item));
3094     item.mask = LVIF_STATE;
3095     item.iItem = 0;
3096     item.stateMask = LVIS_SELECTED;
3097     item.state     = LVIS_SELECTED;
3098     res = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM)&item);
3099     expect(FALSE, res);
3100     memset(&item, 0, sizeof(item));
3101     item.pszText = test_str;
3102     res = SendMessageA(hwnd, LVM_SETITEMTEXTA, 0, (LPARAM)&item);
3103     expect(FALSE, res);
3104     DestroyWindow(hwnd);
3105 
3106     /* check notifications after focused/selected changed */
3107     hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT);
3108     ok(hwnd != NULL, "failed to create a listview window\n");
3109     res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 20, 0);
3110     expect(1, res);
3111 
3112     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3113 
3114     memset(&item, 0, sizeof(item));
3115     item.stateMask = LVIS_SELECTED;
3116     item.state     = LVIS_SELECTED;
3117     res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
3118     expect(TRUE, res);
3119 
3120     ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_select_focus_parent_seq,
3121                 "ownerdata select notification", TRUE);
3122 
3123     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3124 
3125     memset(&item, 0, sizeof(item));
3126     item.stateMask = LVIS_FOCUSED;
3127     item.state     = LVIS_FOCUSED;
3128     res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
3129     expect(TRUE, res);
3130 
3131     ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_select_focus_parent_seq,
3132                 "ownerdata focus notification", TRUE);
3133 
3134     /* select all, check notifications */
3135     item.stateMask = LVIS_SELECTED;
3136     item.state     = 0;
3137     res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
3138     expect(TRUE, res);
3139 
3140     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3141 
3142     item.stateMask = LVIS_SELECTED;
3143     item.state     = LVIS_SELECTED;
3144 
3145     memset(&g_nmlistview, 0xcc, sizeof(g_nmlistview));
3146     res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
3147     expect(TRUE, res);
3148     ok(g_nmlistview.iItem == -1, "got item %d\n", g_nmlistview.iItem);
3149     ok(g_nmlistview.iSubItem == 0, "got subitem %d\n", g_nmlistview.iSubItem);
3150     ok(g_nmlistview.uNewState == LVIS_SELECTED, "got new state 0x%08x\n", g_nmlistview.uNewState);
3151     ok(g_nmlistview.uOldState == 0, "got old state 0x%08x\n", g_nmlistview.uOldState);
3152     ok(g_nmlistview.uChanged == LVIF_STATE, "got changed 0x%08x\n", g_nmlistview.uChanged);
3153     ok(g_nmlistview.ptAction.x == 0 && g_nmlistview.ptAction.y == 0, "got wrong ptAction value\n");
3154     ok(g_nmlistview.lParam == 0, "got wrong lparam\n");
3155 
3156     ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_setstate_all_parent_seq,
3157                 "ownerdata select all notification", FALSE);
3158 
3159     /* select all again, note that all items are selected already */
3160     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3161     item.stateMask = LVIS_SELECTED;
3162     item.state     = LVIS_SELECTED;
3163 
3164     memset(&g_nmlistview, 0xcc, sizeof(g_nmlistview));
3165     res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
3166     expect(TRUE, res);
3167     ok(g_nmlistview.iItem == -1, "got item %d\n", g_nmlistview.iItem);
3168     ok(g_nmlistview.iSubItem == 0, "got subitem %d\n", g_nmlistview.iSubItem);
3169     ok(g_nmlistview.uNewState == LVIS_SELECTED, "got new state 0x%08x\n", g_nmlistview.uNewState);
3170     ok(g_nmlistview.uOldState == 0, "got old state 0x%08x\n", g_nmlistview.uOldState);
3171     ok(g_nmlistview.uChanged == LVIF_STATE, "got changed 0x%08x\n", g_nmlistview.uChanged);
3172     ok(g_nmlistview.ptAction.x == 0 && g_nmlistview.ptAction.y == 0, "got wrong ptAction value\n");
3173     ok(g_nmlistview.lParam == 0, "got wrong lparam\n");
3174 
3175     ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_setstate_all_parent_seq,
3176                 "ownerdata select all notification", FALSE);
3177 
3178     /* deselect all */
3179     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3180     item.stateMask = LVIS_SELECTED;
3181     item.state     = 0;
3182 
3183     memset(&g_nmlistview, 0xcc, sizeof(g_nmlistview));
3184     res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
3185     expect(TRUE, res);
3186     ok(g_nmlistview.iItem == -1, "got item %d\n", g_nmlistview.iItem);
3187     ok(g_nmlistview.iSubItem == 0, "got subitem %d\n", g_nmlistview.iSubItem);
3188     ok(g_nmlistview.uNewState == 0, "got new state 0x%08x\n", g_nmlistview.uNewState);
3189     ok(g_nmlistview.uOldState == LVIS_SELECTED, "got old state 0x%08x\n", g_nmlistview.uOldState);
3190     ok(g_nmlistview.uChanged == LVIF_STATE, "got changed 0x%08x\n", g_nmlistview.uChanged);
3191     ok(g_nmlistview.ptAction.x == 0 && g_nmlistview.ptAction.y == 0, "got wrong ptAction value\n");
3192     ok(g_nmlistview.lParam == 0, "got wrong lparam\n");
3193 
3194     ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_deselect_all_parent_seq,
3195                 "ownerdata deselect all notification", TRUE);
3196 
3197     /* nothing selected, deselect all again */
3198     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3199     item.stateMask = LVIS_SELECTED;
3200     item.state     = 0;
3201 
3202     res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
3203     expect(TRUE, res);
3204 
3205     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "ownerdata deselect all notification", FALSE);
3206 
3207     /* select one, then deselect all */
3208     item.stateMask = LVIS_SELECTED;
3209     item.state     = LVIS_SELECTED;
3210     res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
3211     expect(TRUE, res);
3212     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3213     item.stateMask = LVIS_SELECTED;
3214     item.state     = 0;
3215 
3216     memset(&g_nmlistview, 0xcc, sizeof(g_nmlistview));
3217     res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
3218     expect(TRUE, res);
3219     ok(g_nmlistview.iItem == -1, "got item %d\n", g_nmlistview.iItem);
3220     ok(g_nmlistview.iSubItem == 0, "got subitem %d\n", g_nmlistview.iSubItem);
3221     ok(g_nmlistview.uNewState == 0, "got new state 0x%08x\n", g_nmlistview.uNewState);
3222     ok(g_nmlistview.uOldState == LVIS_SELECTED, "got old state 0x%08x\n", g_nmlistview.uOldState);
3223     ok(g_nmlistview.uChanged == LVIF_STATE, "got changed 0x%08x\n", g_nmlistview.uChanged);
3224     ok(g_nmlistview.ptAction.x == 0 && g_nmlistview.ptAction.y == 0, "got wrong ptAction value\n");
3225     ok(g_nmlistview.lParam == 0, "got wrong lparam\n");
3226 
3227     ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_deselect_all_parent_seq,
3228                 "ownerdata select all notification", TRUE);
3229 
3230     /* remove focused, try to focus all */
3231     item.stateMask = LVIS_FOCUSED;
3232     item.state     = LVIS_FOCUSED;
3233     res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
3234     expect(TRUE, res);
3235     item.stateMask = LVIS_FOCUSED;
3236     item.state     = 0;
3237     res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
3238     expect(TRUE, res);
3239     item.stateMask = LVIS_FOCUSED;
3240     res = SendMessageA(hwnd, LVM_GETITEMSTATE, 0, LVIS_FOCUSED);
3241     expect(0, res);
3242 
3243     /* setting all to focused returns failure value */
3244     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3245     item.stateMask = LVIS_FOCUSED;
3246     item.state     = LVIS_FOCUSED;
3247 
3248     res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
3249     expect(FALSE, res);
3250 
3251     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq,
3252                 "ownerdata focus all notification", FALSE);
3253 
3254     /* focus single item, remove all */
3255     item.stateMask = LVIS_FOCUSED;
3256     item.state     = LVIS_FOCUSED;
3257     res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
3258     expect(TRUE, res);
3259     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3260     item.stateMask = LVIS_FOCUSED;
3261     item.state     = 0;
3262 
3263     memset(&g_nmlistview, 0xcc, sizeof(g_nmlistview));
3264     res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
3265     expect(TRUE, res);
3266     ok(g_nmlistview.iItem == -1, "got item %d\n", g_nmlistview.iItem);
3267     ok(g_nmlistview.iSubItem == 0, "got subitem %d\n", g_nmlistview.iSubItem);
3268     ok(g_nmlistview.uNewState == 0, "got new state 0x%08x\n", g_nmlistview.uNewState);
3269     ok(g_nmlistview.uOldState == LVIS_FOCUSED, "got old state 0x%08x\n", g_nmlistview.uOldState);
3270     ok(g_nmlistview.uChanged == LVIF_STATE, "got changed 0x%08x\n", g_nmlistview.uChanged);
3271     ok(g_nmlistview.ptAction.x == 0 && g_nmlistview.ptAction.y == 0, "got wrong ptAction value\n");
3272     ok(g_nmlistview.lParam == 0, "got wrong lparam\n");
3273 
3274     ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_defocus_all_parent_seq,
3275                 "ownerdata remove focus all notification", TRUE);
3276 
3277     /* set all cut */
3278     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3279     item.stateMask = LVIS_CUT;
3280     item.state     = LVIS_CUT;
3281 
3282     memset(&g_nmlistview, 0xcc, sizeof(g_nmlistview));
3283     res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
3284     expect(TRUE, res);
3285     ok(g_nmlistview.iItem == -1, "got item %d\n", g_nmlistview.iItem);
3286     ok(g_nmlistview.iSubItem == 0, "got subitem %d\n", g_nmlistview.iSubItem);
3287     ok(g_nmlistview.uNewState == LVIS_CUT, "got new state 0x%08x\n", g_nmlistview.uNewState);
3288     ok(g_nmlistview.uOldState == 0, "got old state 0x%08x\n", g_nmlistview.uOldState);
3289     ok(g_nmlistview.uChanged == LVIF_STATE, "got changed 0x%08x\n", g_nmlistview.uChanged);
3290     ok(g_nmlistview.ptAction.x == 0 && g_nmlistview.ptAction.y == 0, "got wrong ptAction value\n");
3291     ok(g_nmlistview.lParam == 0, "got wrong lparam\n");
3292 
3293     ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_setstate_all_parent_seq,
3294                 "ownerdata cut all notification", FALSE);
3295 
3296     /* all marked cut, try again */
3297     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3298     item.stateMask = LVIS_CUT;
3299     item.state     = LVIS_CUT;
3300 
3301     memset(&g_nmlistview, 0xcc, sizeof(g_nmlistview));
3302     res = SendMessageA(hwnd, LVM_SETITEMSTATE, -1, (LPARAM)&item);
3303     expect(TRUE, res);
3304     ok(g_nmlistview.iItem == -1, "got item %d\n", g_nmlistview.iItem);
3305     ok(g_nmlistview.iSubItem == 0, "got subitem %d\n", g_nmlistview.iSubItem);
3306     ok(g_nmlistview.uNewState == LVIS_CUT, "got new state 0x%08x\n", g_nmlistview.uNewState);
3307     ok(g_nmlistview.uOldState == 0, "got old state 0x%08x\n", g_nmlistview.uOldState);
3308     ok(g_nmlistview.uChanged == LVIF_STATE, "got changed 0x%08x\n", g_nmlistview.uChanged);
3309     ok(g_nmlistview.ptAction.x == 0 && g_nmlistview.ptAction.y == 0, "got wrong ptAction value\n");
3310     ok(g_nmlistview.lParam == 0, "got wrong lparam\n");
3311 
3312     ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_setstate_all_parent_seq,
3313                 "ownerdata cut all notification #2", FALSE);
3314 
3315     DestroyWindow(hwnd);
3316 
3317     /* check notifications on LVM_GETITEM */
3318     /* zero callback mask */
3319     hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT);
3320     ok(hwnd != NULL, "failed to create a listview window\n");
3321     res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0);
3322     expect(1, res);
3323 
3324     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3325 
3326     memset(&item, 0, sizeof(item));
3327     item.stateMask = LVIS_SELECTED;
3328     item.mask      = LVIF_STATE;
3329     res = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
3330     expect(TRUE, res);
3331 
3332     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq,
3333                 "ownerdata getitem selected state 1", FALSE);
3334 
3335     /* non zero callback mask but not we asking for */
3336     res = SendMessageA(hwnd, LVM_SETCALLBACKMASK, LVIS_OVERLAYMASK, 0);
3337     expect(TRUE, res);
3338 
3339     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3340 
3341     memset(&item, 0, sizeof(item));
3342     item.stateMask = LVIS_SELECTED;
3343     item.mask      = LVIF_STATE;
3344     res = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
3345     expect(TRUE, res);
3346 
3347     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq,
3348                 "ownerdata getitem selected state 2", FALSE);
3349 
3350     /* LVIS_OVERLAYMASK callback mask, asking for index */
3351     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3352 
3353     memset(&item, 0, sizeof(item));
3354     item.stateMask = LVIS_OVERLAYMASK;
3355     item.mask      = LVIF_STATE;
3356     res = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
3357     expect(TRUE, res);
3358 
3359     ok_sequence(sequences, PARENT_SEQ_INDEX, single_getdispinfo_parent_seq,
3360                 "ownerdata getitem selected state 2", FALSE);
3361 
3362     DestroyWindow(hwnd);
3363 
3364     /* LVS_SORTASCENDING/LVS_SORTDESCENDING aren't compatible with LVS_OWNERDATA */
3365     hwnd = create_listview_control(LVS_OWNERDATA | LVS_SORTASCENDING | LVS_REPORT);
3366     ok(hwnd != NULL, "failed to create a listview window\n");
3367     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
3368     ok(style & LVS_OWNERDATA, "Expected LVS_OWNERDATA\n");
3369     ok(style & LVS_SORTASCENDING, "Expected LVS_SORTASCENDING to be set\n");
3370     SetWindowLongPtrA(hwnd, GWL_STYLE, style & ~LVS_SORTASCENDING);
3371     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
3372     ok(!(style & LVS_SORTASCENDING), "Expected LVS_SORTASCENDING not set\n");
3373     DestroyWindow(hwnd);
3374     /* apparently it's allowed to switch these style on after creation */
3375     hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT);
3376     ok(hwnd != NULL, "failed to create a listview window\n");
3377     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
3378     ok(style & LVS_OWNERDATA, "Expected LVS_OWNERDATA\n");
3379     SetWindowLongPtrA(hwnd, GWL_STYLE, style | LVS_SORTASCENDING);
3380     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
3381     ok(style & LVS_SORTASCENDING, "Expected LVS_SORTASCENDING to be set\n");
3382     DestroyWindow(hwnd);
3383 
3384     hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT);
3385     ok(hwnd != NULL, "failed to create a listview window\n");
3386     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
3387     ok(style & LVS_OWNERDATA, "Expected LVS_OWNERDATA\n");
3388     SetWindowLongPtrA(hwnd, GWL_STYLE, style | LVS_SORTDESCENDING);
3389     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
3390     ok(style & LVS_SORTDESCENDING, "Expected LVS_SORTDESCENDING to be set\n");
3391     DestroyWindow(hwnd);
3392 
3393     /* The focused item is updated after the invalidation */
3394     hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT);
3395     ok(hwnd != NULL, "failed to create a listview window\n");
3396     res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 3, 0);
3397     expect(TRUE, res);
3398 
3399     memset(&item, 0, sizeof(item));
3400     item.stateMask = LVIS_FOCUSED;
3401     item.state     = LVIS_FOCUSED;
3402     res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
3403     expect(TRUE, res);
3404 
3405     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3406     res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 0, 0);
3407     expect(TRUE, res);
3408     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq,
3409                 "ownerdata setitemcount", FALSE);
3410 
3411     res = SendMessageA(hwnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
3412     expect(-1, res);
3413     DestroyWindow(hwnd);
3414 }
3415 
3416 static void test_norecompute(void)
3417 {
3418     static CHAR testA[] = "test";
3419     CHAR buff[10];
3420     LVITEMA item;
3421     HWND hwnd;
3422     DWORD res;
3423 
3424     /* self containing control */
3425     hwnd = create_listview_control(LVS_REPORT);
3426     ok(hwnd != NULL, "failed to create a listview window\n");
3427     memset(&item, 0, sizeof(item));
3428     item.mask = LVIF_TEXT | LVIF_STATE;
3429     item.iItem = 0;
3430     item.stateMask = LVIS_SELECTED;
3431     item.state     = LVIS_SELECTED;
3432     item.pszText   = testA;
3433     res = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item);
3434     expect(0, res);
3435     /* retrieve with LVIF_NORECOMPUTE */
3436     item.mask  = LVIF_TEXT | LVIF_NORECOMPUTE;
3437     item.iItem = 0;
3438     item.pszText    = buff;
3439     item.cchTextMax = sizeof(buff)/sizeof(CHAR);
3440     res = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
3441     expect(TRUE, res);
3442     ok(lstrcmpA(buff, testA) == 0, "Expected (%s), got (%s)\n", testA, buff);
3443 
3444     item.mask = LVIF_TEXT;
3445     item.iItem = 1;
3446     item.pszText = LPSTR_TEXTCALLBACKA;
3447     res = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item);
3448     expect(1, res);
3449 
3450     item.mask  = LVIF_TEXT | LVIF_NORECOMPUTE;
3451     item.iItem = 1;
3452     item.pszText    = buff;
3453     item.cchTextMax = sizeof(buff)/sizeof(CHAR);
3454 
3455     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3456     res = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
3457     expect(TRUE, res);
3458     ok(item.pszText == LPSTR_TEXTCALLBACKA, "Expected (%p), got (%p)\n",
3459        LPSTR_TEXTCALLBACKA, (VOID*)item.pszText);
3460     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "retrieve with LVIF_NORECOMPUTE seq", FALSE);
3461 
3462     DestroyWindow(hwnd);
3463 
3464     /* LVS_OWNERDATA */
3465     hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT);
3466     ok(hwnd != NULL, "failed to create a listview window\n");
3467 
3468     item.mask = LVIF_STATE;
3469     item.stateMask = LVIS_SELECTED;
3470     item.state     = LVIS_SELECTED;
3471     item.iItem = 0;
3472     res = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item);
3473     expect(0, res);
3474 
3475     item.mask  = LVIF_TEXT | LVIF_NORECOMPUTE;
3476     item.iItem = 0;
3477     item.pszText    = buff;
3478     item.cchTextMax = sizeof(buff)/sizeof(CHAR);
3479     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3480     res = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
3481     expect(TRUE, res);
3482     ok(item.pszText == LPSTR_TEXTCALLBACKA, "Expected (%p), got (%p)\n",
3483        LPSTR_TEXTCALLBACKA, (VOID*)item.pszText);
3484     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "retrieve with LVIF_NORECOMPUTE seq 2", FALSE);
3485 
3486     DestroyWindow(hwnd);
3487 }
3488 
3489 static void test_nosortheader(void)
3490 {
3491     HWND hwnd, header;
3492     LONG_PTR style;
3493 
3494     hwnd = create_listview_control(LVS_REPORT);
3495     ok(hwnd != NULL, "failed to create a listview window\n");
3496 
3497     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
3498     ok(IsWindow(header), "header expected\n");
3499 
3500     style = GetWindowLongPtrA(header, GWL_STYLE);
3501     ok(style & HDS_BUTTONS, "expected header to have HDS_BUTTONS\n");
3502 
3503     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
3504     SetWindowLongPtrA(hwnd, GWL_STYLE, style | LVS_NOSORTHEADER);
3505     /* HDS_BUTTONS retained */
3506     style = GetWindowLongPtrA(header, GWL_STYLE);
3507     ok(style & HDS_BUTTONS, "expected header to retain HDS_BUTTONS\n");
3508 
3509     DestroyWindow(hwnd);
3510 
3511     /* create with LVS_NOSORTHEADER */
3512     hwnd = create_listview_control(LVS_NOSORTHEADER | LVS_REPORT);
3513     ok(hwnd != NULL, "failed to create a listview window\n");
3514 
3515     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
3516     ok(IsWindow(header), "header expected\n");
3517 
3518     style = GetWindowLongPtrA(header, GWL_STYLE);
3519     ok(!(style & HDS_BUTTONS), "expected header to have no HDS_BUTTONS\n");
3520 
3521     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
3522     SetWindowLongPtrA(hwnd, GWL_STYLE, style & ~LVS_NOSORTHEADER);
3523     /* not changed here */
3524     style = GetWindowLongPtrA(header, GWL_STYLE);
3525     ok(!(style & HDS_BUTTONS), "expected header to have no HDS_BUTTONS\n");
3526 
3527     DestroyWindow(hwnd);
3528 }
3529 
3530 static void test_setredraw(void)
3531 {
3532     HWND hwnd;
3533     DWORD_PTR style;
3534     DWORD ret;
3535     HDC hdc;
3536     RECT rect;
3537 
3538     hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT);
3539     ok(hwnd != NULL, "failed to create a listview window\n");
3540 
3541     /* Passing WM_SETREDRAW to DefWinProc removes WS_VISIBLE.
3542        ListView seems to handle it internally without DefWinProc */
3543 
3544     /* default value first */
3545     ret = SendMessageA(hwnd, WM_SETREDRAW, TRUE, 0);
3546     expect(0, ret);
3547     /* disable */
3548     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
3549     ok(style & WS_VISIBLE, "Expected WS_VISIBLE to be set\n");
3550     ret = SendMessageA(hwnd, WM_SETREDRAW, FALSE, 0);
3551     expect(0, ret);
3552     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
3553     ok(style & WS_VISIBLE, "Expected WS_VISIBLE to be set\n");
3554     ret = SendMessageA(hwnd, WM_SETREDRAW, TRUE, 0);
3555     expect(0, ret);
3556 
3557     /* check update rect after redrawing */
3558     ret = SendMessageA(hwnd, WM_SETREDRAW, FALSE, 0);
3559     expect(0, ret);
3560     InvalidateRect(hwnd, NULL, FALSE);
3561     RedrawWindow(hwnd, NULL, NULL, RDW_UPDATENOW);
3562     rect.right = rect.bottom = 1;
3563     GetUpdateRect(hwnd, &rect, FALSE);
3564     expect(0, rect.right);
3565     expect(0, rect.bottom);
3566 
3567     /* WM_ERASEBKGND */
3568     hdc = GetWindowDC(hwndparent);
3569     ret = SendMessageA(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0);
3570     expect(TRUE, ret);
3571     ret = SendMessageA(hwnd, WM_SETREDRAW, FALSE, 0);
3572     expect(0, ret);
3573     ret = SendMessageA(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0);
3574     expect(TRUE, ret);
3575     ret = SendMessageA(hwnd, WM_SETREDRAW, TRUE, 0);
3576     expect(0, ret);
3577     ReleaseDC(hwndparent, hdc);
3578 
3579     /* check notification messages to show that repainting is disabled */
3580     ret = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0);
3581     expect(TRUE, ret);
3582     ret = SendMessageA(hwnd, WM_SETREDRAW, FALSE, 0);
3583     expect(0, ret);
3584     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3585 
3586     InvalidateRect(hwnd, NULL, TRUE);
3587     UpdateWindow(hwnd);
3588     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq,
3589                 "redraw after WM_SETREDRAW (FALSE)", FALSE);
3590 
3591     ret = SendMessageA(hwnd, LVM_SETBKCOLOR, 0, CLR_NONE);
3592     expect(TRUE, ret);
3593     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3594     InvalidateRect(hwnd, NULL, TRUE);
3595     UpdateWindow(hwnd);
3596     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq,
3597                 "redraw after WM_SETREDRAW (FALSE) with CLR_NONE bkgnd", FALSE);
3598 
3599     /* message isn't forwarded to header */
3600     subclass_header(hwnd);
3601     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3602     ret = SendMessageA(hwnd, WM_SETREDRAW, FALSE, 0);
3603     expect(0, ret);
3604     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, setredraw_seq,
3605                 "WM_SETREDRAW: not forwarded to header", FALSE);
3606 
3607     DestroyWindow(hwnd);
3608 }
3609 
3610 static void test_hittest(void)
3611 {
3612     HWND hwnd;
3613     DWORD r;
3614     RECT bounds;
3615     LVITEMA item;
3616     static CHAR text[] = "1234567890ABCDEFGHIJKLMNOPQRST";
3617     POINT pos;
3618     INT x, y, i;
3619     WORD vert;
3620     HIMAGELIST himl, himl2;
3621     HBITMAP hbmp;
3622 
3623     hwnd = create_listview_control(LVS_REPORT);
3624     ok(hwnd != NULL, "failed to create a listview window\n");
3625 
3626     /* LVS_REPORT with a single subitem (2 columns) */
3627     insert_column(hwnd, 0);
3628     insert_column(hwnd, 1);
3629     insert_item(hwnd, 0);
3630 
3631     item.iSubItem = 0;
3632     /* the only purpose of that line is to be as long as a half item rect */
3633     item.pszText  = text;
3634     r = SendMessageA(hwnd, LVM_SETITEMTEXTA, 0, (LPARAM)&item);
3635     expect(TRUE, r);
3636 
3637     r = SendMessageA(hwnd, LVM_SETCOLUMNWIDTH, 0, MAKELPARAM(100, 0));
3638     expect(TRUE, r);
3639     r = SendMessageA(hwnd, LVM_SETCOLUMNWIDTH, 1, MAKELPARAM(100, 0));
3640     expect(TRUE, r);
3641 
3642     SetRect(&bounds, LVIR_BOUNDS, 0, 0, 0);
3643     r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&bounds);
3644     expect(1, r);
3645     ok(bounds.bottom - bounds.top > 0, "Expected non zero item height\n");
3646     ok(bounds.right - bounds.left > 0, "Expected non zero item width\n");
3647     r = SendMessageA(hwnd, LVM_GETITEMSPACING, TRUE, 0);
3648     vert = HIWORD(r);
3649     ok(bounds.bottom - bounds.top == vert,
3650         "Vertical spacing inconsistent (%d != %d)\n", bounds.bottom - bounds.top, vert);
3651     r = SendMessageA(hwnd, LVM_GETITEMPOSITION, 0, (LPARAM)&pos);
3652     expect(TRUE, r);
3653 
3654     /* LVS_EX_FULLROWSELECT not set, no icons attached */
3655 
3656     /* outside columns by x position - valid is [0, 199] */
3657     x = -1;
3658     y = pos.y + (bounds.bottom - bounds.top) / 2;
3659     test_lvm_hittest(hwnd, x, y, -1, LVHT_TOLEFT, 0, FALSE, FALSE);
3660     test_lvm_subitemhittest(hwnd, x, y, -1, -1, LVHT_NOWHERE, FALSE, FALSE, FALSE);
3661 
3662     x = pos.x + 50; /* column half width */
3663     y = pos.y + (bounds.bottom - bounds.top) / 2;
3664     test_lvm_hittest(hwnd, x, y, 0, LVHT_ONITEMLABEL, 0, FALSE, FALSE);
3665     test_lvm_subitemhittest(hwnd, x, y, 0, 0, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE);
3666     x = pos.x + 150; /* outside column */
3667     y = pos.y + (bounds.bottom - bounds.top) / 2;
3668     test_lvm_hittest(hwnd, x, y, -1, LVHT_TORIGHT, 0, FALSE, FALSE);
3669     test_lvm_subitemhittest(hwnd, x, y, 0, 1, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE);
3670     y = (bounds.bottom - bounds.top) / 2;
3671     test_lvm_hittest(hwnd, x, y, -1, LVHT_TORIGHT, 0, FALSE, TRUE);
3672     test_lvm_subitemhittest(hwnd, x, y, 0, 1, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE);
3673     /* outside possible client rectangle (to right) */
3674     x = pos.x + 500;
3675     y = pos.y + (bounds.bottom - bounds.top) / 2;
3676     test_lvm_hittest(hwnd, x, y, -1, LVHT_TORIGHT, 0, FALSE, FALSE);
3677     test_lvm_subitemhittest(hwnd, x, y, -1, -1, LVHT_NOWHERE, FALSE, FALSE, FALSE);
3678     y = (bounds.bottom - bounds.top) / 2;
3679     test_lvm_hittest(hwnd, x, y, -1, LVHT_TORIGHT, 0, FALSE, TRUE);
3680     test_lvm_subitemhittest(hwnd, x, y, -1, -1, LVHT_NOWHERE, FALSE, FALSE, FALSE);
3681     /* subitem returned with -1 item too */
3682     x = pos.x + 150;
3683     y = bounds.top - vert;
3684     test_lvm_subitemhittest(hwnd, x, y, -1, 1, LVHT_NOWHERE, FALSE, FALSE, FALSE);
3685     test_lvm_subitemhittest(hwnd, x, y - vert + 1, -1, 1, LVHT_NOWHERE, FALSE, FALSE, FALSE);
3686     /* return values appear to underflow with negative indices */
3687     i = -2;
3688     y = y - vert;
3689     while (i > -10) {
3690         test_lvm_subitemhittest(hwnd, x, y, i, 1, LVHT_ONITEMLABEL, TRUE, FALSE, TRUE);
3691         test_lvm_subitemhittest(hwnd, x, y - vert + 1, i, 1, LVHT_ONITEMLABEL, TRUE, FALSE, TRUE);
3692         y = y - vert;
3693         i--;
3694     }
3695     /* parent client area is 100x100 by default */
3696     MoveWindow(hwnd, 0, 0, 300, 100, FALSE);
3697     x = pos.x + 150; /* outside column */
3698     y = pos.y + (bounds.bottom - bounds.top) / 2;
3699     test_lvm_hittest(hwnd, x, y, -1, LVHT_NOWHERE, 0, FALSE, FALSE);
3700     test_lvm_subitemhittest(hwnd, x, y, 0, 1, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE);
3701     y = (bounds.bottom - bounds.top) / 2;
3702     test_lvm_hittest(hwnd, x, y, -1, LVHT_NOWHERE, 0, FALSE, TRUE);
3703     test_lvm_subitemhittest(hwnd, x, y, 0, 1, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE);
3704     /* the same with LVS_EX_FULLROWSELECT */
3705     SendMessageA(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
3706     x = pos.x + 150; /* outside column */
3707     y = pos.y + (bounds.bottom - bounds.top) / 2;
3708     test_lvm_hittest(hwnd, x, y, 0, LVHT_ONITEM, LVHT_ONITEMLABEL, FALSE, FALSE);
3709     test_lvm_subitemhittest(hwnd, x, y, 0, 1, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE);
3710     y = (bounds.bottom - bounds.top) / 2;
3711     test_lvm_subitemhittest(hwnd, x, y, 0, 1, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE);
3712     MoveWindow(hwnd, 0, 0, 100, 100, FALSE);
3713     x = pos.x + 150; /* outside column */
3714     y = pos.y + (bounds.bottom - bounds.top) / 2;
3715     test_lvm_hittest(hwnd, x, y, -1, LVHT_TORIGHT, 0, FALSE, FALSE);
3716     test_lvm_subitemhittest(hwnd, x, y, 0, 1, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE);
3717     y = (bounds.bottom - bounds.top) / 2;
3718     test_lvm_hittest(hwnd, x, y, -1, LVHT_TORIGHT, 0, FALSE, TRUE);
3719     test_lvm_subitemhittest(hwnd, x, y, 0, 1, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE);
3720     /* outside possible client rectangle (to right) */
3721     x = pos.x + 500;
3722     y = pos.y + (bounds.bottom - bounds.top) / 2;
3723     test_lvm_hittest(hwnd, x, y, -1, LVHT_TORIGHT, 0, FALSE, FALSE);
3724     test_lvm_subitemhittest(hwnd, x, y, -1, -1, LVHT_NOWHERE, FALSE, FALSE, FALSE);
3725     y = (bounds.bottom - bounds.top) / 2;
3726     test_lvm_hittest(hwnd, x, y, -1, LVHT_TORIGHT, 0, FALSE, TRUE);
3727     test_lvm_subitemhittest(hwnd, x, y, -1, -1, LVHT_NOWHERE, FALSE, FALSE, FALSE);
3728     /* try with icons, state icons index is 1 based so at least 2 bitmaps needed */
3729     himl = ImageList_Create(16, 16, 0, 4, 4);
3730     ok(himl != NULL, "failed to create imagelist\n");
3731     hbmp = CreateBitmap(16, 16, 1, 1, NULL);
3732     ok(hbmp != NULL, "failed to create bitmap\n");
3733     r = ImageList_Add(himl, hbmp, 0);
3734     ok(r == 0, "should be zero\n");
3735     hbmp = CreateBitmap(16, 16, 1, 1, NULL);
3736     ok(hbmp != NULL, "failed to create bitmap\n");
3737     r = ImageList_Add(himl, hbmp, 0);
3738     ok(r == 1, "should be one\n");
3739 
3740     r = SendMessageA(hwnd, LVM_SETIMAGELIST, LVSIL_STATE, (LPARAM)himl);
3741     expect(0, r);
3742 
3743     item.mask = LVIF_IMAGE;
3744     item.iImage = 0;
3745     item.iItem = 0;
3746     item.iSubItem = 0;
3747     r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM)&item);
3748     expect(TRUE, r);
3749     /* on state icon */
3750     x = pos.x + 8;
3751     y = pos.y + (bounds.bottom - bounds.top) / 2;
3752     test_lvm_hittest(hwnd, x, y, 0, LVHT_ONITEMSTATEICON, 0, FALSE, FALSE);
3753     test_lvm_subitemhittest(hwnd, x, y, 0, 0, LVHT_ONITEMSTATEICON, FALSE, FALSE, FALSE);
3754     y = (bounds.bottom - bounds.top) / 2;
3755     test_lvm_subitemhittest(hwnd, x, y, 0, 0, LVHT_ONITEMSTATEICON, FALSE, FALSE, FALSE);
3756 
3757     /* state icons indices are 1 based, check with valid index */
3758     item.mask = LVIF_STATE;
3759     item.state = INDEXTOSTATEIMAGEMASK(1);
3760     item.stateMask = LVIS_STATEIMAGEMASK;
3761     item.iItem = 0;
3762     item.iSubItem = 0;
3763     r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM)&item);
3764     expect(TRUE, r);
3765     /* on state icon */
3766     x = pos.x + 8;
3767     y = pos.y + (bounds.bottom - bounds.top) / 2;
3768     test_lvm_hittest(hwnd, x, y, 0, LVHT_ONITEMSTATEICON, 0, FALSE, FALSE);
3769     test_lvm_subitemhittest(hwnd, x, y, 0, 0, LVHT_ONITEMSTATEICON, FALSE, FALSE, FALSE);
3770     y = (bounds.bottom - bounds.top) / 2;
3771     test_lvm_subitemhittest(hwnd, x, y, 0, 0, LVHT_ONITEMSTATEICON, FALSE, FALSE, FALSE);
3772 
3773     himl2 = (HIMAGELIST)SendMessageA(hwnd, LVM_SETIMAGELIST, LVSIL_STATE, 0);
3774     ok(himl2 == himl, "should return handle\n");
3775 
3776     r = SendMessageA(hwnd, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)himl);
3777     expect(0, r);
3778     /* on item icon */
3779     x = pos.x + 8;
3780     y = pos.y + (bounds.bottom - bounds.top) / 2;
3781     test_lvm_hittest(hwnd, x, y, 0, LVHT_ONITEMICON, 0, FALSE, FALSE);
3782     test_lvm_subitemhittest(hwnd, x, y, 0, 0, LVHT_ONITEMICON, FALSE, FALSE, FALSE);
3783     y = (bounds.bottom - bounds.top) / 2;
3784     test_lvm_subitemhittest(hwnd, x, y, 0, 0, LVHT_ONITEMICON, FALSE, FALSE, FALSE);
3785 
3786     DestroyWindow(hwnd);
3787 }
3788 
3789 static void test_getviewrect(void)
3790 {
3791     HWND hwnd;
3792     DWORD r;
3793     RECT rect;
3794     LVITEMA item;
3795 
3796     hwnd = create_listview_control(LVS_REPORT);
3797     ok(hwnd != NULL, "failed to create a listview window\n");
3798 
3799     /* empty */
3800     r = SendMessageA(hwnd, LVM_GETVIEWRECT, 0, (LPARAM)&rect);
3801     expect(TRUE, r);
3802 
3803     insert_column(hwnd, 0);
3804     insert_column(hwnd, 1);
3805 
3806     memset(&item, 0, sizeof(item));
3807     item.iItem = 0;
3808     item.iSubItem = 0;
3809     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item);
3810     ok(!r, "got %d\n", r);
3811 
3812     r = SendMessageA(hwnd, LVM_SETCOLUMNWIDTH, 0, MAKELPARAM(100, 0));
3813     expect(TRUE, r);
3814     r = SendMessageA(hwnd, LVM_SETCOLUMNWIDTH, 1, MAKELPARAM(120, 0));
3815     expect(TRUE, r);
3816 
3817     SetRect(&rect, -1, -1, -1, -1);
3818     r = SendMessageA(hwnd, LVM_GETVIEWRECT, 0, (LPARAM)&rect);
3819     expect(TRUE, r);
3820     /* left is set to (2e31-1) - XP SP2 */
3821     expect(0, rect.right);
3822     expect(0, rect.top);
3823     expect(0, rect.bottom);
3824 
3825     /* switch to LVS_ICON */
3826     SetWindowLongA(hwnd, GWL_STYLE, GetWindowLongA(hwnd, GWL_STYLE) & ~LVS_REPORT);
3827 
3828     SetRect(&rect, -1, -1, -1, -1);
3829     r = SendMessageA(hwnd, LVM_GETVIEWRECT, 0, (LPARAM)&rect);
3830     expect(TRUE, r);
3831     expect(0, rect.left);
3832     expect(0, rect.top);
3833     /* precise value differs for 2k, XP and Vista */
3834     ok(rect.bottom > 0, "Expected positive bottom value, got %d\n", rect.bottom);
3835     ok(rect.right  > 0, "Expected positive right value, got %d\n", rect.right);
3836 
3837     DestroyWindow(hwnd);
3838 }
3839 
3840 static void test_getitemposition(void)
3841 {
3842     HWND hwnd, header;
3843     DWORD r;
3844     POINT pt;
3845     RECT rect;
3846 
3847     hwnd = create_listview_control(LVS_REPORT);
3848     ok(hwnd != NULL, "failed to create a listview window\n");
3849     header = subclass_header(hwnd);
3850 
3851     /* LVS_REPORT, single item, no columns added */
3852     insert_item(hwnd, 0);
3853 
3854     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3855 
3856     pt.x = pt.y = -1;
3857     r = SendMessageA(hwnd, LVM_GETITEMPOSITION, 0, (LPARAM)&pt);
3858     expect(TRUE, r);
3859     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, getitemposition_seq1, "get item position 1", FALSE);
3860 
3861     /* LVS_REPORT, single item, single column */
3862     insert_column(hwnd, 0);
3863 
3864     flush_sequences(sequences, NUM_MSG_SEQUENCES);
3865 
3866     pt.x = pt.y = -1;
3867     r = SendMessageA(hwnd, LVM_GETITEMPOSITION, 0, (LPARAM)&pt);
3868     expect(TRUE, r);
3869     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, getitemposition_seq2, "get item position 2", TRUE);
3870 
3871     SetRectEmpty(&rect);
3872     r = SendMessageA(header, HDM_GETITEMRECT, 0, (LPARAM)&rect);
3873     ok(r, "got %d\n", r);
3874     /* some padding? */
3875     expect(2, pt.x);
3876     /* offset by header height */
3877     expect(rect.bottom - rect.top, pt.y);
3878 
3879     DestroyWindow(hwnd);
3880 }
3881 
3882 static void test_columnscreation(void)
3883 {
3884     HWND hwnd, header;
3885     DWORD r;
3886 
3887     hwnd = create_listview_control(LVS_REPORT);
3888     ok(hwnd != NULL, "failed to create a listview window\n");
3889 
3890     insert_item(hwnd, 0);
3891 
3892     /* headers columns aren't created automatically */
3893     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
3894     ok(IsWindow(header), "Expected header handle\n");
3895     r = SendMessageA(header, HDM_GETITEMCOUNT, 0, 0);
3896     expect(0, r);
3897 
3898     DestroyWindow(hwnd);
3899 }
3900 
3901 static void test_getitemrect(void)
3902 {
3903     HWND hwnd;
3904     HIMAGELIST himl, himl_ret;
3905     HBITMAP hbm;
3906     RECT rect;
3907     DWORD r;
3908     LVITEMA item;
3909     LVCOLUMNA col;
3910     INT order[2];
3911     POINT pt;
3912 
3913     /* rectangle isn't empty for empty text items */
3914     hwnd = create_listview_control(LVS_LIST);
3915     memset(&item, 0, sizeof(item));
3916     item.mask = 0;
3917     item.iItem = 0;
3918     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item);
3919     expect(0, r);
3920     rect.left = LVIR_LABEL;
3921     r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect);
3922     expect(TRUE, r);
3923     expect(0, rect.left);
3924     expect(0, rect.top);
3925     /* estimate it as width / height ratio */
3926 todo_wine
3927     ok((rect.right / rect.bottom) >= 5, "got right %d, bottom %d\n", rect.right, rect.bottom);
3928     DestroyWindow(hwnd);
3929 
3930     hwnd = create_listview_control(LVS_REPORT);
3931     ok(hwnd != NULL, "failed to create a listview window\n");
3932 
3933     /* empty item */
3934     memset(&item, 0, sizeof(item));
3935     item.iItem = 0;
3936     item.iSubItem = 0;
3937     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item);
3938     expect(0, r);
3939 
3940     SetRect(&rect, LVIR_BOUNDS, -1, -1, -1);
3941     r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect);
3942     expect(TRUE, r);
3943 
3944     /* zero width rectangle with no padding */
3945     expect(0, rect.left);
3946     expect(0, rect.right);
3947 
3948     insert_column(hwnd, 0);
3949     insert_column(hwnd, 1);
3950 
3951     col.mask = LVCF_WIDTH;
3952     col.cx   = 50;
3953     r = SendMessageA(hwnd, LVM_SETCOLUMNA, 0, (LPARAM)&col);
3954     expect(TRUE, r);
3955 
3956     col.mask = LVCF_WIDTH;
3957     col.cx   = 100;
3958     r = SendMessageA(hwnd, LVM_SETCOLUMNA, 1, (LPARAM)&col);
3959     expect(TRUE, r);
3960 
3961     SetRect(&rect, LVIR_BOUNDS, -1, -1, -1);
3962     r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect);
3963     expect(TRUE, r);
3964 
3965     /* still no left padding */
3966     expect(0, rect.left);
3967     expect(150, rect.right);
3968 
3969     SetRect(&rect, LVIR_SELECTBOUNDS, -1, -1, -1);
3970     r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect);
3971     expect(TRUE, r);
3972     /* padding */
3973     expect(2, rect.left);
3974 
3975     SetRect(&rect, LVIR_LABEL, -1, -1, -1);
3976     r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect);
3977     expect(TRUE, r);
3978     /* padding, column width */
3979     expect(2, rect.left);
3980     expect(50, rect.right);
3981 
3982     /* no icons attached */
3983     SetRect(&rect, LVIR_ICON, -1, -1, -1);
3984     r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect);
3985     expect(TRUE, r);
3986     /* padding */
3987     expect(2, rect.left);
3988     expect(2, rect.right);
3989 
3990     /* change order */
3991     order[0] = 1; order[1] = 0;
3992     r = SendMessageA(hwnd, LVM_SETCOLUMNORDERARRAY, 2, (LPARAM)&order);
3993     expect(TRUE, r);
3994     pt.x = -1;
3995     r = SendMessageA(hwnd, LVM_GETITEMPOSITION, 0, (LPARAM)&pt);
3996     expect(TRUE, r);
3997     /* 1 indexed column width + padding */
3998     expect(102, pt.x);
3999     /* rect is at zero too */
4000     SetRect(&rect, LVIR_BOUNDS, -1, -1, -1);
4001     r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect);
4002     expect(TRUE, r);
4003     expect(0, rect.left);
4004     /* just width sum */
4005     expect(150, rect.right);
4006 
4007     SetRect(&rect, LVIR_SELECTBOUNDS, -1, -1, -1);
4008     r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect);
4009     expect(TRUE, r);
4010     /* column width + padding */
4011     expect(102, rect.left);
4012 
4013     /* back to initial order */
4014     order[0] = 0; order[1] = 1;
4015     r = SendMessageA(hwnd, LVM_SETCOLUMNORDERARRAY, 2, (LPARAM)&order);
4016     expect(TRUE, r);
4017 
4018     /* state icons */
4019     himl = ImageList_Create(16, 16, 0, 2, 2);
4020     ok(himl != NULL, "failed to create imagelist\n");
4021     hbm = CreateBitmap(16, 16, 1, 1, NULL);
4022     ok(hbm != NULL, "failed to create bitmap\n");
4023     r = ImageList_Add(himl, hbm, 0);
4024     expect(0, r);
4025     hbm = CreateBitmap(16, 16, 1, 1, NULL);
4026     ok(hbm != NULL, "failed to create bitmap\n");
4027     r = ImageList_Add(himl, hbm, 0);
4028     expect(1, r);
4029 
4030     r = SendMessageA(hwnd, LVM_SETIMAGELIST, LVSIL_STATE, (LPARAM)himl);
4031     expect(0, r);
4032 
4033     item.mask = LVIF_STATE;
4034     item.state = INDEXTOSTATEIMAGEMASK(1);
4035     item.stateMask = LVIS_STATEIMAGEMASK;
4036     item.iItem = 0;
4037     item.iSubItem = 0;
4038     r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM)&item);
4039     expect(TRUE, r);
4040 
4041     /* icon bounds */
4042     SetRect(&rect, LVIR_ICON, -1, -1, -1);
4043     r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect);
4044     expect(TRUE, r);
4045     /* padding + stateicon width */
4046     expect(18, rect.left);
4047     expect(18, rect.right);
4048     /* label bounds */
4049     SetRect(&rect, LVIR_LABEL, -1, -1, -1);
4050     r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect);
4051     expect(TRUE, r);
4052     /* padding + stateicon width -> column width */
4053     expect(18, rect.left);
4054     expect(50, rect.right);
4055 
4056     himl_ret = (HIMAGELIST)SendMessageA(hwnd, LVM_SETIMAGELIST, LVSIL_STATE, 0);
4057     ok(himl_ret == himl, "got %p, expected %p\n", himl_ret, himl);
4058 
4059     r = SendMessageA(hwnd, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)himl);
4060     expect(0, r);
4061 
4062     item.mask = LVIF_STATE | LVIF_IMAGE;
4063     item.iImage = 1;
4064     item.state = 0;
4065     item.stateMask = ~0;
4066     item.iItem = 0;
4067     item.iSubItem = 0;
4068     r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM)&item);
4069     expect(TRUE, r);
4070 
4071     /* icon bounds */
4072     SetRect(&rect, LVIR_ICON, -1, -1, -1);
4073     r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect);
4074     expect(TRUE, r);
4075     /* padding, icon width */
4076     expect(2, rect.left);
4077     expect(18, rect.right);
4078     /* label bounds */
4079     SetRect(&rect, LVIR_LABEL, -1, -1, -1);
4080     r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect);
4081     expect(TRUE, r);
4082     /* padding + icon width -> column width */
4083     expect(18, rect.left);
4084     expect(50, rect.right);
4085 
4086     /* select bounds */
4087     SetRect(&rect, LVIR_SELECTBOUNDS, -1, -1, -1);
4088     r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect);
4089     expect(TRUE, r);
4090     /* padding, column width */
4091     expect(2, rect.left);
4092     expect(50, rect.right);
4093 
4094     /* try with indentation */
4095     item.mask = LVIF_INDENT;
4096     item.iIndent = 1;
4097     item.iItem = 0;
4098     item.iSubItem = 0;
4099     r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM)&item);
4100     expect(TRUE, r);
4101 
4102     /* bounds */
4103     SetRect(&rect, LVIR_BOUNDS, -1, -1, -1);
4104     r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect);
4105     expect(TRUE, r);
4106     /* padding + 1 icon width, column width */
4107     expect(0, rect.left);
4108     expect(150, rect.right);
4109 
4110     /* select bounds */
4111     SetRect(&rect, LVIR_SELECTBOUNDS, -1, -1, -1);
4112     r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect);
4113     expect(TRUE, r);
4114     /* padding + 1 icon width, column width */
4115     expect(2 + 16, rect.left);
4116     expect(50, rect.right);
4117 
4118     /* label bounds */
4119     SetRect(&rect, LVIR_LABEL, -1, -1, -1);
4120     r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect);
4121     expect(TRUE, r);
4122     /* padding + 2 icon widths, column width */
4123     expect(2 + 16*2, rect.left);
4124     expect(50, rect.right);
4125 
4126     /* icon bounds */
4127     SetRect(&rect, LVIR_ICON, -1, -1, -1);
4128     r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect);
4129     expect(TRUE, r);
4130     /* padding + 1 icon width indentation, icon width */
4131     expect(2 + 16, rect.left);
4132     expect(34, rect.right);
4133 
4134     DestroyWindow(hwnd);
4135 }
4136 
4137 static void test_editbox(void)
4138 {
4139     static CHAR testitemA[]  = "testitem";
4140     static CHAR testitem1A[] = "testitem_quitelongname";
4141     static CHAR testitem2A[] = "testITEM_quitelongname";
4142     static CHAR buffer[25];
4143     HWND hwnd, hwndedit, hwndedit2, header;
4144     LVITEMA item;
4145     INT r;
4146 
4147     hwnd = create_listview_control(LVS_EDITLABELS | LVS_REPORT);
4148     ok(hwnd != NULL, "failed to create a listview window\n");
4149 
4150     insert_column(hwnd, 0);
4151 
4152     memset(&item, 0, sizeof(item));
4153     item.mask = LVIF_TEXT;
4154     item.pszText = testitemA;
4155     item.iItem = 0;
4156     item.iSubItem = 0;
4157     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item);
4158     expect(0, r);
4159 
4160     /* test notifications without edit created */
4161     flush_sequences(sequences, NUM_MSG_SEQUENCES);
4162     r = SendMessageA(hwnd, WM_COMMAND, MAKEWPARAM(0, EN_SETFOCUS), (LPARAM)0xdeadbeef);
4163     expect(0, r);
4164     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq,
4165                 "edit box WM_COMMAND (EN_SETFOCUS), no edit created", FALSE);
4166     /* same thing but with valid window */
4167     hwndedit = CreateWindowA("Edit", "Test edit", WS_VISIBLE | WS_CHILD, 0, 0, 20,
4168                 10, hwnd, (HMENU)1, (HINSTANCE)GetWindowLongPtrA(hwnd, GWLP_HINSTANCE), 0);
4169     flush_sequences(sequences, NUM_MSG_SEQUENCES);
4170     r = SendMessageA(hwnd, WM_COMMAND, MAKEWPARAM(0, EN_SETFOCUS), (LPARAM)hwndedit);
4171     expect(0, r);
4172     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq,
4173                 "edit box WM_COMMAND (EN_SETFOCUS), no edit created #2", FALSE);
4174     DestroyWindow(hwndedit);
4175 
4176     /* setting focus is necessary */
4177     SetFocus(hwnd);
4178     hwndedit = (HWND)SendMessageA(hwnd, LVM_EDITLABELA, 0, 0);
4179     ok(IsWindow(hwndedit), "Expected Edit window to be created\n");
4180 
4181     /* test children Z-order after Edit box created */
4182     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
4183     ok(IsWindow(header), "Expected header to be created\n");
4184     ok(GetTopWindow(hwnd) == header, "Expected header to be on top\n");
4185     ok(GetNextWindow(header, GW_HWNDNEXT) == hwndedit, "got %p\n", GetNextWindow(header, GW_HWNDNEXT));
4186 
4187     /* modify initial string */
4188     r = SendMessageA(hwndedit, WM_SETTEXT, 0, (LPARAM)testitem1A);
4189     expect(TRUE, r);
4190 
4191     /* edit window is resized and repositioned,
4192        check again for Z-order - it should be preserved */
4193     ok(GetTopWindow(hwnd) == header, "Expected header to be on top\n");
4194     ok(GetNextWindow(header, GW_HWNDNEXT) == hwndedit, "got %p\n", GetNextWindow(header, GW_HWNDNEXT));
4195 
4196     /* return focus to listview */
4197     SetFocus(hwnd);
4198 
4199     memset(&item, 0, sizeof(item));
4200     item.mask = LVIF_TEXT;
4201     item.pszText = buffer;
4202     item.cchTextMax = sizeof(buffer);
4203     item.iItem = 0;
4204     item.iSubItem = 0;
4205     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
4206     expect(TRUE, r);
4207 
4208     ok(strcmp(buffer, testitem1A) == 0, "Expected item text to change\n");
4209 
4210     /* send LVM_EDITLABEL on already created edit */
4211     SetFocus(hwnd);
4212     hwndedit = (HWND)SendMessageA(hwnd, LVM_EDITLABELA, 0, 0);
4213     ok(IsWindow(hwndedit), "Expected Edit window to be created\n");
4214     /* focus will be set to edit */
4215     ok(GetFocus() == hwndedit, "Expected Edit window to be focused\n");
4216     hwndedit2 = (HWND)SendMessageA(hwnd, LVM_EDITLABELA, 0, 0);
4217     ok(IsWindow(hwndedit2), "Expected Edit window to be created\n");
4218 
4219     /* creating label disabled when control isn't focused */
4220     SetFocus(0);
4221     hwndedit = (HWND)SendMessageA(hwnd, LVM_EDITLABELA, 0, 0);
4222     todo_wine ok(hwndedit == NULL, "Expected Edit window not to be created\n");
4223 
4224     /* check EN_KILLFOCUS handling */
4225     memset(&item, 0, sizeof(item));
4226     item.pszText = testitemA;
4227     item.iItem = 0;
4228     item.iSubItem = 0;
4229     r = SendMessageA(hwnd, LVM_SETITEMTEXTA, 0, (LPARAM)&item);
4230     expect(TRUE, r);
4231 
4232     SetFocus(hwnd);
4233     hwndedit = (HWND)SendMessageA(hwnd, LVM_EDITLABELA, 0, 0);
4234     ok(IsWindow(hwndedit), "Expected Edit window to be created\n");
4235     /* modify edit and notify control that it lost focus */
4236     r = SendMessageA(hwndedit, WM_SETTEXT, 0, (LPARAM)testitem1A);
4237     expect(TRUE, r);
4238     g_editbox_disp_info.item.pszText = NULL;
4239     r = SendMessageA(hwnd, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)hwndedit);
4240     expect(0, r);
4241     ok(g_editbox_disp_info.item.pszText != NULL, "expected notification with not null text\n");
4242 
4243     memset(&item, 0, sizeof(item));
4244     item.pszText = buffer;
4245     item.cchTextMax = sizeof(buffer);
4246     item.iItem = 0;
4247     item.iSubItem = 0;
4248     r = SendMessageA(hwnd, LVM_GETITEMTEXTA, 0, (LPARAM)&item);
4249     expect(lstrlenA(item.pszText), r);
4250     ok(strcmp(buffer, testitem1A) == 0, "Expected item text to change\n");
4251     ok(!IsWindow(hwndedit), "Expected Edit window to be freed\n");
4252 
4253     /* change item name to differ in casing only */
4254     SetFocus(hwnd);
4255     hwndedit = (HWND)SendMessageA(hwnd, LVM_EDITLABELA, 0, 0);
4256     ok(IsWindow(hwndedit), "Expected Edit window to be created\n");
4257     /* modify edit and notify control that it lost focus */
4258     r = SendMessageA(hwndedit, WM_SETTEXT, 0, (LPARAM)testitem2A);
4259     expect(TRUE, r);
4260     g_editbox_disp_info.item.pszText = NULL;
4261     r = SendMessageA(hwnd, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)hwndedit);
4262     expect(0, r);
4263     ok(g_editbox_disp_info.item.pszText != NULL, "got %p\n", g_editbox_disp_info.item.pszText);
4264 
4265     memset(&item, 0, sizeof(item));
4266     item.pszText = buffer;
4267     item.cchTextMax = sizeof(buffer);
4268     item.iItem = 0;
4269     item.iSubItem = 0;
4270     r = SendMessageA(hwnd, LVM_GETITEMTEXTA, 0, (LPARAM)&item);
4271     expect(lstrlenA(item.pszText), r);
4272     ok(strcmp(buffer, testitem2A) == 0, "got %s, expected %s\n", buffer, testitem2A);
4273     ok(!IsWindow(hwndedit), "Expected Edit window to be freed\n");
4274 
4275     /* end edit without saving */
4276     SetFocus(hwnd);
4277     hwndedit = (HWND)SendMessageA(hwnd, LVM_EDITLABELA, 0, 0);
4278     flush_sequences(sequences, NUM_MSG_SEQUENCES);
4279     r = SendMessageA(hwndedit, WM_KEYDOWN, VK_ESCAPE, 0);
4280     expect(0, r);
4281     ok_sequence(sequences, PARENT_SEQ_INDEX, edit_end_nochange,
4282                 "edit box - end edit, no change, escape", TRUE);
4283     /* end edit with saving */
4284     SetFocus(hwnd);
4285     hwndedit = (HWND)SendMessageA(hwnd, LVM_EDITLABELA, 0, 0);
4286     flush_sequences(sequences, NUM_MSG_SEQUENCES);
4287     r = SendMessageA(hwndedit, WM_KEYDOWN, VK_RETURN, 0);
4288     expect(0, r);
4289     ok_sequence(sequences, PARENT_SEQ_INDEX, edit_end_nochange,
4290                 "edit box - end edit, no change, return", TRUE);
4291 
4292     memset(&item, 0, sizeof(item));
4293     item.pszText = buffer;
4294     item.cchTextMax = sizeof(buffer);
4295     item.iItem = 0;
4296     item.iSubItem = 0;
4297     r = SendMessageA(hwnd, LVM_GETITEMTEXTA, 0, (LPARAM)&item);
4298     expect(lstrlenA(item.pszText), r);
4299     ok(strcmp(buffer, testitem2A) == 0, "Expected item text to change\n");
4300 
4301     /* LVM_EDITLABEL with -1 destroys current edit */
4302     hwndedit = (HWND)SendMessageA(hwnd, LVM_GETEDITCONTROL, 0, 0);
4303     ok(hwndedit == NULL, "Expected Edit window not to be created\n");
4304     /* no edit present */
4305     hwndedit = (HWND)SendMessageA(hwnd, LVM_EDITLABELA, -1, 0);
4306     ok(hwndedit == NULL, "Expected Edit window not to be created\n");
4307     hwndedit = (HWND)SendMessageA(hwnd, LVM_EDITLABELA, 0, 0);
4308     ok(IsWindow(hwndedit), "Expected Edit window to be created\n");
4309     /* edit present */
4310     ok(GetFocus() == hwndedit, "Expected Edit to be focused\n");
4311     hwndedit2 = (HWND)SendMessageA(hwnd, LVM_EDITLABELA, -1, 0);
4312     ok(hwndedit2 == NULL, "Expected Edit window not to be created\n");
4313     ok(!IsWindow(hwndedit), "Expected Edit window to be destroyed\n");
4314     ok(GetFocus() == hwnd, "Expected List to be focused\n");
4315     /* check another negative value */
4316     hwndedit = (HWND)SendMessageA(hwnd, LVM_EDITLABELA, 0, 0);
4317     ok(IsWindow(hwndedit), "Expected Edit window to be created\n");
4318     ok(GetFocus() == hwndedit, "Expected Edit to be focused\n");
4319     hwndedit2 = (HWND)SendMessageA(hwnd, LVM_EDITLABELA, -2, 0);
4320     ok(hwndedit2 == NULL, "Expected Edit window not to be created\n");
4321     ok(!IsWindow(hwndedit), "Expected Edit window to be destroyed\n");
4322     ok(GetFocus() == hwnd, "Expected List to be focused\n");
4323     /* and value greater than max item index */
4324     hwndedit = (HWND)SendMessageA(hwnd, LVM_EDITLABELA, 0, 0);
4325     ok(IsWindow(hwndedit), "Expected Edit window to be created\n");
4326     ok(GetFocus() == hwndedit, "Expected Edit to be focused\n");
4327     r = SendMessageA(hwnd, LVM_GETITEMCOUNT, 0, 0);
4328     hwndedit2 = (HWND)SendMessageA(hwnd, LVM_EDITLABELA, r, 0);
4329     ok(hwndedit2 == NULL, "Expected Edit window not to be created\n");
4330     ok(!IsWindow(hwndedit), "Expected Edit window to be destroyed\n");
4331     ok(GetFocus() == hwnd, "Expected List to be focused\n");
4332 
4333     /* messaging tests */
4334     SetFocus(hwnd);
4335     flush_sequences(sequences, NUM_MSG_SEQUENCES);
4336     blockEdit = FALSE;
4337     hwndedit = (HWND)SendMessageA(hwnd, LVM_EDITLABELA, 0, 0);
4338     ok(IsWindow(hwndedit), "Expected Edit window to be created\n");
4339     /* testing only sizing messages */
4340     ok_sequence(sequences, EDITBOX_SEQ_INDEX, editbox_create_pos,
4341                 "edit box create - sizing", FALSE);
4342 
4343     /* WM_COMMAND with EN_KILLFOCUS isn't forwarded to parent */
4344     SetFocus(hwnd);
4345     hwndedit = (HWND)SendMessageA(hwnd, LVM_EDITLABELA, 0, 0);
4346     ok(IsWindow(hwndedit), "Expected Edit window to be created\n");
4347     flush_sequences(sequences, NUM_MSG_SEQUENCES);
4348     r = SendMessageA(hwnd, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)hwndedit);
4349     expect(0, r);
4350     ok_sequence(sequences, PARENT_SEQ_INDEX, edit_end_nochange,
4351                 "edit box WM_COMMAND (EN_KILLFOCUS)", TRUE);
4352 
4353     DestroyWindow(hwnd);
4354 }
4355 
4356 static void test_notifyformat(void)
4357 {
4358     HWND hwnd, header;
4359     DWORD r;
4360 
4361     hwnd = create_listview_control(LVS_REPORT);
4362     ok(hwnd != NULL, "failed to create a listview window\n");
4363 
4364     /* CCM_GETUNICODEFORMAT == LVM_GETUNICODEFORMAT,
4365        CCM_SETUNICODEFORMAT == LVM_SETUNICODEFORMAT */
4366     r = SendMessageA(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
4367     expect(0, r);
4368     SendMessageA(hwnd, WM_NOTIFYFORMAT, 0, NF_QUERY);
4369     /* set */
4370     r = SendMessageA(hwnd, LVM_SETUNICODEFORMAT, 1, 0);
4371     expect(0, r);
4372     r = SendMessageA(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
4373     ok(r == 1, "Unexpected return value %d.\n", r);
4374     r = SendMessageA(hwnd, LVM_SETUNICODEFORMAT, 0, 0);
4375     expect(1, r);
4376     r = SendMessageA(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
4377     expect(0, r);
4378 
4379     DestroyWindow(hwnd);
4380 
4381     /* test failure in parent WM_NOTIFYFORMAT  */
4382     notifyFormat = 0;
4383     hwnd = create_listview_control(LVS_REPORT);
4384     ok(hwnd != NULL, "failed to create a listview window\n");
4385     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
4386     ok(IsWindow(header), "expected header to be created\n");
4387     r = SendMessageA(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
4388     expect(0, r);
4389     r = SendMessageA(header, HDM_GETUNICODEFORMAT, 0, 0);
4390     ok( r == 1, "Expected 1, got %d\n", r );
4391     r = SendMessageA(hwnd, WM_NOTIFYFORMAT, 0, NF_QUERY);
4392     ok(r != 0, "Expected valid format\n");
4393 
4394     notifyFormat = NFR_UNICODE;
4395     r = SendMessageA(hwnd, WM_NOTIFYFORMAT, 0, NF_REQUERY);
4396     expect(NFR_UNICODE, r);
4397     r = SendMessageA(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
4398     expect(1, r);
4399     r = SendMessageA(header, HDM_GETUNICODEFORMAT, 0, 0);
4400     ok( r == 1, "Expected 1, got %d\n", r );
4401 
4402     notifyFormat = NFR_ANSI;
4403     r = SendMessageA(hwnd, WM_NOTIFYFORMAT, 0, NF_REQUERY);
4404     expect(NFR_ANSI, r);
4405     r = SendMessageA(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
4406     expect(0, r);
4407     r = SendMessageA(header, HDM_GETUNICODEFORMAT, 0, 0);
4408     ok( r == 1, "Expected 1, got %d\n", r );
4409 
4410     DestroyWindow(hwnd);
4411 
4412     hwndparentW = create_parent_window(TRUE);
4413     ok(IsWindow(hwndparentW), "Unicode parent creation failed\n");
4414     if (!IsWindow(hwndparentW))  return;
4415 
4416     notifyFormat = -1;
4417     hwnd = create_listview_controlW(LVS_REPORT, hwndparentW);
4418     ok(hwnd != NULL, "failed to create a listview window\n");
4419     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
4420     ok(IsWindow(header), "expected header to be created\n");
4421     r = SendMessageW(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
4422     expect(1, r);
4423     r = SendMessageA(header, HDM_GETUNICODEFORMAT, 0, 0);
4424     expect(1, r);
4425     DestroyWindow(hwnd);
4426     /* receiving error code defaulting to ansi */
4427     notifyFormat = 0;
4428     hwnd = create_listview_controlW(LVS_REPORT, hwndparentW);
4429     ok(hwnd != NULL, "failed to create a listview window\n");
4430     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
4431     ok(IsWindow(header), "expected header to be created\n");
4432     r = SendMessageW(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
4433     expect(0, r);
4434     r = SendMessageA(header, HDM_GETUNICODEFORMAT, 0, 0);
4435     expect(1, r);
4436     DestroyWindow(hwnd);
4437     /* receiving ansi code from unicode window, use it */
4438     notifyFormat = NFR_ANSI;
4439     hwnd = create_listview_controlW(LVS_REPORT, hwndparentW);
4440     ok(hwnd != NULL, "failed to create a listview window\n");
4441     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
4442     ok(IsWindow(header), "expected header to be created\n");
4443     r = SendMessageW(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
4444     expect(0, r);
4445     r = SendMessageA(header, HDM_GETUNICODEFORMAT, 0, 0);
4446     expect(1, r);
4447     DestroyWindow(hwnd);
4448     /* unicode listview with ansi parent window */
4449     notifyFormat = -1;
4450     hwnd = create_listview_controlW(LVS_REPORT, hwndparent);
4451     ok(hwnd != NULL, "failed to create a listview window\n");
4452     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
4453     ok(IsWindow(header), "expected header to be created\n");
4454     r = SendMessageW(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
4455     expect(0, r);
4456     r = SendMessageA(header, HDM_GETUNICODEFORMAT, 0, 0);
4457     expect(1, r);
4458     DestroyWindow(hwnd);
4459     /* unicode listview with ansi parent window, return error code */
4460     notifyFormat = 0;
4461     hwnd = create_listview_controlW(LVS_REPORT, hwndparent);
4462     ok(hwnd != NULL, "failed to create a listview window\n");
4463     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
4464     ok(IsWindow(header), "expected header to be created\n");
4465     r = SendMessageW(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
4466     expect(0, r);
4467     r = SendMessageA(header, HDM_GETUNICODEFORMAT, 0, 0);
4468     expect(1, r);
4469     DestroyWindow(hwnd);
4470 
4471     DestroyWindow(hwndparentW);
4472 }
4473 
4474 static void test_indentation(void)
4475 {
4476     HWND hwnd;
4477     LVITEMA item;
4478     DWORD r;
4479 
4480     hwnd = create_listview_control(LVS_REPORT);
4481     ok(hwnd != NULL, "failed to create a listview window\n");
4482 
4483     memset(&item, 0, sizeof(item));
4484     item.mask = LVIF_INDENT;
4485     item.iItem = 0;
4486     item.iIndent = I_INDENTCALLBACK;
4487     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item);
4488     expect(0, r);
4489 
4490     flush_sequences(sequences, NUM_MSG_SEQUENCES);
4491 
4492     item.iItem = 0;
4493     item.mask = LVIF_INDENT;
4494     r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
4495     expect(TRUE, r);
4496 
4497     ok_sequence(sequences, PARENT_SEQ_INDEX, single_getdispinfo_parent_seq,
4498                 "get indent dispinfo", FALSE);
4499 
4500     DestroyWindow(hwnd);
4501 }
4502 
4503 static INT CALLBACK DummyCompareEx(LPARAM first, LPARAM second, LPARAM param)
4504 {
4505     return 0;
4506 }
4507 
4508 static BOOL is_below_comctl_5(void)
4509 {
4510     HWND hwnd;
4511     BOOL ret;
4512 
4513     hwnd = create_listview_control(LVS_REPORT);
4514     ok(hwnd != NULL, "failed to create a listview window\n");
4515     insert_item(hwnd, 0);
4516 
4517     ret = SendMessageA(hwnd, LVM_SORTITEMSEX, 0, (LPARAM)&DummyCompareEx);
4518 
4519     DestroyWindow(hwnd);
4520 
4521     return !ret;
4522 }
4523 
4524 static void test_get_set_view(void)
4525 {
4526     HWND hwnd;
4527     DWORD ret;
4528     DWORD_PTR style;
4529 
4530     /* test style->view mapping */
4531     hwnd = create_listview_control(LVS_REPORT);
4532     ok(hwnd != NULL, "failed to create a listview window\n");
4533 
4534     ret = SendMessageA(hwnd, LVM_GETVIEW, 0, 0);
4535     expect(LV_VIEW_DETAILS, ret);
4536 
4537     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
4538     /* LVS_ICON == 0 */
4539     SetWindowLongPtrA(hwnd, GWL_STYLE, style & ~LVS_REPORT);
4540     ret = SendMessageA(hwnd, LVM_GETVIEW, 0, 0);
4541     expect(LV_VIEW_ICON, ret);
4542 
4543     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
4544     SetWindowLongPtrA(hwnd, GWL_STYLE, style | LVS_SMALLICON);
4545     ret = SendMessageA(hwnd, LVM_GETVIEW, 0, 0);
4546     expect(LV_VIEW_SMALLICON, ret);
4547 
4548     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
4549     SetWindowLongPtrA(hwnd, GWL_STYLE, (style & ~LVS_SMALLICON) | LVS_LIST);
4550     ret = SendMessageA(hwnd, LVM_GETVIEW, 0, 0);
4551     expect(LV_VIEW_LIST, ret);
4552 
4553     /* switching view doesn't touch window style */
4554     ret = SendMessageA(hwnd, LVM_SETVIEW, LV_VIEW_DETAILS, 0);
4555     expect(1, ret);
4556     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
4557     ok(style & LVS_LIST, "Expected style to be preserved\n");
4558     ret = SendMessageA(hwnd, LVM_SETVIEW, LV_VIEW_ICON, 0);
4559     expect(1, ret);
4560     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
4561     ok(style & LVS_LIST, "Expected style to be preserved\n");
4562     ret = SendMessageA(hwnd, LVM_SETVIEW, LV_VIEW_SMALLICON, 0);
4563     expect(1, ret);
4564     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
4565     ok(style & LVS_LIST, "Expected style to be preserved\n");
4566 
4567     /* now change window style to see if view is remapped */
4568     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
4569     SetWindowLongPtrA(hwnd, GWL_STYLE, style | LVS_SHOWSELALWAYS);
4570     ret = SendMessageA(hwnd, LVM_GETVIEW, 0, 0);
4571     expect(LV_VIEW_SMALLICON, ret);
4572 
4573     DestroyWindow(hwnd);
4574 }
4575 
4576 static void test_canceleditlabel(void)
4577 {
4578     HWND hwnd, hwndedit;
4579     DWORD ret;
4580     CHAR buff[10];
4581     LVITEMA itema;
4582     static CHAR test[] = "test";
4583     static const CHAR test1[] = "test1";
4584 
4585     hwnd = create_listview_control(LVS_EDITLABELS | LVS_REPORT);
4586     ok(hwnd != NULL, "failed to create a listview window\n");
4587 
4588     insert_item(hwnd, 0);
4589 
4590     /* try without edit created */
4591     flush_sequences(sequences, NUM_MSG_SEQUENCES);
4592     ret = SendMessageA(hwnd, LVM_CANCELEDITLABEL, 0, 0);
4593     expect(TRUE, ret);
4594     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq,
4595                 "cancel edit label without edit", FALSE);
4596 
4597     /* cancel without data change */
4598     SetFocus(hwnd);
4599     hwndedit = (HWND)SendMessageA(hwnd, LVM_EDITLABELA, 0, 0);
4600     ok(IsWindow(hwndedit), "Expected edit control to be created\n");
4601     ret = SendMessageA(hwnd, LVM_CANCELEDITLABEL, 0, 0);
4602     expect(TRUE, ret);
4603     ok(!IsWindow(hwndedit), "Expected edit control to be destroyed\n");
4604 
4605     /* cancel after data change */
4606     memset(&itema, 0, sizeof(itema));
4607     itema.pszText = test;
4608     ret = SendMessageA(hwnd, LVM_SETITEMTEXTA, 0, (LPARAM)&itema);
4609     expect(TRUE, ret);
4610     SetFocus(hwnd);
4611     hwndedit = (HWND)SendMessageA(hwnd, LVM_EDITLABELA, 0, 0);
4612     ok(IsWindow(hwndedit), "Expected edit control to be created\n");
4613     ret = SetWindowTextA(hwndedit, test1);
4614     expect(1, ret);
4615     ret = SendMessageA(hwnd, LVM_CANCELEDITLABEL, 0, 0);
4616     expect(TRUE, ret);
4617     ok(!IsWindow(hwndedit), "Expected edit control to be destroyed\n");
4618     memset(&itema, 0, sizeof(itema));
4619     itema.pszText = buff;
4620     itema.cchTextMax = sizeof(buff)/sizeof(CHAR);
4621     ret = SendMessageA(hwnd, LVM_GETITEMTEXTA, 0, (LPARAM)&itema);
4622     expect(5, ret);
4623     ok(strcmp(buff, test1) == 0, "Expected label text not to change\n");
4624 
4625     DestroyWindow(hwnd);
4626 }
4627 
4628 static void test_mapidindex(void)
4629 {
4630     HWND hwnd;
4631     INT ret;
4632 
4633     /* LVM_MAPINDEXTOID unsupported with LVS_OWNERDATA */
4634     hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT);
4635     ok(hwnd != NULL, "failed to create a listview window\n");
4636     insert_item(hwnd, 0);
4637     ret = SendMessageA(hwnd, LVM_MAPINDEXTOID, 0, 0);
4638     expect(-1, ret);
4639     DestroyWindow(hwnd);
4640 
4641     hwnd = create_listview_control(LVS_REPORT);
4642     ok(hwnd != NULL, "failed to create a listview window\n");
4643 
4644     /* LVM_MAPINDEXTOID with invalid index */
4645     ret = SendMessageA(hwnd, LVM_MAPINDEXTOID, 0, 0);
4646     expect(-1, ret);
4647 
4648     insert_item(hwnd, 0);
4649     insert_item(hwnd, 1);
4650 
4651     ret = SendMessageA(hwnd, LVM_MAPINDEXTOID, -1, 0);
4652     expect(-1, ret);
4653     ret = SendMessageA(hwnd, LVM_MAPINDEXTOID, 2, 0);
4654     expect(-1, ret);
4655 
4656     ret = SendMessageA(hwnd, LVM_MAPINDEXTOID, 0, 0);
4657     expect(0, ret);
4658     ret = SendMessageA(hwnd, LVM_MAPINDEXTOID, 1, 0);
4659     expect(1, ret);
4660     /* remove 0 indexed item, id retained */
4661     SendMessageA(hwnd, LVM_DELETEITEM, 0, 0);
4662     ret = SendMessageA(hwnd, LVM_MAPINDEXTOID, 0, 0);
4663     expect(1, ret);
4664     /* new id starts from previous value */
4665     insert_item(hwnd, 1);
4666     ret = SendMessageA(hwnd, LVM_MAPINDEXTOID, 1, 0);
4667     expect(2, ret);
4668 
4669     /* get index by id */
4670     ret = SendMessageA(hwnd, LVM_MAPIDTOINDEX, -1, 0);
4671     expect(-1, ret);
4672     ret = SendMessageA(hwnd, LVM_MAPIDTOINDEX, 0, 0);
4673     expect(-1, ret);
4674     ret = SendMessageA(hwnd, LVM_MAPIDTOINDEX, 1, 0);
4675     expect(0, ret);
4676     ret = SendMessageA(hwnd, LVM_MAPIDTOINDEX, 2, 0);
4677     expect(1, ret);
4678 
4679     DestroyWindow(hwnd);
4680 }
4681 
4682 static void test_getitemspacing(void)
4683 {
4684     HWND hwnd;
4685     DWORD ret;
4686     INT cx, cy;
4687     HIMAGELIST himl40, himl80;
4688 
4689     cx = GetSystemMetrics(SM_CXICONSPACING) - GetSystemMetrics(SM_CXICON);
4690     cy = GetSystemMetrics(SM_CYICONSPACING) - GetSystemMetrics(SM_CYICON);
4691 
4692     /* LVS_ICON */
4693     hwnd = create_listview_control(LVS_ICON);
4694     ret = SendMessageA(hwnd, LVM_GETITEMSPACING, FALSE, 0);
4695     expect(cx, LOWORD(ret));
4696     expect(cy, HIWORD(ret));
4697 
4698     /* now try with icons */
4699     himl40 = ImageList_Create(40, 40, 0, 4, 4);
4700     ok(himl40 != NULL, "failed to create imagelist\n");
4701     himl80 = ImageList_Create(80, 80, 0, 4, 4);
4702     ok(himl80 != NULL, "failed to create imagelist\n");
4703     ret = SendMessageA(hwnd, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)himl40);
4704     expect(0, ret);
4705 
4706     ret = SendMessageA(hwnd, LVM_GETITEMSPACING, FALSE, 0);
4707     /* spacing + icon size returned */
4708     expect(cx + 40, LOWORD(ret));
4709     expect(cy + 40, HIWORD(ret));
4710     /* try changing icon size */
4711     SendMessageA(hwnd, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)himl80);
4712 
4713     ret = SendMessageA(hwnd, LVM_GETITEMSPACING, FALSE, 0);
4714     /* spacing + icon size returned */
4715     expect(cx + 80, LOWORD(ret));
4716     expect(cy + 80, HIWORD(ret));
4717 
4718     /* set own icon spacing */
4719     ret = SendMessageA(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(100, 100));
4720     expect(cx + 80, LOWORD(ret));
4721     expect(cy + 80, HIWORD(ret));
4722 
4723     ret = SendMessageA(hwnd, LVM_GETITEMSPACING, FALSE, 0);
4724     /* set size returned */
4725     expect(100, LOWORD(ret));
4726     expect(100, HIWORD(ret));
4727 
4728     /* now change image list - icon spacing should be unaffected */
4729     SendMessageA(hwnd, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)himl40);
4730 
4731     ret = SendMessageA(hwnd, LVM_GETITEMSPACING, FALSE, 0);
4732     /* set size returned */
4733     expect(100, LOWORD(ret));
4734     expect(100, HIWORD(ret));
4735 
4736     /* spacing = 0 - keep previous value */
4737     ret = SendMessageA(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(0, -1));
4738     expect(100, LOWORD(ret));
4739     expect(100, HIWORD(ret));
4740 
4741     ret = SendMessageA(hwnd, LVM_GETITEMSPACING, FALSE, 0);
4742     expect(100, LOWORD(ret));
4743 
4744     expect(0xFFFF, HIWORD(ret));
4745 
4746     if (sizeof(void*) == 8)
4747     {
4748         /* NOTE: -1 is not treated the same as (DWORD)-1 by 64bit listview */
4749         ret = SendMessageA(hwnd, LVM_SETICONSPACING, 0, (DWORD)-1);
4750         expect(100, LOWORD(ret));
4751         expect(0xFFFF, HIWORD(ret));
4752 
4753         ret = SendMessageA(hwnd, LVM_SETICONSPACING, 0, -1);
4754         expect(0xFFFF, LOWORD(ret));
4755         expect(0xFFFF, HIWORD(ret));
4756     }
4757     else
4758     {
4759         ret = SendMessageA(hwnd, LVM_SETICONSPACING, 0, -1);
4760         expect(100, LOWORD(ret));
4761         expect(0xFFFF, HIWORD(ret));
4762     }
4763     ret = SendMessageA(hwnd, LVM_GETITEMSPACING, FALSE, 0);
4764     /* spacing + icon size returned */
4765     expect(cx + 40, LOWORD(ret));
4766     expect(cy + 40, HIWORD(ret));
4767 
4768     SendMessageA(hwnd, LVM_SETIMAGELIST, LVSIL_NORMAL, 0);
4769     ImageList_Destroy(himl80);
4770     DestroyWindow(hwnd);
4771     /* LVS_SMALLICON */
4772     hwnd = create_listview_control(LVS_SMALLICON);
4773     ret = SendMessageA(hwnd, LVM_GETITEMSPACING, FALSE, 0);
4774     expect(cx, LOWORD(ret));
4775     expect(cy, HIWORD(ret));
4776 
4777     /* spacing does not depend on selected view type */
4778     ret = SendMessageA(hwnd, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)himl40);
4779     expect(0, ret);
4780 
4781     ret = SendMessageA(hwnd, LVM_GETITEMSPACING, FALSE, 0);
4782     /* spacing + icon size returned */
4783     expect(cx + 40, LOWORD(ret));
4784     expect(cy + 40, HIWORD(ret));
4785 
4786     SendMessageA(hwnd, LVM_SETIMAGELIST, LVSIL_NORMAL, 0);
4787     ImageList_Destroy(himl40);
4788     DestroyWindow(hwnd);
4789     /* LVS_REPORT */
4790     hwnd = create_listview_control(LVS_REPORT);
4791     ret = SendMessageA(hwnd, LVM_GETITEMSPACING, FALSE, 0);
4792     expect(cx, LOWORD(ret));
4793     expect(cy, HIWORD(ret));
4794 
4795     DestroyWindow(hwnd);
4796     /* LVS_LIST */
4797     hwnd = create_listview_control(LVS_LIST);
4798     ret = SendMessageA(hwnd, LVM_GETITEMSPACING, FALSE, 0);
4799     expect(cx, LOWORD(ret));
4800     expect(cy, HIWORD(ret));
4801 
4802     DestroyWindow(hwnd);
4803 }
4804 
4805 static INT get_current_font_height(HWND listview)
4806 {
4807     TEXTMETRICA tm;
4808     HFONT hfont;
4809     HWND hwnd;
4810     HDC hdc;
4811 
4812     hwnd = (HWND)SendMessageA(listview, LVM_GETHEADER, 0, 0);
4813     if (!hwnd)
4814         hwnd = listview;
4815 
4816     hfont = (HFONT)SendMessageA(hwnd, WM_GETFONT, 0, 0);
4817     if (!hfont) {
4818         hdc = GetDC(hwnd);
4819         GetTextMetricsA(hdc, &tm);
4820         ReleaseDC(hwnd, hdc);
4821     }
4822     else {
4823         HFONT oldfont;
4824 
4825         hdc = GetDC(0);
4826         oldfont = SelectObject(hdc, hfont);
4827         GetTextMetricsA(hdc, &tm);
4828         SelectObject(hdc, oldfont);
4829         ReleaseDC(0, hdc);
4830     }
4831 
4832     return tm.tmHeight;
4833 }
4834 
4835 static void test_getcolumnwidth(void)
4836 {
4837     HWND hwnd;
4838     INT ret;
4839     DWORD_PTR style;
4840     LVCOLUMNA col;
4841     LVITEMA itema;
4842     INT height;
4843 
4844     /* default column width */
4845     hwnd = create_listview_control(LVS_ICON);
4846     ret = SendMessageA(hwnd, LVM_GETCOLUMNWIDTH, 0, 0);
4847     expect(0, ret);
4848     style = GetWindowLongA(hwnd, GWL_STYLE);
4849     SetWindowLongA(hwnd, GWL_STYLE, style | LVS_LIST);
4850     ret = SendMessageA(hwnd, LVM_GETCOLUMNWIDTH, 0, 0);
4851     todo_wine expect(8, ret);
4852     style = GetWindowLongA(hwnd, GWL_STYLE) & ~LVS_LIST;
4853     SetWindowLongA(hwnd, GWL_STYLE, style | LVS_REPORT);
4854     col.mask = 0;
4855     ret = SendMessageA(hwnd, LVM_INSERTCOLUMNA, 0, (LPARAM)&col);
4856     expect(0, ret);
4857     ret = SendMessageA(hwnd, LVM_GETCOLUMNWIDTH, 0, 0);
4858     expect(10, ret);
4859     DestroyWindow(hwnd);
4860 
4861     /* default column width with item added */
4862     hwnd = create_listview_control(LVS_LIST);
4863     memset(&itema, 0, sizeof(itema));
4864     ret = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&itema);
4865     ok(!ret, "got %d\n", ret);
4866     ret = SendMessageA(hwnd, LVM_GETCOLUMNWIDTH, 0, 0);
4867     height = get_current_font_height(hwnd);
4868     ok((ret / height) >= 6, "got width %d, height %d\n", ret, height);
4869     DestroyWindow(hwnd);
4870 }
4871 
4872 static void test_scrollnotify(void)
4873 {
4874     HWND hwnd;
4875     DWORD ret;
4876 
4877     hwnd = create_listview_control(LVS_REPORT);
4878 
4879     insert_column(hwnd, 0);
4880     insert_column(hwnd, 1);
4881     insert_item(hwnd, 0);
4882 
4883     /* make it scrollable - resize */
4884     ret = SendMessageA(hwnd, LVM_SETCOLUMNWIDTH, 0, MAKELPARAM(100, 0));
4885     expect(TRUE, ret);
4886     ret = SendMessageA(hwnd, LVM_SETCOLUMNWIDTH, 1, MAKELPARAM(100, 0));
4887     expect(TRUE, ret);
4888 
4889     /* try with dummy call */
4890     flush_sequences(sequences, NUM_MSG_SEQUENCES);
4891     ret = SendMessageA(hwnd, LVM_SCROLL, 0, 0);
4892     expect(TRUE, ret);
4893     ok_sequence(sequences, PARENT_SEQ_INDEX, scroll_parent_seq,
4894                 "scroll notify 1", TRUE);
4895 
4896     flush_sequences(sequences, NUM_MSG_SEQUENCES);
4897     ret = SendMessageA(hwnd, LVM_SCROLL, 1, 0);
4898     expect(TRUE, ret);
4899     ok_sequence(sequences, PARENT_SEQ_INDEX, scroll_parent_seq,
4900                 "scroll notify 2", TRUE);
4901 
4902     flush_sequences(sequences, NUM_MSG_SEQUENCES);
4903     ret = SendMessageA(hwnd, LVM_SCROLL, 1, 1);
4904     expect(TRUE, ret);
4905     ok_sequence(sequences, PARENT_SEQ_INDEX, scroll_parent_seq,
4906                 "scroll notify 3", TRUE);
4907 
4908     DestroyWindow(hwnd);
4909 }
4910 
4911 static void test_LVS_EX_TRANSPARENTBKGND(void)
4912 {
4913     HWND hwnd;
4914     DWORD ret;
4915     HDC hdc;
4916 
4917     hwnd = create_listview_control(LVS_REPORT);
4918 
4919     ret = SendMessageA(hwnd, LVM_SETBKCOLOR, 0, RGB(0, 0, 0));
4920     expect(TRUE, ret);
4921 
4922     SendMessageA(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_TRANSPARENTBKGND,
4923                                                     LVS_EX_TRANSPARENTBKGND);
4924 
4925     ret = SendMessageA(hwnd, LVM_GETBKCOLOR, 0, 0);
4926     if (ret != CLR_NONE)
4927     {
4928         win_skip("LVS_EX_TRANSPARENTBKGND unsupported\n");
4929         DestroyWindow(hwnd);
4930         return;
4931     }
4932 
4933     /* try to set some back color and check this style bit */
4934     ret = SendMessageA(hwnd, LVM_SETBKCOLOR, 0, RGB(0, 0, 0));
4935     expect(TRUE, ret);
4936     ret = SendMessageA(hwnd, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
4937     ok(!(ret & LVS_EX_TRANSPARENTBKGND), "Expected LVS_EX_TRANSPARENTBKGND to unset\n");
4938 
4939     /* now test what this style actually does */
4940     SendMessageA(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_TRANSPARENTBKGND,
4941                                                     LVS_EX_TRANSPARENTBKGND);
4942 
4943     hdc = GetWindowDC(hwndparent);
4944 
4945     flush_sequences(sequences, NUM_MSG_SEQUENCES);
4946     SendMessageA(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0);
4947     ok_sequence(sequences, PARENT_SEQ_INDEX, lvs_ex_transparentbkgnd_seq,
4948                 "LVS_EX_TRANSPARENTBKGND parent", FALSE);
4949 
4950     ReleaseDC(hwndparent, hdc);
4951 
4952     DestroyWindow(hwnd);
4953 }
4954 
4955 static void test_approximate_viewrect(void)
4956 {
4957     static CHAR test[] = "abracadabra, a very long item label";
4958     DWORD item_width, item_height, header_height;
4959     static CHAR column_header[] = "Header";
4960     unsigned const column_width = 100;
4961     DWORD ret, item_count;
4962     HIMAGELIST himl;
4963     LVITEMA itema;
4964     LVCOLUMNA col;
4965     HBITMAP hbmp;
4966     HWND hwnd;
4967 
4968     /* LVS_ICON */
4969     hwnd = create_listview_control(LVS_ICON);
4970     himl = ImageList_Create(40, 40, 0, 4, 4);
4971     ok(himl != NULL, "failed to create imagelist\n");
4972     hbmp = CreateBitmap(40, 40, 1, 1, NULL);
4973     ok(hbmp != NULL, "failed to create bitmap\n");
4974     ret = ImageList_Add(himl, hbmp, 0);
4975     expect(0, ret);
4976     ret = SendMessageA(hwnd, LVM_SETIMAGELIST, 0, (LPARAM)himl);
4977     expect(0, ret);
4978 
4979     itema.mask = LVIF_IMAGE;
4980     itema.iImage = 0;
4981     itema.iItem = 0;
4982     itema.iSubItem = 0;
4983     ret = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&itema);
4984     expect(0, ret);
4985 
4986     ret = SendMessageA(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(75, 75));
4987     ok(ret != 0, "Unexpected return value %#x.\n", ret);
4988 
4989     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 11, MAKELPARAM(100,100));
4990     expect(MAKELONG(77,827), ret);
4991 
4992     ret = SendMessageA(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(50, 50));
4993     ok(ret != 0, "got 0\n");
4994 
4995     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 11, MAKELPARAM(100,100));
4996     expect(MAKELONG(102,302), ret);
4997 
4998     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, -1, MAKELPARAM(100,100));
4999     expect(MAKELONG(52,52), ret);
5000 
5001     itema.pszText = test;
5002     ret = SendMessageA(hwnd, LVM_SETITEMTEXTA, 0, (LPARAM)&itema);
5003     expect(TRUE, ret);
5004     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, -1, MAKELPARAM(100,100));
5005     expect(MAKELONG(52,52), ret);
5006 
5007     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 0, MAKELPARAM(100,100));
5008     expect(MAKELONG(52,2), ret);
5009     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 1, MAKELPARAM(100,100));
5010     expect(MAKELONG(52,52), ret);
5011     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 2, MAKELPARAM(100,100));
5012     expect(MAKELONG(102,52), ret);
5013     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 3, MAKELPARAM(100,100));
5014     expect(MAKELONG(102,102), ret);
5015     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 4, MAKELPARAM(100,100));
5016     expect(MAKELONG(102,102), ret);
5017     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 5, MAKELPARAM(100,100));
5018     expect(MAKELONG(102,152), ret);
5019     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 6, MAKELPARAM(100,100));
5020     expect(MAKELONG(102,152), ret);
5021     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 7, MAKELPARAM(160,100));
5022     expect(MAKELONG(152,152), ret);
5023 
5024     DestroyWindow(hwnd);
5025 
5026     /* LVS_REPORT */
5027     hwnd = create_listview_control(LVS_REPORT);
5028 
5029     /* Empty control without columns */
5030     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 0, MAKELPARAM(100, 100));
5031 todo_wine
5032     ok(LOWORD(ret) == 0, "Unexpected width %d.\n", LOWORD(ret));
5033     ok(HIWORD(ret) != 0, "Unexpected height %d.\n", HIWORD(ret));
5034 
5035     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 0, 0);
5036     ok(LOWORD(ret) == 0, "Unexpected width %d.\n", LOWORD(ret));
5037 todo_wine
5038     ok(HIWORD(ret) != 0, "Unexpected height %d.\n", HIWORD(ret));
5039 
5040     header_height = HIWORD(ret);
5041 
5042     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 1, 0);
5043     ok(LOWORD(ret) == 0, "Unexpected width %d.\n", LOWORD(ret));
5044 todo_wine
5045     ok(HIWORD(ret) > header_height, "Unexpected height %d.\n", HIWORD(ret));
5046 
5047     item_height = HIWORD(ret) - header_height;
5048 
5049     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, -2, 0);
5050     ok(LOWORD(ret) == 0, "Unexpected width %d.\n", LOWORD(ret));
5051     ok(HIWORD(ret) == (header_height - 2 * item_height), "Unexpected height %d.\n", HIWORD(ret)) ;
5052 
5053     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, -1, 0);
5054     ok(LOWORD(ret) == 0, "Unexpected width %d.\n", LOWORD(ret));
5055     ok(HIWORD(ret) == header_height, "Unexpected height.\n");
5056     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 2, 0);
5057     ok(LOWORD(ret) == 0, "Unexpected width %d.\n", LOWORD(ret));
5058     ok(HIWORD(ret) == header_height + 2 * item_height, "Unexpected height %d.\n", HIWORD(ret));
5059 
5060     /* Insert column */
5061     col.mask = LVCF_TEXT | LVCF_WIDTH;
5062     col.pszText = column_header;
5063     col.cx = column_width;
5064     ret = SendMessageA(hwnd, LVM_INSERTCOLUMNA, 0, (LPARAM)&col);
5065     ok(ret == 0, "Unexpected return value %d.\n", ret);
5066 
5067     /* Empty control with column */
5068     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 0, 0);
5069 todo_wine {
5070     ok(LOWORD(ret) >= column_width, "Unexpected width %d.\n", LOWORD(ret));
5071     ok(HIWORD(ret) != 0, "Unexpected height %d.\n", HIWORD(ret));
5072 }
5073     header_height = HIWORD(ret);
5074     item_width = LOWORD(ret);
5075 
5076     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 1, 0);
5077     ok(LOWORD(ret) == item_width, "Unexpected width %d.\n", LOWORD(ret));
5078 todo_wine
5079     ok(HIWORD(ret) > header_height, "Unexpected height %d.\n", HIWORD(ret));
5080 
5081     item_height = HIWORD(ret) - header_height;
5082 
5083     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, -2, 0);
5084     ok(LOWORD(ret) == item_width, "Unexpected width %d.\n", LOWORD(ret));
5085     ok(HIWORD(ret) == header_height - 2 * item_height, "Unexpected height %d.\n", HIWORD(ret));
5086 
5087     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, -1, 0);
5088     ok(LOWORD(ret) == item_width, "Unexpected width %d.\n", LOWORD(ret));
5089     ok(HIWORD(ret) == header_height, "Unexpected height %d.\n", HIWORD(ret));
5090 
5091     ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 2, 0);
5092     ok(LOWORD(ret) == item_width, "Unexpected width %d.\n", LOWORD(ret));
5093     ok(HIWORD(ret) == header_height + 2 * item_height, "Unexpected height %d.\n", HIWORD(ret));
5094 
5095     for (item_count = 1; item_count <= 2; ++item_count)
5096     {
5097         itema.mask = LVIF_TEXT;
5098         itema.iItem = 0;
5099         itema.iSubItem = 0;
5100         itema.pszText = test;
5101         ret = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&itema);
5102         ok(ret == 0, "Unexpected return value %d.\n", ret);
5103 
5104         ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 0, 0);
5105         ok(LOWORD(ret) >= column_width, "Unexpected width %d.\n", LOWORD(ret));
5106     todo_wine
5107         ok(HIWORD(ret) != 0, "Unexpected height %d.\n", HIWORD(ret));
5108 
5109         header_height = HIWORD(ret);
5110         item_width = LOWORD(ret);
5111 
5112         ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 1, 0);
5113         ok(LOWORD(ret) == item_width, "Unexpected width %d, item %d\n", LOWORD(ret), item_count - 1);
5114         ok(HIWORD(ret) > header_height, "Unexpected height %d. item %d.\n", HIWORD(ret),  item_count - 1);
5115 
5116         item_height = HIWORD(ret) - header_height;
5117 
5118         ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, -2, 0);
5119         ok(LOWORD(ret) == item_width, "Unexpected width %d.\n", LOWORD(ret));
5120     todo_wine
5121         ok(HIWORD(ret) == header_height - 2 * item_height, "Unexpected height %d.\n", HIWORD(ret));
5122 
5123         ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, -1, 0);
5124         ok(LOWORD(ret) == item_width, "Unexpected width %d.\n", LOWORD(ret));
5125         ok(HIWORD(ret) == header_height + item_count * item_height, "Unexpected height %d.\n", HIWORD(ret));
5126 
5127         ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 2, 0);
5128         ok(LOWORD(ret) == item_width, "Unexpected width %d.\n", LOWORD(ret));
5129         ok(HIWORD(ret) == header_height + 2 * item_height, "Unexpected height %d.\n", HIWORD(ret));
5130 
5131         ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 2, MAKELONG(item_width * 2, header_height + 3 * item_height));
5132         ok(LOWORD(ret) == item_width, "Unexpected width %d.\n", LOWORD(ret));
5133         ok(HIWORD(ret) == header_height + 2 * item_height, "Unexpected height %d.\n", HIWORD(ret));
5134 
5135         ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, -2, MAKELONG(item_width * 2, 0));
5136         ok(LOWORD(ret) == item_width, "Unexpected width %d.\n", LOWORD(ret));
5137     todo_wine
5138         ok(HIWORD(ret) == header_height - 2 * item_height, "Unexpected height %d.\n", HIWORD(ret));
5139 
5140         ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, -2, MAKELONG(-1, -1));
5141         ok(LOWORD(ret) == item_width, "Unexpected width %d.\n", LOWORD(ret));
5142     todo_wine
5143         ok(HIWORD(ret) == header_height - 2 * item_height, "Unexpected height %d.\n", HIWORD(ret));
5144     }
5145 
5146     DestroyWindow(hwnd);
5147 
5148 }
5149 
5150 static void test_finditem(void)
5151 {
5152     LVFINDINFOA fi;
5153     static char f[5];
5154     HWND hwnd;
5155     INT r;
5156 
5157     hwnd = create_listview_control(LVS_REPORT);
5158     insert_item(hwnd, 0);
5159 
5160     memset(&fi, 0, sizeof(fi));
5161 
5162     /* full string search, inserted text was "foo" */
5163     strcpy(f, "foo");
5164     fi.flags = LVFI_STRING;
5165     fi.psz = f;
5166     r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi);
5167     expect(0, r);
5168 
5169     fi.flags = LVFI_STRING | LVFI_PARTIAL;
5170     r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi);
5171     expect(0, r);
5172 
5173     fi.flags = LVFI_PARTIAL;
5174     r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi);
5175     expect(0, r);
5176 
5177     /* partial string search, inserted text was "foo" */
5178     strcpy(f, "fo");
5179     fi.flags = LVFI_STRING | LVFI_PARTIAL;
5180     fi.psz = f;
5181     r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi);
5182     expect(0, r);
5183 
5184     fi.flags = LVFI_STRING;
5185     r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi);
5186     expect(-1, r);
5187 
5188     fi.flags = LVFI_PARTIAL;
5189     r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi);
5190     expect(0, r);
5191 
5192     /* partial string search, part after start char */
5193     strcpy(f, "oo");
5194     fi.flags = LVFI_STRING | LVFI_PARTIAL;
5195     fi.psz = f;
5196     r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi);
5197     expect(-1, r);
5198 
5199     /* try with LVFI_SUBSTRING */
5200     strcpy(f, "fo");
5201     fi.flags = LVFI_SUBSTRING;
5202     fi.psz = f;
5203     r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi);
5204     expect(0, r);
5205     strcpy(f, "f");
5206     fi.flags = LVFI_SUBSTRING;
5207     fi.psz = f;
5208     r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi);
5209     expect(0, r);
5210     strcpy(f, "o");
5211     fi.flags = LVFI_SUBSTRING;
5212     fi.psz = f;
5213     r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi);
5214     expect(-1, r);
5215 
5216     strcpy(f, "o");
5217     fi.flags = LVFI_SUBSTRING | LVFI_PARTIAL;
5218     fi.psz = f;
5219     r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi);
5220     expect(-1, r);
5221 
5222     strcpy(f, "f");
5223     fi.flags = LVFI_SUBSTRING | LVFI_STRING;
5224     fi.psz = f;
5225     r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi);
5226     expect(0, r);
5227 
5228     fi.flags = LVFI_SUBSTRING | LVFI_PARTIAL;
5229     r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi);
5230     expect(0, r);
5231 
5232     DestroyWindow(hwnd);
5233 }
5234 
5235 static void test_LVS_EX_HEADERINALLVIEWS(void)
5236 {
5237     HWND hwnd, header;
5238     DWORD style;
5239 
5240     hwnd = create_listview_control(LVS_ICON);
5241 
5242     SendMessageA(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_HEADERINALLVIEWS,
5243                                                     LVS_EX_HEADERINALLVIEWS);
5244 
5245     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
5246     if (!IsWindow(header))
5247     {
5248         win_skip("LVS_EX_HEADERINALLVIEWS unsupported\n");
5249         DestroyWindow(hwnd);
5250         return;
5251     }
5252 
5253     /* LVS_NOCOLUMNHEADER works as before */
5254     style = GetWindowLongA(hwnd, GWL_STYLE);
5255     SetWindowLongW(hwnd, GWL_STYLE, style | LVS_NOCOLUMNHEADER);
5256     style = GetWindowLongA(header, GWL_STYLE);
5257     ok(style & HDS_HIDDEN, "Expected HDS_HIDDEN\n");
5258     style = GetWindowLongA(hwnd, GWL_STYLE);
5259     SetWindowLongW(hwnd, GWL_STYLE, style & ~LVS_NOCOLUMNHEADER);
5260     style = GetWindowLongA(header, GWL_STYLE);
5261     ok(!(style & HDS_HIDDEN), "Expected HDS_HIDDEN to be unset\n");
5262 
5263     /* try to remove style */
5264     SendMessageA(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_HEADERINALLVIEWS, 0);
5265     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
5266     ok(IsWindow(header), "Expected header to be created\n");
5267     style = GetWindowLongA(header, GWL_STYLE);
5268     ok(!(style & HDS_HIDDEN), "HDS_HIDDEN not expected\n");
5269 
5270     DestroyWindow(hwnd);
5271 
5272     /* check other styles */
5273     hwnd = create_listview_control(LVS_LIST);
5274     SendMessageA(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_HEADERINALLVIEWS,
5275                                                     LVS_EX_HEADERINALLVIEWS);
5276     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
5277     ok(IsWindow(header), "Expected header to be created\n");
5278     DestroyWindow(hwnd);
5279 
5280     hwnd = create_listview_control(LVS_SMALLICON);
5281     SendMessageA(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_HEADERINALLVIEWS,
5282                                                     LVS_EX_HEADERINALLVIEWS);
5283     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
5284     ok(IsWindow(header), "Expected header to be created\n");
5285     DestroyWindow(hwnd);
5286 
5287     hwnd = create_listview_control(LVS_REPORT);
5288     SendMessageA(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_HEADERINALLVIEWS,
5289                                                     LVS_EX_HEADERINALLVIEWS);
5290     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
5291     ok(IsWindow(header), "Expected header to be created\n");
5292     DestroyWindow(hwnd);
5293 }
5294 
5295 static void test_hover(void)
5296 {
5297     HWND hwnd, fg;
5298     DWORD r;
5299 
5300     hwnd = create_listview_control(LVS_ICON);
5301     SetForegroundWindow(hwndparent);
5302     fg = GetForegroundWindow();
5303     if (fg != hwndparent)
5304     {
5305         skip("Window is not in the foreground. Skipping hover tests.\n");
5306         DestroyWindow(hwnd);
5307         return;
5308     }
5309 
5310     /* test WM_MOUSEHOVER forwarding */
5311     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5312     r = SendMessageA(hwnd, WM_MOUSEHOVER, 0, 0);
5313     expect(0, r);
5314     ok_sequence(sequences, PARENT_SEQ_INDEX, hover_parent, "NM_HOVER allow test", TRUE);
5315     g_block_hover = TRUE;
5316     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5317     r = SendMessageA(hwnd, WM_MOUSEHOVER, 0, 0);
5318     expect(0, r);
5319     ok_sequence(sequences, PARENT_SEQ_INDEX, hover_parent, "NM_HOVER block test", TRUE);
5320     g_block_hover = FALSE;
5321 
5322     r = SendMessageA(hwnd, LVM_SETHOVERTIME, 0, 500);
5323     expect(HOVER_DEFAULT, r);
5324     r = SendMessageA(hwnd, LVM_GETHOVERTIME, 0, 0);
5325     expect(500, r);
5326 
5327     DestroyWindow(hwnd);
5328 }
5329 
5330 static void test_destroynotify(void)
5331 {
5332     HWND hwnd;
5333     BOOL ret;
5334 
5335     hwnd = create_listview_control(LVS_REPORT);
5336     ok(hwnd != NULL, "failed to create listview window\n");
5337 
5338     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5339     DestroyWindow(hwnd);
5340     ok_sequence(sequences, COMBINED_SEQ_INDEX, listview_destroy, "check destroy order", FALSE);
5341 
5342     /* same for ownerdata list */
5343     hwnd = create_listview_control(LVS_REPORT|LVS_OWNERDATA);
5344     ok(hwnd != NULL, "failed to create listview window\n");
5345 
5346     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5347     DestroyWindow(hwnd);
5348     ok_sequence(sequences, COMBINED_SEQ_INDEX, listview_ownerdata_destroy, "check destroy order, ownerdata", FALSE);
5349 
5350     hwnd = create_listview_control(LVS_REPORT|LVS_OWNERDATA);
5351     ok(hwnd != NULL, "failed to create listview window\n");
5352 
5353     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5354     ret = SendMessageA(hwnd, LVM_DELETEALLITEMS, 0, 0);
5355     ok(ret == TRUE, "got %d\n", ret);
5356     ok_sequence(sequences, COMBINED_SEQ_INDEX, listview_ownerdata_deleteall, "deleteall ownerdata", FALSE);
5357     DestroyWindow(hwnd);
5358 }
5359 
5360 static void test_header_notification(void)
5361 {
5362     static char textA[] = "newtext";
5363     HWND list, header;
5364     HDITEMA item;
5365     NMHEADERA nmh;
5366     LVCOLUMNA col;
5367     DWORD ret;
5368     BOOL r;
5369 
5370     list = create_listview_control(LVS_REPORT);
5371     ok(list != NULL, "failed to create listview window\n");
5372 
5373     memset(&col, 0, sizeof(col));
5374     col.mask = LVCF_WIDTH;
5375     col.cx = 100;
5376     ret = SendMessageA(list, LVM_INSERTCOLUMNA, 0, (LPARAM)&col);
5377     expect(0, ret);
5378 
5379     /* check list parent notification after header item changed,
5380        this test should be placed before header subclassing to avoid
5381        Listview -> Header messages to be logged */
5382     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5383 
5384     col.mask = LVCF_TEXT;
5385     col.pszText = textA;
5386     r = SendMessageA(list, LVM_SETCOLUMNA, 0, (LPARAM)&col);
5387     expect(TRUE, r);
5388 
5389     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_header_changed_seq,
5390                 "header notify, listview", FALSE);
5391     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq,
5392                 "header notify, parent", FALSE);
5393 
5394     header = subclass_header(list);
5395 
5396     ret = SendMessageA(header, HDM_GETITEMCOUNT, 0, 0);
5397     expect(1, ret);
5398 
5399     memset(&item, 0, sizeof(item));
5400     item.mask = HDI_WIDTH;
5401     ret = SendMessageA(header, HDM_GETITEMA, 0, (LPARAM)&item);
5402     expect(1, ret);
5403     expect(100, item.cxy);
5404 
5405     nmh.hdr.hwndFrom = header;
5406     nmh.hdr.idFrom = GetWindowLongPtrA(header, GWLP_ID);
5407     nmh.hdr.code = HDN_ITEMCHANGEDA;
5408     nmh.iItem = 0;
5409     nmh.iButton = 0;
5410     item.mask = HDI_WIDTH;
5411     item.cxy = 50;
5412     nmh.pitem = &item;
5413     ret = SendMessageA(list, WM_NOTIFY, 0, (LPARAM)&nmh);
5414     expect(0, ret);
5415 
5416     DestroyWindow(list);
5417 }
5418 
5419 static void test_header_notification2(void)
5420 {
5421     static char textA[] = "newtext";
5422     HWND list, header;
5423     HDITEMW itemW;
5424     NMHEADERW nmhdr;
5425     LVCOLUMNA col;
5426     DWORD ret;
5427     WCHAR buffer[100];
5428     struct message parent_header_notify_seq[] = {
5429         { WM_NOTIFY, sent|id, 0, 0, 0 },
5430         { 0 }
5431     };
5432 
5433     list = create_listview_control(LVS_REPORT);
5434     ok(list != NULL, "failed to create listview window\n");
5435 
5436     memset(&col, 0, sizeof(col));
5437     col.mask = LVCF_WIDTH | LVCF_TEXT;
5438     col.cx = 100;
5439     col.pszText = textA;
5440     ret = SendMessageA(list, LVM_INSERTCOLUMNA, 0, (LPARAM)&col);
5441     expect(0, ret);
5442 
5443     header = (HWND)SendMessageA(list, LVM_GETHEADER, 0, 0);
5444     ok(header != 0, "No header\n");
5445     memset(&itemW, 0, sizeof(itemW));
5446     itemW.mask = HDI_WIDTH | HDI_ORDER | HDI_TEXT;
5447     itemW.pszText = buffer;
5448     itemW.cchTextMax = sizeof(buffer);
5449     ret = SendMessageW(header, HDM_GETITEMW, 0, (LPARAM)&itemW);
5450     expect(1, ret);
5451 
5452     nmhdr.hdr.hwndFrom = header;
5453     nmhdr.hdr.idFrom = GetWindowLongPtrW(header, GWLP_ID);
5454     nmhdr.iItem = 0;
5455     nmhdr.iButton = 0;
5456     nmhdr.pitem = &itemW;
5457 
5458     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5459     nmhdr.hdr.code = HDN_ITEMCHANGINGW;
5460     ret = SendMessageW(list, WM_NOTIFY, 0, (LPARAM)&nmhdr);
5461     ok(ret == 0, "got %d\n", ret);
5462     parent_header_notify_seq[0].id = HDN_ITEMCHANGINGA;
5463     ok_sequence(sequences, PARENT_SEQ_INDEX, parent_header_notify_seq,
5464                 "header notify, parent", TRUE);
5465     todo_wine
5466     ok(nmhdr.hdr.code == HDN_ITEMCHANGINGA, "Expected ANSI notification code\n");
5467     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5468     nmhdr.hdr.code = HDN_ITEMCHANGEDW;
5469     ret = SendMessageW(list, WM_NOTIFY, 0, (LPARAM)&nmhdr);
5470     ok(ret == 0, "got %d\n", ret);
5471     parent_header_notify_seq[0].id = HDN_ITEMCHANGEDA;
5472     ok_sequence(sequences, PARENT_SEQ_INDEX, parent_header_notify_seq,
5473                 "header notify, parent", TRUE);
5474     todo_wine
5475     ok(nmhdr.hdr.code == HDN_ITEMCHANGEDA, "Expected ANSI notification code\n");
5476     /* HDN_ITEMCLICK sets focus to list, which generates messages we don't want to check */
5477     SetFocus(list);
5478     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5479     nmhdr.hdr.code = HDN_ITEMCLICKW;
5480     ret = SendMessageW(list, WM_NOTIFY, 0, (LPARAM)&nmhdr);
5481     ok(ret == 0, "got %d\n", ret);
5482     ok_sequence(sequences, PARENT_SEQ_INDEX, parent_header_click_seq,
5483                 "header notify, parent", FALSE);
5484     ok(nmhdr.hdr.code == HDN_ITEMCLICKA, "Expected ANSI notification code\n");
5485     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5486     nmhdr.hdr.code = HDN_ITEMDBLCLICKW;
5487     ret = SendMessageW(list, WM_NOTIFY, 0, (LPARAM)&nmhdr);
5488     ok(ret == 0, "got %d\n", ret);
5489     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq,
5490                 "header notify, parent", FALSE);
5491     ok(nmhdr.hdr.code == HDN_ITEMDBLCLICKW, "Expected Unicode notification code\n");
5492     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5493     nmhdr.hdr.code = HDN_DIVIDERDBLCLICKW;
5494     ret = SendMessageW(list, WM_NOTIFY, 0, (LPARAM)&nmhdr);
5495     ok(ret == 0, "got %d\n", ret);
5496     ok_sequence(sequences, PARENT_SEQ_INDEX, parent_header_divider_dclick_seq,
5497                 "header notify, parent", TRUE);
5498     ok(nmhdr.hdr.code == HDN_DIVIDERDBLCLICKA, "Expected ANSI notification code\n");
5499     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5500     nmhdr.hdr.code = HDN_BEGINTRACKW;
5501     ret = SendMessageW(list, WM_NOTIFY, 0, (LPARAM)&nmhdr);
5502     ok(ret == 0, "got %d\n", ret);
5503     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq,
5504                 "header notify, parent", FALSE);
5505     ok(nmhdr.hdr.code == HDN_BEGINTRACKW, "Expected Unicode notification code\n");
5506     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5507     nmhdr.hdr.code = HDN_ENDTRACKW;
5508     ret = SendMessageW(list, WM_NOTIFY, 0, (LPARAM)&nmhdr);
5509     ok(ret == 0, "got %d\n", ret);
5510     parent_header_notify_seq[0].id = HDN_ENDTRACKA;
5511     ok_sequence(sequences, PARENT_SEQ_INDEX, parent_header_notify_seq,
5512                 "header notify, parent", FALSE);
5513     ok(nmhdr.hdr.code == HDN_ENDTRACKA, "Expected ANSI notification code\n");
5514     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5515     nmhdr.hdr.code = HDN_TRACKW;
5516     ret = SendMessageW(list, WM_NOTIFY, 0, (LPARAM)&nmhdr);
5517     ok(ret == 0, "got %d\n", ret);
5518     parent_header_notify_seq[0].id = HDN_TRACKA;
5519     ok_sequence(sequences, PARENT_SEQ_INDEX, parent_header_notify_seq,
5520                 "header notify, parent", FALSE);
5521     ok(nmhdr.hdr.code == HDN_TRACKA, "Expected ANSI notification code\n");
5522     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5523     nmhdr.hdr.code = HDN_BEGINDRAG;
5524     ret = SendMessageW(list, WM_NOTIFY, 0, (LPARAM)&nmhdr);
5525     ok(ret == 1, "got %d\n", ret);
5526     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq,
5527                 "header notify, parent", FALSE);
5528     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5529     nmhdr.hdr.code = HDN_ENDDRAG;
5530     ret = SendMessageW(list, WM_NOTIFY, 0, (LPARAM)&nmhdr);
5531     ok(ret == 0, "got %d\n", ret);
5532     parent_header_notify_seq[0].id = HDN_ENDDRAG;
5533     ok_sequence(sequences, PARENT_SEQ_INDEX, parent_header_notify_seq,
5534                 "header notify, parent", FALSE);
5535     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5536     nmhdr.hdr.code = HDN_FILTERCHANGE;
5537     ret = SendMessageW(list, WM_NOTIFY, 0, (LPARAM)&nmhdr);
5538     ok(ret == 0, "got %d\n", ret);
5539     parent_header_notify_seq[0].id = HDN_FILTERCHANGE;
5540     parent_header_notify_seq[0].flags |= optional; /* NT4 does not send this message */
5541     ok_sequence(sequences, PARENT_SEQ_INDEX, parent_header_notify_seq,
5542                 "header notify, parent", FALSE);
5543     parent_header_notify_seq[0].flags &= ~optional;
5544     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5545     nmhdr.hdr.code = HDN_BEGINFILTEREDIT;
5546     ret = SendMessageW(list, WM_NOTIFY, 0, (LPARAM)&nmhdr);
5547     ok(ret == 0, "got %d\n", ret);
5548     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq,
5549                 "header notify, parent", FALSE);
5550     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5551     nmhdr.hdr.code = HDN_ENDFILTEREDIT;
5552     ret = SendMessageW(list, WM_NOTIFY, 0, (LPARAM)&nmhdr);
5553     ok(ret == 0, "got %d\n", ret);
5554     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq,
5555                 "header notify, parent", FALSE);
5556     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5557     nmhdr.hdr.code = HDN_ITEMSTATEICONCLICK;
5558     ret = SendMessageW(list, WM_NOTIFY, 0, (LPARAM)&nmhdr);
5559     ok(ret == 0, "got %d\n", ret);
5560     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq,
5561                 "header notify, parent", FALSE);
5562     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5563     nmhdr.hdr.code = HDN_ITEMKEYDOWN;
5564     ret = SendMessageW(list, WM_NOTIFY, 0, (LPARAM)&nmhdr);
5565     ok(ret == 0, "got %d\n", ret);
5566     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq,
5567                 "header notify, parent", FALSE);
5568 
5569     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5570 
5571     DestroyWindow(list);
5572 }
5573 
5574 static void test_createdragimage(void)
5575 {
5576     HIMAGELIST himl;
5577     POINT pt;
5578     HWND list;
5579 
5580     list = create_listview_control(LVS_ICON);
5581     ok(list != NULL, "failed to create listview window\n");
5582 
5583     insert_item(list, 0);
5584 
5585     /* NULL point */
5586     himl = (HIMAGELIST)SendMessageA(list, LVM_CREATEDRAGIMAGE, 0, 0);
5587     ok(himl == NULL, "got %p\n", himl);
5588 
5589     himl = (HIMAGELIST)SendMessageA(list, LVM_CREATEDRAGIMAGE, 0, (LPARAM)&pt);
5590     ok(himl != NULL, "got %p\n", himl);
5591     ImageList_Destroy(himl);
5592 
5593     DestroyWindow(list);
5594 }
5595 
5596 static void test_dispinfo(void)
5597 {
5598     static const char testA[] = "TEST";
5599     WCHAR buff[10];
5600     LVITEMA item;
5601     HWND hwnd;
5602     DWORD ret;
5603 
5604     hwnd = create_listview_control(LVS_ICON);
5605     ok(hwnd != NULL, "failed to create listview window\n");
5606 
5607     insert_item(hwnd, 0);
5608 
5609     memset(&item, 0, sizeof(item));
5610     item.pszText = LPSTR_TEXTCALLBACKA;
5611     ret = SendMessageA(hwnd, LVM_SETITEMTEXTA, 0, (LPARAM)&item);
5612     expect(1, ret);
5613 
5614     g_disp_A_to_W = TRUE;
5615     item.pszText = (char*)buff;
5616     item.cchTextMax = sizeof(buff)/sizeof(WCHAR);
5617     ret = SendMessageA(hwnd, LVM_GETITEMTEXTA, 0, (LPARAM)&item);
5618     ok(ret == sizeof(testA)-1, "got %d, expected 4\n", ret);
5619     g_disp_A_to_W = FALSE;
5620 
5621     ok(memcmp(item.pszText, testA, sizeof(testA)) == 0,
5622         "got %s, expected %s\n", item.pszText, testA);
5623 
5624     DestroyWindow(hwnd);
5625 }
5626 
5627 static void test_LVM_SETITEMTEXT(void)
5628 {
5629     static char testA[] = "TEST";
5630     LVITEMA item;
5631     HWND hwnd;
5632     DWORD ret;
5633 
5634     hwnd = create_listview_control(LVS_ICON);
5635     ok(hwnd != NULL, "failed to create listview window\n");
5636 
5637     insert_item(hwnd, 0);
5638 
5639     /* null item pointer */
5640     ret = SendMessageA(hwnd, LVM_SETITEMTEXTA, 0, 0);
5641     expect(FALSE, ret);
5642 
5643     ret = SendMessageA(hwnd, LVM_SETITEMTEXTW, 0, 0);
5644     expect(FALSE, ret);
5645 
5646     /* index out of bounds */
5647     item.pszText = testA;
5648     item.cchTextMax = 0; /* ignored */
5649     item.iSubItem = 0;
5650 
5651     ret = SendMessageA(hwnd, LVM_SETITEMTEXTA, 1, (LPARAM)&item);
5652     expect(FALSE, ret);
5653 
5654     ret = SendMessageA(hwnd, LVM_SETITEMTEXTA, -1, (LPARAM)&item);
5655     expect(FALSE, ret);
5656 
5657     ret = SendMessageA(hwnd, LVM_SETITEMTEXTA, 0, (LPARAM)&item);
5658     expect(TRUE, ret);
5659 
5660     DestroyWindow(hwnd);
5661 }
5662 
5663 static void test_LVM_REDRAWITEMS(void)
5664 {
5665     HWND list;
5666     DWORD ret;
5667 
5668     list = create_listview_control(LVS_ICON);
5669     ok(list != NULL, "failed to create listview window\n");
5670 
5671     ret = SendMessageA(list, LVM_REDRAWITEMS, 0, 0);
5672     expect(TRUE, ret);
5673 
5674     insert_item(list, 0);
5675 
5676     ret = SendMessageA(list, LVM_REDRAWITEMS, -1, 0);
5677     expect(TRUE, ret);
5678 
5679     ret = SendMessageA(list, LVM_REDRAWITEMS, 0, -1);
5680     expect(TRUE, ret);
5681 
5682     ret = SendMessageA(list, LVM_REDRAWITEMS, 0, 0);
5683     expect(TRUE, ret);
5684 
5685     ret = SendMessageA(list, LVM_REDRAWITEMS, 0, 1);
5686     expect(TRUE, ret);
5687 
5688     ret = SendMessageA(list, LVM_REDRAWITEMS, 0, 2);
5689     expect(TRUE, ret);
5690 
5691     ret = SendMessageA(list, LVM_REDRAWITEMS, 1, 0);
5692     expect(TRUE, ret);
5693 
5694     ret = SendMessageA(list, LVM_REDRAWITEMS, 2, 3);
5695     expect(TRUE, ret);
5696 
5697     DestroyWindow(list);
5698 }
5699 
5700 static void test_imagelists(void)
5701 {
5702     HWND hwnd, header;
5703     HIMAGELIST himl1, himl2, himl3;
5704     LRESULT ret;
5705 
5706     himl1 = ImageList_Create(40, 40, 0, 4, 4);
5707     himl2 = ImageList_Create(40, 40, 0, 4, 4);
5708     himl3 = ImageList_Create(40, 40, 0, 4, 4);
5709     ok(himl1 != NULL, "Failed to create imagelist\n");
5710     ok(himl2 != NULL, "Failed to create imagelist\n");
5711     ok(himl3 != NULL, "Failed to create imagelist\n");
5712 
5713     hwnd = create_listview_control(LVS_REPORT | LVS_SHAREIMAGELISTS);
5714     header = subclass_header(hwnd);
5715 
5716     ok(header != NULL, "Expected header\n");
5717     ret = SendMessageA(header, HDM_GETIMAGELIST, 0, 0);
5718     ok(ret == 0, "Expected no imagelist, got %p\n", (HIMAGELIST)ret);
5719 
5720     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5721 
5722     ret = SendMessageW(hwnd, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)himl1);
5723     ok(ret == 0, "Expected no imagelist, got %p\n", (HIMAGELIST)ret);
5724     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_set_imagelist,
5725                 "set normal image list", FALSE);
5726 
5727     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5728 
5729     ret = SendMessageW(hwnd, LVM_SETIMAGELIST, LVSIL_STATE, (LPARAM)himl2);
5730     ok(ret == 0, "Expected no imagelist, got %p\n", (HIMAGELIST)ret);
5731     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_set_imagelist,
5732                 "set state image list", TRUE);
5733 
5734     ret = SendMessageA(header, HDM_GETIMAGELIST, 0, 0);
5735     ok(ret == 0, "Expected no imagelist, got %p\n", (HIMAGELIST)ret);
5736 
5737     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5738 
5739     ret = SendMessageW(hwnd, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)himl3);
5740     ok(ret == 0, "Expected no imagelist, got %p\n", (HIMAGELIST)ret);
5741     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_header_set_imagelist,
5742                 "set small image list", FALSE);
5743 
5744     ret = SendMessageA(header, HDM_GETIMAGELIST, 0, 0);
5745     ok((HIMAGELIST)ret == himl3, "Expected imagelist %p, got %p\n", himl3, (HIMAGELIST)ret);
5746     DestroyWindow(hwnd);
5747 
5748     hwnd = create_listview_control(WS_VISIBLE | LVS_ICON);
5749 
5750     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5751 
5752     ret = SendMessageW(hwnd, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)himl1);
5753     ok(ret == 0, "Expected no imagelist, got %p\n", (HIMAGELIST)ret);
5754     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_set_imagelist,
5755                 "set normal image list", FALSE);
5756 
5757     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5758 
5759     ret = SendMessageW(hwnd, LVM_SETIMAGELIST, LVSIL_STATE, (LPARAM)himl2);
5760     ok(ret == 0, "Expected no imagelist, got %p\n", (HIMAGELIST)ret);
5761     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_set_imagelist,
5762                 "set state image list", FALSE);
5763 
5764     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5765 
5766     ret = SendMessageW(hwnd, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)himl3);
5767     ok(ret == 0, "Expected no imagelist, got %p\n", (HIMAGELIST)ret);
5768     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_set_imagelist,
5769                 "set small image list", FALSE);
5770 
5771     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
5772     ok(header == NULL, "Expected no header, got %p\n", header);
5773 
5774     SetWindowLongPtrA(hwnd, GWL_STYLE, GetWindowLongPtrA(hwnd, GWL_STYLE) | LVS_REPORT);
5775 
5776     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
5777     ok(header != NULL, "Expected header, got NULL\n");
5778 
5779     ret = SendMessageA(header, HDM_GETIMAGELIST, 0, 0);
5780     ok((HIMAGELIST)ret == himl3, "Expected imagelist %p, got %p\n", himl3, (HIMAGELIST)ret);
5781 
5782     DestroyWindow(hwnd);
5783 }
5784 
5785 static void test_deleteitem(void)
5786 {
5787     LVITEMA item;
5788     UINT state;
5789     HWND hwnd;
5790     BOOL ret;
5791 
5792     hwnd = create_listview_control(LVS_REPORT);
5793 
5794     insert_item(hwnd, 0);
5795     insert_item(hwnd, 0);
5796     insert_item(hwnd, 0);
5797     insert_item(hwnd, 0);
5798     insert_item(hwnd, 0);
5799 
5800     g_focus_test_LVN_DELETEITEM = TRUE;
5801 
5802     /* delete focused item (not the last index) */
5803     item.stateMask = LVIS_FOCUSED;
5804     item.state = LVIS_FOCUSED;
5805     ret = SendMessageA(hwnd, LVM_SETITEMSTATE, 2, (LPARAM)&item);
5806     ok(ret == TRUE, "got %d\n", ret);
5807     ret = SendMessageA(hwnd, LVM_DELETEITEM, 2, 0);
5808     ok(ret == TRUE, "got %d\n", ret);
5809     /* next item gets focus */
5810     state = SendMessageA(hwnd, LVM_GETITEMSTATE, 2, LVIS_FOCUSED);
5811     ok(state == LVIS_FOCUSED, "got %x\n", state);
5812 
5813     /* focus last item and delete it */
5814     item.stateMask = LVIS_FOCUSED;
5815     item.state = LVIS_FOCUSED;
5816     ret = SendMessageA(hwnd, LVM_SETITEMSTATE, 3, (LPARAM)&item);
5817     ok(ret == TRUE, "got %d\n", ret);
5818     ret = SendMessageA(hwnd, LVM_DELETEITEM, 3, 0);
5819     ok(ret == TRUE, "got %d\n", ret);
5820     /* new last item gets focus */
5821     state = SendMessageA(hwnd, LVM_GETITEMSTATE, 2, LVIS_FOCUSED);
5822     ok(state == LVIS_FOCUSED, "got %x\n", state);
5823 
5824     /* focus first item and delete it */
5825     item.stateMask = LVIS_FOCUSED;
5826     item.state = LVIS_FOCUSED;
5827     ret = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
5828     ok(ret == TRUE, "got %d\n", ret);
5829     ret = SendMessageA(hwnd, LVM_DELETEITEM, 0, 0);
5830     ok(ret == TRUE, "got %d\n", ret);
5831     /* new first item gets focus */
5832     state = SendMessageA(hwnd, LVM_GETITEMSTATE, 0, LVIS_FOCUSED);
5833     ok(state == LVIS_FOCUSED, "got %x\n", state);
5834 
5835     g_focus_test_LVN_DELETEITEM = FALSE;
5836 
5837     DestroyWindow(hwnd);
5838 }
5839 
5840 static void test_insertitem(void)
5841 {
5842     LVITEMA item;
5843     UINT state;
5844     HWND hwnd;
5845     INT ret;
5846 
5847     hwnd = create_listview_control(LVS_REPORT);
5848 
5849     /* insert item 0 focused */
5850     item.mask = LVIF_STATE;
5851     item.state = LVIS_FOCUSED;
5852     item.stateMask = LVIS_FOCUSED;
5853     item.iItem = 0;
5854     item.iSubItem = 0;
5855     ret = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item);
5856     ok(ret == 0, "got %d\n", ret);
5857 
5858     state = SendMessageA(hwnd, LVM_GETITEMSTATE, 0, LVIS_FOCUSED);
5859     ok(state == LVIS_FOCUSED, "got %x\n", state);
5860 
5861     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5862 
5863     /* insert item 1, focus shift */
5864     item.mask = LVIF_STATE;
5865     item.state = LVIS_FOCUSED;
5866     item.stateMask = LVIS_FOCUSED;
5867     item.iItem = 1;
5868     item.iSubItem = 0;
5869     ret = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item);
5870     ok(ret == 1, "got %d\n", ret);
5871 
5872     ok_sequence(sequences, PARENT_SEQ_INDEX, parent_insert_focused_seq, "insert focused", TRUE);
5873 
5874     state = SendMessageA(hwnd, LVM_GETITEMSTATE, 1, LVIS_FOCUSED);
5875     ok(state == LVIS_FOCUSED, "got %x\n", state);
5876 
5877     /* insert item 2, no focus shift */
5878     item.mask = LVIF_STATE;
5879     item.state = 0;
5880     item.stateMask = LVIS_FOCUSED;
5881     item.iItem = 2;
5882     item.iSubItem = 0;
5883     ret = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item);
5884     ok(ret == 2, "got %d\n", ret);
5885 
5886     state = SendMessageA(hwnd, LVM_GETITEMSTATE, 1, LVIS_FOCUSED);
5887     ok(state == LVIS_FOCUSED, "got %x\n", state);
5888 
5889     DestroyWindow(hwnd);
5890 }
5891 
5892 static void test_header_proc(void)
5893 {
5894     HWND hwnd, header, hdr;
5895     WNDPROC proc1, proc2;
5896 
5897     hwnd = create_listview_control(LVS_REPORT);
5898 
5899     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
5900     ok(header != NULL, "got %p\n", header);
5901 
5902     hdr = CreateWindowExA(0, WC_HEADERA, NULL,
5903 			     WS_BORDER|WS_VISIBLE|HDS_BUTTONS|HDS_HORZ,
5904 			     0, 0, 0, 0,
5905 			     NULL, NULL, NULL, NULL);
5906     ok(hdr != NULL, "got %p\n", hdr);
5907 
5908     proc1 = (WNDPROC)GetWindowLongPtrW(header, GWLP_WNDPROC);
5909     proc2 = (WNDPROC)GetWindowLongPtrW(hdr, GWLP_WNDPROC);
5910     ok(proc1 == proc2, "got %p, expected %p\n", proc1, proc2);
5911 
5912     DestroyWindow(hdr);
5913     DestroyWindow(hwnd);
5914 }
5915 
5916 static void flush_events(void)
5917 {
5918     MSG msg;
5919     int diff = 200;
5920     int min_timeout = 100;
5921     DWORD time = GetTickCount() + diff;
5922 
5923     while (diff > 0)
5924     {
5925         if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break;
5926         while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
5927         diff = time - GetTickCount();
5928     }
5929 }
5930 
5931 static void test_oneclickactivate(void)
5932 {
5933     TRACKMOUSEEVENT track;
5934     char item1[] = "item1";
5935     LVITEMA item;
5936     HWND hwnd, fg;
5937     RECT rect;
5938     INT r;
5939     POINT orig_pos;
5940 
5941     hwnd = CreateWindowExA(0, "SysListView32", "foo", WS_VISIBLE|WS_CHILD|LVS_LIST,
5942             10, 10, 100, 200, hwndparent, NULL, NULL, NULL);
5943     ok(hwnd != NULL, "failed to create listview window\n");
5944     r = SendMessageA(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_ONECLICKACTIVATE);
5945     ok(r == 0, "should return zero\n");
5946 
5947     SetForegroundWindow(hwndparent);
5948     flush_events();
5949     fg = GetForegroundWindow();
5950     if (fg != hwndparent)
5951     {
5952         skip("Window is not in the foreground. Skipping oneclickactivate tests.\n");
5953         DestroyWindow(hwnd);
5954         return;
5955     }
5956 
5957     item.mask = LVIF_TEXT;
5958     item.iItem = 0;
5959     item.iSubItem = 0;
5960     item.iImage = 0;
5961     item.pszText = item1;
5962     r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
5963     ok(r == 0, "should not fail\n");
5964 
5965     GetWindowRect(hwnd, &rect);
5966     GetCursorPos(&orig_pos);
5967     SetCursorPos(rect.left+5, rect.top+5);
5968     flush_events();
5969     r = SendMessageA(hwnd, WM_MOUSEMOVE, MAKELONG(1, 1), 0);
5970     expect(0, r);
5971 
5972     track.cbSize = sizeof(track);
5973     track.dwFlags = TME_QUERY;
5974     _TrackMouseEvent(&track);
5975     ok(track.hwndTrack == hwnd, "hwndTrack != hwnd\n");
5976     ok(track.dwFlags == TME_LEAVE, "dwFlags = %x\n", track.dwFlags);
5977 
5978     r = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
5979     expect(0, r);
5980     r = SendMessageA(hwnd, WM_MOUSEHOVER, MAKELONG(1, 1), 0);
5981     expect(0, r);
5982     r = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
5983     expect(1, r);
5984 
5985     DestroyWindow(hwnd);
5986     SetCursorPos(orig_pos.x, orig_pos.y);
5987 }
5988 
5989 static void test_callback_mask(void)
5990 {
5991     LVITEMA item;
5992     DWORD mask;
5993     HWND hwnd;
5994     BOOL ret;
5995 
5996     hwnd = create_listview_control(LVS_REPORT);
5997 
5998     ret = SendMessageA(hwnd, LVM_SETCALLBACKMASK, ~0u, 0);
5999     ok(ret, "got %d\n", ret);
6000 
6001     ret = SendMessageA(hwnd, LVM_SETCALLBACKMASK, ~0u, 1);
6002     ok(ret, "got %d\n", ret);
6003 
6004     mask = SendMessageA(hwnd, LVM_GETCALLBACKMASK, 0, 0);
6005     ok(mask == ~0u, "got 0x%08x\n", mask);
6006 
6007     DestroyWindow(hwnd);
6008 
6009     /* LVS_OWNERDATA, mask LVIS_FOCUSED */
6010     hwnd = create_listview_control(LVS_REPORT | LVS_OWNERDATA);
6011 
6012     mask = SendMessageA(hwnd, LVM_GETCALLBACKMASK, 0, 0);
6013     ok(mask == 0, "Unexpected callback mask %#x.\n", mask);
6014 
6015     ret = SendMessageA(hwnd, LVM_SETCALLBACKMASK, LVIS_FOCUSED, 0);
6016     ok(ret, "Failed to set callback mask, %d\n", ret);
6017 
6018     mask = SendMessageA(hwnd, LVM_GETCALLBACKMASK, 0, 0);
6019     ok(mask == LVIS_FOCUSED, "Unexpected callback mask %#x.\n", mask);
6020 
6021     ret = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0);
6022     ok(ret, "Failed to set item count.\n");
6023 
6024     ret = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
6025     ok(ret == -1, "Unexpected selection mark, %d\n", ret);
6026 
6027     item.stateMask = LVIS_FOCUSED;
6028     item.state = LVIS_FOCUSED;
6029     ret = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
6030     ok(ret, "Failed to set item state.\n");
6031 
6032     flush_sequences(sequences, NUM_MSG_SEQUENCES);
6033 
6034     ret = SendMessageA(hwnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
6035 todo_wine
6036     ok(ret == 0, "Unexpected focused item, ret %d\n", ret);
6037 
6038     ret = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
6039 todo_wine
6040     ok(ret == 0, "Unexpected selection mark, %d\n", ret);
6041 
6042     ret = SendMessageA(hwnd, LVM_SETITEMCOUNT, 0, 0);
6043     ok(ret, "Failed to set item count.\n");
6044 
6045     ret = SendMessageA(hwnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
6046     ok(ret == -1, "Unexpected focused item, ret %d\n", ret);
6047 
6048     ret = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
6049     ok(ret == -1, "Unexpected selection mark, %d\n", ret);
6050 
6051     ret = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0);
6052     ok(ret, "Failed to set item count.\n");
6053 
6054     ret = SendMessageA(hwnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
6055     ok(ret == -1, "Unexpected focused item, ret %d\n", ret);
6056 
6057     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "parent seq, owner data/focus 1", FALSE);
6058 
6059     /* LVS_OWNDERDATA, empty mask */
6060     ret = SendMessageA(hwnd, LVM_SETCALLBACKMASK, 0, 0);
6061     ok(ret, "Failed to set callback mask, %d\n", ret);
6062 
6063     ret = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0);
6064     ok(ret, "Failed to set item count.\n");
6065 
6066     ret = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
6067     ok(ret == -1, "Unexpected selection mark, %d\n", ret);
6068 
6069     item.stateMask = LVIS_FOCUSED;
6070     item.state = LVIS_FOCUSED;
6071     ret = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
6072     ok(ret, "Failed to set item state.\n");
6073 
6074     ret = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
6075     ok(ret == 0, "Unexpected selection mark, %d\n", ret);
6076 
6077     flush_sequences(sequences, NUM_MSG_SEQUENCES);
6078 
6079     ret = SendMessageA(hwnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
6080     ok(ret == 0, "Unexpected focused item, ret %d\n", ret);
6081 
6082     ret = SendMessageA(hwnd, LVM_SETITEMCOUNT, 0, 0);
6083     ok(ret, "Failed to set item count.\n");
6084 
6085     ret = SendMessageA(hwnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
6086     ok(ret == -1, "Unexpected focused item, ret %d\n", ret);
6087 
6088     ret = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
6089 todo_wine
6090     ok(ret == -1, "Unexpected selection mark, %d\n", ret);
6091 
6092     ret = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0);
6093     ok(ret, "Failed to set item count.\n");
6094 
6095     ret = SendMessageA(hwnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
6096     ok(ret == -1, "Unexpected focused item, ret %d\n", ret);
6097 
6098     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "parent seq, owner data/focus 2", FALSE);
6099 
6100     /* 2 items, focus on index 0, reduce to 1 item. */
6101     flush_sequences(sequences, NUM_MSG_SEQUENCES);
6102 
6103     ret = SendMessageA(hwnd, LVM_SETITEMCOUNT, 2, 0);
6104     ok(ret, "Failed to set item count.\n");
6105 
6106     ret = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
6107     ok(ret, "Failed to set item state.\n");
6108 
6109     ret = SendMessageA(hwnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
6110     ok(ret == 0, "Unexpected focused item, ret %d\n", ret);
6111 
6112     ret = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0);
6113     ok(ret, "Failed to set item count.\n");
6114 
6115     ret = SendMessageA(hwnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
6116     ok(ret == 0, "Unexpected focused item, ret %d\n", ret);
6117 
6118     ok_sequence(sequences, PARENT_SEQ_INDEX, parent_focus_change_ownerdata_seq,
6119         "parent seq, owner data/focus 3", TRUE);
6120 
6121     DestroyWindow(hwnd);
6122 }
6123 
6124 static void test_state_image(void)
6125 {
6126     static const DWORD styles[] =
6127     {
6128         LVS_ICON,
6129         LVS_REPORT,
6130         LVS_SMALLICON,
6131         LVS_LIST,
6132     };
6133     int i;
6134 
6135     for (i = 0; i < sizeof(styles)/sizeof(styles[0]); i++)
6136     {
6137         static char text[] = "Item";
6138         static char subtext[] = "Subitem";
6139         char buff[16];
6140         LVITEMA item;
6141         HWND hwnd;
6142         int r;
6143 
6144         hwnd = create_listview_control(styles[i]);
6145 
6146         insert_column(hwnd, 0);
6147         insert_column(hwnd, 1);
6148 
6149         item.mask = LVIF_TEXT;
6150         item.iItem = 0;
6151         item.iSubItem = 0;
6152         item.pszText = text;
6153         r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item);
6154         ok(r == 0, "Failed to insert an item.\n");
6155 
6156         item.mask = LVIF_STATE;
6157         item.state = INDEXTOSTATEIMAGEMASK(1) | LVIS_SELECTED;
6158         item.stateMask = LVIS_STATEIMAGEMASK | LVIS_SELECTED;
6159         item.iItem = 0;
6160         item.iSubItem = 0;
6161         r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM)&item);
6162         ok(r, "Failed to set item state.\n");
6163 
6164         item.mask = LVIF_TEXT;
6165         item.iItem = 0;
6166         item.iSubItem = 1;
6167         item.pszText = subtext;
6168         r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM)&item);
6169         ok(r, "Failed to set subitem text.\n");
6170 
6171         item.mask = LVIF_STATE;
6172         item.stateMask = LVIS_STATEIMAGEMASK | LVIS_SELECTED;
6173         item.state = 0;
6174         item.iItem = 0;
6175         item.iSubItem = 0;
6176         r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
6177         ok(r, "Failed to get item state.\n");
6178         ok(item.state == (INDEXTOSTATEIMAGEMASK(1) | LVIS_SELECTED), "Unexpected item state %#x.\n", item.state);
6179 
6180         item.mask = LVIF_STATE;
6181         item.stateMask = LVIS_STATEIMAGEMASK | LVIS_SELECTED;
6182         item.state = INDEXTOSTATEIMAGEMASK(2);
6183         item.iItem = 0;
6184         item.iSubItem = 1;
6185         r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
6186         ok(r, "Failed to get subitem state.\n");
6187     todo_wine
6188         ok(item.state == 0, "Unexpected state %#x.\n", item.state);
6189 
6190         item.mask = LVIF_STATE;
6191         item.stateMask = LVIS_STATEIMAGEMASK | LVIS_SELECTED;
6192         item.state = INDEXTOSTATEIMAGEMASK(2);
6193         item.iItem = 0;
6194         item.iSubItem = 2;
6195         r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
6196         ok(r, "Failed to get subitem state.\n");
6197     todo_wine
6198         ok(item.state == 0, "Unexpected state %#x.\n", item.state);
6199 
6200         item.mask = LVIF_TEXT;
6201         item.iItem = 0;
6202         item.iSubItem = 1;
6203         item.pszText = buff;
6204         item.cchTextMax = sizeof(buff);
6205         r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
6206         ok(r, "Failed to get subitem text %d.\n", r);
6207         ok(!strcmp(buff, subtext), "Unexpected subitem text %s.\n", buff);
6208 
6209         DestroyWindow(hwnd);
6210     }
6211 }
6212 
6213 START_TEST(listview)
6214 {
6215     HMODULE hComctl32;
6216     BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
6217 
6218     ULONG_PTR ctx_cookie;
6219     HANDLE hCtx;
6220 
6221     hComctl32 = GetModuleHandleA("comctl32.dll");
6222     pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
6223     if (pInitCommonControlsEx)
6224     {
6225         INITCOMMONCONTROLSEX iccex;
6226         iccex.dwSize = sizeof(iccex);
6227         iccex.dwICC  = ICC_LISTVIEW_CLASSES;
6228         pInitCommonControlsEx(&iccex);
6229     }
6230     else
6231         InitCommonControls();
6232 
6233     init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
6234 
6235     hwndparent = create_parent_window(FALSE);
6236     flush_sequences(sequences, NUM_MSG_SEQUENCES);
6237 
6238     g_is_below_5 = is_below_comctl_5();
6239 
6240     test_header_notification();
6241     test_header_notification2();
6242     test_images();
6243     test_checkboxes();
6244     test_items();
6245     test_create();
6246     test_redraw();
6247     test_customdraw();
6248     test_icon_spacing();
6249     test_color();
6250     test_item_count();
6251     test_item_position();
6252     test_columns();
6253     test_getorigin();
6254     test_multiselect();
6255     test_getitemrect();
6256     test_subitem_rect();
6257     test_sorting();
6258     test_ownerdata();
6259     test_norecompute();
6260     test_nosortheader();
6261     test_setredraw();
6262     test_hittest();
6263     test_getviewrect();
6264     test_getitemposition();
6265     test_columnscreation();
6266     test_editbox();
6267     test_notifyformat();
6268     test_indentation();
6269     test_getitemspacing();
6270     test_getcolumnwidth();
6271     test_approximate_viewrect();
6272     test_finditem();
6273     test_hover();
6274     test_destroynotify();
6275     test_createdragimage();
6276     test_dispinfo();
6277     test_LVM_SETITEMTEXT();
6278     test_LVM_REDRAWITEMS();
6279     test_imagelists();
6280     test_deleteitem();
6281     test_insertitem();
6282     test_header_proc();
6283     test_oneclickactivate();
6284     test_callback_mask();
6285     test_state_image();
6286 
6287     if (!load_v6_module(&ctx_cookie, &hCtx))
6288     {
6289         DestroyWindow(hwndparent);
6290         return;
6291     }
6292 
6293     /* comctl32 version 6 tests start here */
6294     test_get_set_view();
6295     test_canceleditlabel();
6296     test_mapidindex();
6297     test_scrollnotify();
6298     test_LVS_EX_TRANSPARENTBKGND();
6299     test_LVS_EX_HEADERINALLVIEWS();
6300     test_deleteitem();
6301     test_multiselect();
6302     test_insertitem();
6303     test_header_proc();
6304     test_images();
6305     test_checkboxes();
6306     test_items();
6307     test_color();
6308     test_columns();
6309     test_sorting();
6310     test_ownerdata();
6311     test_norecompute();
6312     test_nosortheader();
6313     test_columnscreation();
6314     test_indentation();
6315     test_finditem();
6316     test_hover();
6317     test_destroynotify();
6318     test_createdragimage();
6319     test_dispinfo();
6320     test_LVM_SETITEMTEXT();
6321     test_LVM_REDRAWITEMS();
6322     test_oneclickactivate();
6323     test_state_image();
6324 
6325     unload_v6_module(ctx_cookie, hCtx);
6326 
6327     DestroyWindow(hwndparent);
6328 }
6329