ReactOS 0.4.16-dev-188-g678aa63
listbox.c
Go to the documentation of this file.
1/* Unit test suite for list boxes.
2 *
3 * Copyright 2003 Ferenc Wagner
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20#include <stdarg.h>
21#include <stdio.h>
22
23#include "windef.h"
24#include "winbase.h"
25#include "wingdi.h"
26#include "winuser.h"
27#include "winnls.h"
28#include "commctrl.h"
29
30#include "wine/heap.h"
31#include "wine/test.h"
32#include "v6util.h"
33#include "msg.h"
34
36{
40};
41
43
44/* encoded MEASUREITEMSTRUCT into a WPARAM */
45typedef struct
46{
47 union
48 {
49 struct
50 {
57 } u;
59
60static unsigned hash_Ly_W(const WCHAR *str)
61{
62 unsigned hash = 0;
63
64 for (; *str; str++)
65 hash = hash * 1664525u + (unsigned char)(*str) + 1013904223u;
66
67 return hash;
68}
69
70static unsigned hash_Ly(const char *str)
71{
72 unsigned hash = 0;
73
74 for (; *str; str++)
75 hash = hash * 1664525u + (unsigned char)(*str) + 1013904223u;
76
77 return hash;
78}
79
80static const char * const strings[4] = {
81 "First added",
82 "Second added",
83 "Third added",
84 "Fourth added which is very long because at some time we only had a 256 byte character buffer and "
85 "that was overflowing in one of those applications that had a common dialog file open box and tried "
86 "to add a 300 characters long custom filter string which of course the code did not like and crashed. "
87 "Just make sure this string is longer than 256 characters."
88};
89
90static const char BAD_EXTENSION[] = "*.badtxt";
91
92#define ID_LISTBOX 1
93
95{
97 static LONG defwndproc_counter = 0;
98 struct message msg = { 0 };
100
101 switch (message)
102 {
103 case WM_SIZE:
104 case WM_GETTEXT:
105 case WM_PAINT:
106 case WM_ERASEBKGND:
109 case WM_NCCALCSIZE:
110 case WM_NCPAINT:
111 case WM_NCHITTEST:
112 case WM_DEVICECHANGE:
113 break;
114
115 default:
116 msg.message = message;
117 msg.flags = sent|wparam|lparam;
118 if (defwndproc_counter) msg.flags |= defwinproc;
119 msg.wParam = wParam;
120 msg.lParam = lParam;
122 }
123
124 defwndproc_counter++;
126 defwndproc_counter--;
127
128 return ret;
129}
130
132{
133 INT_PTR ctl_id = 0;
134 WNDPROC oldproc;
135 HWND handle;
136
137 if (parent)
138 ctl_id = ID_LISTBOX;
139
140 handle = CreateWindowA(WC_LISTBOXA, "TestList", (LBS_STANDARD & ~LBS_SORT) | add_style, 0, 0, 100, 100,
141 parent, (HMENU)ctl_id, NULL, 0);
142 ok(handle != NULL, "Failed to create listbox window.\n");
143
148
151
152 return handle;
153}
154
156{
158};
159
161{
163};
164
166{
171};
172
174{
175 results->selected = SendMessageA(handle, LB_GETCURSEL, 0, 0);
178 results->selcount = SendMessageA(handle, LB_GETSELCOUNT, 0, 0);
179}
180
182{
183 LPARAM lp = x + (y << 16);
184
187}
188
189static void keypress(HWND handle, WPARAM keycode, BYTE scancode, BOOL extended)
190{
191 LPARAM lp = 1 + (scancode << 16) + (extended ? KEYEVENTF_EXTENDEDKEY : 0);
192
193 SendMessageA(handle, WM_KEYDOWN, keycode, lp);
194 SendMessageA(handle, WM_KEYUP , keycode, lp | 0xc000000);
195}
196
197#define listbox_field_ok(t, s, f, got) \
198 ok (t.s.f==got.f, "style %#x, step " #s ", field " #f \
199 ": expected %d, got %d\n", style, t.s.f, got.f)
200
201#define listbox_todo_field_ok(t, s, f, got) \
202 todo_wine_if (t.s##_todo.f) { listbox_field_ok(t, s, f, got); }
203
204#define listbox_ok(t, s, got) \
205 listbox_todo_field_ok(t, s, selected, got); \
206 listbox_todo_field_ok(t, s, anchor, got); \
207 listbox_todo_field_ok(t, s, caret, got); \
208 listbox_todo_field_ok(t, s, selcount, got)
209
210static void run_test(DWORD style, const struct listbox_test test)
211{
212 static const struct message delete_seq[] =
213 {
219 { 0 }
220 };
221 struct listbox_stat answer;
222 int i, res, count;
223 RECT second_item;
224 HWND hLB;
225
226 hLB = create_listbox (style, 0);
227
228 listbox_query (hLB, &answer);
229 listbox_ok (test, init, answer);
230
231 SendMessageA(hLB, LB_GETITEMRECT, 1, (LPARAM) &second_item);
232 buttonpress(hLB, (WORD)second_item.left, (WORD)second_item.top);
233
234 listbox_query(hLB, &answer);
235 listbox_ok(test, click, answer);
236
237 keypress(hLB, VK_DOWN, 0x50, TRUE);
238
239 listbox_query(hLB, &answer);
240 listbox_ok(test, step, answer);
241
242 DestroyWindow(hLB);
243
244 hLB = create_listbox(style, 0);
245
247 listbox_query(hLB, &answer);
248 listbox_ok(test, sel, answer);
249
250 for (i = 0; i < 4 && !(style & LBS_NODATA); i++)
251 {
253 int resA, resW;
254 WCHAR *txtw;
255 CHAR *txt;
256
257 txt = heap_alloc_zero(size + 1);
258 resA = SendMessageA(hLB, LB_GETTEXT, i, (LPARAM)txt);
259 ok(!strcmp(txt, strings[i]), "returned string for item %d does not match %s vs %s\n", i, txt, strings[i]);
260
261 txtw = heap_alloc_zero((size + 1) * sizeof(*txtw));
262 resW = SendMessageW(hLB, LB_GETTEXT, i, (LPARAM)txtw);
263 ok(resA == resW, "Unexpected text length.\n");
264 WideCharToMultiByte(CP_ACP, 0, txtw, -1, txt, size, NULL, NULL);
265 ok(!strcmp (txt, strings[i]), "Unexpected string for item %d, %s vs %s.\n", i, txt, strings[i]);
266
267 heap_free(txtw);
268 heap_free(txt);
269 }
270
271 /* Confirm the count of items, and that an invalid delete does not remove anything */
272 res = SendMessageA(hLB, LB_GETCOUNT, 0, 0);
273 ok(res == 4, "Expected 4 items, got %d\n", res);
274 res = SendMessageA(hLB, LB_DELETESTRING, -1, 0);
275 ok(res == LB_ERR, "Expected LB_ERR items, got %d\n", res);
276 res = SendMessageA(hLB, LB_DELETESTRING, 4, 0);
277 ok(res == LB_ERR, "Expected LB_ERR items, got %d\n", res);
278 count = SendMessageA(hLB, LB_GETCOUNT, 0, 0);
279 ok(count == 4, "Unexpected item count %d.\n", count);
280
281 /* Emptying listbox sends a LB_RESETCONTENT to itself. */
283 for (i = count; i--;)
284 {
285 res = SendMessageA(hLB, LB_DELETESTRING, 0, 0);
286 ok(res == i, "Unexpected return value %d.\n", res);
287 }
288 ok_sequence(sequences, LB_SEQ_INDEX, delete_seq, "Emptying listbox", FALSE);
289
290 DestroyWindow(hLB);
291}
292
293static void test_item_height(void)
294{
295 INT itemHeight;
297 HFONT font;
298 HWND hLB;
299 HDC hdc;
300
301 hLB = create_listbox (0, 0);
302 ok ((hdc = GetDCEx( hLB, 0, DCX_CACHE )) != 0, "Can't get hdc\n");
303 ok ((font = GetCurrentObject(hdc, OBJ_FONT)) != 0, "Can't get the current font\n");
304 ok (GetTextMetricsA( hdc, &tm ), "Can't read font metrics\n");
305 ReleaseDC( hLB, hdc);
306
307 ok (SendMessageA(hLB, WM_SETFONT, (WPARAM)font, 0) == 0, "Can't set font\n");
308
309 itemHeight = SendMessageA(hLB, LB_GETITEMHEIGHT, 0, 0);
310 ok (itemHeight == tm.tmHeight, "Item height wrong, got %d, expecting %d\n", itemHeight, tm.tmHeight);
311
312 DestroyWindow (hLB);
313
314 hLB = CreateWindowA(WC_LISTBOXA, "TestList", LBS_OWNERDRAWVARIABLE, 0, 0, 100, 100, NULL, NULL, NULL, 0);
315
316 itemHeight = SendMessageA(hLB, LB_GETITEMHEIGHT, 0, 0);
317 ok(itemHeight > 0 && itemHeight <= tm.tmHeight, "Unexpected item height %d, expected %d.\n",
318 itemHeight, tm.tmHeight);
319 itemHeight = SendMessageA(hLB, LB_GETITEMHEIGHT, 5, 0);
320 ok(itemHeight > 0 && itemHeight <= tm.tmHeight, "Unexpected item height %d, expected %d.\n",
321 itemHeight, tm.tmHeight);
322 itemHeight = SendMessageA(hLB, LB_GETITEMHEIGHT, -5, 0);
323 ok(itemHeight > 0 && itemHeight <= tm.tmHeight, "Unexpected item height %d, expected %d.\n",
324 itemHeight, tm.tmHeight);
325
326 DestroyWindow (hLB);
327}
328
329static int got_selchange;
330
332{
333 static LONG defwndproc_counter = 0;
334 struct message m = { 0 };
335 LRESULT ret;
336
337 m.message = msg;
338 m.flags = sent|wparam|lparam;
339 if (defwndproc_counter) m.flags |= defwinproc;
340 m.wParam = wParam;
341 m.lParam = lParam;
342
343 switch (msg)
344 {
345 case WM_MEASUREITEM:
346 {
347 MEASUREITEMSTRUCT *mis = (void *)lParam;
348 BOOL is_unicode_data = FALSE;
350
351 if (mis->CtlType == ODT_LISTBOX)
352 {
353 HWND ctrl = GetDlgItem(hwnd, mis->CtlID);
354 is_unicode_data = GetWindowLongA(ctrl, GWL_STYLE) & LBS_HASSTRINGS;
355 }
356
357 mi.u.wp = 0;
358 mi.u.item.CtlType = mis->CtlType;
359 mi.u.item.CtlID = mis->CtlID;
360 mi.u.item.itemID = mis->itemID;
361 mi.u.item.wParam = wParam;
362
363 m.wParam = mi.u.wp;
364 if (is_unicode_data)
365 m.lParam = mis->itemData ? hash_Ly_W((const WCHAR *)mis->itemData) : 0;
366 else
367 m.lParam = mis->itemData ? hash_Ly((const char *)mis->itemData) : 0;
369
370 ok(wParam == mis->CtlID, "got wParam=%08lx, expected %08x\n", wParam, mis->CtlID);
371 ok(mis->CtlType == ODT_LISTBOX, "mi->CtlType = %u\n", mis->CtlType);
372 ok(mis->CtlID == 1, "mi->CtlID = %u\n", mis->CtlID);
373 ok(mis->itemHeight, "mi->itemHeight = 0\n");
374
375 break;
376 }
377 case WM_COMPAREITEM:
378 {
380 HWND ctrl = GetDlgItem(hwnd, cis->CtlID);
381 BOOL is_unicode_data = TRUE;
382
383 ok(wParam == cis->CtlID, "expected %#x, got %#lx\n", cis->CtlID, wParam);
384 ok(cis->hwndItem == ctrl, "expected %p, got %p\n", ctrl, cis->hwndItem);
385 ok((int)cis->itemID1 >= 0, "expected >= 0, got %d\n", cis->itemID1);
386 ok((int)cis->itemID2 == -1, "expected -1, got %d\n", cis->itemID2);
387
388 if (cis->CtlType == ODT_LISTBOX)
389 is_unicode_data = GetWindowLongA(ctrl, GWL_STYLE) & LBS_HASSTRINGS;
390
391 if (is_unicode_data)
392 {
393 m.wParam = cis->itemData1 ? hash_Ly_W((const WCHAR *)cis->itemData1) : 0;
394 m.lParam = cis->itemData2 ? hash_Ly_W((const WCHAR *)cis->itemData2) : 0;
395 }
396 else
397 {
398 m.wParam = cis->itemData1 ? hash_Ly((const char *)cis->itemData1) : 0;
399 m.lParam = cis->itemData2 ? hash_Ly((const char *)cis->itemData2) : 0;
400 }
402 break;
403 }
404 case WM_DRAWITEM:
405 {
406 RECT rc_item, rc_client, rc_clip;
408
409 ok(wParam == dis->CtlID, "got wParam=%08lx instead of %08x\n", wParam, dis->CtlID);
410 ok(dis->CtlType == ODT_LISTBOX, "wrong CtlType %04x\n", dis->CtlType);
411
412 GetClientRect(dis->hwndItem, &rc_client);
413 GetClipBox(dis->hDC, &rc_clip);
414 ok(EqualRect(&rc_client, &rc_clip) || IsRectEmpty(&rc_clip),
415 "client rect of the listbox should be equal to the clip box,"
416 "or the clip box should be empty\n");
417
418 SendMessageA(dis->hwndItem, LB_GETITEMRECT, dis->itemID, (LPARAM)&rc_item);
419 ok(EqualRect(&dis->rcItem, &rc_item), "item rects are not equal\n");
420
421 break;
422 }
423
424 case WM_COMMAND:
426 break;
427
428 default:
429 break;
430 }
431
432 defwndproc_counter++;
434 defwndproc_counter--;
435
436 return msg == WM_COMPAREITEM ? -1 : ret;
437}
438
439static HWND create_parent( void )
440{
441 static ATOM class;
442 WNDCLASSA cls;
443
444 if (!class)
445 {
446 cls.style = 0;
448 cls.cbClsExtra = 0;
449 cls.cbWndExtra = 0;
451 cls.hIcon = 0;
454 cls.lpszMenuName = NULL;
455 cls.lpszClassName = "main_window_class";
456 class = RegisterClassA( &cls );
457 }
458
459 return CreateWindowExA(0, "main_window_class", NULL, WS_POPUP | WS_VISIBLE, 100, 100, 400, 400, GetDesktopWindow(),
461}
462
463static void test_ownerdraw(void)
464{
465 static const DWORD styles[] =
466 {
467 0,
469 };
470 HWND parent, hLB;
471 INT ret;
472 RECT rc;
473 UINT i;
474
476 ok(parent != NULL, "Failed to create parent window.\n");
477
478 for (i = 0; i < ARRAY_SIZE(styles); i++)
479 {
481 ok(hLB != NULL, "Failed to create listbox window.\n");
482
484 UpdateWindow(hLB);
485
486 /* make height short enough */
487 SendMessageA(hLB, LB_GETITEMRECT, 0, (LPARAM)&rc);
488 SetWindowPos(hLB, 0, 0, 0, 100, rc.bottom - rc.top + 1, SWP_NOZORDER | SWP_NOMOVE);
489
490 /* make 0 item invisible */
491 SendMessageA(hLB, LB_SETTOPINDEX, 1, 0);
492 ret = SendMessageA(hLB, LB_GETTOPINDEX, 0, 0);
493 ok(ret == 1, "wrong top index %d\n", ret);
494
495 SendMessageA(hLB, LB_GETITEMRECT, 0, (LPARAM)&rc);
496 ok(!IsRectEmpty(&rc), "empty item rect\n");
497 ok(rc.top < 0, "rc.top is not negative (%d)\n", rc.top);
498
499 DestroyWindow(hLB);
500
501 /* Both FIXED and VARIABLE, FIXED should override VARIABLE. */
503 0, 0, 100, 100, NULL, NULL, NULL, 0);
504 ok(hLB != NULL, "last error 0x%08x\n", GetLastError());
505
506 ok(GetWindowLongA(hLB, GWL_STYLE) & LBS_OWNERDRAWVARIABLE, "Unexpected window style.\n");
507
508 ret = SendMessageA(hLB, LB_INSERTSTRING, -1, 0);
509 ok(ret == 0, "Unexpected return value %d.\n", ret);
510 ret = SendMessageA(hLB, LB_INSERTSTRING, -1, 0);
511 ok(ret == 1, "Unexpected return value %d.\n", ret);
512
513 ret = SendMessageA(hLB, LB_SETITEMHEIGHT, 0, 13);
514 ok(ret == LB_OKAY, "Failed to set item height, %d.\n", ret);
515
516 ret = SendMessageA(hLB, LB_GETITEMHEIGHT, 0, 0);
517 ok(ret == 13, "Unexpected item height %d.\n", ret);
518
519 ret = SendMessageA(hLB, LB_SETITEMHEIGHT, 1, 42);
520 ok(ret == LB_OKAY, "Failed to set item height, %d.\n", ret);
521
522 ret = SendMessageA(hLB, LB_GETITEMHEIGHT, 0, 0);
523 ok(ret == 42, "Unexpected item height %d.\n", ret);
524
525 ret = SendMessageA(hLB, LB_GETITEMHEIGHT, 1, 0);
526 ok(ret == 42, "Unexpected item height %d.\n", ret);
527
528 DestroyWindow (hLB);
529 }
530
532}
533
534#define listbox_test_query(exp, got) \
535 ok(exp.selected == got.selected, "expected selected %d, got %d\n", exp.selected, got.selected); \
536 ok(exp.anchor == got.anchor, "expected anchor %d, got %d\n", exp.anchor, got.anchor); \
537 ok(exp.caret == got.caret, "expected caret %d, got %d\n", exp.caret, got.caret); \
538 ok(exp.selcount == got.selcount, "expected selcount %d, got %d\n", exp.selcount, got.selcount);
539
540static void test_LB_SELITEMRANGE(void)
541{
542 static const struct listbox_stat test_nosel = { 0, LB_ERR, 0, 0 };
543 static const struct listbox_stat test_1 = { 0, LB_ERR, 0, 2 };
544 static const struct listbox_stat test_2 = { 0, LB_ERR, 0, 3 };
545 static const struct listbox_stat test_3 = { 0, LB_ERR, 0, 4 };
546 struct listbox_stat answer;
547 HWND hLB;
548 INT ret;
549
551 ok(hLB != NULL, "Failed to create listbox window.\n");
552
553 listbox_query(hLB, &answer);
554 listbox_test_query(test_nosel, answer);
555
557 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
558 listbox_query(hLB, &answer);
559 listbox_test_query(test_1, answer);
560
561 SendMessageA(hLB, LB_SETSEL, FALSE, -1);
562 listbox_query(hLB, &answer);
563 listbox_test_query(test_nosel, answer);
564
566 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
567 listbox_query(hLB, &answer);
568 listbox_test_query(test_3, answer);
569
570 SendMessageA(hLB, LB_SETSEL, FALSE, -1);
571 listbox_query(hLB, &answer);
572 listbox_test_query(test_nosel, answer);
573
575 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
576 listbox_query(hLB, &answer);
577 listbox_test_query(test_nosel, answer);
578
579 SendMessageA(hLB, LB_SETSEL, FALSE, -1);
580 listbox_query(hLB, &answer);
581 listbox_test_query(test_nosel, answer);
582
584 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
585 listbox_query(hLB, &answer);
586 listbox_test_query(test_1, answer);
587
588 SendMessageA(hLB, LB_SETSEL, FALSE, -1);
589 listbox_query(hLB, &answer);
590 listbox_test_query(test_nosel, answer);
591
593 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
594 listbox_query(hLB, &answer);
595 listbox_test_query(test_nosel, answer);
596
597 SendMessageA(hLB, LB_SETSEL, FALSE, -1);
598 listbox_query(hLB, &answer);
599 listbox_test_query(test_nosel, answer);
600
602 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
603 listbox_query(hLB, &answer);
604 listbox_test_query(test_2, answer);
605
606 SendMessageA(hLB, LB_SETSEL, FALSE, -1);
607 listbox_query(hLB, &answer);
608 listbox_test_query(test_nosel, answer);
609
611 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
612 listbox_query(hLB, &answer);
613 listbox_test_query(test_2, answer);
614
615 DestroyWindow(hLB);
616}
617
618static void test_LB_SETCURSEL(void)
619{
620 HWND parent, hLB;
621 INT ret;
622
624 ok(parent != NULL, "Failed to create parent window.\n");
625
627 ok(hLB != NULL, "Failed to create listbox.\n");
628
629 SendMessageA(hLB, LB_SETITEMHEIGHT, 0, 32);
630
631 ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
632 ok(ret == -1, "Unexpected anchor index %d.\n", ret);
633
634 ret = SendMessageA(hLB, LB_SETCURSEL, 2, 0);
635 ok(ret == 2, "LB_SETCURSEL returned %d instead of 2\n", ret);
636 ret = GetScrollPos(hLB, SB_VERT);
637 ok(ret == 0, "expected vscroll 0, got %d\n", ret);
638
639 ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
640 ok(ret == -1, "Unexpected anchor index %d.\n", ret);
641
642 ret = SendMessageA(hLB, LB_SETCURSEL, 3, 0);
643 ok(ret == 3, "LB_SETCURSEL returned %d instead of 3\n", ret);
644 ret = GetScrollPos(hLB, SB_VERT);
645 ok(ret == 1, "expected vscroll 1, got %d\n", ret);
646
647 ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
648 ok(ret == -1, "Unexpected anchor index %d.\n", ret);
649
650 DestroyWindow(hLB);
651
652 hLB = create_listbox(0, 0);
653 ok(hLB != NULL, "Failed to create ListBox window.\n");
654
655 ret = SendMessageA(hLB, LB_SETCURSEL, 1, 0);
656 ok(ret == 1, "Unexpected return value %d.\n", ret);
657
658 ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
659 ok(ret == -1, "Unexpected anchor index %d.\n", ret);
660
661 DestroyWindow(hLB);
662
663 /* LBS_EXTENDEDSEL */
665 ok(hLB != NULL, "Failed to create listbox.\n");
666
667 ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
668 ok(ret == -1, "Unexpected anchor index %d.\n", ret);
669
670 ret = SendMessageA(hLB, LB_SETCURSEL, 2, 0);
671 ok(ret == -1, "LB_SETCURSEL returned %d instead of 2\n", ret);
672
673 ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
674 ok(ret == -1, "Unexpected anchor index %d.\n", ret);
675
676 DestroyWindow(hLB);
677
678 /* LBS_MULTIPLESEL */
680 ok(hLB != NULL, "Failed to create listbox.\n");
681
682 ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
683 ok(ret == -1, "Unexpected anchor index %d.\n", ret);
684
685 ret = SendMessageA(hLB, LB_SETCURSEL, 2, 0);
686 ok(ret == -1, "LB_SETCURSEL returned %d instead of 2\n", ret);
687
688 ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
689 ok(ret == -1, "Unexpected anchor index %d.\n", ret);
690
691 DestroyWindow(hLB);
692}
693
694static void test_LB_SETSEL(void)
695{
696 HWND list;
697 int ret;
698
699 /* LBS_EXTENDEDSEL */
701 ok(list != NULL, "Failed to create ListBox window.\n");
702
704 ok(ret == -1, "Unexpected anchor index %d.\n", ret);
705
707 ok(ret == 0, "Unexpected return value %d.\n", ret);
709 ok(ret == 0, "Unexpected anchor index %d.\n", ret);
711 ok(ret == 0, "Unexpected caret index %d.\n", ret);
712
714 ok(ret == 0, "Unexpected return value %d.\n", ret);
716 ok(ret == 1, "Unexpected anchor index %d.\n", ret);
718 ok(ret == 1, "Unexpected caret index %d.\n", ret);
719
721 ok(ret == 0, "Unexpected return value %d.\n", ret);
723 ok(ret == 1, "Unexpected anchor index %d.\n", ret);
725 ok(ret == 1, "Unexpected caret index %d.\n", ret);
726
728
729 /* LBS_MULTIPLESEL */
731 ok(list != NULL, "Failed to create ListBox window.\n");
732
734 ok(ret == -1, "Unexpected anchor index %d.\n", ret);
735
737 ok(ret == 0, "Unexpected return value %d.\n", ret);
739 ok(ret == 0, "Unexpected anchor index %d.\n", ret);
741 ok(ret == 0, "Unexpected caret index %d.\n", ret);
742
744 ok(ret == 0, "Unexpected return value %d.\n", ret);
746 ok(ret == 1, "Unexpected anchor index %d.\n", ret);
748 ok(ret == 1, "Unexpected caret index %d.\n", ret);
749
751 ok(ret == 0, "Unexpected return value %d.\n", ret);
753 ok(ret == 1, "Unexpected anchor index %d.\n", ret);
755 ok(ret == 1, "Unexpected caret index %d.\n", ret);
756
758}
759
760static void test_listbox_height(void)
761{
762 HWND hList;
763 int r, id;
764
765 hList = CreateWindowA( WC_LISTBOXA, "list test", 0,
766 1, 1, 600, 100, NULL, NULL, NULL, NULL );
767 ok( hList != NULL, "failed to create listbox\n");
768
769 id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi");
770 ok( id == 0, "item id wrong\n");
771
773 ok( r == 0, "send message failed\n");
774
776 ok( r == 20, "height wrong\n");
777
779 ok( r == -1, "send message failed\n");
780
782 ok( r == 20, "height wrong\n");
783
784 /* Before Windows 10 1709 (or 1703?) the item height was limited to 255.
785 * Since then, with comctl32 V6 the limit is 65535.
786 */
788 ok(r == 0 || broken(r == -1), "Failed to set item height, %d.\n", r);
789 if (r == -1)
790 {
792 ok( r == 20, "Unexpected item height %d.\n", r);
793 }
794 else
795 {
797 ok( r == 256, "Unexpected item height %d.\n", r);
798
799 r = SendMessageA( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 65535, 0 ));
800 ok(r == 0, "Failed to set item height, %d.\n", r);
801
803 ok( r == 65535, "Unexpected item height %d.\n", r);
804 }
805
806 r = SendMessageA( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 0xff, 0 ));
807 ok( r == 0, "send message failed\n");
808
810 ok( r == 0xff, "height wrong\n");
811
813}
814
816{
817 static const DWORD styles[] =
818 {
819 0,
821 };
822 static const DWORD selstyles[] =
823 {
824 0,
828 };
829 static const LONG selexpect_single[] = { 0, 0, 1 };
830 static const LONG selexpect_single2[] = { 1, 0, 0 };
831 static const LONG selexpect_multi[] = { 1, 0, 1 };
832 static const LONG selexpect_multi2[] = { 1, 1, 0 };
833
834 HWND parent, listbox;
835 DWORD style;
836 LONG ret;
837 UINT i, j, k;
838
840 ok(parent != NULL, "Failed to create parent window.\n");
841 for (i = 0; i < ARRAY_SIZE(styles); i++)
842 {
843 /* Test if changing selection styles affects selection storage */
844 for (j = 0; j < ARRAY_SIZE(selstyles); j++)
845 {
846 LONG setcursel_expect, selitemrange_expect, getselcount_expect;
847 const LONG *selexpect;
848
849 listbox = CreateWindowA(WC_LISTBOXA, "TestList", styles[i] | selstyles[j] | WS_CHILD | WS_VISIBLE,
850 0, 0, 100, 100, parent, (HMENU)ID_LISTBOX, NULL, 0);
851 ok(listbox != NULL, "%u: Failed to create ListBox window.\n", j);
852
853 if (selstyles[j] & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL))
854 {
855 setcursel_expect = LB_ERR;
856 selitemrange_expect = LB_OKAY;
857 getselcount_expect = 2;
858 selexpect = selexpect_multi;
859 }
860 else
861 {
862 setcursel_expect = 2;
863 selitemrange_expect = LB_ERR;
864 getselcount_expect = LB_ERR;
865 selexpect = selexpect_single;
866 }
867
868 for (k = 0; k < ARRAY_SIZE(selexpect_multi); k++)
869 {
870 ret = SendMessageA(listbox, LB_INSERTSTRING, -1, (LPARAM)"x");
871 ok(ret == k, "%u: Unexpected return value %d, expected %d.\n", j, ret, k);
872 }
873 ret = SendMessageA(listbox, LB_GETCOUNT, 0, 0);
874 ok(ret == ARRAY_SIZE(selexpect_multi), "%u: Unexpected count %d.\n", j, ret);
875
876 /* Select items with different methods */
877 ret = SendMessageA(listbox, LB_SETCURSEL, 2, 0);
878 ok(ret == setcursel_expect, "%u: Unexpected return value %d.\n", j, ret);
879 ret = SendMessageA(listbox, LB_SELITEMRANGE, TRUE, MAKELPARAM(0, 0));
880 ok(ret == selitemrange_expect, "%u: Unexpected return value %d.\n", j, ret);
881 ret = SendMessageA(listbox, LB_SELITEMRANGE, TRUE, MAKELPARAM(2, 2));
882 ok(ret == selitemrange_expect, "%u: Unexpected return value %d.\n", j, ret);
883
884 /* Verify that the proper items are selected */
885 for (k = 0; k < ARRAY_SIZE(selexpect_multi); k++)
886 {
887 ret = SendMessageA(listbox, LB_GETSEL, k, 0);
888 ok(ret == selexpect[k], "%u: Unexpected selection state %d, expected %d.\n",
889 j, ret, selexpect[k]);
890 }
891
892 /* Now change the selection style */
893 style = GetWindowLongA(listbox, GWL_STYLE);
894 ok((style & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) == selstyles[j],
895 "%u: unexpected window styles %#x.\n", j, style);
896 if (selstyles[j] & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL))
897 style &= ~selstyles[j];
898 else
900 SetWindowLongA(listbox, GWL_STYLE, style);
901 style = GetWindowLongA(listbox, GWL_STYLE);
902 ok(!(style & selstyles[j]), "%u: unexpected window styles %#x.\n", j, style);
903
904 /* Verify that the same items are selected */
905 ret = SendMessageA(listbox, LB_GETSELCOUNT, 0, 0);
906 ok(ret == getselcount_expect, "%u: expected %d from LB_GETSELCOUNT, got %d\n",
907 j, getselcount_expect, ret);
908
909 for (k = 0; k < ARRAY_SIZE(selexpect_multi); k++)
910 {
911 ret = SendMessageA(listbox, LB_GETSEL, k, 0);
912 ok(ret == selexpect[k], "%u: Unexpected selection state %d, expected %d.\n",
913 j, ret, selexpect[k]);
914 }
915
916 /* Lastly see if we can still change the selection as before with old style */
917 if (setcursel_expect != LB_ERR) setcursel_expect = 0;
918 ret = SendMessageA(listbox, LB_SETCURSEL, 0, 0);
919 ok(ret == setcursel_expect, "%u: Unexpected return value %d.\n", j, ret);
920 ret = SendMessageA(listbox, LB_SELITEMRANGE, TRUE, MAKELPARAM(1, 1));
921 ok(ret == selitemrange_expect, "%u: Unexpected return value %d.\n", j, ret);
922 ret = SendMessageA(listbox, LB_SELITEMRANGE, FALSE, MAKELPARAM(2, 2));
923 ok(ret == selitemrange_expect, "%u: Unexpected return value %d.\n", j, ret);
924
925 /* And verify the selections */
926 selexpect = (selstyles[j] & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) ? selexpect_multi2 : selexpect_single2;
927 ret = SendMessageA(listbox, LB_GETSELCOUNT, 0, 0);
928 ok(ret == getselcount_expect, "%u: expected %d from LB_GETSELCOUNT, got %d\n",
929 j, getselcount_expect, ret);
930
931 for (k = 0; k < ARRAY_SIZE(selexpect_multi); k++)
932 {
933 ret = SendMessageA(listbox, LB_GETSEL, k, 0);
934 ok(ret == selexpect[k], "%u: Unexpected selection state %d, expected %d.\n",
935 j, ret, selexpect[k]);
936 }
937
938 DestroyWindow(listbox);
939 }
940 }
942}
943
944static void test_itemfrompoint(void)
945{
946 /* WS_POPUP is required in order to have a more accurate size calculation (
947 without caption). LBS_NOINTEGRALHEIGHT is required in order to test
948 behavior of partially-displayed item.
949 */
950 HWND hList = CreateWindowA( WC_LISTBOXA, "list test",
952 1, 1, 600, 100, NULL, NULL, NULL, NULL );
953 ULONG r, id;
954 RECT rc;
955
956 r = SendMessageA(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
957 ok( r == MAKELPARAM(0xffff, 1), "Unexpected ret value %#x.\n", r );
958
960 ok( r == MAKELPARAM(0xffff, 1), "Unexpected ret value %#x.\n", r );
961
963 ok( r == MAKELPARAM(0xffff, 1), "Unexpected ret value %#x.\n", r );
964
965 id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi");
966 ok( id == 0, "item id wrong\n");
967 id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi1");
968 ok( id == 1, "item id wrong\n");
969
970 r = SendMessageA(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
971 ok( r == 0x1, "ret %x\n", r );
972
973 r = SendMessageA(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 601 ));
974 ok( r == MAKELPARAM(1, 1), "Unexpected ret value %#x.\n", r );
975
976 /* Resize control so that below assertions about sizes are valid */
978 ok( r == 1, "ret %x\n", r);
979 r = MoveWindow(hList, 1, 1, 600, (rc.bottom - rc.top + 1) * 9 / 2, TRUE);
980 ok( r != 0, "ret %x\n", r);
981
982 id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi2");
983 ok( id == 2, "item id wrong\n");
984 id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi3");
985 ok( id == 3, "item id wrong\n");
986 id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi4");
987 ok( id == 4, "item id wrong\n");
988 id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi5");
989 ok( id == 5, "item id wrong\n");
990 id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi6");
991 ok( id == 6, "item id wrong\n");
992 id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi7");
993 ok( id == 7, "item id wrong\n");
994
995 /* Set the listbox up so that id 1 is at the top, this leaves 5
996 partially visible at the bottom and 6, 7 are invisible */
997
1000 ok( r == 1, "top %d\n", r);
1001
1003 ok( r == 1, "ret %x\n", r);
1005 ok( r == 0, "ret %x\n", r);
1006
1007 r = SendMessageA( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(/* x */ 10, /* y */ 10) );
1008 ok( r == 1, "ret %x\n", r);
1009
1010 r = SendMessageA( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(1000, 10) );
1011 ok( r == 0x10001, "ret %x\n", r );
1012
1013 r = SendMessageA( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, -10) );
1014 ok( r == 0x10001, "ret %x\n", r );
1015
1016 r = SendMessageA( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, 100) );
1017 ok( r == 0x10005, "item %x\n", r );
1018
1019 r = SendMessageA( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, 200) );
1020 ok( r == 0x10005, "item %x\n", r );
1021
1023}
1024
1025static void test_listbox_item_data(void)
1026{
1027 HWND hList;
1028 int r, id;
1029
1030 hList = CreateWindowA( WC_LISTBOXA, "list test", 0,
1031 1, 1, 600, 100, NULL, NULL, NULL, NULL );
1032 ok( hList != NULL, "failed to create listbox\n");
1033
1034 id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi");
1035 ok( id == 0, "item id wrong\n");
1036
1037 r = SendMessageA( hList, LB_SETITEMDATA, 0, MAKELPARAM( 20, 0 ));
1038 ok(r == TRUE, "LB_SETITEMDATA returned %d instead of TRUE\n", r);
1039
1041 ok( r == 20, "get item data failed\n");
1042
1044}
1045
1046static void test_listbox_LB_DIR(void)
1047{
1048 char path[MAX_PATH], curdir[MAX_PATH];
1049 HWND hList;
1050 int res, itemCount;
1051 int itemCount_justFiles;
1052 int itemCount_justDrives;
1053 int itemCount_allFiles;
1054 int itemCount_allDirs;
1055 int i;
1056 char pathBuffer[MAX_PATH];
1057 char * p;
1058 char driveletter;
1059 const char *wildcard = "*";
1060 HANDLE file;
1061 BOOL ret;
1062
1063 GetCurrentDirectoryA(ARRAY_SIZE(curdir), curdir);
1064
1067 ok(ret, "Failed to set current directory.\n");
1068
1069 ret = CreateDirectoryA("lb_dir_test", NULL);
1070 ok(ret, "Failed to create test directory.\n");
1071
1073 ok(file != INVALID_HANDLE_VALUE, "Error creating the test file: %d\n", GetLastError());
1074 CloseHandle( file );
1075
1076 /* NOTE: for this test to succeed, there must be no subdirectories
1077 under the current directory. In addition, there must be at least
1078 one file that fits the wildcard w*.c . Normally, the test
1079 directory itself satisfies both conditions.
1080 */
1082 1, 1, 600, 100, NULL, NULL, NULL, NULL );
1083 ok(hList != NULL, "Failed to create listbox window.\n");
1084
1085 /* Test for standard usage */
1086
1087 /* This should list all the files in the test directory. */
1088 strcpy(pathBuffer, wildcard);
1091 if (res == -1) /* "*" wildcard doesn't work on win9x */
1092 {
1093 wildcard = "*.*";
1094 strcpy(pathBuffer, wildcard);
1096 }
1097 ok (res >= 0, "SendMessage(LB_DIR, 0, *) failed - 0x%08x\n", GetLastError());
1098
1099 /* There should be some content in the listbox */
1100 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1101 ok (itemCount > 0, "SendMessage(LB_DIR) did NOT fill the listbox!\n");
1102 itemCount_allFiles = itemCount;
1103 ok(res + 1 == itemCount,
1104 "SendMessage(LB_DIR, 0, *) returned incorrect index (expected %d got %d)!\n",
1105 itemCount - 1, res);
1106
1107 /* This tests behavior when no files match the wildcard */
1111 ok (res == -1, "SendMessage(LB_DIR, 0, %s) returned %d, expected -1\n", BAD_EXTENSION, res);
1112
1113 /* There should be NO content in the listbox */
1114 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1115 ok (itemCount == 0, "SendMessage(LB_DIR) DID fill the listbox!\n");
1116
1117
1118 /* This should list all the w*.c files in the test directory
1119 * As of this writing, this includes win.c, winstation.c, wsprintf.c
1120 */
1121 strcpy(pathBuffer, "w*.c");
1124 ok (res >= 0, "SendMessage(LB_DIR, 0, w*.c) failed - 0x%08x\n", GetLastError());
1125
1126 /* Path specification does NOT converted to uppercase */
1127 ok (!strcmp(pathBuffer, "w*.c"),
1128 "expected no change to pathBuffer, got %s\n", pathBuffer);
1129
1130 /* There should be some content in the listbox */
1131 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1132 ok (itemCount > 0, "SendMessage(LB_DIR) did NOT fill the listbox!\n");
1133 itemCount_justFiles = itemCount;
1134 ok(res + 1 == itemCount,
1135 "SendMessage(LB_DIR, 0, w*.c) returned incorrect index (expected %d got %d)!\n",
1136 itemCount - 1, res);
1137
1138 /* Every single item in the control should start with a w and end in .c */
1139 for (i = 0; i < itemCount; i++)
1140 {
1144 ok(((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1145 (*(p-1) == 'c' || *(p-1) == 'C') &&
1146 (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1147 }
1148
1149 /* Test DDL_DIRECTORY */
1150 strcpy(pathBuffer, wildcard);
1153 ok (res > 0, "SendMessage(LB_DIR, DDL_DIRECTORY, *) failed - 0x%08x\n", GetLastError());
1154
1155 /* There should be some content in the listbox.
1156 * All files plus "[..]"
1157 */
1158 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1159 itemCount_allDirs = itemCount - itemCount_allFiles;
1160 ok (itemCount >= itemCount_allFiles,
1161 "SendMessage(LB_DIR, DDL_DIRECTORY, *) filled with %d entries, expected > %d\n",
1162 itemCount, itemCount_allFiles);
1163 ok(res + 1 == itemCount,
1164 "SendMessage(LB_DIR, DDL_DIRECTORY, *) returned incorrect index (expected %d got %d)!\n",
1165 itemCount - 1, res);
1166
1167 /* This tests behavior when no files match the wildcard */
1171 ok (res == -1, "SendMessage(LB_DIR, DDL_DIRECTORY, %s) returned %d, expected -1\n", BAD_EXTENSION, res);
1172
1173 /* There should be NO content in the listbox */
1174 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1175 ok (itemCount == 0, "SendMessage(LB_DIR) DID fill the listbox!\n");
1176
1177 /* Test DDL_DIRECTORY */
1178 strcpy(pathBuffer, "w*.c");
1181 ok (res >= 0, "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) failed - 0x%08x\n", GetLastError());
1182
1183 /* There should be some content in the listbox. Since the parent directory does not
1184 * fit w*.c, there should be exactly the same number of items as without DDL_DIRECTORY
1185 */
1186 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1187 ok (itemCount == itemCount_justFiles,
1188 "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) filled with %d entries, expected %d\n",
1189 itemCount, itemCount_justFiles);
1190 ok(res + 1 == itemCount,
1191 "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) returned incorrect index (expected %d got %d)!\n",
1192 itemCount - 1, res);
1193
1194 /* Every single item in the control should start with a w and end in .c. */
1195 for (i = 0; i < itemCount; i++)
1196 {
1200 ok(
1201 ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1202 (*(p-1) == 'c' || *(p-1) == 'C') &&
1203 (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1204 }
1205
1206 /* Test DDL_DRIVES|DDL_EXCLUSIVE */
1207 strcpy(pathBuffer, wildcard);
1210 ok (res >= 0, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) failed - 0x%08x\n", GetLastError());
1211
1212 /* There should be some content in the listbox. In particular, there should
1213 * be at least one element before, since the string "[-c-]" should
1214 * have been added. Depending on the user setting, more drives might have
1215 * been added.
1216 */
1217 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1218 ok (itemCount >= 1,
1219 "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) filled with %d entries, expected at least %d\n",
1220 itemCount, 1);
1221 itemCount_justDrives = itemCount;
1222 ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) returned incorrect index!\n");
1223
1224 /* Every single item in the control should fit the format [-c-] */
1225 for (i = 0; i < itemCount; i++)
1226 {
1228 driveletter = '\0';
1230 ok( strlen(pathBuffer) == 5, "Length of drive string is not 5\n" );
1231 ok( sscanf(pathBuffer, "[-%c-]", &driveletter) == 1, "Element %d (%s) does not fit [-X-]\n", i, pathBuffer);
1232 ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1233 if (!(driveletter >= 'a' && driveletter <= 'z'))
1234 {
1235 /* Correct after invalid entry is found */
1236 itemCount_justDrives--;
1237 }
1238 }
1239
1240 /* This tests behavior when no files match the wildcard */
1244 ok (res == itemCount_justDrives -1, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1245 BAD_EXTENSION, res, itemCount_justDrives -1);
1246
1247 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1248 ok (itemCount == itemCount_justDrives, "SendMessage(LB_DIR) returned %d expected %d\n",
1249 itemCount, itemCount_justDrives);
1250
1251 /* Test DDL_DRIVES. */
1252 strcpy(pathBuffer, wildcard);
1255 ok (res > 0, "SendMessage(LB_DIR, DDL_DRIVES, *) failed - 0x%08x\n", GetLastError());
1256
1257 /* There should be some content in the listbox. In particular, there should
1258 * be at least one element before, since the string "[-c-]" should
1259 * have been added. Depending on the user setting, more drives might have
1260 * been added.
1261 */
1262 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1263 ok (itemCount == itemCount_justDrives + itemCount_allFiles,
1264 "SendMessage(LB_DIR, DDL_DRIVES, *) filled with %d entries, expected %d\n",
1265 itemCount, itemCount_justDrives + itemCount_allFiles);
1266 ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DRIVES, *) returned incorrect index!\n");
1267
1268 /* This tests behavior when no files match the wildcard */
1272 ok (res == itemCount_justDrives -1, "SendMessage(LB_DIR, DDL_DRIVES, %s) returned %d, expected %d\n",
1273 BAD_EXTENSION, res, itemCount_justDrives -1);
1274
1275 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1276 ok (itemCount == res + 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount, res + 1);
1277
1278 /* Test DDL_DRIVES. */
1279 strcpy(pathBuffer, "w*.c");
1282 ok (res > 0, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) failed - 0x%08x\n", GetLastError());
1283
1284 /* There should be some content in the listbox. In particular, there should
1285 * be at least one element before, since the string "[-c-]" should
1286 * have been added. Depending on the user setting, more drives might have
1287 * been added.
1288 */
1289 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1290 ok (itemCount == itemCount_justDrives + itemCount_justFiles,
1291 "SendMessage(LB_DIR, DDL_DRIVES, w*.c) filled with %d entries, expected %d\n",
1292 itemCount, itemCount_justDrives + itemCount_justFiles);
1293 ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) returned incorrect index!\n");
1294
1295 /* Every single item in the control should fit the format [-c-], or w*.c */
1296 for (i = 0; i < itemCount; i++)
1297 {
1299 driveletter = '\0';
1302 if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1)
1303 {
1304 ok( strlen(pathBuffer) == 5, "Length of drive string is not 5\n" );
1305 ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1306 }
1307 else
1308 {
1309 ok(
1310 ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1311 (*(p-1) == 'c' || *(p-1) == 'C') &&
1312 (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1313 }
1314 }
1315
1316 /* Test DDL_DIRECTORY|DDL_DRIVES. This does *not* imply DDL_EXCLUSIVE */
1317 strcpy(pathBuffer, wildcard);
1320 ok (res > 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, *) failed - 0x%08x\n", GetLastError());
1321
1322 /* There should be some content in the listbox. In particular, there should
1323 * be exactly the number of plain files, plus the number of mapped drives.
1324 */
1325 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1326 ok (itemCount == itemCount_allFiles + itemCount_justDrives + itemCount_allDirs,
1327 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1328 itemCount, itemCount_allFiles + itemCount_justDrives + itemCount_allDirs);
1329 ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
1330
1331 /* Every single item in the control should start with a w and end in .c,
1332 * except for the "[..]" string, which should appear exactly as it is,
1333 * and the mapped drives in the format "[-X-]".
1334 */
1335 for (i = 0; i < itemCount; i++)
1336 {
1338 driveletter = '\0';
1340 if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1)
1341 ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1342 }
1343
1344 /* This tests behavior when no files match the wildcard */
1348 ok (res == itemCount_justDrives -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, %s) returned %d, expected %d\n",
1349 BAD_EXTENSION, res, itemCount_justDrives -1);
1350
1351 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1352 ok (itemCount == res + 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount, res + 1);
1353
1354 /* Test DDL_DIRECTORY|DDL_DRIVES. */
1355 strcpy(pathBuffer, "w*.c");
1358 ok (res > 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) failed - 0x%08x\n", GetLastError());
1359
1360 /* There should be some content in the listbox. In particular, there should
1361 * be exactly the number of plain files, plus the number of mapped drives.
1362 */
1363 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1364 ok (itemCount == itemCount_justFiles + itemCount_justDrives,
1365 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1366 itemCount, itemCount_justFiles + itemCount_justDrives);
1367 ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
1368
1369 /* Every single item in the control should start with a w and end in .c,
1370 * except the mapped drives in the format "[-X-]". The "[..]" directory
1371 * should not appear.
1372 */
1373 for (i = 0; i < itemCount; i++)
1374 {
1376 driveletter = '\0';
1379 if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1)
1380 ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1381 else
1382 ok(
1383 ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1384 (*(p-1) == 'c' || *(p-1) == 'C') &&
1385 (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1386 }
1387
1388 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1389 strcpy(pathBuffer, wildcard);
1392 ok (res != -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) failed err %u\n",
1393 GetLastError());
1394
1395 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1396 ok (itemCount == itemCount_allDirs,
1397 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1398 itemCount, itemCount_allDirs);
1399 ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) returned incorrect index!\n");
1400
1401 if (itemCount)
1402 {
1405 ok( !strcmp(pathBuffer, "[..]"), "First element is %s, not [..]\n", pathBuffer);
1406 }
1407
1408 /* This tests behavior when no files match the wildcard */
1412 ok (res == -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1413 BAD_EXTENSION, res, -1);
1414
1415 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1416 ok (itemCount == res + 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount, res + 1);
1417
1418
1419 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1420 strcpy(pathBuffer, "w*.c");
1423 ok (res == LB_ERR, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, w*.c) returned %d expected %d\n", res, LB_ERR);
1424
1425 /* There should be no elements, since "[..]" does not fit w*.c */
1426 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1427 ok (itemCount == 0,
1428 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1429 itemCount, 0);
1430
1431 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1432 strcpy(pathBuffer, wildcard);
1435 ok (res > 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
1436
1437 /* There should be no plain files on the listbox */
1438 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1439 ok (itemCount == itemCount_justDrives + itemCount_allDirs,
1440 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1441 itemCount, itemCount_justDrives + itemCount_allDirs);
1442 ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
1443
1444 for (i = 0; i < itemCount; i++)
1445 {
1447 driveletter = '\0';
1449 if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1)
1450 ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1451 else
1452 ok( pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']',
1453 "Element %d (%s) does not fit expected [...]\n", i, pathBuffer);
1454 }
1455
1456 /* This tests behavior when no files match the wildcard */
1460 ok (res == itemCount_justDrives -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1461 BAD_EXTENSION, res, itemCount_justDrives -1);
1462
1463 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1464 ok (itemCount == res + 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount, res + 1);
1465
1466 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1467 strcpy(pathBuffer, "w*.c");
1470 ok (res >= 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
1471
1472 /* There should be no plain files on the listbox, and no [..], since it does not fit w*.c */
1473 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1474 ok (itemCount == itemCount_justDrives,
1475 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1476 itemCount, itemCount_justDrives);
1477 ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
1478
1479 for (i = 0; i < itemCount; i++)
1480 {
1482 driveletter = '\0';
1484 ok (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1, "Element %d (%s) does not fit [-X-]\n", i, pathBuffer);
1485 ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1486 }
1488
1489 DeleteFileA( "wtest1.tmp.c" );
1490 RemoveDirectoryA("lb_dir_test");
1491
1492 SetCurrentDirectoryA(curdir);
1493}
1494
1497
1498#define ID_TEST_LABEL 1001
1499#define ID_TEST_LISTBOX 1002
1500
1502{
1503 g_label = CreateWindowA(WC_STATICA, "Contents of static control before DlgDirList.",
1504 WS_CHILD | WS_VISIBLE, 10, 10, 512, 32, hwnd, (HMENU)ID_TEST_LABEL, NULL, 0);
1505 if (!g_label) return FALSE;
1506
1507 g_listBox = CreateWindowA(WC_LISTBOXA, "DlgDirList test",
1508 WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | WS_VSCROLL, 10, 60, 256, 256,
1510 if (!g_listBox) return FALSE;
1511
1512 return TRUE;
1513}
1514
1516{
1517 LRESULT result = 0;
1518
1519 switch (uiMsg)
1520 {
1521 case WM_DESTROY:
1522 PostQuitMessage(0);
1523 break;
1524 case WM_CREATE:
1526 break;
1527 default:
1529 break;
1530 }
1531 return result;
1532}
1533
1535{
1536 WNDCLASSA cls;
1537
1538 cls.style = 0;
1539 cls.cbClsExtra = 0;
1540 cls.cbWndExtra = 0;
1541 cls.hInstance = hInst;
1542 cls.hIcon = NULL;
1544 cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
1545 cls.lpszMenuName = NULL;
1547 cls.lpszClassName = "ListboxContainerClass";
1548 if (!RegisterClassA (&cls)) return FALSE;
1549
1550 return TRUE;
1551}
1552
1553static void test_listbox_dlgdir(void)
1554{
1556 HWND hWnd;
1557 int res, itemCount;
1558 int itemCount_allDirs;
1559 int itemCount_justFiles;
1560 int itemCount_justDrives;
1561 int i;
1562 char pathBuffer[MAX_PATH];
1563 char itemBuffer[MAX_PATH];
1564 char tempBuffer[MAX_PATH];
1565 char * p;
1566 char driveletter;
1567 HANDLE file;
1568 BOOL ret;
1569
1571 ok(file != INVALID_HANDLE_VALUE, "Error creating the test file: %d\n", GetLastError());
1572 CloseHandle( file );
1573
1574 /* NOTE: for this test to succeed, there must be no subdirectories
1575 under the current directory. In addition, there must be at least
1576 one file that fits the wildcard w*.c . Normally, the test
1577 directory itself satisfies both conditions.
1578 */
1579
1582 ok(ret, "Failed to register test class.\n");
1583
1584 hWnd = CreateWindowA("ListboxContainerClass", "ListboxContainerClass",
1587 NULL, NULL, hInst, 0);
1588 ok(hWnd != NULL, "Failed to create container window.\n");
1589
1590 /* Test for standard usage */
1591
1592 /* The following should be overwritten by the directory path */
1593 SendMessageA(g_label, WM_SETTEXT, 0, (LPARAM)"default contents");
1594
1595 /* This should list all the w*.c files in the test directory
1596 * As of this writing, this includes win.c, winstation.c, wsprintf.c
1597 */
1598 strcpy(pathBuffer, "w*.c");
1600 ok (res == 1, "DlgDirList(*.c, 0) returned %d - expected 1 - 0x%08x\n", res, GetLastError());
1601
1602 /* Path specification gets converted to uppercase */
1603 ok (!strcmp(pathBuffer, "W*.C"),
1604 "expected conversion to uppercase, got %s\n", pathBuffer);
1605
1606 /* Loaded path should have overwritten the label text */
1608 ok (strcmp("default contents", pathBuffer), "DlgDirList() did not modify static control!\n");
1609
1610 /* There should be some content in the listbox */
1611 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1612 ok (itemCount > 0, "DlgDirList() did NOT fill the listbox!\n");
1613 itemCount_justFiles = itemCount;
1614
1615 /* Every single item in the control should start with a w and end in .c */
1616 for (i = 0; i < itemCount; i++)
1617 {
1621 ok(((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1622 (*(p-1) == 'c' || *(p-1) == 'C') &&
1623 (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1624 }
1625
1626 /* Test behavior when no files match the wildcard */
1629 ok (res == 1, "DlgDirList(%s, 0) returned %d expected 1\n", BAD_EXTENSION, res);
1630
1631 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1632 ok (itemCount == 0, "DlgDirList() DID fill the listbox!\n");
1633
1634 /* Test DDL_DIRECTORY */
1635 strcpy(pathBuffer, "w*.c");
1637 ok (res == 1, "DlgDirList(*.c, DDL_DIRECTORY) failed - 0x%08x\n", GetLastError());
1638
1639 /* There should be some content in the listbox. In particular, there should
1640 * be exactly more elements than before, since the directories should
1641 * have been added.
1642 */
1643 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1644 itemCount_allDirs = itemCount - itemCount_justFiles;
1645 ok (itemCount >= itemCount_justFiles, "DlgDirList(DDL_DIRECTORY) filled with %d entries, expected > %d\n",
1646 itemCount, itemCount_justFiles);
1647
1648 /* Every single item in the control should start with a w and end in .c,
1649 * except for the "[..]" string, which should appear exactly as it is.
1650 */
1651 for (i = 0; i < itemCount; i++)
1652 {
1656 ok( (pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']') ||
1657 ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1658 (*(p-1) == 'c' || *(p-1) == 'C') &&
1659 (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1660 }
1661
1662 /* Test behavior when no files match the wildcard */
1665 ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY) returned %d expected 1\n", BAD_EXTENSION, res);
1666
1667 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1668 ok (itemCount == itemCount_allDirs, "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
1669 itemCount_allDirs, itemCount);
1670 for (i = 0; i < itemCount; i++)
1671 {
1674 ok( pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']',
1675 "Element %d (%s) does not fit requested [...]\n", i, pathBuffer);
1676 }
1677
1678 /* Test DDL_DRIVES. At least on WinXP-SP2, this implies DDL_EXCLUSIVE */
1679 strcpy(pathBuffer, "w*.c");
1681 ok (res == 1, "DlgDirList(*.c, DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1682
1683 /* There should be some content in the listbox. In particular, there should
1684 * be at least one element before, since the string "[-c-]" should
1685 * have been added. Depending on the user setting, more drives might have
1686 * been added.
1687 */
1688 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1689 ok (itemCount >= 1,
1690 "DlgDirList(DDL_DRIVES) filled with %d entries, expected at least %d\n",
1691 itemCount, 1);
1692 itemCount_justDrives = itemCount;
1693
1694 /* Every single item in the control should fit the format [-c-] */
1695 for (i = 0; i < itemCount; i++)
1696 {
1698 driveletter = '\0';
1700 ok( strlen(pathBuffer) == 5, "Length of drive string is not 5\n" );
1701 ok( sscanf(pathBuffer, "[-%c-]", &driveletter) == 1, "Element %d (%s) does not fit [-X-]\n", i, pathBuffer);
1702 ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1703 if (!(driveletter >= 'a' && driveletter <= 'z')) {
1704 /* Correct after invalid entry is found */
1705 trace("removing count of invalid entry %s\n", pathBuffer);
1706 itemCount_justDrives--;
1707 }
1708 }
1709
1710 /* Test behavior when no files match the wildcard */
1713 ok (res == 1, "DlgDirList(%s, DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION, res);
1714
1715 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1716 ok (itemCount == itemCount_justDrives, "DlgDirList() incorrectly filled the listbox!\n");
1717
1718 /* Test DDL_DIRECTORY|DDL_DRIVES. This does *not* imply DDL_EXCLUSIVE */
1719 strcpy(pathBuffer, "w*.c");
1721 ok (res == 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1722
1723 /* There should be some content in the listbox. In particular, there should
1724 * be exactly the number of plain files, plus the number of mapped drives,
1725 * plus one "[..]"
1726 */
1727 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1728 ok (itemCount == itemCount_justFiles + itemCount_justDrives + itemCount_allDirs,
1729 "DlgDirList(DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1730 itemCount, itemCount_justFiles + itemCount_justDrives + itemCount_allDirs);
1731
1732 /* Every single item in the control should start with a w and end in .c,
1733 * except for the "[..]" string, which should appear exactly as it is,
1734 * and the mapped drives in the format "[-X-]".
1735 */
1736 for (i = 0; i < itemCount; i++)
1737 {
1739 driveletter = '\0';
1742 if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1)
1743 ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1744 else
1745 ok( (pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']') ||
1746 ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1747 (*(p-1) == 'c' || *(p-1) == 'C') &&
1748 (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1749 }
1750
1751 /* Test behavior when no files match the wildcard */
1754 ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION, res);
1755
1756 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1757 ok (itemCount == itemCount_justDrives + itemCount_allDirs,
1758 "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
1759 itemCount_justDrives + itemCount_allDirs, itemCount);
1760
1761 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1762 strcpy(pathBuffer, "w*.c");
1764 ok (res == 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_EXCLUSIVE) failed - 0x%08x\n", GetLastError());
1765
1766 /* There should be exactly one element: "[..]" */
1767 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1768 ok (itemCount == itemCount_allDirs,
1769 "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1770 itemCount, itemCount_allDirs);
1771
1772 if (itemCount && GetCurrentDirectoryA( MAX_PATH, pathBuffer ) > 3) /* there's no [..] in drive root */
1773 {
1776 ok( !strcmp(pathBuffer, "[..]"), "First (and only) element is not [..]\n");
1777 }
1778
1779 /* Test behavior when no files match the wildcard */
1782 ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION, res);
1783
1784 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1785 ok (itemCount == itemCount_allDirs, "DlgDirList() incorrectly filled the listbox!\n");
1786
1787 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1788 strcpy(pathBuffer, "w*.c");
1790 ok (res == 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) failed - 0x%08x\n", GetLastError());
1791
1792 /* There should be no plain files on the listbox */
1793 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1794 ok (itemCount == itemCount_justDrives + itemCount_allDirs,
1795 "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1796 itemCount, itemCount_justDrives + itemCount_allDirs);
1797
1798 for (i = 0; i < itemCount; i++)
1799 {
1801 driveletter = '\0';
1803 if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1)
1804 ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1805 else
1806 ok( pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']',
1807 "Element %d (%s) does not fit expected [...]\n", i, pathBuffer);
1808 }
1809
1810 /* Test behavior when no files match the wildcard */
1813 ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION, res);
1814
1815 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1816 ok (itemCount == itemCount_justDrives + itemCount_allDirs, "DlgDirList() incorrectly filled the listbox!\n");
1817
1818 /* Now test DlgDirSelectEx() in normal operation */
1819 /* Fill with everything - drives, directory and all plain files. */
1820 strcpy(pathBuffer, "*");
1822 ok (res != 0, "DlgDirList(*, DDL_DIRECTORY|DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1823
1824 SendMessageA(g_listBox, LB_SETCURSEL, -1, 0); /* Unselect any current selection */
1826 SetLastError(0xdeadbeef);
1828 ok (GetLastError() == 0xdeadbeef,
1829 "DlgDirSelectEx() with no selection modified last error code from 0xdeadbeef to 0x%08x\n",
1830 GetLastError());
1831 ok (res == 0, "DlgDirSelectEx() with no selection returned %d, expected 0\n", res);
1832 /* WinXP-SP2 leaves pathBuffer untouched, but Win98 fills it with garbage. */
1833 /*
1834 ok (!*pathBuffer, "DlgDirSelectEx() with no selection filled buffer with %s\n", pathBuffer);
1835 */
1836 /* Test proper drive/dir/file recognition */
1837 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1838 for (i = 0; i < itemCount; i++)
1839 {
1840 memset(itemBuffer, 0, MAX_PATH);
1842 memset(tempBuffer, 0, MAX_PATH);
1843 driveletter = '\0';
1844 SendMessageA(g_listBox, LB_GETTEXT, i, (LPARAM)itemBuffer);
1846 ok (res == i, "SendMessageA(LB_SETCURSEL, %d) failed\n", i);
1847 if (sscanf(itemBuffer, "[-%c-]", &driveletter) == 1)
1848 {
1849 /* Current item is a drive letter */
1850 SetLastError(0xdeadbeef);
1852 ok (GetLastError() == 0xdeadbeef,
1853 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1854 i, GetLastError());
1855 ok(res == 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer, pathBuffer);
1856
1857 /* For drive letters, DlgDirSelectEx tacks on a colon */
1858 ok (pathBuffer[0] == driveletter && pathBuffer[1] == ':' && pathBuffer[2] == '\0',
1859 "%d: got \"%s\" expected \"%c:\"\n", i, pathBuffer, driveletter);
1860 }
1861 else if (itemBuffer[0] == '[')
1862 {
1863 /* Current item is the parent directory */
1864 SetLastError(0xdeadbeef);
1866 ok (GetLastError() == 0xdeadbeef,
1867 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1868 i, GetLastError());
1869 ok(res == 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer, pathBuffer);
1870
1871 /* For directories, DlgDirSelectEx tacks on a backslash */
1873 ok (*(p-1) == '\\', "DlgDirSelectEx did NOT tack on a backslash to dir, got %s\n", pathBuffer);
1874
1875 tempBuffer[0] = '[';
1876 lstrcpynA(tempBuffer + 1, pathBuffer, strlen(pathBuffer));
1877 strcat(tempBuffer, "]");
1878 ok (!strcmp(tempBuffer, itemBuffer), "Formatted directory should be %s, got %s\n", tempBuffer, itemBuffer);
1879 }
1880 else
1881 {
1882 /* Current item is a plain file */
1883 SetLastError(0xdeadbeef);
1885 ok (GetLastError() == 0xdeadbeef,
1886 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1887 i, GetLastError());
1888 ok(res == 0, "DlgDirSelectEx() thinks %s (%s) is a drive/directory!\n", itemBuffer, pathBuffer);
1889
1890 /* NOTE: WinXP tacks a period on all files that lack an extension. This affects
1891 * for example, "Makefile", which gets reported as "Makefile."
1892 */
1893 strcpy(tempBuffer, itemBuffer);
1894 if (strchr(tempBuffer, '.') == NULL) strcat(tempBuffer, ".");
1895 ok (!strcmp(pathBuffer, tempBuffer), "Formatted file should be %s, got %s\n", tempBuffer, pathBuffer);
1896 }
1897 }
1898
1899 DeleteFileA( "wtest1.tmp.c" );
1900
1901 /* Now test DlgDirSelectEx() in abnormal operation */
1902 /* Fill list with bogus entries, that look somewhat valid */
1904 SendMessageA(g_listBox, LB_ADDSTRING, 0, (LPARAM)"[notexist.dir]");
1905 SendMessageA(g_listBox, LB_ADDSTRING, 0, (LPARAM)"notexist.fil");
1906 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1907 for (i = 0; i < itemCount; i++)
1908 {
1909 memset(itemBuffer, 0, MAX_PATH);
1911 memset(tempBuffer, 0, MAX_PATH);
1912 driveletter = '\0';
1913 SendMessageA(g_listBox, LB_GETTEXT, i, (LPARAM)itemBuffer);
1915 ok (res == i, "SendMessage(LB_SETCURSEL, %d) failed\n", i);
1916 if (sscanf(itemBuffer, "[-%c-]", &driveletter) == 1)
1917 {
1918 /* Current item is a drive letter */
1919 SetLastError(0xdeadbeef);
1921 ok (GetLastError() == 0xdeadbeef,
1922 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1923 i, GetLastError());
1924 ok(res == 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer, pathBuffer);
1925
1926 /* For drive letters, DlgDirSelectEx tacks on a colon */
1927 ok (pathBuffer[0] == driveletter && pathBuffer[1] == ':' && pathBuffer[2] == '\0',
1928 "%d: got \"%s\" expected \"%c:\"\n", i, pathBuffer, driveletter);
1929 }
1930 else if (itemBuffer[0] == '[')
1931 {
1932 /* Current item is the parent directory */
1933 SetLastError(0xdeadbeef);
1935 ok (GetLastError() == 0xdeadbeef,
1936 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1937 i, GetLastError());
1938 ok(res == 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer, pathBuffer);
1939
1940 /* For directories, DlgDirSelectEx tacks on a backslash */
1942 ok (*(p-1) == '\\', "DlgDirSelectEx did NOT tack on a backslash to dir, got %s\n", pathBuffer);
1943
1944 tempBuffer[0] = '[';
1945 lstrcpynA(tempBuffer + 1, pathBuffer, strlen(pathBuffer));
1946 strcat(tempBuffer, "]");
1947 ok (!strcmp(tempBuffer, itemBuffer), "Formatted directory should be %s, got %s\n", tempBuffer, itemBuffer);
1948 }
1949 else
1950 {
1951 /* Current item is a plain file */
1952 SetLastError(0xdeadbeef);
1954 ok (GetLastError() == 0xdeadbeef,
1955 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1956 i, GetLastError());
1957 ok(res == 0, "DlgDirSelectEx() thinks %s (%s) is a drive/directory!\n", itemBuffer, pathBuffer);
1958
1959 /* NOTE: WinXP and Win98 tack a period on all files that lack an extension.
1960 * This affects for example, "Makefile", which gets reported as "Makefile."
1961 */
1962 strcpy(tempBuffer, itemBuffer);
1963 if (strchr(tempBuffer, '.') == NULL) strcat(tempBuffer, ".");
1964 ok (!strcmp(pathBuffer, tempBuffer), "Formatted file should be %s, got %s\n", tempBuffer, pathBuffer);
1965 }
1966 }
1967
1968 /* Test behavior when loading folders from root with and without wildcard */
1969 strcpy(pathBuffer, "C:\\");
1971 ok(res, "DlgDirList failed to list C:\\ folders\n");
1972 ok(!strcmp(pathBuffer, "*"), "DlgDirList set the invalid path spec '%s', expected '*'\n", pathBuffer);
1973
1974 strcpy(pathBuffer, "C:\\*");
1976 ok(res, "DlgDirList failed to list C:\\* folders\n");
1977 ok(!strcmp(pathBuffer, "*"), "DlgDirList set the invalid path spec '%s', expected '*'\n", pathBuffer);
1978
1979 /* Try loading files from an invalid folder */
1980 SetLastError(0xdeadbeef);
1981 strcpy(pathBuffer, "C:\\INVALID$$DIR");
1983 ok(!res, "DlgDirList should have failed with 0 but %d was returned\n", res);
1985 "GetLastError should return 0x589, got 0x%X\n",GetLastError());
1986
1988}
1989
1990static void test_set_count( void )
1991{
1992 static const DWORD styles[] =
1993 {
1996 };
1997 HWND parent, listbox;
1998 unsigned int i;
1999 LONG ret;
2000 RECT r;
2001
2004
2005 UpdateWindow( listbox );
2006 GetUpdateRect( listbox, &r, TRUE );
2007 ok( IsRectEmpty( &r ), "got non-empty rect\n");
2008
2009 ret = SendMessageA( listbox, LB_SETCOUNT, 100, 0 );
2010 ok( ret == 0, "got %d\n", ret );
2011 ret = SendMessageA( listbox, LB_GETCOUNT, 0, 0 );
2012 ok( ret == 100, "got %d\n", ret );
2013
2014 GetUpdateRect( listbox, &r, TRUE );
2015 ok( !IsRectEmpty( &r ), "got empty rect\n");
2016
2017 ValidateRect( listbox, NULL );
2018 GetUpdateRect( listbox, &r, TRUE );
2019 ok( IsRectEmpty( &r ), "got non-empty rect\n");
2020
2021 ret = SendMessageA( listbox, LB_SETCOUNT, 99, 0 );
2022 ok( ret == 0, "got %d\n", ret );
2023
2024 GetUpdateRect( listbox, &r, TRUE );
2025 ok( !IsRectEmpty( &r ), "got empty rect\n");
2026
2027 ret = SendMessageA( listbox, LB_SETCOUNT, -5, 0 );
2028 ok( ret == 0, "got %d\n", ret );
2029 ret = SendMessageA( listbox, LB_GETCOUNT, 0, 0 );
2030 ok( ret == -5, "got %d\n", ret );
2031
2032 DestroyWindow( listbox );
2033
2034 for (i = 0; i < ARRAY_SIZE(styles); ++i)
2035 {
2036 listbox = create_listbox( styles[i] | WS_CHILD | WS_VISIBLE, parent );
2037
2038 SetLastError( 0xdeadbeef );
2039 ret = SendMessageA( listbox, LB_SETCOUNT, 100, 0 );
2040 ok( ret == LB_ERR, "expected %d, got %d\n", LB_ERR, ret );
2041 ok( GetLastError() == 0xdeadbeef, "Unexpected error %d.\n", GetLastError() );
2042
2043 DestroyWindow( listbox );
2044 }
2045
2047}
2048
2049static void test_GetListBoxInfo(void)
2050{
2051 static const struct message getlistboxinfo_seq[] =
2052 {
2054 { 0 }
2055 };
2056 HWND listbox, parent;
2057 DWORD ret;
2058
2061
2063 ret = GetListBoxInfo(listbox);
2064 ok(ret > 0, "got %d\n", ret);
2065 ok_sequence(sequences, LB_SEQ_INDEX, getlistboxinfo_seq, "GetListBoxInfo()", FALSE);
2066
2067 DestroyWindow(listbox);
2069}
2070
2071static void test_init_storage( void )
2072{
2073 static const DWORD styles[] =
2074 {
2077 };
2078 HWND parent, listbox;
2079 LONG ret, items_size;
2080 int i, j;
2081
2083 for (i = 0; i < ARRAY_SIZE(styles); i++)
2084 {
2085 listbox = CreateWindowA(WC_LISTBOXA, "TestList", styles[i] | WS_CHILD,
2086 0, 0, 100, 100, parent, (HMENU)ID_LISTBOX, NULL, 0);
2087
2088 items_size = SendMessageA(listbox, LB_INITSTORAGE, 100, 0);
2089 ok(items_size >= 100, "expected at least 100, got %d\n", items_size);
2090
2091 ret = SendMessageA(listbox, LB_INITSTORAGE, 0, 0);
2092 ok(ret == items_size, "expected %d, got %d\n", items_size, ret);
2093
2094 /* it doesn't grow since the space was already reserved */
2095 ret = SendMessageA(listbox, LB_INITSTORAGE, items_size, 0);
2096 ok(ret == items_size, "expected %d, got %d\n", items_size, ret);
2097
2098 /* it doesn't shrink the reserved space */
2099 ret = SendMessageA(listbox, LB_INITSTORAGE, 42, 0);
2100 ok(ret == items_size, "expected %d, got %d\n", items_size, ret);
2101
2102 /* now populate almost all of it so it's not reserved anymore */
2103 if (styles[i] & LBS_NODATA)
2104 {
2105 ret = SendMessageA(listbox, LB_SETCOUNT, items_size - 1, 0);
2106 ok(ret == 0, "unexpected return value %d\n", ret);
2107 }
2108 else
2109 {
2110 for (j = 0; j < items_size - 1; j++)
2111 {
2112 ret = SendMessageA(listbox, LB_INSERTSTRING, -1, (LPARAM)"");
2113 ok(ret == j, "expected %d, got %d\n", j, ret);
2114 }
2115 }
2116
2117 /* we still have one more reserved slot, so it doesn't grow yet */
2118 ret = SendMessageA(listbox, LB_INITSTORAGE, 1, 0);
2119 ok(ret == items_size, "expected %d, got %d\n", items_size, ret);
2120
2121 /* fill the slot and check again, it should grow this time */
2122 ret = SendMessageA(listbox, LB_INSERTSTRING, -1, (LPARAM)"");
2123 ok(ret == items_size - 1, "expected %d, got %d\n", items_size - 1, ret);
2124 ret = SendMessageA(listbox, LB_INITSTORAGE, 0, 0);
2125 ok(ret == items_size, "expected %d, got %d\n", items_size, ret);
2126 ret = SendMessageA(listbox, LB_INITSTORAGE, 1, 0);
2127 ok(ret > items_size, "expected it to grow past %d, got %d\n", items_size, ret);
2128
2129 DestroyWindow(listbox);
2130 }
2132}
2133
2134static void test_missing_lbuttonup(void)
2135{
2136 HWND listbox, parent, capture;
2137
2140
2141 /* Send button down without a corresponding button up */
2142 SendMessageA(listbox, WM_LBUTTONDOWN, 0, MAKELPARAM(10, 10));
2143 capture = GetCapture();
2144 ok(capture == listbox, "got %p expected %p\n", capture, listbox);
2145
2146 /* Capture is released and LBN_SELCHANGE sent during WM_KILLFOCUS */
2147 got_selchange = 0;
2148 SetFocus(NULL);
2149 capture = GetCapture();
2150 ok(capture == NULL, "got %p\n", capture);
2151 ok(got_selchange, "got %d\n", got_selchange);
2152
2153 DestroyWindow(listbox);
2155}
2156
2157static void test_extents(void)
2158{
2159 HWND listbox, parent;
2161 DWORD res;
2162 BOOL br;
2163
2165
2167
2168 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2169 ok(res == 0, "Got wrong initial horizontal extent: %u\n", res);
2170
2171 sinfo.cbSize = sizeof(sinfo);
2172 sinfo.fMask = SIF_RANGE;
2173 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2174 ok(br == TRUE, "GetScrollInfo failed\n");
2175 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2176 ok(sinfo.nMax == 100, "got wrong max: %u\n", sinfo.nMax);
2177 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
2178 "List box should not have a horizontal scroll bar\n");
2179
2180 /* horizontal extent < width */
2181 SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 64, 0);
2182
2183 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2184 ok(res == 64, "Got wrong horizontal extent: %u\n", res);
2185
2186 sinfo.cbSize = sizeof(sinfo);
2187 sinfo.fMask = SIF_RANGE;
2188 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2189 ok(br == TRUE, "GetScrollInfo failed\n");
2190 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2191 ok(sinfo.nMax == 100, "got wrong max: %u\n", sinfo.nMax);
2192 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
2193 "List box should not have a horizontal scroll bar\n");
2194
2195 /* horizontal extent > width */
2196 SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 184, 0);
2197
2198 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2199 ok(res == 184, "Got wrong horizontal extent: %u\n", res);
2200
2201 sinfo.cbSize = sizeof(sinfo);
2202 sinfo.fMask = SIF_RANGE;
2203 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2204 ok(br == TRUE, "GetScrollInfo failed\n");
2205 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2206 ok(sinfo.nMax == 100, "got wrong max: %u\n", sinfo.nMax);
2207 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
2208 "List box should not have a horizontal scroll bar\n");
2209
2210 DestroyWindow(listbox);
2211
2213
2214 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2215 ok(res == 0, "Got wrong initial horizontal extent: %u\n", res);
2216
2217 sinfo.cbSize = sizeof(sinfo);
2218 sinfo.fMask = SIF_RANGE;
2219 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2220 ok(br == TRUE, "GetScrollInfo failed\n");
2221 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2222 ok(sinfo.nMax == 100, "got wrong max: %u\n", sinfo.nMax);
2223 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
2224 "List box should not have a horizontal scroll bar\n");
2225
2226 /* horizontal extent < width */
2227 SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 64, 0);
2228
2229 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2230 ok(res == 64, "Got wrong horizontal extent: %u\n", res);
2231
2232 sinfo.cbSize = sizeof(sinfo);
2233 sinfo.fMask = SIF_RANGE;
2234 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2235 ok(br == TRUE, "GetScrollInfo failed\n");
2236 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2237 ok(sinfo.nMax == 63, "got wrong max: %u\n", sinfo.nMax);
2238 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
2239 "List box should not have a horizontal scroll bar\n");
2240
2241 /* horizontal extent > width */
2242 SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 184, 0);
2243
2244 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2245 ok(res == 184, "Got wrong horizontal extent: %u\n", res);
2246
2247 sinfo.cbSize = sizeof(sinfo);
2248 sinfo.fMask = SIF_RANGE;
2249 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2250 ok(br == TRUE, "GetScrollInfo failed\n");
2251 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2252 ok(sinfo.nMax == 183, "got wrong max: %u\n", sinfo.nMax);
2253 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) != 0,
2254 "List box should have a horizontal scroll bar\n");
2255
2256 SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 0, 0);
2257
2258 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2259 ok(res == 0, "Got wrong horizontal extent: %u\n", res);
2260
2261 sinfo.cbSize = sizeof(sinfo);
2262 sinfo.fMask = SIF_RANGE;
2263 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2264 ok(br == TRUE, "GetScrollInfo failed\n");
2265 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2266 ok(sinfo.nMax == 0, "got wrong max: %u\n", sinfo.nMax);
2267 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
2268 "List box should not have a horizontal scroll bar\n");
2269
2270 DestroyWindow(listbox);
2271
2272
2274
2275 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2276 ok(res == 0, "Got wrong initial horizontal extent: %u\n", res);
2277
2278 sinfo.cbSize = sizeof(sinfo);
2279 sinfo.fMask = SIF_RANGE;
2280 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2281 ok(br == TRUE, "GetScrollInfo failed\n");
2282 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2283 ok(sinfo.nMax == 0, "got wrong max: %u\n", sinfo.nMax);
2284 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) != 0,
2285 "List box should have a horizontal scroll bar\n");
2286
2287 /* horizontal extent < width */
2288 SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 64, 0);
2289
2290 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2291 ok(res == 64, "Got wrong horizontal extent: %u\n", res);
2292
2293 sinfo.cbSize = sizeof(sinfo);
2294 sinfo.fMask = SIF_RANGE;
2295 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2296 ok(br == TRUE, "GetScrollInfo failed\n");
2297 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2298 ok(sinfo.nMax == 63, "got wrong max: %u\n", sinfo.nMax);
2299 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) != 0,
2300 "List box should have a horizontal scroll bar\n");
2301
2302 /* horizontal extent > width */
2303 SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 184, 0);
2304
2305 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2306 ok(res == 184, "Got wrong horizontal extent: %u\n", res);
2307
2308 sinfo.cbSize = sizeof(sinfo);
2309 sinfo.fMask = SIF_RANGE;
2310 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2311 ok(br == TRUE, "GetScrollInfo failed\n");
2312 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2313 ok(sinfo.nMax == 183, "got wrong max: %u\n", sinfo.nMax);
2314 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) != 0,
2315 "List box should have a horizontal scroll bar\n");
2316
2317 SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 0, 0);
2318
2319 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2320 ok(res == 0, "Got wrong horizontal extent: %u\n", res);
2321
2322 sinfo.cbSize = sizeof(sinfo);
2323 sinfo.fMask = SIF_RANGE;
2324 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2325 ok(br == TRUE, "GetScrollInfo failed\n");
2326 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2327 ok(sinfo.nMax == 0, "got wrong max: %u\n", sinfo.nMax);
2328 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) != 0,
2329 "List box should have a horizontal scroll bar\n");
2330
2331 DestroyWindow(listbox);
2332
2334}
2335
2336static void test_listbox(void)
2337{
2338 static const struct listbox_test SS =
2339 /* {add_style} */
2340 {{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
2341 { 1, 1, 1, LB_ERR}, {0,0,0,0},
2342 { 2, 2, 2, LB_ERR}, {0,0,0,0},
2343 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
2344
2345 /* {selected, anchor, caret, selcount}{TODO fields} */
2346 static const struct listbox_test SS_NS =
2347 {{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
2348 { 1, 1, 1, LB_ERR}, {0,0,0,0},
2349 { 2, 2, 2, LB_ERR}, {0,0,0,0},
2350 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
2351
2352 static const struct listbox_test MS =
2353 {{ 0, LB_ERR, 0, 0}, {0,0,0,0},
2354 { 1, 1, 1, 1}, {0,0,0,0},
2355 { 2, 1, 2, 1}, {0,0,0,0},
2356 { 0, LB_ERR, 0, 2}, {0,0,0,0}};
2357
2358 static const struct listbox_test MS_NS =
2359 {{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
2360 { 1, 1, 1, LB_ERR}, {0,0,0,0},
2361 { 2, 2, 2, LB_ERR}, {0,0,0,0},
2362 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
2363
2364 static const struct listbox_test ES =
2365 {{ 0, LB_ERR, 0, 0}, {0,0,0,0},
2366 { 1, 1, 1, 1}, {0,0,0,0},
2367 { 2, 2, 2, 1}, {0,0,0,0},
2368 { 0, LB_ERR, 0, 2}, {0,0,0,0}};
2369
2370 static const struct listbox_test ES_NS =
2371 {{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
2372 { 1, 1, 1, LB_ERR}, {0,0,0,0},
2373 { 2, 2, 2, LB_ERR}, {0,0,0,0},
2374 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
2375
2376 static const struct listbox_test EMS =
2377 {{ 0, LB_ERR, 0, 0}, {0,0,0,0},
2378 { 1, 1, 1, 1}, {0,0,0,0},
2379 { 2, 2, 2, 1}, {0,0,0,0},
2380 { 0, LB_ERR, 0, 2}, {0,0,0,0}};
2381
2382 static const struct listbox_test EMS_NS =
2383 {{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
2384 { 1, 1, 1, LB_ERR}, {0,0,0,0},
2385 { 2, 2, 2, LB_ERR}, {0,0,0,0},
2386 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
2387
2388 run_test(0, SS);
2389 run_test(LBS_NOSEL, SS_NS);
2396
2405}
2406
2408{
2409 { WM_MEASUREITEM, sent|wparam|lparam, 0x1012, 0xf30604ed },
2410 { WM_MEASUREITEM, sent|wparam|lparam, 0x1112, 0xf30604ee },
2411 { WM_MEASUREITEM, sent|wparam|lparam, 0x1212, 0xf30604ef },
2412 { 0 }
2413};
2414
2416{
2417 { WM_MEASUREITEM, sent|wparam|lparam, 0x1012, 0xf30604ed },
2418 { WM_COMPAREITEM, sent|wparam|lparam, 0xf30604ed, 0xf30604ee },
2419 { WM_MEASUREITEM, sent|wparam|lparam, 0x1112, 0xf30604ee },
2420 { WM_COMPAREITEM, sent|wparam|lparam, 0xf30604ed, 0xf30604ef },
2421 { WM_COMPAREITEM, sent|wparam|lparam, 0xf30604ee, 0xf30604ef },
2422 { WM_MEASUREITEM, sent|wparam|lparam, 0x1212, 0xf30604ef },
2423 { 0 }
2424};
2425
2426static const struct message empty_seq[] =
2427{
2428 { 0 }
2429};
2430
2431static void test_WM_MEASUREITEM(void)
2432{
2433 HWND parent, listbox;
2434 LRESULT data, ret;
2435
2438
2439 data = SendMessageA(listbox, LB_GETITEMDATA, 0, 0);
2440 ok(data == (LRESULT)strings[0], "data = %08lx, expected %p\n", data, strings[0]);
2442
2445
2446 data = SendMessageA(listbox, LB_GETITEMDATA, 0, 0);
2447 ok(!data, "data = %08lx\n", data);
2448
2449 /* LBS_HASSTRINGS */
2453 10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
2454
2456
2457 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
2458 ok(ret == 0, "expected 0, got %ld\n", ret);
2459 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
2460 ok(ret == 1, "expected 1, got %ld\n", ret);
2461 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
2462 ok(ret == 2, "expected 2, got %ld\n", ret);
2463
2465 "LB_ADDSTRING (LBS_HASSTRINGS, ownerdraw)", FALSE);
2466 DestroyWindow(listbox);
2467
2468 /* LBS_SORT, no LBS_HASSTRINGS */
2471 10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
2472
2474
2475 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
2476 ok(ret == 0, "expected 0, got %ld\n", ret);
2477 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
2478 ok(ret == 1, "expected 1, got %ld\n", ret);
2479 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
2480 ok(ret == 2, "expected 2, got %ld\n", ret);
2481
2483 DestroyWindow(listbox);
2484
2485 /* LBS_HASSTRINGS */
2488 10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
2489
2491
2492 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
2493 ok(ret == 0, "expected 0, got %ld\n", ret);
2494 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
2495 ok(ret == 1, "expected 1, got %ld\n", ret);
2496 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
2497 ok(ret == 2, "expected 2, got %ld\n", ret);
2498
2499 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "LB_ADDSTRING (LBS_HASSTRINGS)", FALSE);
2500 DestroyWindow(listbox);
2501
2502 /* LBS_HASSTRINGS, LBS_SORT */
2505 10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
2506
2508
2509 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
2510 ok(ret == 0, "expected 0, got %ld\n", ret);
2511 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
2512 ok(ret == 0, "expected 0, got %ld\n", ret);
2513 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
2514 ok(ret == 1, "expected 1, got %ld\n", ret);
2515
2516 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "LB_ADDSTRING (LBS_HASSTRINGS, LBS_SORT)", FALSE);
2517 DestroyWindow(listbox);
2518
2520}
2521
2522static void test_LBS_NODATA(void)
2523{
2524 static const DWORD invalid_styles[] =
2525 {
2526 0,
2528 LBS_SORT,
2532 };
2533 static const UINT invalid_idx[] = { -2, 2 };
2534 static const UINT valid_idx[] = { 0, 1 };
2535 static const ULONG_PTR zero_data;
2536 HWND listbox, parent;
2537 INT ret, text_len;
2538 unsigned int i;
2540 BOOL is_wow64;
2541
2543 0, 0, 100, 100, NULL, NULL, NULL, 0);
2544 ok(listbox != NULL, "Failed to create ListBox window.\n");
2545
2546 ret = SendMessageA(listbox, LB_INSERTSTRING, -1, 0);
2547 ok(ret == 0, "Unexpected return value %d.\n", ret);
2548 ret = SendMessageA(listbox, LB_INSERTSTRING, -1, 0);
2549 ok(ret == 1, "Unexpected return value %d.\n", ret);
2550 ret = SendMessageA(listbox, LB_GETCOUNT, 0, 0);
2551 ok(ret == 2, "Unexpected return value %d.\n", ret);
2552
2553 /* Invalid indices. */
2554 for (i = 0; i < ARRAY_SIZE(invalid_idx); ++i)
2555 {
2556 ret = SendMessageA(listbox, LB_SETITEMDATA, invalid_idx[i], 42);
2557 ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2558 ret = SendMessageA(listbox, LB_GETTEXTLEN, invalid_idx[i], 0);
2559 ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2560 if (ret == LB_ERR)
2561 {
2562 ret = SendMessageA(listbox, LB_GETTEXT, invalid_idx[i], (LPARAM)&data);
2563 ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2564 }
2565 ret = SendMessageA(listbox, LB_GETITEMDATA, invalid_idx[i], 0);
2566 ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2567 }
2568
2570#ifdef _WIN64
2571 text_len = 8;
2572#else
2573 text_len = is_wow64 ? 8 : 4;
2574#endif
2575
2576 /* Valid indices. */
2577 for (i = 0; i < ARRAY_SIZE(valid_idx); ++i)
2578 {
2579 ret = SendMessageA(listbox, LB_SETITEMDATA, valid_idx[i], 42);
2580 ok(ret == TRUE, "Unexpected return value %d.\n", ret);
2581 ret = SendMessageA(listbox, LB_GETTEXTLEN, valid_idx[i], 0);
2583 ok(ret == text_len, "Unexpected return value %d.\n", ret);
2584
2585 memset(&data, 0xee, sizeof(data));
2586 ret = SendMessageA(listbox, LB_GETTEXT, valid_idx[i], (LPARAM)&data);
2587 ok(ret == sizeof(data), "Unexpected return value %d.\n", ret);
2588 ok(!memcmp(&data, &zero_data, sizeof(data)), "Unexpected item data.\n");
2589
2590 ret = SendMessageA(listbox, LB_GETITEMDATA, valid_idx[i], 0);
2591 ok(ret == 0, "Unexpected return value %d.\n", ret);
2592 }
2593
2594 /* More messages that don't work with LBS_NODATA. */
2595 ret = SendMessageA(listbox, LB_FINDSTRING, 1, 0);
2596 ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2597 ret = SendMessageA(listbox, LB_FINDSTRING, 1, 42);
2598 ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2599 ret = SendMessageA(listbox, LB_FINDSTRINGEXACT, 1, 0);
2600 ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2601 ret = SendMessageA(listbox, LB_FINDSTRINGEXACT, 1, 42);
2602 ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2603 ret = SendMessageA(listbox, LB_SELECTSTRING, 1, 0);
2604 ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2605 ret = SendMessageA(listbox, LB_SELECTSTRING, 1, 42);
2606 ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2607
2608 DestroyWindow(listbox);
2609
2610 /* Invalid window style combinations. */
2612 ok(parent != NULL, "Failed to create parent window.\n");
2613
2614 for (i = 0; i < ARRAY_SIZE(invalid_styles); ++i)
2615 {
2616 DWORD style;
2617
2618 listbox = CreateWindowA(WC_LISTBOXA, "TestList", LBS_NODATA | WS_CHILD | invalid_styles[i],
2619 0, 0, 100, 100, parent, (HMENU)ID_LISTBOX, NULL, 0);
2620 ok(listbox != NULL, "Failed to create a listbox.\n");
2621
2622 style = GetWindowLongA(listbox, GWL_STYLE);
2623 ok((style & invalid_styles[i]) == invalid_styles[i], "%u: unexpected window styles %#x.\n", i, style);
2624 ret = SendMessageA(listbox, LB_SETCOUNT, 100, 0);
2625 ok(ret == LB_ERR, "%u: unexpected return value %d.\n", i, ret);
2626 DestroyWindow(listbox);
2627 }
2628
2630}
2631
2633{
2634 ULONG_PTR ctx_cookie;
2635 HANDLE hCtx;
2636
2637 if (!load_v6_module(&ctx_cookie, &hCtx))
2638 return;
2639
2641
2642 test_listbox();
2657 test_extents();
2661
2662 unload_v6_module(ctx_cookie, hCtx);
2663}
static struct _test_info results[8]
Definition: SetCursorPos.c:31
@ sent
Definition: SystemMenu.c:27
@ defwinproc
Definition: SystemMenu.c:32
@ lparam
Definition: SystemMenu.c:31
@ wparam
Definition: SystemMenu.c:30
#define add_message(msg)
Definition: SystemMenu.c:98
#define ok_sequence(exp, contx, todo)
Definition: SystemMenu.c:275
static void flush_sequence(void)
Definition: SystemMenu.c:184
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
char * strchr(const char *String, int ch)
Definition: utclib.c:501
Arabic default style
Definition: afstyles.h:94
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define msg(x)
Definition: auth_time.c:54
HWND hWnd
Definition: settings.c:17
#define ARRAY_SIZE(A)
Definition: main.h:20
static LPWSTR pathBuffer
Definition: treeview.c:16
static NTSTATUS zero_data(device_extension *Vcb, fcb *fcb, uint64_t start, uint64_t length, PIRP Irp, LIST_ENTRY *rollback)
Definition: fsctl.c:1811
Definition: list.h:37
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
static void init_msg_sequences(struct msg_sequence **seq, int n)
Definition: msg.h:393
static void flush_sequences(struct msg_sequence **seq, int n)
Definition: msg.h:99
WORD ATOM
Definition: dimm.idl:113
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define CP_ACP
Definition: compat.h:109
#define lstrcpynA
Definition: compat.h:751
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define GetCurrentProcess()
Definition: compat.h:759
#define GENERIC_READ
Definition: compat.h:135
#define IsWow64Process
Definition: compat.h:760
#define MAX_PATH
Definition: compat.h:34
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define CALLBACK
Definition: compat.h:35
#define WideCharToMultiByte
Definition: compat.h:111
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2146
BOOL WINAPI SetCurrentDirectoryA(IN LPCSTR lpPathName)
Definition: path.c:2206
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2054
BOOL is_wow64
Definition: msi.c:52
r parent
Definition: btrfs.c:3010
HINSTANCE hInst
Definition: dxdiag.c:13
#define SS(fs)
Definition: ff.c:54
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizeiptr size
Definition: glext.h:5919
GLuint res
Definition: glext.h:9613
GLsizei const GLchar *const * strings
Definition: glext.h:7622
GLfloat GLfloat p
Definition: glext.h:8902
GLuint64EXT * result
Definition: glext.h:11304
GLuint id
Definition: glext.h:5910
const GLfloat * m
Definition: glext.h:10848
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define MS
Definition: i386-dis.c:451
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
HWND hList
Definition: livecd.c:10
@ ES
Definition: bidi.c:78
#define CREATE_NEW
Definition: disk.h:69
HDC hdc
Definition: main.c:9
seq_index
Definition: edit.c:37
static HDC
Definition: imagelist.c:88
static void test_listbox_height(void)
Definition: listbox.c:760
static LRESULT WINAPI main_window_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: listbox.c:331
static LRESULT CALLBACK listbox_container_window_procA(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
Definition: listbox.c:1515
static void test_listbox_dlgdir(void)
Definition: listbox.c:1553
static void test_listbox(void)
Definition: listbox.c:2336
static HWND create_listbox(DWORD add_style, HWND parent)
Definition: listbox.c:131
static void test_listbox_LB_DIR(void)
Definition: listbox.c:1046
static void test_item_height(void)
Definition: listbox.c:293
static HWND g_listBox
Definition: listbox.c:1495
static const struct message lb_addstring_ownerdraw_parent_seq[]
Definition: listbox.c:2407
static void test_set_count(void)
Definition: listbox.c:1990
@ LB_SEQ_INDEX
Definition: listbox.c:37
@ NUM_MSG_SEQUENCES
Definition: listbox.c:39
@ PARENT_SEQ_INDEX
Definition: listbox.c:38
#define listbox_ok(t, s, got)
Definition: listbox.c:204
static void listbox_query(HWND handle, struct listbox_stat *results)
Definition: listbox.c:173
static void test_WM_MEASUREITEM(void)
Definition: listbox.c:2431
static void test_itemfrompoint(void)
Definition: listbox.c:944
static BOOL on_listbox_container_create(HWND hwnd, CREATESTRUCTA *lpcs)
Definition: listbox.c:1501
static void test_LB_SETCURSEL(void)
Definition: listbox.c:618
static void test_changing_selection_styles(void)
Definition: listbox.c:815
static void keypress(HWND handle, WPARAM keycode, BYTE scancode, BOOL extended)
Definition: listbox.c:189
static struct msg_sequence * sequences[NUM_MSG_SEQUENCES]
Definition: listbox.c:42
static void test_init_storage(void)
Definition: listbox.c:2071
static const struct message lb_addstring_sort_parent_seq[]
Definition: listbox.c:2415
static LRESULT WINAPI listbox_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: listbox.c:94
static void test_LB_SETSEL(void)
Definition: listbox.c:694
static void test_missing_lbuttonup(void)
Definition: listbox.c:2134
static int got_selchange
Definition: listbox.c:329
#define listbox_test_query(exp, got)
Definition: listbox.c:534
static void test_LBS_NODATA(void)
Definition: listbox.c:2522
static unsigned hash_Ly(const char *str)
Definition: listbox.c:70
static HWND g_label
Definition: listbox.c:1496
static void test_LB_SELITEMRANGE(void)
Definition: listbox.c:540
static void test_extents(void)
Definition: listbox.c:2157
static HWND create_parent(void)
Definition: listbox.c:439
#define ID_LISTBOX
Definition: listbox.c:92
static void test_ownerdraw(void)
Definition: listbox.c:463
static const char BAD_EXTENSION[]
Definition: listbox.c:90
static unsigned hash_Ly_W(const WCHAR *str)
Definition: listbox.c:60
#define ID_TEST_LABEL
Definition: listbox.c:1498
static void test_GetListBoxInfo(void)
Definition: listbox.c:2049
static BOOL RegisterListboxWindowClass(HINSTANCE hInst)
Definition: listbox.c:1534
static void buttonpress(HWND handle, WORD x, WORD y)
Definition: listbox.c:181
static void test_listbox_item_data(void)
Definition: listbox.c:1025
#define ID_TEST_LISTBOX
Definition: listbox.c:1499
static const struct message empty_seq[]
Definition: listbox.c:2426
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
#define todo_wine_if(is_todo)
Definition: custom.c:86
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
static ATOM item
Definition: dde.c:856
#define ctrl
Definition: input.c:1756
int k
Definition: mpi.c:3369
#define run_test(test)
Definition: ms_seh.c:71
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
Definition: mk_font.cpp:20
unsigned int UINT
Definition: ndis.h:50
#define GENERIC_WRITE
Definition: nt_native.h:90
#define OBJ_FONT
Definition: objidl.idl:1414
#define LRESULT
Definition: ole.h:14
#define WS_CHILD
Definition: pedump.c:617
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
#define LBS_DISABLENOSCROLL
Definition: pedump.c:690
#define LBS_SORT
Definition: pedump.c:679
#define WS_EX_NOPARENTNOTIFY
Definition: pedump.c:646
#define WS_TABSTOP
Definition: pedump.c:634
#define WS_BORDER
Definition: pedump.c:625
#define LBS_OWNERDRAWFIXED
Definition: pedump.c:682
#define WS_POPUP
Definition: pedump.c:616
#define LBS_HASSTRINGS
Definition: pedump.c:684
#define WS_VSCROLL
Definition: pedump.c:627
#define LBS_OWNERDRAWVARIABLE
Definition: pedump.c:683
#define WS_VISIBLE
Definition: pedump.c:620
long LONG
Definition: pedump.c:60
#define LBS_MULTIPLESEL
Definition: pedump.c:681
#define WS_HSCROLL
Definition: pedump.c:628
#define LBS_NOINTEGRALHEIGHT
Definition: pedump.c:686
#define LBS_NOTIFY
Definition: pedump.c:678
#define LBS_EXTENDEDSEL
Definition: pedump.c:689
#define WC_STATICA
Definition: commctrl.h:4684
#define WC_LISTBOXA
Definition: commctrl.h:4715
#define list
Definition: rosglue.h:35
#define test
Definition: rosglue.h:37
const WCHAR * str
#define memset(x, y, z)
Definition: compat.h:39
HBRUSH hbrBackground
Definition: winuser.h:3173
HICON hIcon
Definition: winuser.h:3171
HINSTANCE hInstance
Definition: winuser.h:3170
HCURSOR hCursor
Definition: winuser.h:3172
int cbWndExtra
Definition: winuser.h:3169
UINT style
Definition: winuser.h:3166
LPCSTR lpszMenuName
Definition: winuser.h:3174
LPCSTR lpszClassName
Definition: winuser.h:3175
WNDPROC lpfnWndProc
Definition: winuser.h:3167
int cbClsExtra
Definition: winuser.h:3168
Definition: fci.c:127
Definition: _hash_fun.h:40
DWORD add_style
Definition: listbox.c:157
int selcount
Definition: listbox.c:162
int anchor
Definition: listbox.c:162
int selected
Definition: listbox.c:162
struct listbox_stat sel sel_todo
Definition: listbox.c:170
struct listbox_stat click click_todo
Definition: listbox.c:168
struct listbox_stat init init_todo
Definition: listbox.c:167
struct listbox_stat step step_todo
Definition: listbox.c:169
Definition: tftpd.h:60
UINT message
Definition: SystemMenu.c:42
Definition: general.c:220
ULONG_PTR itemData1
Definition: winuser.h:2997
ULONG_PTR itemData2
Definition: winuser.h:2999
ULONG_PTR itemData
Definition: winuser.h:3649
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
Definition: time.h:68
#define GWLP_WNDPROC
Definition: treelist.c:66
#define GWLP_USERDATA
Definition: treelist.c:63
int32_t INT_PTR
Definition: typedefs.h:64
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
static BOOL load_v6_module(ULONG_PTR *pcookie, HANDLE *hCtx)
Definition: v6util.h:73
static void unload_v6_module(ULONG_PTR cookie, HANDLE hCtx)
Definition: v6util.h:65
int ret
static MONITORINFO mi
Definition: win.c:7338
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
#define WINAPI
Definition: msvc.h:6
#define ERROR_NO_WILDCARD_CHARACTERS
Definition: winerror.h:898
HGDIOBJ WINAPI GetStockObject(_In_ int)
int WINAPI GetClipBox(_In_ HDC, _Out_ LPRECT)
HGDIOBJ WINAPI GetCurrentObject(_In_ HDC, _In_ UINT)
Definition: dc.c:428
#define WHITE_BRUSH
Definition: wingdi.h:902
BOOL WINAPI GetTextMetricsA(_In_ HDC, _Out_ LPTEXTMETRICA)
Definition: text.c:200
static int init
Definition: wintirpc.c:33
#define WM_PAINT
Definition: winuser.h:1623
#define LB_ERR
Definition: winuser.h:2435
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define WM_ERASEBKGND
Definition: winuser.h:1628
#define SetWindowLongPtrA
Definition: winuser.h:5357
#define LB_GETCOUNT
Definition: winuser.h:2041
#define LB_FINDSTRINGEXACT
Definition: winuser.h:2038
#define LB_GETITEMDATA
Definition: winuser.h:2044
#define MAKELPARAM(l, h)
Definition: winuser.h:4011
#define LB_SETHORIZONTALEXTENT
Definition: winuser.h:2067
#define WM_KEYUP
Definition: winuser.h:1719
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
#define COLOR_WINDOW
Definition: winuser.h:921
#define DCX_CACHE
Definition: winuser.h:2117
LONG WINAPI GetWindowLongA(_In_ HWND, _In_ int)
#define LB_SETCOUNT
Definition: winuser.h:2065
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define LB_OKAY
Definition: winuser.h:2434
#define LB_GETTEXT
Definition: winuser.h:2052
#define LB_SETTOPINDEX
Definition: winuser.h:2073
#define WM_WINDOWPOSCHANGING
Definition: winuser.h:1664
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4318
LONG WINAPI SetWindowLongA(_In_ HWND, _In_ int, _In_ LONG)
#define SIF_RANGE
Definition: winuser.h:1238
#define WM_CREATE
Definition: winuser.h:1611
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#define LB_DIR
Definition: winuser.h:2036
#define WM_SIZE
Definition: winuser.h:1614
#define SB_VERT
Definition: winuser.h:553
#define LB_GETSELCOUNT
Definition: winuser.h:2050
#define SWP_NOMOVE
Definition: winuser.h:1247
BOOL WINAPI ValidateRect(_In_opt_ HWND, _In_opt_ LPCRECT)
#define WM_COMMAND
Definition: winuser.h:1743
#define LB_GETITEMRECT
Definition: winuser.h:2046
BOOL WINAPI SetForegroundWindow(_In_ HWND)
#define IDC_ARROW
Definition: winuser.h:687
#define LB_GETTOPINDEX
Definition: winuser.h:2054
#define LB_GETANCHORINDEX
Definition: winuser.h:2039
#define WM_NCHITTEST
Definition: winuser.h:1689
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define DDL_DRIVES
Definition: winuser.h:425
BOOL WINAPI IsRectEmpty(_In_ LPCRECT)
#define WM_GETTEXT
Definition: winuser.h:1621
HDC WINAPI GetDCEx(_In_opt_ HWND, _In_opt_ HRGN, _In_ DWORD)
HWND WINAPI GetCapture(void)
Definition: message.c:2881
#define GetWindowLongPtrA
Definition: winuser.h:4831
#define WM_LBUTTONDOWN
Definition: winuser.h:1779
#define LB_GETSEL
Definition: winuser.h:2049
#define WM_DEVICECHANGE
Definition: winuser.h:1814
#define LB_ADDSTRING
Definition: winuser.h:2034
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
#define WM_DRAWITEM
Definition: winuser.h:1648
#define LB_SELITEMRANGE
Definition: winuser.h:2060
#define LB_SETITEMHEIGHT
Definition: winuser.h:2069
#define LB_GETLISTBOXINFO
Definition: winuser.h:2047
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:628
#define WM_SETTEXT
Definition: winuser.h:1620
#define DDL_EXCLUSIVE
Definition: winuser.h:426
#define LB_SELECTSTRING
Definition: winuser.h:2059
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
#define LB_RESETCONTENT
Definition: winuser.h:2058
#define LB_DELETESTRING
Definition: winuser.h:2035
HWND WINAPI SetFocus(_In_opt_ HWND)
#define LB_FINDSTRING
Definition: winuser.h:2037
#define DDL_DIRECTORY
Definition: winuser.h:422
#define LB_GETITEMHEIGHT
Definition: winuser.h:2045
#define WM_SETFONT
Definition: winuser.h:1653
#define LBS_STANDARD
Definition: winuser.h:321
#define LB_GETHORIZONTALEXTENT
Definition: winuser.h:2043
#define LB_INSERTSTRING
Definition: winuser.h:2056
#define LBS_NODATA
Definition: winuser.h:313
BOOL WINAPI UpdateWindow(_In_ HWND)
#define LB_ITEMFROMPOINT
Definition: winuser.h:2057
#define WM_MEASUREITEM
Definition: winuser.h:1649
#define WM_LBUTTONUP
Definition: winuser.h:1780
#define LB_GETTEXTLEN
Definition: winuser.h:2053
#define CW_USEDEFAULT
Definition: winuser.h:225
#define LB_SETITEMDATA
Definition: winuser.h:2068
#define LBN_SELCHANGE
Definition: winuser.h:2078
#define KEYEVENTF_EXTENDEDKEY
Definition: winuser.h:1104
#define VK_DOWN
Definition: winuser.h:2230
#define LB_GETCARETINDEX
Definition: winuser.h:2040
#define MK_LBUTTON
Definition: winuser.h:2370
#define LB_SETSEL
Definition: winuser.h:2071
#define WM_DESTROY
Definition: winuser.h:1612
#define LBS_NOSEL
Definition: winuser.h:316
#define LB_SETCURSEL
Definition: winuser.h:2066
#define WM_KEYDOWN
Definition: winuser.h:1718
int WINAPI GetScrollPos(_In_ HWND, _In_ int)
#define WM_COMPAREITEM
Definition: winuser.h:1658
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2909
#define SWP_NOZORDER
Definition: winuser.h:1250
#define LB_GETCURSEL
Definition: winuser.h:2042
#define WM_NCCALCSIZE
Definition: winuser.h:1688
#define GWL_STYLE
Definition: winuser.h:855
BOOL WINAPI GetScrollInfo(_In_ HWND, _In_ int, _Inout_ LPSCROLLINFO)
BOOL WINAPI GetUpdateRect(_In_ HWND, _Out_opt_ LPRECT, _In_ BOOL)
#define LB_INITSTORAGE
Definition: winuser.h:2055
#define WM_WINDOWPOSCHANGED
Definition: winuser.h:1665
BOOL WINAPI DestroyWindow(_In_ HWND)
int WINAPI DlgDirListA(_In_ HWND, _Inout_ LPSTR, _In_ int, _In_ int, _In_ UINT)
#define ODT_LISTBOX
Definition: winuser.h:2541
BOOL WINAPI DlgDirSelectExA(_In_ HWND hwndDlg, _Out_writes_(chCount) LPSTR lpString, _In_ int chCount, _In_ int idListBox)
BOOL WINAPI EqualRect(_In_ LPCRECT, _In_ LPCRECT)
DWORD WINAPI GetListBoxInfo(_In_ HWND)
BOOL WINAPI MoveWindow(_In_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ BOOL)
LRESULT WINAPI CallWindowProcA(_In_ WNDPROC, _In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2142
#define SB_HORZ
Definition: winuser.h:552
#define WM_NCPAINT
Definition: winuser.h:1690
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193