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