1 /* Unit test suite for list boxes.
3 * Copyright 2003 Ferenc Wagner
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.
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.
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
30 #include "wine/test.h"
33 #define WAIT Sleep (1000)
34 #define REDRAW RedrawWindow (handle, NULL, 0, RDW_UPDATENOW)
40 static const char * const strings
[4] = {
44 "Fourth added which is very long because at some time we only had a 256 byte character buffer and that was overflowing in one of those applications that had a common dialog file open box and tried to add a 300 characters long custom filter string which of course the code did not like and crashed. Just make sure this string is longer than 256 characters."
47 static const char BAD_EXTENSION
[] = "*.badtxt";
49 static int strcmp_aw(LPCWSTR strw
, const char *stra
)
54 MultiByteToWideChar(CP_ACP
, 0, stra
, -1, buf
, ARRAY_SIZE(buf
));
55 return lstrcmpW(strw
, buf
);
59 create_listbox (DWORD add_style
, HWND parent
)
65 handle
=CreateWindowA("LISTBOX", "TestList",
66 (LBS_STANDARD
& ~LBS_SORT
) | add_style
,
68 parent
, (HMENU
)ctl_id
, NULL
, 0);
71 SendMessageA(handle
, LB_ADDSTRING
, 0, (LPARAM
) strings
[0]);
72 SendMessageA(handle
, LB_ADDSTRING
, 0, (LPARAM
) strings
[1]);
73 SendMessageA(handle
, LB_ADDSTRING
, 0, (LPARAM
) strings
[2]);
74 SendMessageA(handle
, LB_ADDSTRING
, 0, (LPARAM
) strings
[3]);
77 ShowWindow (handle
, SW_SHOW
);
89 int selected
, anchor
, caret
, selcount
;
93 struct listbox_stat init
, init_todo
;
94 struct listbox_stat click
, click_todo
;
95 struct listbox_stat step
, step_todo
;
96 struct listbox_stat sel
, sel_todo
;
100 listbox_query (HWND handle
, struct listbox_stat
*results
)
102 results
->selected
= SendMessageA(handle
, LB_GETCURSEL
, 0, 0);
103 results
->anchor
= SendMessageA(handle
, LB_GETANCHORINDEX
, 0, 0);
104 results
->caret
= SendMessageA(handle
, LB_GETCARETINDEX
, 0, 0);
105 results
->selcount
= SendMessageA(handle
, LB_GETSELCOUNT
, 0, 0);
109 buttonpress (HWND handle
, WORD x
, WORD y
)
114 SendMessageA(handle
, WM_LBUTTONDOWN
, MK_LBUTTON
, lp
);
115 SendMessageA(handle
, WM_LBUTTONUP
, 0, lp
);
120 keypress (HWND handle
, WPARAM keycode
, BYTE scancode
, BOOL extended
)
122 LPARAM lp
=1+(scancode
<<16)+(extended
?KEYEVENTF_EXTENDEDKEY
:0);
125 SendMessageA(handle
, WM_KEYDOWN
, keycode
, lp
);
126 SendMessageA(handle
, WM_KEYUP
, keycode
, lp
| 0xc000000);
130 #define listbox_field_ok(t, s, f, got) \
131 ok (t.s.f==got.f, "style %#x, step " #s ", field " #f \
132 ": expected %d, got %d\n", style, t.s.f, got.f)
134 #define listbox_todo_field_ok(t, s, f, got) \
135 todo_wine_if (t.s##_todo.f) { listbox_field_ok(t, s, f, got); }
137 #define listbox_ok(t, s, got) \
138 listbox_todo_field_ok(t, s, selected, got); \
139 listbox_todo_field_ok(t, s, anchor, got); \
140 listbox_todo_field_ok(t, s, caret, got); \
141 listbox_todo_field_ok(t, s, selcount, got)
144 check (DWORD style
, const struct listbox_test test
)
146 struct listbox_stat answer
;
152 hLB
= create_listbox (style
, 0);
154 listbox_query (hLB
, &answer
);
155 listbox_ok (test
, init
, answer
);
157 SendMessageA(hLB
, LB_GETITEMRECT
, 1, (LPARAM
) &second_item
);
158 buttonpress(hLB
, (WORD
)second_item
.left
, (WORD
)second_item
.top
);
160 listbox_query (hLB
, &answer
);
161 listbox_ok (test
, click
, answer
);
163 keypress (hLB
, VK_DOWN
, 0x50, TRUE
);
165 listbox_query (hLB
, &answer
);
166 listbox_ok (test
, step
, answer
);
169 hLB
= create_listbox(style
, 0);
171 SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(1, 2));
172 listbox_query (hLB
, &answer
);
173 listbox_ok (test
, sel
, answer
);
175 for (i
= 0; i
< 4 && !(style
& LBS_NODATA
); i
++) {
176 DWORD size
= SendMessageA(hLB
, LB_GETTEXTLEN
, i
, 0);
181 txt
= HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY
, size
+1);
182 resA
=SendMessageA(hLB
, LB_GETTEXT
, i
, (LPARAM
)txt
);
183 ok(!strcmp (txt
, strings
[i
]), "returned string for item %d does not match %s vs %s\n", i
, txt
, strings
[i
]);
185 txtw
= HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY
, 2*size
+2);
186 resW
=SendMessageW(hLB
, LB_GETTEXT
, i
, (LPARAM
)txtw
);
187 ok(resA
== resW
, "Unexpected text length.\n");
188 WideCharToMultiByte( CP_ACP
, 0, txtw
, -1, txt
, size
, NULL
, NULL
);
189 ok(!strcmp (txt
, strings
[i
]), "returned string for item %d does not match %s vs %s\n", i
, txt
, strings
[i
]);
191 HeapFree (GetProcessHeap(), 0, txtw
);
192 HeapFree (GetProcessHeap(), 0, txt
);
195 /* Confirm the count of items, and that an invalid delete does not remove anything */
196 res
= SendMessageA(hLB
, LB_GETCOUNT
, 0, 0);
197 ok((res
==4), "Expected 4 items, got %d\n", res
);
198 res
= SendMessageA(hLB
, LB_DELETESTRING
, -1, 0);
199 ok((res
==LB_ERR
), "Expected LB_ERR items, got %d\n", res
);
200 res
= SendMessageA(hLB
, LB_DELETESTRING
, 4, 0);
201 ok((res
==LB_ERR
), "Expected LB_ERR items, got %d\n", res
);
202 res
= SendMessageA(hLB
, LB_GETCOUNT
, 0, 0);
203 ok((res
==4), "Expected 4 items, got %d\n", res
);
209 static void check_item_height(void)
217 hLB
= create_listbox (0, 0);
218 ok ((hdc
= GetDCEx( hLB
, 0, DCX_CACHE
)) != 0, "Can't get hdc\n");
219 ok ((font
= GetCurrentObject(hdc
, OBJ_FONT
)) != 0, "Can't get the current font\n");
220 ok (GetTextMetricsA( hdc
, &tm
), "Can't read font metrics\n");
221 ReleaseDC( hLB
, hdc
);
223 ok (SendMessageA(hLB
, WM_SETFONT
, (WPARAM
)font
, 0) == 0, "Can't set font\n");
225 itemHeight
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 0, 0);
226 ok (itemHeight
== tm
.tmHeight
, "Item height wrong, got %d, expecting %d\n", itemHeight
, tm
.tmHeight
);
230 hLB
= CreateWindowA("LISTBOX", "TestList", LBS_OWNERDRAWVARIABLE
,
231 0, 0, 100, 100, NULL
, NULL
, NULL
, 0);
232 itemHeight
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 0, 0);
233 ok(itemHeight
== tm
.tmHeight
, "itemHeight %d\n", itemHeight
);
234 itemHeight
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 5, 0);
235 ok(itemHeight
== tm
.tmHeight
, "itemHeight %d\n", itemHeight
);
236 itemHeight
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, -5, 0);
237 ok(itemHeight
== tm
.tmHeight
, "itemHeight %d\n", itemHeight
);
241 static int got_selchange
;
243 static LRESULT WINAPI
main_window_proc(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
249 DWORD style
= GetWindowLongA(GetWindow(hwnd
, GW_CHILD
), GWL_STYLE
);
250 MEASUREITEMSTRUCT
*mi
= (void*)lparam
;
252 ok(wparam
== mi
->CtlID
, "got wParam=%08lx, expected %08x\n", wparam
, mi
->CtlID
);
253 ok(mi
->CtlType
== ODT_LISTBOX
, "mi->CtlType = %u\n", mi
->CtlType
);
254 ok(mi
->CtlID
== 1, "mi->CtlID = %u\n", mi
->CtlID
);
255 ok(mi
->itemHeight
, "mi->itemHeight = 0\n");
257 if (mi
->itemID
> 4 || style
& LBS_OWNERDRAWFIXED
)
260 if (style
& LBS_HASSTRINGS
)
262 ok(!strcmp_aw((WCHAR
*)mi
->itemData
, strings
[mi
->itemID
]),
263 "mi->itemData = %s (%d)\n", wine_dbgstr_w((WCHAR
*)mi
->itemData
), mi
->itemID
);
267 ok((void*)mi
->itemData
== strings
[mi
->itemID
],
268 "mi->itemData = %08lx, expected %p\n", mi
->itemData
, strings
[mi
->itemID
]);
274 RECT rc_item
, rc_client
, rc_clip
;
275 DRAWITEMSTRUCT
*dis
= (DRAWITEMSTRUCT
*)lparam
;
277 trace("%p WM_DRAWITEM %08lx %08lx\n", hwnd
, wparam
, lparam
);
279 ok(wparam
== dis
->CtlID
, "got wParam=%08lx instead of %08x\n",
281 ok(dis
->CtlType
== ODT_LISTBOX
, "wrong CtlType %04x\n", dis
->CtlType
);
283 GetClientRect(dis
->hwndItem
, &rc_client
);
284 trace("hwndItem %p client rect %s\n", dis
->hwndItem
, wine_dbgstr_rect(&rc_client
));
285 GetClipBox(dis
->hDC
, &rc_clip
);
286 trace("clip rect %s\n", wine_dbgstr_rect(&rc_clip
));
287 ok(EqualRect(&rc_client
, &rc_clip
) || IsRectEmpty(&rc_clip
),
288 "client rect of the listbox should be equal to the clip box,"
289 "or the clip box should be empty\n");
291 trace("rcItem %s\n", wine_dbgstr_rect(&dis
->rcItem
));
292 SendMessageA(dis
->hwndItem
, LB_GETITEMRECT
, dis
->itemID
, (LPARAM
)&rc_item
);
293 trace("item rect %s\n", wine_dbgstr_rect(&rc_item
));
294 ok(EqualRect(&dis
->rcItem
, &rc_item
), "item rects are not equal\n");
300 if (HIWORD( wparam
) == LBN_SELCHANGE
) got_selchange
++;
307 return DefWindowProcA(hwnd
, msg
, wparam
, lparam
);
310 static HWND
create_parent( void )
319 cls
.lpfnWndProc
= main_window_proc
;
322 cls
.hInstance
= GetModuleHandleA(NULL
);
324 cls
.hCursor
= LoadCursorA(0, (LPCSTR
)IDC_ARROW
);
325 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
326 cls
.lpszMenuName
= NULL
;
327 cls
.lpszClassName
= "main_window_class";
328 class = RegisterClassA( &cls
);
331 parent
= CreateWindowExA(0, "main_window_class", NULL
,
332 WS_POPUP
| WS_VISIBLE
,
334 GetDesktopWindow(), 0,
335 GetModuleHandleA(NULL
), NULL
);
339 static void test_ownerdraw(void)
345 parent
= create_parent();
348 hLB
= create_listbox(LBS_OWNERDRAWFIXED
| WS_CHILD
| WS_VISIBLE
, parent
);
351 SetForegroundWindow(hLB
);
354 /* make height short enough */
355 SendMessageA(hLB
, LB_GETITEMRECT
, 0, (LPARAM
)&rc
);
356 SetWindowPos(hLB
, 0, 0, 0, 100, rc
.bottom
- rc
.top
+ 1,
357 SWP_NOZORDER
| SWP_NOMOVE
);
359 /* make 0 item invisible */
360 SendMessageA(hLB
, LB_SETTOPINDEX
, 1, 0);
361 ret
= SendMessageA(hLB
, LB_GETTOPINDEX
, 0, 0);
362 ok(ret
== 1, "wrong top index %d\n", ret
);
364 SendMessageA(hLB
, LB_GETITEMRECT
, 0, (LPARAM
)&rc
);
365 trace("item 0 rect %s\n", wine_dbgstr_rect(&rc
));
366 ok(!IsRectEmpty(&rc
), "empty item rect\n");
367 ok(rc
.top
< 0, "rc.top is not negative (%d)\n", rc
.top
);
371 /* Both FIXED and VARIABLE, FIXED should override VARIABLE. */
372 hLB
= CreateWindowA("listbox", "TestList", LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
, 0, 0, 100, 100,
373 NULL
, NULL
, NULL
, 0);
374 ok(hLB
!= NULL
, "last error 0x%08x\n", GetLastError());
376 ok(GetWindowLongA(hLB
, GWL_STYLE
) & LBS_OWNERDRAWVARIABLE
, "Unexpected window style.\n");
378 ret
= SendMessageA(hLB
, LB_INSERTSTRING
, -1, 0);
379 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
380 ret
= SendMessageA(hLB
, LB_INSERTSTRING
, -1, 0);
381 ok(ret
== 1, "Unexpected return value %d.\n", ret
);
383 ret
= SendMessageA(hLB
, LB_SETITEMHEIGHT
, 0, 13);
384 ok(ret
== LB_OKAY
, "Failed to set item height, %d.\n", ret
);
386 ret
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 0, 0);
387 ok(ret
== 13, "Unexpected item height %d.\n", ret
);
389 ret
= SendMessageA(hLB
, LB_SETITEMHEIGHT
, 1, 42);
390 ok(ret
== LB_OKAY
, "Failed to set item height, %d.\n", ret
);
392 ret
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 0, 0);
393 ok(ret
== 42, "Unexpected item height %d.\n", ret
);
395 ret
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 1, 0);
396 ok(ret
== 42, "Unexpected item height %d.\n", ret
);
400 DestroyWindow(parent
);
403 #define listbox_test_query(exp, got) \
404 ok(exp.selected == got.selected, "expected selected %d, got %d\n", exp.selected, got.selected); \
405 ok(exp.anchor == got.anchor, "expected anchor %d, got %d\n", exp.anchor, got.anchor); \
406 ok(exp.caret == got.caret, "expected caret %d, got %d\n", exp.caret, got.caret); \
407 ok(exp.selcount == got.selcount, "expected selcount %d, got %d\n", exp.selcount, got.selcount);
409 static void test_LB_SELITEMRANGE(void)
411 static const struct listbox_stat test_nosel
= { 0, LB_ERR
, 0, 0 };
412 static const struct listbox_stat test_1
= { 0, LB_ERR
, 0, 2 };
413 static const struct listbox_stat test_2
= { 0, LB_ERR
, 0, 3 };
414 static const struct listbox_stat test_3
= { 0, LB_ERR
, 0, 4 };
416 struct listbox_stat answer
;
419 trace("testing LB_SELITEMRANGE\n");
421 hLB
= create_listbox(LBS_EXTENDEDSEL
, 0);
424 listbox_query(hLB
, &answer
);
425 listbox_test_query(test_nosel
, answer
);
427 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(1, 2));
428 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
429 listbox_query(hLB
, &answer
);
430 listbox_test_query(test_1
, answer
);
432 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
433 listbox_query(hLB
, &answer
);
434 listbox_test_query(test_nosel
, answer
);
436 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(0, 4));
437 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
438 listbox_query(hLB
, &answer
);
439 listbox_test_query(test_3
, answer
);
441 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
442 listbox_query(hLB
, &answer
);
443 listbox_test_query(test_nosel
, answer
);
445 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(-5, 5));
446 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
447 listbox_query(hLB
, &answer
);
448 listbox_test_query(test_nosel
, answer
);
450 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
451 listbox_query(hLB
, &answer
);
452 listbox_test_query(test_nosel
, answer
);
454 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(2, 10));
455 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
456 listbox_query(hLB
, &answer
);
457 listbox_test_query(test_1
, answer
);
459 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
460 listbox_query(hLB
, &answer
);
461 listbox_test_query(test_nosel
, answer
);
463 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(4, 10));
464 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
465 listbox_query(hLB
, &answer
);
466 listbox_test_query(test_nosel
, answer
);
468 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
469 listbox_query(hLB
, &answer
);
470 listbox_test_query(test_nosel
, answer
);
472 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(10, 1));
473 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
474 listbox_query(hLB
, &answer
);
475 listbox_test_query(test_2
, answer
);
477 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
478 listbox_query(hLB
, &answer
);
479 listbox_test_query(test_nosel
, answer
);
481 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(1, -1));
482 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
483 listbox_query(hLB
, &answer
);
484 listbox_test_query(test_2
, answer
);
489 static void test_LB_SETCURSEL(void)
494 trace("testing LB_SETCURSEL\n");
496 parent
= create_parent();
499 hLB
= create_listbox(LBS_NOINTEGRALHEIGHT
| WS_CHILD
, parent
);
502 SendMessageA(hLB
, LB_SETITEMHEIGHT
, 0, 32);
504 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
505 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
507 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 2, 0);
508 ok(ret
== 2, "LB_SETCURSEL returned %d instead of 2\n", ret
);
509 ret
= GetScrollPos(hLB
, SB_VERT
);
510 ok(ret
== 0, "expected vscroll 0, got %d\n", ret
);
512 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
513 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
515 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 3, 0);
516 ok(ret
== 3, "LB_SETCURSEL returned %d instead of 3\n", ret
);
517 ret
= GetScrollPos(hLB
, SB_VERT
);
518 ok(ret
== 1, "expected vscroll 1, got %d\n", ret
);
520 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
521 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
525 hLB
= create_listbox(0, 0);
526 ok(hLB
!= NULL
, "Failed to create ListBox window.\n");
528 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 1, 0);
529 ok(ret
== 1, "Unexpected return value %d.\n", ret
);
531 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
532 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
536 /* LBS_EXTENDEDSEL */
537 hLB
= create_listbox(LBS_EXTENDEDSEL
, 0);
538 ok(hLB
!= NULL
, "Failed to create ListBox window.\n");
540 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
541 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
543 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 2, 0);
544 ok(ret
== -1, "Unexpected return value %d.\n", ret
);
546 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
547 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
551 /* LBS_MULTIPLESEL */
552 hLB
= create_listbox(LBS_MULTIPLESEL
, 0);
553 ok(hLB
!= NULL
, "Failed to create ListBox window.\n");
555 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
556 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
558 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 2, 0);
559 ok(ret
== -1, "Unexpected return value %d.\n", ret
);
561 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
562 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
567 static void test_LB_SETSEL(void)
572 /* LBS_EXTENDEDSEL */
573 list
= create_listbox(LBS_EXTENDEDSEL
, 0);
574 ok(list
!= NULL
, "Failed to create ListBox window.\n");
576 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
577 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
579 ret
= SendMessageA(list
, LB_SETSEL
, TRUE
, 0);
580 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
581 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
582 ok(ret
== 0, "Unexpected anchor index %d.\n", ret
);
584 ret
= SendMessageA(list
, LB_SETSEL
, TRUE
, 1);
585 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
586 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
587 ok(ret
== 1, "Unexpected anchor index %d.\n", ret
);
589 ret
= SendMessageA(list
, LB_SETSEL
, FALSE
, 1);
590 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
591 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
592 ok(ret
== 1, "Unexpected anchor index %d.\n", ret
);
596 /* LBS_MULTIPLESEL */
597 list
= create_listbox(LBS_MULTIPLESEL
, 0);
598 ok(list
!= NULL
, "Failed to create ListBox window.\n");
600 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
601 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
603 ret
= SendMessageA(list
, LB_SETSEL
, TRUE
, 0);
604 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
605 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
606 ok(ret
== 0, "Unexpected anchor index %d.\n", ret
);
608 ret
= SendMessageA(list
, LB_SETSEL
, TRUE
, 1);
609 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
610 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
611 ok(ret
== 1, "Unexpected anchor index %d.\n", ret
);
613 ret
= SendMessageA(list
, LB_SETSEL
, FALSE
, 1);
614 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
615 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
616 ok(ret
== 1, "Unexpected anchor index %d.\n", ret
);
621 static void test_listbox_height(void)
626 hList
= CreateWindowA( "ListBox", "list test", 0,
627 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
628 ok( hList
!= NULL
, "failed to create listbox\n");
630 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi");
631 ok( id
== 0, "item id wrong\n");
633 r
= SendMessageA( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 20, 0 ));
634 ok( r
== 0, "send message failed\n");
636 r
= SendMessageA(hList
, LB_GETITEMHEIGHT
, 0, 0 );
637 ok( r
== 20, "height wrong\n");
639 r
= SendMessageA( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 0, 30 ));
640 ok( r
== -1, "send message failed\n");
642 r
= SendMessageA(hList
, LB_GETITEMHEIGHT
, 0, 0 );
643 ok( r
== 20, "height wrong\n");
645 r
= SendMessageA( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 0x100, 0 ));
646 ok( r
== -1, "send message failed\n");
648 r
= SendMessageA(hList
, LB_GETITEMHEIGHT
, 0, 0 );
649 ok( r
== 20, "height wrong\n");
651 r
= SendMessageA( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 0xff, 0 ));
652 ok( r
== 0, "send message failed\n");
654 r
= SendMessageA(hList
, LB_GETITEMHEIGHT
, 0, 0 );
655 ok( r
== 0xff, "height wrong\n");
657 DestroyWindow( hList
);
660 static void test_itemfrompoint(void)
662 /* WS_POPUP is required in order to have a more accurate size calculation (
663 without caption). LBS_NOINTEGRALHEIGHT is required in order to test
664 behavior of partially-displayed item.
666 HWND hList
= CreateWindowA( "ListBox", "list test",
667 WS_VISIBLE
|WS_POPUP
|LBS_NOINTEGRALHEIGHT
,
668 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
672 /* For an empty listbox win2k returns 0x1ffff, win98 returns 0x10000, nt4 returns 0xffffffff */
673 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
674 ok( r
== 0x1ffff || r
== 0x10000 || r
== 0xffffffff, "ret %x\n", r
);
676 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( 700, 30 ));
677 ok( r
== 0x1ffff || r
== 0x10000 || r
== 0xffffffff, "ret %x\n", r
);
679 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( 30, 300 ));
680 ok( r
== 0x1ffff || r
== 0x10000 || r
== 0xffffffff, "ret %x\n", r
);
682 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi");
683 ok( id
== 0, "item id wrong\n");
684 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi1");
685 ok( id
== 1, "item id wrong\n");
687 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
688 ok( r
== 0x1, "ret %x\n", r
);
690 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( /* x */ 30, /* y */ 601 ));
691 ok( r
== 0x10001 || broken(r
== 1), /* nt4 */
694 /* Resize control so that below assertions about sizes are valid */
695 r
= SendMessageA( hList
, LB_GETITEMRECT
, 0, (LPARAM
)&rc
);
696 ok( r
== 1, "ret %x\n", r
);
697 r
= MoveWindow(hList
, 1, 1, 600, (rc
.bottom
- rc
.top
+ 1) * 9 / 2, TRUE
);
698 ok( r
!= 0, "ret %x\n", r
);
700 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi2");
701 ok( id
== 2, "item id wrong\n");
702 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi3");
703 ok( id
== 3, "item id wrong\n");
704 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi4");
705 ok( id
== 4, "item id wrong\n");
706 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi5");
707 ok( id
== 5, "item id wrong\n");
708 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi6");
709 ok( id
== 6, "item id wrong\n");
710 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi7");
711 ok( id
== 7, "item id wrong\n");
713 /* Set the listbox up so that id 1 is at the top, this leaves 5
714 partially visible at the bottom and 6, 7 are invisible */
716 SendMessageA( hList
, LB_SETTOPINDEX
, 1, 0);
717 r
= SendMessageA( hList
, LB_GETTOPINDEX
, 0, 0);
718 ok( r
== 1, "top %d\n", r
);
720 r
= SendMessageA( hList
, LB_GETITEMRECT
, 5, (LPARAM
)&rc
);
721 ok( r
== 1, "ret %x\n", r
);
722 r
= SendMessageA( hList
, LB_GETITEMRECT
, 6, (LPARAM
)&rc
);
723 ok( r
== 0, "ret %x\n", r
);
725 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(/* x */ 10, /* y */ 10) );
726 ok( r
== 1, "ret %x\n", r
);
728 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(1000, 10) );
729 ok( r
== 0x10001 || broken(r
== 1), /* nt4 */
732 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(10, -10) );
733 ok( r
== 0x10001 || broken(r
== 1), /* nt4 */
736 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(10, 100) );
737 ok( r
== 0x10005 || broken(r
== 5), /* nt4 */
740 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(10, 200) );
741 ok( r
== 0x10005 || broken(r
== 5), /* nt4 */
744 DestroyWindow( hList
);
747 static void test_listbox_item_data(void)
752 hList
= CreateWindowA( "ListBox", "list test", 0,
753 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
754 ok( hList
!= NULL
, "failed to create listbox\n");
756 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi");
757 ok( id
== 0, "item id wrong\n");
759 r
= SendMessageA( hList
, LB_SETITEMDATA
, 0, MAKELPARAM( 20, 0 ));
760 ok(r
== TRUE
, "LB_SETITEMDATA returned %d instead of TRUE\n", r
);
762 r
= SendMessageA( hList
, LB_GETITEMDATA
, 0, 0);
763 ok( r
== 20, "get item data failed\n");
765 DestroyWindow( hList
);
768 static void test_listbox_LB_DIR(void)
770 char path
[MAX_PATH
], curdir
[MAX_PATH
];
773 int itemCount_justFiles
;
774 int itemCount_justDrives
;
775 int itemCount_allFiles
;
776 int itemCount_allDirs
;
778 char pathBuffer
[MAX_PATH
];
781 const char *wildcard
= "*";
785 GetCurrentDirectoryA(ARRAY_SIZE(curdir
), curdir
);
787 GetTempPathA(ARRAY_SIZE(path
), path
);
788 ret
= SetCurrentDirectoryA(path
);
789 ok(ret
, "Failed to set current directory.\n");
791 ret
= CreateDirectoryA("lb_dir_test", NULL
);
792 ok(ret
, "Failed to create test directory.\n");
794 file
= CreateFileA( "wtest1.tmp.c", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, FILE_ATTRIBUTE_NORMAL
, NULL
);
795 ok(file
!= INVALID_HANDLE_VALUE
, "Error creating the test file: %d\n", GetLastError());
798 /* NOTE: for this test to succeed, there must be no subdirectories
799 under the current directory. In addition, there must be at least
800 one file that fits the wildcard w*.c . Normally, the test
801 directory itself satisfies both conditions.
803 hList
= CreateWindowA( "ListBox", "list test", WS_VISIBLE
|WS_POPUP
,
804 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
807 /* Test for standard usage */
809 /* This should list all the files in the test directory. */
810 strcpy(pathBuffer
, wildcard
);
811 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
812 res
= SendMessageA(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
813 if (res
== -1) /* "*" wildcard doesn't work on win9x */
816 strcpy(pathBuffer
, wildcard
);
817 res
= SendMessageA(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
819 ok (res
>= 0, "SendMessage(LB_DIR, 0, *) failed - 0x%08x\n", GetLastError());
821 /* There should be some content in the listbox */
822 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
823 ok (itemCount
> 0, "SendMessage(LB_DIR) did NOT fill the listbox!\n");
824 itemCount_allFiles
= itemCount
;
825 ok(res
+ 1 == itemCount
,
826 "SendMessage(LB_DIR, 0, *) returned incorrect index (expected %d got %d)!\n",
829 /* This tests behavior when no files match the wildcard */
830 strcpy(pathBuffer
, BAD_EXTENSION
);
831 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
832 res
= SendMessageA(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
833 ok (res
== -1, "SendMessage(LB_DIR, 0, %s) returned %d, expected -1\n", BAD_EXTENSION
, res
);
835 /* There should be NO content in the listbox */
836 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
837 ok (itemCount
== 0, "SendMessage(LB_DIR) DID fill the listbox!\n");
840 /* This should list all the w*.c files in the test directory
841 * As of this writing, this includes win.c, winstation.c, wsprintf.c
843 strcpy(pathBuffer
, "w*.c");
844 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
845 res
= SendMessageA(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
846 ok (res
>= 0, "SendMessage(LB_DIR, 0, w*.c) failed - 0x%08x\n", GetLastError());
848 /* Path specification does NOT converted to uppercase */
849 ok (!strcmp(pathBuffer
, "w*.c"),
850 "expected no change to pathBuffer, got %s\n", pathBuffer
);
852 /* There should be some content in the listbox */
853 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
854 ok (itemCount
> 0, "SendMessage(LB_DIR) did NOT fill the listbox!\n");
855 itemCount_justFiles
= itemCount
;
856 ok(res
+ 1 == itemCount
,
857 "SendMessage(LB_DIR, 0, w*.c) returned incorrect index (expected %d got %d)!\n",
860 /* Every single item in the control should start with a w and end in .c */
861 for (i
= 0; i
< itemCount
; i
++) {
862 memset(pathBuffer
, 0, MAX_PATH
);
863 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
864 p
= pathBuffer
+ strlen(pathBuffer
);
865 ok(((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
866 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
867 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
870 /* Test DDL_DIRECTORY */
871 strcpy(pathBuffer
, wildcard
);
872 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
873 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
, (LPARAM
)pathBuffer
);
874 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY, *) failed - 0x%08x\n", GetLastError());
876 /* There should be some content in the listbox.
877 * All files plus "[..]"
879 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
880 itemCount_allDirs
= itemCount
- itemCount_allFiles
;
881 ok (itemCount
> itemCount_allFiles
,
882 "SendMessage(LB_DIR, DDL_DIRECTORY, *) filled with %d entries, expected > %d\n",
883 itemCount
, itemCount_allFiles
);
884 ok(res
+ 1 == itemCount
,
885 "SendMessage(LB_DIR, DDL_DIRECTORY, *) returned incorrect index (expected %d got %d)!\n",
888 /* This tests behavior when no files match the wildcard */
889 strcpy(pathBuffer
, BAD_EXTENSION
);
890 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
891 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
, (LPARAM
)pathBuffer
);
892 ok (res
== -1, "SendMessage(LB_DIR, DDL_DIRECTORY, %s) returned %d, expected -1\n", BAD_EXTENSION
, res
);
894 /* There should be NO content in the listbox */
895 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
896 ok (itemCount
== 0, "SendMessage(LB_DIR) DID fill the listbox!\n");
899 /* Test DDL_DIRECTORY */
900 strcpy(pathBuffer
, "w*.c");
901 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
902 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
, (LPARAM
)pathBuffer
);
903 ok (res
>= 0, "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) failed - 0x%08x\n", GetLastError());
905 /* There should be some content in the listbox. Since the parent directory does not
906 * fit w*.c, there should be exactly the same number of items as without DDL_DIRECTORY
908 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
909 ok (itemCount
== itemCount_justFiles
,
910 "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) filled with %d entries, expected %d\n",
911 itemCount
, itemCount_justFiles
);
912 ok(res
+ 1 == itemCount
,
913 "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) returned incorrect index (expected %d got %d)!\n",
916 /* Every single item in the control should start with a w and end in .c. */
917 for (i
= 0; i
< itemCount
; i
++) {
918 memset(pathBuffer
, 0, MAX_PATH
);
919 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
920 p
= pathBuffer
+ strlen(pathBuffer
);
922 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
923 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
924 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
928 /* Test DDL_DRIVES|DDL_EXCLUSIVE */
929 strcpy(pathBuffer
, wildcard
);
930 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
931 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
932 ok (res
>= 0, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) failed - 0x%08x\n", GetLastError());
934 /* There should be some content in the listbox. In particular, there should
935 * be at least one element before, since the string "[-c-]" should
936 * have been added. Depending on the user setting, more drives might have
939 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
941 "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) filled with %d entries, expected at least %d\n",
943 itemCount_justDrives
= itemCount
;
944 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) returned incorrect index!\n");
946 /* Every single item in the control should fit the format [-c-] */
947 for (i
= 0; i
< itemCount
; i
++) {
948 memset(pathBuffer
, 0, MAX_PATH
);
950 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
951 ok( strlen(pathBuffer
) == 5, "Length of drive string is not 5\n" );
952 ok( sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1, "Element %d (%s) does not fit [-X-]\n", i
, pathBuffer
);
953 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
954 if (!(driveletter
>= 'a' && driveletter
<= 'z')) {
955 /* Correct after invalid entry is found */
956 trace("removing count of invalid entry %s\n", pathBuffer
);
957 itemCount_justDrives
--;
961 /* This tests behavior when no files match the wildcard */
962 strcpy(pathBuffer
, BAD_EXTENSION
);
963 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
964 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
965 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
966 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
968 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
969 ok (itemCount
== itemCount_justDrives
, "SendMessage(LB_DIR) returned %d expected %d\n",
970 itemCount
, itemCount_justDrives
);
972 trace("Files with w*.c: %d Mapped drives: %d Directories: 1\n",
973 itemCount_justFiles
, itemCount_justDrives
);
975 /* Test DDL_DRIVES. */
976 strcpy(pathBuffer
, wildcard
);
977 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
978 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
, (LPARAM
)pathBuffer
);
979 ok (res
> 0, "SendMessage(LB_DIR, DDL_DRIVES, *) failed - 0x%08x\n", GetLastError());
981 /* There should be some content in the listbox. In particular, there should
982 * be at least one element before, since the string "[-c-]" should
983 * have been added. Depending on the user setting, more drives might have
986 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
987 ok (itemCount
== itemCount_justDrives
+ itemCount_allFiles
,
988 "SendMessage(LB_DIR, DDL_DRIVES, *) filled with %d entries, expected %d\n",
989 itemCount
, itemCount_justDrives
+ itemCount_allFiles
);
990 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DRIVES, *) returned incorrect index!\n");
992 /* This tests behavior when no files match the wildcard */
993 strcpy(pathBuffer
, BAD_EXTENSION
);
994 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
995 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
, (LPARAM
)pathBuffer
);
996 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DRIVES, %s) returned %d, expected %d\n",
997 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
999 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1000 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
1003 /* Test DDL_DRIVES. */
1004 strcpy(pathBuffer
, "w*.c");
1005 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1006 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
, (LPARAM
)pathBuffer
);
1007 ok (res
> 0, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) failed - 0x%08x\n", GetLastError());
1009 /* There should be some content in the listbox. In particular, there should
1010 * be at least one element before, since the string "[-c-]" should
1011 * have been added. Depending on the user setting, more drives might have
1014 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1015 ok (itemCount
== itemCount_justDrives
+ itemCount_justFiles
,
1016 "SendMessage(LB_DIR, DDL_DRIVES, w*.c) filled with %d entries, expected %d\n",
1017 itemCount
, itemCount_justDrives
+ itemCount_justFiles
);
1018 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) returned incorrect index!\n");
1020 /* Every single item in the control should fit the format [-c-], or w*.c */
1021 for (i
= 0; i
< itemCount
; i
++) {
1022 memset(pathBuffer
, 0, MAX_PATH
);
1024 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1025 p
= pathBuffer
+ strlen(pathBuffer
);
1026 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1) {
1027 ok( strlen(pathBuffer
) == 5, "Length of drive string is not 5\n" );
1028 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1031 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1032 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1033 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1038 /* Test DDL_DIRECTORY|DDL_DRIVES. This does *not* imply DDL_EXCLUSIVE */
1039 strcpy(pathBuffer
, wildcard
);
1040 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1041 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
, (LPARAM
)pathBuffer
);
1042 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, *) failed - 0x%08x\n", GetLastError());
1044 /* There should be some content in the listbox. In particular, there should
1045 * be exactly the number of plain files, plus the number of mapped drives.
1047 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1048 ok (itemCount
== itemCount_allFiles
+ itemCount_justDrives
+ itemCount_allDirs
,
1049 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1050 itemCount
, itemCount_allFiles
+ itemCount_justDrives
+ itemCount_allDirs
);
1051 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
1053 /* Every single item in the control should start with a w and end in .c,
1054 * except for the "[..]" string, which should appear exactly as it is,
1055 * and the mapped drives in the format "[-X-]".
1057 for (i
= 0; i
< itemCount
; i
++) {
1058 memset(pathBuffer
, 0, MAX_PATH
);
1060 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1061 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1) {
1062 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1066 /* This tests behavior when no files match the wildcard */
1067 strcpy(pathBuffer
, BAD_EXTENSION
);
1068 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1069 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
, (LPARAM
)pathBuffer
);
1070 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, %s) returned %d, expected %d\n",
1071 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
1073 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1074 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
1078 /* Test DDL_DIRECTORY|DDL_DRIVES. */
1079 strcpy(pathBuffer
, "w*.c");
1080 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1081 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
, (LPARAM
)pathBuffer
);
1082 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) failed - 0x%08x\n", GetLastError());
1084 /* There should be some content in the listbox. In particular, there should
1085 * be exactly the number of plain files, plus the number of mapped drives.
1087 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1088 ok (itemCount
== itemCount_justFiles
+ itemCount_justDrives
,
1089 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1090 itemCount
, itemCount_justFiles
+ itemCount_justDrives
);
1091 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
1093 /* Every single item in the control should start with a w and end in .c,
1094 * except the mapped drives in the format "[-X-]". The "[..]" directory
1095 * should not appear.
1097 for (i
= 0; i
< itemCount
; i
++) {
1098 memset(pathBuffer
, 0, MAX_PATH
);
1100 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1101 p
= pathBuffer
+ strlen(pathBuffer
);
1102 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1) {
1103 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1106 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1107 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1108 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1112 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1113 strcpy(pathBuffer
, wildcard
);
1114 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1115 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1116 ok (res
!= -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) failed err %u\n", GetLastError());
1118 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1119 ok (itemCount
== itemCount_allDirs
,
1120 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1121 itemCount
, itemCount_allDirs
);
1122 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) returned incorrect index!\n");
1126 memset(pathBuffer
, 0, MAX_PATH
);
1127 SendMessageA(hList
, LB_GETTEXT
, 0, (LPARAM
)pathBuffer
);
1128 ok( !strcmp(pathBuffer
, "[..]"), "First element is %s, not [..]\n", pathBuffer
);
1131 /* This tests behavior when no files match the wildcard */
1132 strcpy(pathBuffer
, BAD_EXTENSION
);
1133 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1134 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1135 ok (res
== -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1136 BAD_EXTENSION
, res
, -1);
1138 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1139 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
1142 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1143 strcpy(pathBuffer
, "w*.c");
1144 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1145 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1146 ok (res
== LB_ERR
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, w*.c) returned %d expected %d\n", res
, LB_ERR
);
1148 /* There should be no elements, since "[..]" does not fit w*.c */
1149 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1151 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1154 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1155 strcpy(pathBuffer
, wildcard
);
1156 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1157 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1158 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
1160 /* There should be no plain files on the listbox */
1161 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1162 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
1163 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1164 itemCount
, itemCount_justDrives
+ itemCount_allDirs
);
1165 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
1167 for (i
= 0; i
< itemCount
; i
++) {
1168 memset(pathBuffer
, 0, MAX_PATH
);
1170 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1171 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1) {
1172 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1174 ok( pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']',
1175 "Element %d (%s) does not fit expected [...]\n", i
, pathBuffer
);
1179 /* This tests behavior when no files match the wildcard */
1180 strcpy(pathBuffer
, BAD_EXTENSION
);
1181 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1182 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1183 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1184 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
1186 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1187 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
1189 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1190 strcpy(pathBuffer
, "w*.c");
1191 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1192 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1193 ok (res
>= 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
1195 /* There should be no plain files on the listbox, and no [..], since it does not fit w*.c */
1196 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1197 ok (itemCount
== itemCount_justDrives
,
1198 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1199 itemCount
, itemCount_justDrives
);
1200 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
1202 for (i
= 0; i
< itemCount
; i
++) {
1203 memset(pathBuffer
, 0, MAX_PATH
);
1205 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1206 ok (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1, "Element %d (%s) does not fit [-X-]\n", i
, pathBuffer
);
1207 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1209 DestroyWindow(hList
);
1211 DeleteFileA( "wtest1.tmp.c" );
1212 RemoveDirectoryA("lb_dir_test");
1214 SetCurrentDirectoryA(curdir
);
1217 static HWND g_listBox
;
1218 static HWND g_label
;
1220 #define ID_TEST_LABEL 1001
1221 #define ID_TEST_LISTBOX 1002
1223 static BOOL
on_listbox_container_create (HWND hwnd
, LPCREATESTRUCTA lpcs
)
1225 g_label
= CreateWindowA(
1227 "Contents of static control before DlgDirList.",
1228 WS_CHILD
| WS_VISIBLE
,
1230 hwnd
, (HMENU
)ID_TEST_LABEL
, NULL
, 0);
1231 if (!g_label
) return FALSE
;
1232 g_listBox
= CreateWindowA(
1235 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| WS_BORDER
| WS_VSCROLL
,
1237 hwnd
, (HMENU
)ID_TEST_LISTBOX
, NULL
, 0);
1238 if (!g_listBox
) return FALSE
;
1243 static LRESULT CALLBACK
listbox_container_window_procA (
1244 HWND hwnd
, UINT uiMsg
, WPARAM wParam
, LPARAM lParam
)
1253 result
= on_listbox_container_create(hwnd
, (LPCREATESTRUCTA
) lParam
)
1257 result
= DefWindowProcA (hwnd
, uiMsg
, wParam
, lParam
);
1263 static BOOL
RegisterListboxWindowClass(HINSTANCE hInst
)
1270 cls
.hInstance
= hInst
;
1272 cls
.hCursor
= LoadCursorA (NULL
, (LPCSTR
)IDC_ARROW
);
1273 cls
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
1274 cls
.lpszMenuName
= NULL
;
1275 cls
.lpfnWndProc
= listbox_container_window_procA
;
1276 cls
.lpszClassName
= "ListboxContainerClass";
1277 if (!RegisterClassA (&cls
)) return FALSE
;
1282 static void test_listbox_dlgdir(void)
1287 int itemCount_allDirs
;
1288 int itemCount_justFiles
;
1289 int itemCount_justDrives
;
1291 char pathBuffer
[MAX_PATH
];
1292 char itemBuffer
[MAX_PATH
];
1293 char tempBuffer
[MAX_PATH
];
1298 file
= CreateFileA( "wtest1.tmp.c", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1299 ok(file
!= INVALID_HANDLE_VALUE
, "Error creating the test file: %d\n", GetLastError());
1300 CloseHandle( file
);
1302 /* NOTE: for this test to succeed, there must be no subdirectories
1303 under the current directory. In addition, there must be at least
1304 one file that fits the wildcard w*.c . Normally, the test
1305 directory itself satisfies both conditions.
1308 hInst
= GetModuleHandleA(0);
1309 if (!RegisterListboxWindowClass(hInst
)) assert(0);
1310 hWnd
= CreateWindowA("ListboxContainerClass", "ListboxContainerClass",
1311 WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
1312 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
1313 NULL
, NULL
, hInst
, 0);
1316 /* Test for standard usage */
1318 /* The following should be overwritten by the directory path */
1319 SendMessageA(g_label
, WM_SETTEXT
, 0, (LPARAM
)"default contents");
1321 /* This should list all the w*.c files in the test directory
1322 * As of this writing, this includes win.c, winstation.c, wsprintf.c
1324 strcpy(pathBuffer
, "w*.c");
1325 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, 0);
1326 ok (res
== 1, "DlgDirList(*.c, 0) returned %d - expected 1 - 0x%08x\n", res
, GetLastError());
1328 /* Path specification gets converted to uppercase */
1329 ok (!strcmp(pathBuffer
, "W*.C"),
1330 "expected conversion to uppercase, got %s\n", pathBuffer
);
1332 /* Loaded path should have overwritten the label text */
1333 SendMessageA(g_label
, WM_GETTEXT
, MAX_PATH
, (LPARAM
)pathBuffer
);
1334 trace("Static control after DlgDirList: %s\n", pathBuffer
);
1335 ok (strcmp("default contents", pathBuffer
), "DlgDirList() did not modify static control!\n");
1337 /* There should be some content in the listbox */
1338 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1339 ok (itemCount
> 0, "DlgDirList() did NOT fill the listbox!\n");
1340 itemCount_justFiles
= itemCount
;
1342 /* Every single item in the control should start with a w and end in .c */
1343 for (i
= 0; i
< itemCount
; i
++) {
1344 memset(pathBuffer
, 0, MAX_PATH
);
1345 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1346 p
= pathBuffer
+ strlen(pathBuffer
);
1347 ok(((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1348 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1349 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1352 /* Test behavior when no files match the wildcard */
1353 strcpy(pathBuffer
, BAD_EXTENSION
);
1354 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, 0);
1355 ok (res
== 1, "DlgDirList(%s, 0) returned %d expected 1\n", BAD_EXTENSION
, res
);
1357 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1358 ok (itemCount
== 0, "DlgDirList() DID fill the listbox!\n");
1360 /* Test DDL_DIRECTORY */
1361 strcpy(pathBuffer
, "w*.c");
1362 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1364 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY) failed - 0x%08x\n", GetLastError());
1366 /* There should be some content in the listbox. In particular, there should
1367 * be exactly more elements than before, since the directories should
1370 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1371 itemCount_allDirs
= itemCount
- itemCount_justFiles
;
1372 ok (itemCount
>= itemCount_justFiles
,
1373 "DlgDirList(DDL_DIRECTORY) filled with %d entries, expected > %d\n",
1374 itemCount
, itemCount_justFiles
);
1376 /* Every single item in the control should start with a w and end in .c,
1377 * except for the "[..]" string, which should appear exactly as it is.
1379 for (i
= 0; i
< itemCount
; i
++) {
1380 memset(pathBuffer
, 0, MAX_PATH
);
1381 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1382 p
= pathBuffer
+ strlen(pathBuffer
);
1383 ok( (pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']') ||
1384 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1385 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1386 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1389 /* Test behavior when no files match the wildcard */
1390 strcpy(pathBuffer
, BAD_EXTENSION
);
1391 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1393 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY) returned %d expected 1\n", BAD_EXTENSION
, res
);
1395 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1396 ok (itemCount
== itemCount_allDirs
,
1397 "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
1398 itemCount_allDirs
, itemCount
);
1399 for (i
= 0; i
< itemCount
; i
++) {
1400 memset(pathBuffer
, 0, MAX_PATH
);
1401 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1402 ok( pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']',
1403 "Element %d (%s) does not fit requested [...]\n", i
, pathBuffer
);
1407 /* Test DDL_DRIVES. At least on WinXP-SP2, this implies DDL_EXCLUSIVE */
1408 strcpy(pathBuffer
, "w*.c");
1409 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1411 ok (res
== 1, "DlgDirList(*.c, DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1413 /* There should be some content in the listbox. In particular, there should
1414 * be at least one element before, since the string "[-c-]" should
1415 * have been added. Depending on the user setting, more drives might have
1418 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1420 "DlgDirList(DDL_DRIVES) filled with %d entries, expected at least %d\n",
1422 itemCount_justDrives
= itemCount
;
1424 /* Every single item in the control should fit the format [-c-] */
1425 for (i
= 0; i
< itemCount
; i
++) {
1426 memset(pathBuffer
, 0, MAX_PATH
);
1428 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1429 ok( strlen(pathBuffer
) == 5, "Length of drive string is not 5\n" );
1430 ok( sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1, "Element %d (%s) does not fit [-X-]\n", i
, pathBuffer
);
1431 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1432 if (!(driveletter
>= 'a' && driveletter
<= 'z')) {
1433 /* Correct after invalid entry is found */
1434 trace("removing count of invalid entry %s\n", pathBuffer
);
1435 itemCount_justDrives
--;
1439 /* Test behavior when no files match the wildcard */
1440 strcpy(pathBuffer
, BAD_EXTENSION
);
1441 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1443 ok (res
== 1, "DlgDirList(%s, DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION
, res
);
1445 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1446 ok (itemCount
== itemCount_justDrives
, "DlgDirList() incorrectly filled the listbox!\n");
1449 /* Test DDL_DIRECTORY|DDL_DRIVES. This does *not* imply DDL_EXCLUSIVE */
1450 strcpy(pathBuffer
, "w*.c");
1451 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1452 DDL_DIRECTORY
|DDL_DRIVES
);
1453 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1455 /* There should be some content in the listbox. In particular, there should
1456 * be exactly the number of plain files, plus the number of mapped drives,
1459 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1460 ok (itemCount
== itemCount_justFiles
+ itemCount_justDrives
+ itemCount_allDirs
,
1461 "DlgDirList(DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1462 itemCount
, itemCount_justFiles
+ itemCount_justDrives
+ itemCount_allDirs
);
1464 /* Every single item in the control should start with a w and end in .c,
1465 * except for the "[..]" string, which should appear exactly as it is,
1466 * and the mapped drives in the format "[-X-]".
1468 for (i
= 0; i
< itemCount
; i
++) {
1469 memset(pathBuffer
, 0, MAX_PATH
);
1471 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1472 p
= pathBuffer
+ strlen(pathBuffer
);
1473 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1) {
1474 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1476 ok( (pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']') ||
1477 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1478 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1479 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1483 /* Test behavior when no files match the wildcard */
1484 strcpy(pathBuffer
, BAD_EXTENSION
);
1485 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1486 DDL_DIRECTORY
|DDL_DRIVES
);
1487 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION
, res
);
1489 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1490 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
1491 "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
1492 itemCount_justDrives
+ itemCount_allDirs
, itemCount
);
1496 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1497 strcpy(pathBuffer
, "w*.c");
1498 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1499 DDL_DIRECTORY
|DDL_EXCLUSIVE
);
1500 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_EXCLUSIVE) failed - 0x%08x\n", GetLastError());
1502 /* There should be exactly one element: "[..]" */
1503 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1504 ok (itemCount
== itemCount_allDirs
,
1505 "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1506 itemCount
, itemCount_allDirs
);
1508 if (itemCount
&& GetCurrentDirectoryA( MAX_PATH
, pathBuffer
) > 3) /* there's no [..] in drive root */
1510 memset(pathBuffer
, 0, MAX_PATH
);
1511 SendMessageA(g_listBox
, LB_GETTEXT
, 0, (LPARAM
)pathBuffer
);
1512 ok( !strcmp(pathBuffer
, "[..]"), "First (and only) element is not [..]\n");
1515 /* Test behavior when no files match the wildcard */
1516 strcpy(pathBuffer
, BAD_EXTENSION
);
1517 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1518 DDL_DIRECTORY
|DDL_EXCLUSIVE
);
1519 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION
, res
);
1521 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1522 ok (itemCount
== itemCount_allDirs
, "DlgDirList() incorrectly filled the listbox!\n");
1525 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1526 strcpy(pathBuffer
, "w*.c");
1527 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1528 DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
);
1529 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) failed - 0x%08x\n", GetLastError());
1531 /* There should be no plain files on the listbox */
1532 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1533 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
1534 "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1535 itemCount
, itemCount_justDrives
+ itemCount_allDirs
);
1537 for (i
= 0; i
< itemCount
; i
++) {
1538 memset(pathBuffer
, 0, MAX_PATH
);
1540 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1541 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1) {
1542 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1544 ok( pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']',
1545 "Element %d (%s) does not fit expected [...]\n", i
, pathBuffer
);
1549 /* Test behavior when no files match the wildcard */
1550 strcpy(pathBuffer
, BAD_EXTENSION
);
1551 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1552 DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
);
1553 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION
, res
);
1555 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1556 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
1557 "DlgDirList() incorrectly filled the listbox!\n");
1559 /* Now test DlgDirSelectEx() in normal operation */
1560 /* Fill with everything - drives, directory and all plain files. */
1561 strcpy(pathBuffer
, "*");
1562 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1563 DDL_DIRECTORY
|DDL_DRIVES
);
1564 ok (res
!= 0, "DlgDirList(*, DDL_DIRECTORY|DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1566 SendMessageA(g_listBox
, LB_SETCURSEL
, -1, 0); /* Unselect any current selection */
1567 memset(pathBuffer
, 0, MAX_PATH
);
1568 SetLastError(0xdeadbeef);
1569 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1570 ok (GetLastError() == 0xdeadbeef,
1571 "DlgDirSelectEx() with no selection modified last error code from 0xdeadbeef to 0x%08x\n",
1573 ok (res
== 0, "DlgDirSelectEx() with no selection returned %d, expected 0\n", res
);
1574 /* WinXP-SP2 leaves pathBuffer untouched, but Win98 fills it with garbage. */
1576 ok (strlen(pathBuffer) == 0, "DlgDirSelectEx() with no selection filled buffer with %s\n", pathBuffer);
1578 /* Test proper drive/dir/file recognition */
1579 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1580 for (i
= 0; i
< itemCount
; i
++) {
1581 memset(itemBuffer
, 0, MAX_PATH
);
1582 memset(pathBuffer
, 0, MAX_PATH
);
1583 memset(tempBuffer
, 0, MAX_PATH
);
1585 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)itemBuffer
);
1586 res
= SendMessageA(g_listBox
, LB_SETCURSEL
, i
, 0);
1587 ok (res
== i
, "SendMessageA(LB_SETCURSEL, %d) failed\n", i
);
1588 if (sscanf(itemBuffer
, "[-%c-]", &driveletter
) == 1) {
1589 /* Current item is a drive letter */
1590 SetLastError(0xdeadbeef);
1591 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1592 ok (GetLastError() == 0xdeadbeef,
1593 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1595 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1597 /* For drive letters, DlgDirSelectEx tacks on a colon */
1598 ok (pathBuffer
[0] == driveletter
&& pathBuffer
[1] == ':' && pathBuffer
[2] == '\0',
1599 "%d: got \"%s\" expected \"%c:\"\n", i
, pathBuffer
, driveletter
);
1600 } else if (itemBuffer
[0] == '[') {
1601 /* Current item is the parent directory */
1602 SetLastError(0xdeadbeef);
1603 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1604 ok (GetLastError() == 0xdeadbeef,
1605 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1607 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1609 /* For directories, DlgDirSelectEx tacks on a backslash */
1610 p
= pathBuffer
+ strlen(pathBuffer
);
1611 ok (*(p
-1) == '\\', "DlgDirSelectEx did NOT tack on a backslash to dir, got %s\n", pathBuffer
);
1613 tempBuffer
[0] = '[';
1614 lstrcpynA(tempBuffer
+ 1, pathBuffer
, strlen(pathBuffer
));
1615 strcat(tempBuffer
, "]");
1616 ok (!strcmp(tempBuffer
, itemBuffer
), "Formatted directory should be %s, got %s\n", tempBuffer
, itemBuffer
);
1618 /* Current item is a plain file */
1619 SetLastError(0xdeadbeef);
1620 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1621 ok (GetLastError() == 0xdeadbeef,
1622 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1624 ok(res
== 0, "DlgDirSelectEx() thinks %s (%s) is a drive/directory!\n", itemBuffer
, pathBuffer
);
1626 /* NOTE: WinXP tacks a period on all files that lack an extension. This affects
1627 * for example, "Makefile", which gets reported as "Makefile."
1629 strcpy(tempBuffer
, itemBuffer
);
1630 if (strchr(tempBuffer
, '.') == NULL
) strcat(tempBuffer
, ".");
1631 ok (!strcmp(pathBuffer
, tempBuffer
), "Formatted file should be %s, got %s\n", tempBuffer
, pathBuffer
);
1635 DeleteFileA( "wtest1.tmp.c" );
1637 /* Now test DlgDirSelectEx() in abnormal operation */
1638 /* Fill list with bogus entries, that look somewhat valid */
1639 SendMessageA(g_listBox
, LB_RESETCONTENT
, 0, 0);
1640 SendMessageA(g_listBox
, LB_ADDSTRING
, 0, (LPARAM
)"[notexist.dir]");
1641 SendMessageA(g_listBox
, LB_ADDSTRING
, 0, (LPARAM
)"notexist.fil");
1642 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1643 for (i
= 0; i
< itemCount
; i
++) {
1644 memset(itemBuffer
, 0, MAX_PATH
);
1645 memset(pathBuffer
, 0, MAX_PATH
);
1646 memset(tempBuffer
, 0, MAX_PATH
);
1648 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)itemBuffer
);
1649 res
= SendMessageA(g_listBox
, LB_SETCURSEL
, i
, 0);
1650 ok (res
== i
, "SendMessage(LB_SETCURSEL, %d) failed\n", i
);
1651 if (sscanf(itemBuffer
, "[-%c-]", &driveletter
) == 1) {
1652 /* Current item is a drive letter */
1653 SetLastError(0xdeadbeef);
1654 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1655 ok (GetLastError() == 0xdeadbeef,
1656 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1658 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1660 /* For drive letters, DlgDirSelectEx tacks on a colon */
1661 ok (pathBuffer
[0] == driveletter
&& pathBuffer
[1] == ':' && pathBuffer
[2] == '\0',
1662 "%d: got \"%s\" expected \"%c:\"\n", i
, pathBuffer
, driveletter
);
1663 } else if (itemBuffer
[0] == '[') {
1664 /* Current item is the parent directory */
1665 SetLastError(0xdeadbeef);
1666 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1667 ok (GetLastError() == 0xdeadbeef,
1668 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1670 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1672 /* For directories, DlgDirSelectEx tacks on a backslash */
1673 p
= pathBuffer
+ strlen(pathBuffer
);
1674 ok (*(p
-1) == '\\', "DlgDirSelectEx did NOT tack on a backslash to dir, got %s\n", pathBuffer
);
1676 tempBuffer
[0] = '[';
1677 lstrcpynA(tempBuffer
+ 1, pathBuffer
, strlen(pathBuffer
));
1678 strcat(tempBuffer
, "]");
1679 ok (!strcmp(tempBuffer
, itemBuffer
), "Formatted directory should be %s, got %s\n", tempBuffer
, itemBuffer
);
1681 /* Current item is a plain file */
1682 SetLastError(0xdeadbeef);
1683 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1684 ok (GetLastError() == 0xdeadbeef,
1685 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1687 ok(res
== 0, "DlgDirSelectEx() thinks %s (%s) is a drive/directory!\n", itemBuffer
, pathBuffer
);
1689 /* NOTE: WinXP and Win98 tack a period on all files that lack an extension.
1690 * This affects for example, "Makefile", which gets reported as "Makefile."
1692 strcpy(tempBuffer
, itemBuffer
);
1693 if (strchr(tempBuffer
, '.') == NULL
) strcat(tempBuffer
, ".");
1694 ok (!strcmp(pathBuffer
, tempBuffer
), "Formatted file should be %s, got %s\n", tempBuffer
, pathBuffer
);
1698 /* Test behavior when loading folders from root with and without wildcard */
1699 strcpy(pathBuffer
, "C:\\");
1700 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, 0, DDL_DIRECTORY
| DDL_EXCLUSIVE
);
1701 ok(res
|| broken(!res
) /* NT4/W2K */, "DlgDirList failed to list C:\\ folders\n");
1702 todo_wine
ok(!strcmp(pathBuffer
, "*") || broken(!res
) /* NT4/W2K */,
1703 "DlgDirList set the invalid path spec '%s', expected '*'\n", pathBuffer
);
1705 strcpy(pathBuffer
, "C:\\*");
1706 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, 0, DDL_DIRECTORY
| DDL_EXCLUSIVE
);
1707 ok(res
|| broken(!res
) /* NT4/W2K */, "DlgDirList failed to list C:\\* folders\n");
1708 ok(!strcmp(pathBuffer
, "*") || broken(!res
) /* NT4/W2K */,
1709 "DlgDirList set the invalid path spec '%s', expected '*'\n", pathBuffer
);
1711 /* Try loading files from an invalid folder */
1712 SetLastError(0xdeadbeef);
1713 strcpy(pathBuffer
, "C:\\INVALID$$DIR");
1714 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, 0, DDL_DIRECTORY
| DDL_EXCLUSIVE
);
1715 todo_wine
ok(!res
, "DlgDirList should have failed with 0 but %d was returned\n", res
);
1716 todo_wine
ok(GetLastError() == ERROR_NO_WILDCARD_CHARACTERS
,
1717 "GetLastError should return 0x589, got 0x%X\n",GetLastError());
1719 DestroyWindow(hWnd
);
1722 static void test_set_count( void )
1724 static const DWORD styles
[] =
1729 HWND parent
, listbox
;
1734 parent
= create_parent();
1735 listbox
= create_listbox( LBS_OWNERDRAWFIXED
| LBS_NODATA
| WS_CHILD
| WS_VISIBLE
, parent
);
1737 UpdateWindow( listbox
);
1738 GetUpdateRect( listbox
, &r
, TRUE
);
1739 ok( IsRectEmpty( &r
), "got non-empty rect\n");
1741 ret
= SendMessageA( listbox
, LB_SETCOUNT
, 100, 0 );
1742 ok( ret
== 0, "got %d\n", ret
);
1743 ret
= SendMessageA( listbox
, LB_GETCOUNT
, 0, 0 );
1744 ok( ret
== 100, "got %d\n", ret
);
1746 GetUpdateRect( listbox
, &r
, TRUE
);
1747 ok( !IsRectEmpty( &r
), "got empty rect\n");
1749 ValidateRect( listbox
, NULL
);
1750 GetUpdateRect( listbox
, &r
, TRUE
);
1751 ok( IsRectEmpty( &r
), "got non-empty rect\n");
1753 ret
= SendMessageA( listbox
, LB_SETCOUNT
, 99, 0 );
1754 ok( ret
== 0, "got %d\n", ret
);
1756 GetUpdateRect( listbox
, &r
, TRUE
);
1757 ok( !IsRectEmpty( &r
), "got empty rect\n");
1759 DestroyWindow( listbox
);
1761 for (i
= 0; i
< ARRAY_SIZE(styles
); ++i
)
1763 listbox
= create_listbox( styles
[i
] | WS_CHILD
| WS_VISIBLE
, parent
);
1765 SetLastError( 0xdeadbeef );
1766 ret
= SendMessageA( listbox
, LB_SETCOUNT
, 100, 0 );
1767 ok( ret
== LB_ERR
, "expected %d, got %d\n", LB_ERR
, ret
);
1768 ok( GetLastError() == ERROR_SETCOUNT_ON_BAD_LB
, "Unexpected error %d.\n", GetLastError() );
1770 DestroyWindow( listbox
);
1773 DestroyWindow( parent
);
1776 static DWORD (WINAPI
*pGetListBoxInfo
)(HWND
);
1777 static int lb_getlistboxinfo
;
1779 static LRESULT WINAPI
listbox_subclass_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1781 WNDPROC oldproc
= (WNDPROC
)GetWindowLongPtrA(hwnd
, GWLP_USERDATA
);
1783 if (message
== LB_GETLISTBOXINFO
)
1784 lb_getlistboxinfo
++;
1786 return CallWindowProcA(oldproc
, hwnd
, message
, wParam
, lParam
);
1789 static void test_GetListBoxInfo(void)
1791 HWND listbox
, parent
;
1795 pGetListBoxInfo
= (void*)GetProcAddress(GetModuleHandleA("user32.dll"), "GetListBoxInfo");
1797 if (!pGetListBoxInfo
)
1799 win_skip("GetListBoxInfo() not available\n");
1803 parent
= create_parent();
1804 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
, parent
);
1806 oldproc
= (WNDPROC
)SetWindowLongPtrA(listbox
, GWLP_WNDPROC
, (LONG_PTR
)listbox_subclass_proc
);
1807 SetWindowLongPtrA(listbox
, GWLP_USERDATA
, (LONG_PTR
)oldproc
);
1809 lb_getlistboxinfo
= 0;
1810 ret
= pGetListBoxInfo(listbox
);
1811 ok(ret
> 0, "got %d\n", ret
);
1813 ok(lb_getlistboxinfo
== 0, "got %d\n", lb_getlistboxinfo
);
1815 DestroyWindow(listbox
);
1816 DestroyWindow(parent
);
1819 static void test_missing_lbuttonup( void )
1821 HWND listbox
, parent
, capture
;
1823 parent
= create_parent();
1824 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
, parent
);
1826 /* Send button down without a corresponding button up */
1827 SendMessageA(listbox
, WM_LBUTTONDOWN
, 0, MAKELPARAM(10,10));
1828 capture
= GetCapture();
1829 ok(capture
== listbox
, "got %p expected %p\n", capture
, listbox
);
1831 /* Capture is released and LBN_SELCHANGE sent during WM_KILLFOCUS */
1834 capture
= GetCapture();
1835 ok(capture
== NULL
, "got %p\n", capture
);
1836 ok(got_selchange
, "got %d\n", got_selchange
);
1838 DestroyWindow(listbox
);
1839 DestroyWindow(parent
);
1842 static void test_extents(void)
1844 HWND listbox
, parent
;
1849 parent
= create_parent();
1851 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
, parent
);
1853 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1854 ok(res
== 0, "Got wrong initial horizontal extent: %u\n", res
);
1856 sinfo
.cbSize
= sizeof(sinfo
);
1857 sinfo
.fMask
= SIF_RANGE
;
1858 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1859 ok(br
== TRUE
, "GetScrollInfo failed\n");
1860 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1861 ok(sinfo
.nMax
== 100, "got wrong max: %u\n", sinfo
.nMax
);
1862 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1863 "List box should not have a horizontal scroll bar\n");
1865 /* horizontal extent < width */
1866 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 64, 0);
1868 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1869 ok(res
== 64, "Got wrong horizontal extent: %u\n", res
);
1871 sinfo
.cbSize
= sizeof(sinfo
);
1872 sinfo
.fMask
= SIF_RANGE
;
1873 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1874 ok(br
== TRUE
, "GetScrollInfo failed\n");
1875 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1876 ok(sinfo
.nMax
== 100, "got wrong max: %u\n", sinfo
.nMax
);
1877 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1878 "List box should not have a horizontal scroll bar\n");
1880 /* horizontal extent > width */
1881 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 184, 0);
1883 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1884 ok(res
== 184, "Got wrong horizontal extent: %u\n", res
);
1886 sinfo
.cbSize
= sizeof(sinfo
);
1887 sinfo
.fMask
= SIF_RANGE
;
1888 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1889 ok(br
== TRUE
, "GetScrollInfo failed\n");
1890 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1891 ok(sinfo
.nMax
== 100, "got wrong max: %u\n", sinfo
.nMax
);
1892 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1893 "List box should not have a horizontal scroll bar\n");
1895 DestroyWindow(listbox
);
1898 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
| WS_HSCROLL
, parent
);
1900 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1901 ok(res
== 0, "Got wrong initial horizontal extent: %u\n", res
);
1903 sinfo
.cbSize
= sizeof(sinfo
);
1904 sinfo
.fMask
= SIF_RANGE
;
1905 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1906 ok(br
== TRUE
, "GetScrollInfo failed\n");
1907 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1908 ok(sinfo
.nMax
== 100, "got wrong max: %u\n", sinfo
.nMax
);
1909 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1910 "List box should not have a horizontal scroll bar\n");
1912 /* horizontal extent < width */
1913 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 64, 0);
1915 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1916 ok(res
== 64, "Got wrong horizontal extent: %u\n", res
);
1918 sinfo
.cbSize
= sizeof(sinfo
);
1919 sinfo
.fMask
= SIF_RANGE
;
1920 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1921 ok(br
== TRUE
, "GetScrollInfo failed\n");
1922 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1923 ok(sinfo
.nMax
== 63, "got wrong max: %u\n", sinfo
.nMax
);
1924 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1925 "List box should not have a horizontal scroll bar\n");
1927 /* horizontal extent > width */
1928 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 184, 0);
1930 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1931 ok(res
== 184, "Got wrong horizontal extent: %u\n", res
);
1933 sinfo
.cbSize
= sizeof(sinfo
);
1934 sinfo
.fMask
= SIF_RANGE
;
1935 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1936 ok(br
== TRUE
, "GetScrollInfo failed\n");
1937 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1938 ok(sinfo
.nMax
== 183, "got wrong max: %u\n", sinfo
.nMax
);
1939 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
1940 "List box should have a horizontal scroll bar\n");
1942 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 0, 0);
1944 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1945 ok(res
== 0, "Got wrong horizontal extent: %u\n", res
);
1947 sinfo
.cbSize
= sizeof(sinfo
);
1948 sinfo
.fMask
= SIF_RANGE
;
1949 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1950 ok(br
== TRUE
, "GetScrollInfo failed\n");
1951 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1952 ok(sinfo
.nMax
== 0, "got wrong max: %u\n", sinfo
.nMax
);
1953 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1954 "List box should not have a horizontal scroll bar\n");
1956 DestroyWindow(listbox
);
1959 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
| WS_HSCROLL
| LBS_DISABLENOSCROLL
, parent
);
1961 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1962 ok(res
== 0, "Got wrong initial horizontal extent: %u\n", res
);
1964 sinfo
.cbSize
= sizeof(sinfo
);
1965 sinfo
.fMask
= SIF_RANGE
;
1966 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1967 ok(br
== TRUE
, "GetScrollInfo failed\n");
1968 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1969 ok(sinfo
.nMax
== 0, "got wrong max: %u\n", sinfo
.nMax
);
1970 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
1971 "List box should have a horizontal scroll bar\n");
1973 /* horizontal extent < width */
1974 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 64, 0);
1976 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1977 ok(res
== 64, "Got wrong horizontal extent: %u\n", res
);
1979 sinfo
.cbSize
= sizeof(sinfo
);
1980 sinfo
.fMask
= SIF_RANGE
;
1981 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1982 ok(br
== TRUE
, "GetScrollInfo failed\n");
1983 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1984 ok(sinfo
.nMax
== 63, "got wrong max: %u\n", sinfo
.nMax
);
1985 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
1986 "List box should have a horizontal scroll bar\n");
1988 /* horizontal extent > width */
1989 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 184, 0);
1991 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1992 ok(res
== 184, "Got wrong horizontal extent: %u\n", res
);
1994 sinfo
.cbSize
= sizeof(sinfo
);
1995 sinfo
.fMask
= SIF_RANGE
;
1996 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1997 ok(br
== TRUE
, "GetScrollInfo failed\n");
1998 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1999 ok(sinfo
.nMax
== 183, "got wrong max: %u\n", sinfo
.nMax
);
2000 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
2001 "List box should have a horizontal scroll bar\n");
2003 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 0, 0);
2005 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
2006 ok(res
== 0, "Got wrong horizontal extent: %u\n", res
);
2008 sinfo
.cbSize
= sizeof(sinfo
);
2009 sinfo
.fMask
= SIF_RANGE
;
2010 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
2011 ok(br
== TRUE
, "GetScrollInfo failed\n");
2012 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
2013 ok(sinfo
.nMax
== 0, "got wrong max: %u\n", sinfo
.nMax
);
2014 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
2015 "List box should have a horizontal scroll bar\n");
2017 DestroyWindow(listbox
);
2019 DestroyWindow(parent
);
2022 static void test_WM_MEASUREITEM(void)
2024 HWND parent
, listbox
;
2027 parent
= create_parent();
2028 listbox
= create_listbox(WS_CHILD
| LBS_OWNERDRAWVARIABLE
, parent
);
2030 data
= SendMessageA(listbox
, LB_GETITEMDATA
, 0, 0);
2031 ok(data
== (LRESULT
)strings
[0], "data = %08lx, expected %p\n", data
, strings
[0]);
2032 DestroyWindow(parent
);
2034 parent
= create_parent();
2035 listbox
= create_listbox(WS_CHILD
| LBS_OWNERDRAWVARIABLE
| LBS_HASSTRINGS
, parent
);
2037 data
= SendMessageA(listbox
, LB_GETITEMDATA
, 0, 0);
2038 ok(!data
, "data = %08lx\n", data
);
2039 DestroyWindow(parent
);
2042 static void test_LBS_NODATA(void)
2044 static const DWORD invalid_styles
[] =
2047 LBS_OWNERDRAWVARIABLE
,
2050 LBS_OWNERDRAWFIXED
| LBS_SORT
,
2051 LBS_OWNERDRAWFIXED
| LBS_HASSTRINGS
,
2053 static const UINT invalid_idx
[] = { -2, 2 };
2054 static const UINT valid_idx
[] = { 0, 1 };
2055 static const ULONG_PTR zero_data
;
2056 HWND listbox
, parent
;
2061 listbox
= CreateWindowA("listbox", "TestList", LBS_NODATA
| LBS_OWNERDRAWFIXED
| WS_VISIBLE
,
2062 0, 0, 100, 100, NULL
, NULL
, NULL
, 0);
2063 ok(listbox
!= NULL
, "Failed to create ListBox window.\n");
2065 ret
= SendMessageA(listbox
, LB_INSERTSTRING
, -1, 0);
2066 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
2067 ret
= SendMessageA(listbox
, LB_INSERTSTRING
, -1, 0);
2068 ok(ret
== 1, "Unexpected return value %d.\n", ret
);
2069 ret
= SendMessageA(listbox
, LB_GETCOUNT
, 0, 0);
2070 ok(ret
== 2, "Unexpected return value %d.\n", ret
);
2072 /* Invalid indices. */
2073 for (i
= 0; i
< ARRAY_SIZE(invalid_idx
); ++i
)
2075 ret
= SendMessageA(listbox
, LB_SETITEMDATA
, invalid_idx
[i
], 42);
2076 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2077 ret
= SendMessageA(listbox
, LB_GETTEXTLEN
, invalid_idx
[i
], 0);
2078 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2081 ret
= SendMessageA(listbox
, LB_GETTEXT
, invalid_idx
[i
], (LPARAM
)&data
);
2082 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2084 ret
= SendMessageA(listbox
, LB_GETITEMDATA
, invalid_idx
[i
], 0);
2085 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2088 /* Valid indices. */
2089 for (i
= 0; i
< ARRAY_SIZE(valid_idx
); ++i
)
2091 ret
= SendMessageA(listbox
, LB_SETITEMDATA
, valid_idx
[i
], 42);
2092 ok(ret
== TRUE
, "Unexpected return value %d.\n", ret
);
2093 ret
= SendMessageA(listbox
, LB_GETTEXTLEN
, valid_idx
[i
], 0);
2094 todo_wine_if(sizeof(void *) == 8)
2095 ok(ret
== sizeof(data
), "Unexpected return value %d.\n", ret
);
2097 memset(&data
, 0xee, sizeof(data
));
2098 ret
= SendMessageA(listbox
, LB_GETTEXT
, valid_idx
[i
], (LPARAM
)&data
);
2099 todo_wine_if(sizeof(void *) == 8)
2100 ok(ret
== sizeof(data
), "Unexpected return value %d.\n", ret
);
2102 ok(!memcmp(&data
, &zero_data
, sizeof(data
)), "Unexpected item data.\n");
2104 ret
= SendMessageA(listbox
, LB_GETITEMDATA
, valid_idx
[i
], 0);
2106 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
2109 /* More messages that don't work with LBS_NODATA. */
2110 ret
= SendMessageA(listbox
, LB_FINDSTRING
, 1, 42);
2112 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2113 ret
= SendMessageA(listbox
, LB_FINDSTRINGEXACT
, 1, 42);
2115 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2116 ret
= SendMessageA(listbox
, LB_SELECTSTRING
, 1, 42);
2118 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2120 DestroyWindow(listbox
);
2122 /* Invalid window style combinations. */
2123 parent
= create_parent();
2124 ok(parent
!= NULL
, "Failed to create parent window.\n");
2126 for (i
= 0; i
< ARRAY_SIZE(invalid_styles
); ++i
)
2130 listbox
= CreateWindowA("listbox", "TestList", LBS_NODATA
| WS_CHILD
| invalid_styles
[i
],
2131 0, 0, 100, 100, parent
, (HMENU
)1, NULL
, 0);
2132 ok(listbox
!= NULL
, "Failed to create a listbox.\n");
2134 style
= GetWindowLongA(listbox
, GWL_STYLE
);
2135 ok((style
& invalid_styles
[i
]) == invalid_styles
[i
], "%u: unexpected window styles %#x.\n", i
, style
);
2136 ret
= SendMessageA(listbox
, LB_SETCOUNT
, 100, 0);
2137 ok(ret
== LB_ERR
, "%u: unexpected return value %d.\n", i
, ret
);
2138 DestroyWindow(listbox
);
2141 DestroyWindow(parent
);
2146 const struct listbox_test SS
=
2148 {{LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
2149 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
2150 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
2151 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
2152 /* {selected, anchor, caret, selcount}{TODO fields} */
2153 const struct listbox_test SS_NS
=
2154 {{LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
2155 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
2156 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
2157 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
2158 const struct listbox_test MS
=
2159 {{ 0, LB_ERR
, 0, 0}, {0,0,0,0},
2160 { 1, 1, 1, 1}, {0,0,0,0},
2161 { 2, 1, 2, 1}, {0,0,0,0},
2162 { 0, LB_ERR
, 0, 2}, {0,0,0,0}};
2163 const struct listbox_test MS_NS
=
2164 {{LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
2165 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
2166 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
2167 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
2168 const struct listbox_test ES
=
2169 {{ 0, LB_ERR
, 0, 0}, {0,0,0,0},
2170 { 1, 1, 1, 1}, {0,0,0,0},
2171 { 2, 2, 2, 1}, {0,0,0,0},
2172 { 0, LB_ERR
, 0, 2}, {0,0,0,0}};
2173 const struct listbox_test ES_NS
=
2174 {{LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
2175 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
2176 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
2177 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
2178 const struct listbox_test EMS
=
2179 {{ 0, LB_ERR
, 0, 0}, {0,0,0,0},
2180 { 1, 1, 1, 1}, {0,0,0,0},
2181 { 2, 2, 2, 1}, {0,0,0,0},
2182 { 0, LB_ERR
, 0, 2}, {0,0,0,0}};
2183 const struct listbox_test EMS_NS
=
2184 {{LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
2185 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
2186 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
2187 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
2189 trace (" Testing single selection...\n");
2191 trace (" ... with NOSEL\n");
2192 check (LBS_NOSEL
, SS_NS
);
2193 trace (" ... LBS_NODATA variant ...\n");
2194 check (LBS_NODATA
| LBS_OWNERDRAWFIXED
, SS
);
2195 trace (" ... with NOSEL\n");
2196 check (LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_NOSEL
, SS_NS
);
2198 trace (" Testing multiple selection...\n");
2199 check (LBS_MULTIPLESEL
, MS
);
2200 trace (" ... with NOSEL\n");
2201 check (LBS_MULTIPLESEL
| LBS_NOSEL
, MS_NS
);
2202 trace (" ... LBS_NODATA variant ...\n");
2203 check (LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_MULTIPLESEL
, MS
);
2204 trace (" ... with NOSEL\n");
2205 check (LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_MULTIPLESEL
| LBS_NOSEL
, MS_NS
);
2207 trace (" Testing extended selection...\n");
2208 check (LBS_EXTENDEDSEL
, ES
);
2209 trace (" ... with NOSEL\n");
2210 check (LBS_EXTENDEDSEL
| LBS_NOSEL
, ES_NS
);
2211 trace (" ... LBS_NODATA variant ...\n");
2212 check (LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_EXTENDEDSEL
, ES
);
2213 trace (" ... with NOSEL\n");
2214 check (LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_EXTENDEDSEL
| LBS_NOSEL
, ES_NS
);
2216 trace (" Testing extended and multiple selection...\n");
2217 check (LBS_EXTENDEDSEL
| LBS_MULTIPLESEL
, EMS
);
2218 trace (" ... with NOSEL\n");
2219 check (LBS_EXTENDEDSEL
| LBS_MULTIPLESEL
| LBS_NOSEL
, EMS_NS
);
2220 trace (" ... LBS_NODATA variant ...\n");
2221 check (LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_EXTENDEDSEL
| LBS_MULTIPLESEL
, EMS
);
2222 trace (" ... with NOSEL\n");
2223 check (LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_EXTENDEDSEL
| LBS_MULTIPLESEL
| LBS_NOSEL
, EMS_NS
);
2225 check_item_height();
2227 test_LB_SELITEMRANGE();
2228 test_LB_SETCURSEL();
2229 test_listbox_height();
2230 test_itemfrompoint();
2231 test_listbox_item_data();
2232 test_listbox_LB_DIR();
2233 test_listbox_dlgdir();
2235 test_GetListBoxInfo();
2236 test_missing_lbuttonup();
2238 test_WM_MEASUREITEM();