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)
341 static const DWORD styles
[] =
351 parent
= create_parent();
354 for (i
= 0; i
< ARRAY_SIZE(styles
); i
++)
356 hLB
= create_listbox(LBS_OWNERDRAWFIXED
| WS_CHILD
| WS_VISIBLE
| styles
[i
], parent
);
359 SetForegroundWindow(hLB
);
362 /* make height short enough */
363 SendMessageA(hLB
, LB_GETITEMRECT
, 0, (LPARAM
)&rc
);
364 SetWindowPos(hLB
, 0, 0, 0, 100, rc
.bottom
- rc
.top
+ 1,
365 SWP_NOZORDER
| SWP_NOMOVE
);
367 /* make 0 item invisible */
368 SendMessageA(hLB
, LB_SETTOPINDEX
, 1, 0);
369 ret
= SendMessageA(hLB
, LB_GETTOPINDEX
, 0, 0);
370 ok(ret
== 1, "wrong top index %d\n", ret
);
372 SendMessageA(hLB
, LB_GETITEMRECT
, 0, (LPARAM
)&rc
);
373 trace("item 0 rect %s\n", wine_dbgstr_rect(&rc
));
374 ok(!IsRectEmpty(&rc
), "empty item rect\n");
375 ok(rc
.top
< 0, "rc.top is not negative (%d)\n", rc
.top
);
379 /* Both FIXED and VARIABLE, FIXED should override VARIABLE. */
380 hLB
= CreateWindowA("listbox", "TestList", LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
| styles
[i
],
381 0, 0, 100, 100, NULL
, NULL
, NULL
, 0);
382 ok(hLB
!= NULL
, "last error 0x%08x\n", GetLastError());
384 ok(GetWindowLongA(hLB
, GWL_STYLE
) & LBS_OWNERDRAWVARIABLE
, "Unexpected window style.\n");
386 ret
= SendMessageA(hLB
, LB_INSERTSTRING
, -1, 0);
387 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
388 ret
= SendMessageA(hLB
, LB_INSERTSTRING
, -1, 0);
389 ok(ret
== 1, "Unexpected return value %d.\n", ret
);
391 ret
= SendMessageA(hLB
, LB_SETITEMHEIGHT
, 0, 13);
392 ok(ret
== LB_OKAY
, "Failed to set item height, %d.\n", ret
);
394 ret
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 0, 0);
395 ok(ret
== 13, "Unexpected item height %d.\n", ret
);
397 ret
= SendMessageA(hLB
, LB_SETITEMHEIGHT
, 1, 42);
398 ok(ret
== LB_OKAY
, "Failed to set item height, %d.\n", ret
);
400 ret
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 0, 0);
401 ok(ret
== 42, "Unexpected item height %d.\n", ret
);
403 ret
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 1, 0);
404 ok(ret
== 42, "Unexpected item height %d.\n", ret
);
408 DestroyWindow(parent
);
411 #define listbox_test_query(exp, got) \
412 ok(exp.selected == got.selected, "expected selected %d, got %d\n", exp.selected, got.selected); \
413 ok(exp.anchor == got.anchor, "expected anchor %d, got %d\n", exp.anchor, got.anchor); \
414 ok(exp.caret == got.caret, "expected caret %d, got %d\n", exp.caret, got.caret); \
415 ok(exp.selcount == got.selcount, "expected selcount %d, got %d\n", exp.selcount, got.selcount);
417 static void test_LB_SELITEMRANGE(void)
419 static const struct listbox_stat test_nosel
= { 0, LB_ERR
, 0, 0 };
420 static const struct listbox_stat test_1
= { 0, LB_ERR
, 0, 2 };
421 static const struct listbox_stat test_2
= { 0, LB_ERR
, 0, 3 };
422 static const struct listbox_stat test_3
= { 0, LB_ERR
, 0, 4 };
424 struct listbox_stat answer
;
427 trace("testing LB_SELITEMRANGE\n");
429 hLB
= create_listbox(LBS_EXTENDEDSEL
, 0);
432 listbox_query(hLB
, &answer
);
433 listbox_test_query(test_nosel
, answer
);
435 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(1, 2));
436 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
437 listbox_query(hLB
, &answer
);
438 listbox_test_query(test_1
, answer
);
440 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
441 listbox_query(hLB
, &answer
);
442 listbox_test_query(test_nosel
, answer
);
444 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(0, 4));
445 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
446 listbox_query(hLB
, &answer
);
447 listbox_test_query(test_3
, answer
);
449 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
450 listbox_query(hLB
, &answer
);
451 listbox_test_query(test_nosel
, answer
);
453 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(-5, 5));
454 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
455 listbox_query(hLB
, &answer
);
456 listbox_test_query(test_nosel
, answer
);
458 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
459 listbox_query(hLB
, &answer
);
460 listbox_test_query(test_nosel
, answer
);
462 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(2, 10));
463 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
464 listbox_query(hLB
, &answer
);
465 listbox_test_query(test_1
, answer
);
467 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
468 listbox_query(hLB
, &answer
);
469 listbox_test_query(test_nosel
, answer
);
471 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(4, 10));
472 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
473 listbox_query(hLB
, &answer
);
474 listbox_test_query(test_nosel
, answer
);
476 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
477 listbox_query(hLB
, &answer
);
478 listbox_test_query(test_nosel
, answer
);
480 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(10, 1));
481 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
482 listbox_query(hLB
, &answer
);
483 listbox_test_query(test_2
, answer
);
485 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
486 listbox_query(hLB
, &answer
);
487 listbox_test_query(test_nosel
, answer
);
489 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(1, -1));
490 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
491 listbox_query(hLB
, &answer
);
492 listbox_test_query(test_2
, answer
);
497 static void test_LB_SETCURSEL(void)
502 trace("testing LB_SETCURSEL\n");
504 parent
= create_parent();
507 hLB
= create_listbox(LBS_NOINTEGRALHEIGHT
| WS_CHILD
, parent
);
510 SendMessageA(hLB
, LB_SETITEMHEIGHT
, 0, 32);
512 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
513 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
515 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 2, 0);
516 ok(ret
== 2, "LB_SETCURSEL returned %d instead of 2\n", ret
);
517 ret
= GetScrollPos(hLB
, SB_VERT
);
518 ok(ret
== 0, "expected vscroll 0, got %d\n", ret
);
520 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
521 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
523 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 3, 0);
524 ok(ret
== 3, "LB_SETCURSEL returned %d instead of 3\n", ret
);
525 ret
= GetScrollPos(hLB
, SB_VERT
);
526 ok(ret
== 1, "expected vscroll 1, got %d\n", ret
);
528 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
529 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
533 hLB
= create_listbox(0, 0);
534 ok(hLB
!= NULL
, "Failed to create ListBox window.\n");
536 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 1, 0);
537 ok(ret
== 1, "Unexpected return value %d.\n", ret
);
539 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
540 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
544 /* LBS_EXTENDEDSEL */
545 hLB
= create_listbox(LBS_EXTENDEDSEL
, 0);
546 ok(hLB
!= NULL
, "Failed to create ListBox window.\n");
548 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
549 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
551 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 2, 0);
552 ok(ret
== -1, "Unexpected return value %d.\n", ret
);
554 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
555 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
559 /* LBS_MULTIPLESEL */
560 hLB
= create_listbox(LBS_MULTIPLESEL
, 0);
561 ok(hLB
!= NULL
, "Failed to create ListBox window.\n");
563 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
564 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
566 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 2, 0);
567 ok(ret
== -1, "Unexpected return value %d.\n", ret
);
569 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
570 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
575 static void test_LB_SETSEL(void)
580 /* LBS_EXTENDEDSEL */
581 list
= create_listbox(LBS_EXTENDEDSEL
, 0);
582 ok(list
!= NULL
, "Failed to create ListBox window.\n");
584 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
585 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
587 ret
= SendMessageA(list
, LB_SETSEL
, TRUE
, 0);
588 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
589 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
590 ok(ret
== 0, "Unexpected anchor index %d.\n", ret
);
592 ret
= SendMessageA(list
, LB_SETSEL
, TRUE
, 1);
593 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
594 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
595 ok(ret
== 1, "Unexpected anchor index %d.\n", ret
);
597 ret
= SendMessageA(list
, LB_SETSEL
, FALSE
, 1);
598 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
599 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
600 ok(ret
== 1, "Unexpected anchor index %d.\n", ret
);
604 /* LBS_MULTIPLESEL */
605 list
= create_listbox(LBS_MULTIPLESEL
, 0);
606 ok(list
!= NULL
, "Failed to create ListBox window.\n");
608 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
609 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
611 ret
= SendMessageA(list
, LB_SETSEL
, TRUE
, 0);
612 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
613 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
614 ok(ret
== 0, "Unexpected anchor index %d.\n", ret
);
616 ret
= SendMessageA(list
, LB_SETSEL
, TRUE
, 1);
617 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
618 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
619 ok(ret
== 1, "Unexpected anchor index %d.\n", ret
);
621 ret
= SendMessageA(list
, LB_SETSEL
, FALSE
, 1);
622 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
623 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
624 ok(ret
== 1, "Unexpected anchor index %d.\n", ret
);
629 static void test_listbox_height(void)
634 hList
= CreateWindowA( "ListBox", "list test", 0,
635 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
636 ok( hList
!= NULL
, "failed to create listbox\n");
638 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi");
639 ok( id
== 0, "item id wrong\n");
641 r
= SendMessageA( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 20, 0 ));
642 ok( r
== 0, "send message failed\n");
644 r
= SendMessageA(hList
, LB_GETITEMHEIGHT
, 0, 0 );
645 ok( r
== 20, "height wrong\n");
647 r
= SendMessageA( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 0, 30 ));
648 ok( r
== -1, "send message failed\n");
650 r
= SendMessageA(hList
, LB_GETITEMHEIGHT
, 0, 0 );
651 ok( r
== 20, "height wrong\n");
653 r
= SendMessageA( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 0x100, 0 ));
654 ok( r
== -1, "send message failed\n");
656 r
= SendMessageA(hList
, LB_GETITEMHEIGHT
, 0, 0 );
657 ok( r
== 20, "height wrong\n");
659 r
= SendMessageA( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 0xff, 0 ));
660 ok( r
== 0, "send message failed\n");
662 r
= SendMessageA(hList
, LB_GETITEMHEIGHT
, 0, 0 );
663 ok( r
== 0xff, "height wrong\n");
665 DestroyWindow( hList
);
668 static void test_changing_selection_styles(void)
670 static const DWORD styles
[] =
673 LBS_NODATA
| LBS_OWNERDRAWFIXED
675 static const DWORD selstyles
[] =
680 LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
682 static const LONG selexpect_single
[] = { 0, 0, 1 };
683 static const LONG selexpect_single2
[] = { 1, 0, 0 };
684 static const LONG selexpect_multi
[] = { 1, 0, 1 };
685 static const LONG selexpect_multi2
[] = { 1, 1, 0 };
687 HWND parent
, listbox
;
692 parent
= create_parent();
693 ok(parent
!= NULL
, "Failed to create parent window.\n");
694 for (i
= 0; i
< ARRAY_SIZE(styles
); i
++)
696 /* Test if changing selection styles affects selection storage */
697 for (j
= 0; j
< ARRAY_SIZE(selstyles
); j
++)
699 LONG setcursel_expect
, selitemrange_expect
, getselcount_expect
;
700 const LONG
*selexpect
;
702 listbox
= CreateWindowA("listbox", "TestList", styles
[i
] | selstyles
[j
] | WS_CHILD
| WS_VISIBLE
,
703 0, 0, 100, 100, parent
, (HMENU
)1, NULL
, 0);
704 ok(listbox
!= NULL
, "%u: Failed to create ListBox window.\n", j
);
706 if (selstyles
[j
] & (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
))
708 setcursel_expect
= LB_ERR
;
709 selitemrange_expect
= LB_OKAY
;
710 getselcount_expect
= 2;
711 selexpect
= selexpect_multi
;
715 setcursel_expect
= 2;
716 selitemrange_expect
= LB_ERR
;
717 getselcount_expect
= LB_ERR
;
718 selexpect
= selexpect_single
;
721 for (k
= 0; k
< ARRAY_SIZE(selexpect_multi
); k
++)
723 ret
= SendMessageA(listbox
, LB_INSERTSTRING
, -1, (LPARAM
)"x");
724 ok(ret
== k
, "%u: Unexpected return value %d, expected %d.\n", j
, ret
, k
);
726 ret
= SendMessageA(listbox
, LB_GETCOUNT
, 0, 0);
727 ok(ret
== ARRAY_SIZE(selexpect_multi
), "%u: Unexpected count %d.\n", j
, ret
);
729 /* Select items with different methods */
730 ret
= SendMessageA(listbox
, LB_SETCURSEL
, 2, 0);
731 ok(ret
== setcursel_expect
, "%u: Unexpected return value %d.\n", j
, ret
);
732 ret
= SendMessageA(listbox
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(0, 0));
733 ok(ret
== selitemrange_expect
, "%u: Unexpected return value %d.\n", j
, ret
);
734 ret
= SendMessageA(listbox
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(2, 2));
735 ok(ret
== selitemrange_expect
, "%u: Unexpected return value %d.\n", j
, ret
);
737 /* Verify that the proper items are selected */
738 for (k
= 0; k
< ARRAY_SIZE(selexpect_multi
); k
++)
740 ret
= SendMessageA(listbox
, LB_GETSEL
, k
, 0);
741 ok(ret
== selexpect
[k
], "%u: Unexpected selection state %d, expected %d.\n",
742 j
, ret
, selexpect
[k
]);
745 /* Now change the selection style */
746 style
= GetWindowLongA(listbox
, GWL_STYLE
);
747 ok((style
& (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
)) == selstyles
[j
],
748 "%u: unexpected window styles %#x.\n", j
, style
);
749 if (selstyles
[j
] & (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
))
750 style
&= ~selstyles
[j
];
752 style
|= LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
;
753 SetWindowLongA(listbox
, GWL_STYLE
, style
);
754 style
= GetWindowLongA(listbox
, GWL_STYLE
);
755 ok(!(style
& selstyles
[j
]), "%u: unexpected window styles %#x.\n", j
, style
);
757 /* Verify that the same items are selected */
758 ret
= SendMessageA(listbox
, LB_GETSELCOUNT
, 0, 0);
759 ok(ret
== getselcount_expect
, "%u: expected %d from LB_GETSELCOUNT, got %d\n",
760 j
, getselcount_expect
, ret
);
762 for (k
= 0; k
< ARRAY_SIZE(selexpect_multi
); k
++)
764 ret
= SendMessageA(listbox
, LB_GETSEL
, k
, 0);
765 ok(ret
== selexpect
[k
], "%u: Unexpected selection state %d, expected %d.\n",
766 j
, ret
, selexpect
[k
]);
769 /* Lastly see if we can still change the selection as before with old style */
770 if (setcursel_expect
!= LB_ERR
) setcursel_expect
= 0;
771 ret
= SendMessageA(listbox
, LB_SETCURSEL
, 0, 0);
772 ok(ret
== setcursel_expect
, "%u: Unexpected return value %d.\n", j
, ret
);
773 ret
= SendMessageA(listbox
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(1, 1));
774 ok(ret
== selitemrange_expect
, "%u: Unexpected return value %d.\n", j
, ret
);
775 ret
= SendMessageA(listbox
, LB_SELITEMRANGE
, FALSE
, MAKELPARAM(2, 2));
776 ok(ret
== selitemrange_expect
, "%u: Unexpected return value %d.\n", j
, ret
);
778 /* And verify the selections */
779 selexpect
= (selstyles
[j
] & (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
)) ? selexpect_multi2
: selexpect_single2
;
780 ret
= SendMessageA(listbox
, LB_GETSELCOUNT
, 0, 0);
781 ok(ret
== getselcount_expect
, "%u: expected %d from LB_GETSELCOUNT, got %d\n",
782 j
, getselcount_expect
, ret
);
784 for (k
= 0; k
< ARRAY_SIZE(selexpect_multi
); k
++)
786 ret
= SendMessageA(listbox
, LB_GETSEL
, k
, 0);
787 ok(ret
== selexpect
[k
], "%u: Unexpected selection state %d, expected %d.\n",
788 j
, ret
, selexpect
[k
]);
791 DestroyWindow(listbox
);
794 DestroyWindow(parent
);
797 static void test_itemfrompoint(void)
799 /* WS_POPUP is required in order to have a more accurate size calculation (
800 without caption). LBS_NOINTEGRALHEIGHT is required in order to test
801 behavior of partially-displayed item.
803 HWND hList
= CreateWindowA( "ListBox", "list test",
804 WS_VISIBLE
|WS_POPUP
|LBS_NOINTEGRALHEIGHT
,
805 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
809 /* For an empty listbox win2k returns 0x1ffff, win98 returns 0x10000, nt4 returns 0xffffffff */
810 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
811 ok( r
== 0x1ffff || r
== 0x10000 || r
== 0xffffffff, "ret %x\n", r
);
813 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( 700, 30 ));
814 ok( r
== 0x1ffff || r
== 0x10000 || r
== 0xffffffff, "ret %x\n", r
);
816 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( 30, 300 ));
817 ok( r
== 0x1ffff || r
== 0x10000 || r
== 0xffffffff, "ret %x\n", r
);
819 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi");
820 ok( id
== 0, "item id wrong\n");
821 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi1");
822 ok( id
== 1, "item id wrong\n");
824 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
825 ok( r
== 0x1, "ret %x\n", r
);
827 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( /* x */ 30, /* y */ 601 ));
828 ok( r
== 0x10001 || broken(r
== 1), /* nt4 */
831 /* Resize control so that below assertions about sizes are valid */
832 r
= SendMessageA( hList
, LB_GETITEMRECT
, 0, (LPARAM
)&rc
);
833 ok( r
== 1, "ret %x\n", r
);
834 r
= MoveWindow(hList
, 1, 1, 600, (rc
.bottom
- rc
.top
+ 1) * 9 / 2, TRUE
);
835 ok( r
!= 0, "ret %x\n", r
);
837 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi2");
838 ok( id
== 2, "item id wrong\n");
839 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi3");
840 ok( id
== 3, "item id wrong\n");
841 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi4");
842 ok( id
== 4, "item id wrong\n");
843 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi5");
844 ok( id
== 5, "item id wrong\n");
845 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi6");
846 ok( id
== 6, "item id wrong\n");
847 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi7");
848 ok( id
== 7, "item id wrong\n");
850 /* Set the listbox up so that id 1 is at the top, this leaves 5
851 partially visible at the bottom and 6, 7 are invisible */
853 SendMessageA( hList
, LB_SETTOPINDEX
, 1, 0);
854 r
= SendMessageA( hList
, LB_GETTOPINDEX
, 0, 0);
855 ok( r
== 1, "top %d\n", r
);
857 r
= SendMessageA( hList
, LB_GETITEMRECT
, 5, (LPARAM
)&rc
);
858 ok( r
== 1, "ret %x\n", r
);
859 r
= SendMessageA( hList
, LB_GETITEMRECT
, 6, (LPARAM
)&rc
);
860 ok( r
== 0, "ret %x\n", r
);
862 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(/* x */ 10, /* y */ 10) );
863 ok( r
== 1, "ret %x\n", r
);
865 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(1000, 10) );
866 ok( r
== 0x10001 || broken(r
== 1), /* nt4 */
869 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(10, -10) );
870 ok( r
== 0x10001 || broken(r
== 1), /* nt4 */
873 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(10, 100) );
874 ok( r
== 0x10005 || broken(r
== 5), /* nt4 */
877 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(10, 200) );
878 ok( r
== 0x10005 || broken(r
== 5), /* nt4 */
881 DestroyWindow( hList
);
884 static void test_listbox_item_data(void)
889 hList
= CreateWindowA( "ListBox", "list test", 0,
890 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
891 ok( hList
!= NULL
, "failed to create listbox\n");
893 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi");
894 ok( id
== 0, "item id wrong\n");
896 r
= SendMessageA( hList
, LB_SETITEMDATA
, 0, MAKELPARAM( 20, 0 ));
897 ok(r
== TRUE
, "LB_SETITEMDATA returned %d instead of TRUE\n", r
);
899 r
= SendMessageA( hList
, LB_GETITEMDATA
, 0, 0);
900 ok( r
== 20, "get item data failed\n");
902 DestroyWindow( hList
);
905 static void test_listbox_LB_DIR(void)
907 char path
[MAX_PATH
], curdir
[MAX_PATH
];
910 int itemCount_justFiles
;
911 int itemCount_justDrives
;
912 int itemCount_allFiles
;
913 int itemCount_allDirs
;
915 char pathBuffer
[MAX_PATH
];
918 const char *wildcard
= "*";
922 GetCurrentDirectoryA(ARRAY_SIZE(curdir
), curdir
);
924 GetTempPathA(ARRAY_SIZE(path
), path
);
925 ret
= SetCurrentDirectoryA(path
);
926 ok(ret
, "Failed to set current directory.\n");
928 ret
= CreateDirectoryA("lb_dir_test", NULL
);
929 ok(ret
, "Failed to create test directory.\n");
931 file
= CreateFileA( "wtest1.tmp.c", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, FILE_ATTRIBUTE_NORMAL
, NULL
);
932 ok(file
!= INVALID_HANDLE_VALUE
, "Error creating the test file: %d\n", GetLastError());
935 /* NOTE: for this test to succeed, there must be no subdirectories
936 under the current directory. In addition, there must be at least
937 one file that fits the wildcard w*.c . Normally, the test
938 directory itself satisfies both conditions.
940 hList
= CreateWindowA( "ListBox", "list test", WS_VISIBLE
|WS_POPUP
,
941 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
944 /* Test for standard usage */
946 /* This should list all the files in the test directory. */
947 strcpy(pathBuffer
, wildcard
);
948 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
949 res
= SendMessageA(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
950 if (res
== -1) /* "*" wildcard doesn't work on win9x */
953 strcpy(pathBuffer
, wildcard
);
954 res
= SendMessageA(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
956 ok (res
>= 0, "SendMessage(LB_DIR, 0, *) failed - 0x%08x\n", GetLastError());
958 /* There should be some content in the listbox */
959 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
960 ok (itemCount
> 0, "SendMessage(LB_DIR) did NOT fill the listbox!\n");
961 itemCount_allFiles
= itemCount
;
962 ok(res
+ 1 == itemCount
,
963 "SendMessage(LB_DIR, 0, *) returned incorrect index (expected %d got %d)!\n",
966 /* This tests behavior when no files match the wildcard */
967 strcpy(pathBuffer
, BAD_EXTENSION
);
968 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
969 res
= SendMessageA(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
970 ok (res
== -1, "SendMessage(LB_DIR, 0, %s) returned %d, expected -1\n", BAD_EXTENSION
, res
);
972 /* There should be NO content in the listbox */
973 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
974 ok (itemCount
== 0, "SendMessage(LB_DIR) DID fill the listbox!\n");
977 /* This should list all the w*.c files in the test directory
978 * As of this writing, this includes win.c, winstation.c, wsprintf.c
980 strcpy(pathBuffer
, "w*.c");
981 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
982 res
= SendMessageA(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
983 ok (res
>= 0, "SendMessage(LB_DIR, 0, w*.c) failed - 0x%08x\n", GetLastError());
985 /* Path specification does NOT converted to uppercase */
986 ok (!strcmp(pathBuffer
, "w*.c"),
987 "expected no change to pathBuffer, got %s\n", pathBuffer
);
989 /* There should be some content in the listbox */
990 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
991 ok (itemCount
> 0, "SendMessage(LB_DIR) did NOT fill the listbox!\n");
992 itemCount_justFiles
= itemCount
;
993 ok(res
+ 1 == itemCount
,
994 "SendMessage(LB_DIR, 0, w*.c) returned incorrect index (expected %d got %d)!\n",
997 /* Every single item in the control should start with a w and end in .c */
998 for (i
= 0; i
< itemCount
; i
++) {
999 memset(pathBuffer
, 0, MAX_PATH
);
1000 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1001 p
= pathBuffer
+ strlen(pathBuffer
);
1002 ok(((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1003 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1004 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1007 /* Test DDL_DIRECTORY */
1008 strcpy(pathBuffer
, wildcard
);
1009 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1010 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
, (LPARAM
)pathBuffer
);
1011 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY, *) failed - 0x%08x\n", GetLastError());
1013 /* There should be some content in the listbox.
1014 * All files plus "[..]"
1016 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1017 itemCount_allDirs
= itemCount
- itemCount_allFiles
;
1018 ok (itemCount
> itemCount_allFiles
,
1019 "SendMessage(LB_DIR, DDL_DIRECTORY, *) filled with %d entries, expected > %d\n",
1020 itemCount
, itemCount_allFiles
);
1021 ok(res
+ 1 == itemCount
,
1022 "SendMessage(LB_DIR, DDL_DIRECTORY, *) returned incorrect index (expected %d got %d)!\n",
1023 itemCount
- 1, res
);
1025 /* This tests behavior when no files match the wildcard */
1026 strcpy(pathBuffer
, BAD_EXTENSION
);
1027 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1028 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
, (LPARAM
)pathBuffer
);
1029 ok (res
== -1, "SendMessage(LB_DIR, DDL_DIRECTORY, %s) returned %d, expected -1\n", BAD_EXTENSION
, res
);
1031 /* There should be NO content in the listbox */
1032 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1033 ok (itemCount
== 0, "SendMessage(LB_DIR) DID fill the listbox!\n");
1036 /* Test DDL_DIRECTORY */
1037 strcpy(pathBuffer
, "w*.c");
1038 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1039 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
, (LPARAM
)pathBuffer
);
1040 ok (res
>= 0, "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) failed - 0x%08x\n", GetLastError());
1042 /* There should be some content in the listbox. Since the parent directory does not
1043 * fit w*.c, there should be exactly the same number of items as without DDL_DIRECTORY
1045 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1046 ok (itemCount
== itemCount_justFiles
,
1047 "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) filled with %d entries, expected %d\n",
1048 itemCount
, itemCount_justFiles
);
1049 ok(res
+ 1 == itemCount
,
1050 "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) returned incorrect index (expected %d got %d)!\n",
1051 itemCount
- 1, res
);
1053 /* Every single item in the control should start with a w and end in .c. */
1054 for (i
= 0; i
< itemCount
; i
++) {
1055 memset(pathBuffer
, 0, MAX_PATH
);
1056 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1057 p
= pathBuffer
+ strlen(pathBuffer
);
1059 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1060 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1061 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1065 /* Test DDL_DRIVES|DDL_EXCLUSIVE */
1066 strcpy(pathBuffer
, wildcard
);
1067 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1068 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1069 ok (res
>= 0, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) failed - 0x%08x\n", GetLastError());
1071 /* There should be some content in the listbox. In particular, there should
1072 * be at least one element before, since the string "[-c-]" should
1073 * have been added. Depending on the user setting, more drives might have
1076 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1078 "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) filled with %d entries, expected at least %d\n",
1080 itemCount_justDrives
= itemCount
;
1081 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) returned incorrect index!\n");
1083 /* Every single item in the control should fit the format [-c-] */
1084 for (i
= 0; i
< itemCount
; i
++) {
1085 memset(pathBuffer
, 0, MAX_PATH
);
1087 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1088 ok( strlen(pathBuffer
) == 5, "Length of drive string is not 5\n" );
1089 ok( sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1, "Element %d (%s) does not fit [-X-]\n", i
, pathBuffer
);
1090 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1091 if (!(driveletter
>= 'a' && driveletter
<= 'z')) {
1092 /* Correct after invalid entry is found */
1093 trace("removing count of invalid entry %s\n", pathBuffer
);
1094 itemCount_justDrives
--;
1098 /* This tests behavior when no files match the wildcard */
1099 strcpy(pathBuffer
, BAD_EXTENSION
);
1100 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1101 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1102 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1103 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
1105 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1106 ok (itemCount
== itemCount_justDrives
, "SendMessage(LB_DIR) returned %d expected %d\n",
1107 itemCount
, itemCount_justDrives
);
1109 trace("Files with w*.c: %d Mapped drives: %d Directories: 1\n",
1110 itemCount_justFiles
, itemCount_justDrives
);
1112 /* Test DDL_DRIVES. */
1113 strcpy(pathBuffer
, wildcard
);
1114 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1115 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
, (LPARAM
)pathBuffer
);
1116 ok (res
> 0, "SendMessage(LB_DIR, DDL_DRIVES, *) failed - 0x%08x\n", GetLastError());
1118 /* There should be some content in the listbox. In particular, there should
1119 * be at least one element before, since the string "[-c-]" should
1120 * have been added. Depending on the user setting, more drives might have
1123 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1124 ok (itemCount
== itemCount_justDrives
+ itemCount_allFiles
,
1125 "SendMessage(LB_DIR, DDL_DRIVES, *) filled with %d entries, expected %d\n",
1126 itemCount
, itemCount_justDrives
+ itemCount_allFiles
);
1127 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DRIVES, *) returned incorrect index!\n");
1129 /* This tests behavior when no files match the wildcard */
1130 strcpy(pathBuffer
, BAD_EXTENSION
);
1131 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1132 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
, (LPARAM
)pathBuffer
);
1133 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DRIVES, %s) returned %d, expected %d\n",
1134 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
1136 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1137 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
1140 /* Test DDL_DRIVES. */
1141 strcpy(pathBuffer
, "w*.c");
1142 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1143 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
, (LPARAM
)pathBuffer
);
1144 ok (res
> 0, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) failed - 0x%08x\n", GetLastError());
1146 /* There should be some content in the listbox. In particular, there should
1147 * be at least one element before, since the string "[-c-]" should
1148 * have been added. Depending on the user setting, more drives might have
1151 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1152 ok (itemCount
== itemCount_justDrives
+ itemCount_justFiles
,
1153 "SendMessage(LB_DIR, DDL_DRIVES, w*.c) filled with %d entries, expected %d\n",
1154 itemCount
, itemCount_justDrives
+ itemCount_justFiles
);
1155 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) returned incorrect index!\n");
1157 /* Every single item in the control should fit the format [-c-], or w*.c */
1158 for (i
= 0; i
< itemCount
; i
++) {
1159 memset(pathBuffer
, 0, MAX_PATH
);
1161 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1162 p
= pathBuffer
+ strlen(pathBuffer
);
1163 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1) {
1164 ok( strlen(pathBuffer
) == 5, "Length of drive string is not 5\n" );
1165 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1168 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1169 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1170 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1175 /* Test DDL_DIRECTORY|DDL_DRIVES. This does *not* imply DDL_EXCLUSIVE */
1176 strcpy(pathBuffer
, wildcard
);
1177 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1178 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
, (LPARAM
)pathBuffer
);
1179 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, *) failed - 0x%08x\n", GetLastError());
1181 /* There should be some content in the listbox. In particular, there should
1182 * be exactly the number of plain files, plus the number of mapped drives.
1184 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1185 ok (itemCount
== itemCount_allFiles
+ itemCount_justDrives
+ itemCount_allDirs
,
1186 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1187 itemCount
, itemCount_allFiles
+ itemCount_justDrives
+ itemCount_allDirs
);
1188 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
1190 /* Every single item in the control should start with a w and end in .c,
1191 * except for the "[..]" string, which should appear exactly as it is,
1192 * and the mapped drives in the format "[-X-]".
1194 for (i
= 0; i
< itemCount
; i
++) {
1195 memset(pathBuffer
, 0, MAX_PATH
);
1197 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1198 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1) {
1199 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1203 /* This tests behavior when no files match the wildcard */
1204 strcpy(pathBuffer
, BAD_EXTENSION
);
1205 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1206 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
, (LPARAM
)pathBuffer
);
1207 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, %s) returned %d, expected %d\n",
1208 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
1210 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1211 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
1215 /* Test DDL_DIRECTORY|DDL_DRIVES. */
1216 strcpy(pathBuffer
, "w*.c");
1217 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1218 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
, (LPARAM
)pathBuffer
);
1219 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) failed - 0x%08x\n", GetLastError());
1221 /* There should be some content in the listbox. In particular, there should
1222 * be exactly the number of plain files, plus the number of mapped drives.
1224 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1225 ok (itemCount
== itemCount_justFiles
+ itemCount_justDrives
,
1226 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1227 itemCount
, itemCount_justFiles
+ itemCount_justDrives
);
1228 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
1230 /* Every single item in the control should start with a w and end in .c,
1231 * except the mapped drives in the format "[-X-]". The "[..]" directory
1232 * should not appear.
1234 for (i
= 0; i
< itemCount
; i
++) {
1235 memset(pathBuffer
, 0, MAX_PATH
);
1237 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1238 p
= pathBuffer
+ strlen(pathBuffer
);
1239 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1) {
1240 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1243 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1244 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1245 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1249 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1250 strcpy(pathBuffer
, wildcard
);
1251 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1252 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1253 ok (res
!= -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) failed err %u\n", GetLastError());
1255 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1256 ok (itemCount
== itemCount_allDirs
,
1257 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1258 itemCount
, itemCount_allDirs
);
1259 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) returned incorrect index!\n");
1263 memset(pathBuffer
, 0, MAX_PATH
);
1264 SendMessageA(hList
, LB_GETTEXT
, 0, (LPARAM
)pathBuffer
);
1265 ok( !strcmp(pathBuffer
, "[..]"), "First element is %s, not [..]\n", pathBuffer
);
1268 /* This tests behavior when no files match the wildcard */
1269 strcpy(pathBuffer
, BAD_EXTENSION
);
1270 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1271 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1272 ok (res
== -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1273 BAD_EXTENSION
, res
, -1);
1275 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1276 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
1279 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1280 strcpy(pathBuffer
, "w*.c");
1281 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1282 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1283 ok (res
== LB_ERR
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, w*.c) returned %d expected %d\n", res
, LB_ERR
);
1285 /* There should be no elements, since "[..]" does not fit w*.c */
1286 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1288 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1291 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1292 strcpy(pathBuffer
, wildcard
);
1293 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1294 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1295 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
1297 /* There should be no plain files on the listbox */
1298 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1299 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
1300 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1301 itemCount
, itemCount_justDrives
+ itemCount_allDirs
);
1302 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
1304 for (i
= 0; i
< itemCount
; i
++) {
1305 memset(pathBuffer
, 0, MAX_PATH
);
1307 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1308 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1) {
1309 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1311 ok( pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']',
1312 "Element %d (%s) does not fit expected [...]\n", i
, pathBuffer
);
1316 /* This tests behavior when no files match the wildcard */
1317 strcpy(pathBuffer
, BAD_EXTENSION
);
1318 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1319 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1320 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1321 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
1323 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1324 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
1326 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1327 strcpy(pathBuffer
, "w*.c");
1328 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1329 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1330 ok (res
>= 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
1332 /* There should be no plain files on the listbox, and no [..], since it does not fit w*.c */
1333 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1334 ok (itemCount
== itemCount_justDrives
,
1335 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1336 itemCount
, itemCount_justDrives
);
1337 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
1339 for (i
= 0; i
< itemCount
; i
++) {
1340 memset(pathBuffer
, 0, MAX_PATH
);
1342 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1343 ok (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1, "Element %d (%s) does not fit [-X-]\n", i
, pathBuffer
);
1344 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1346 DestroyWindow(hList
);
1348 DeleteFileA( "wtest1.tmp.c" );
1349 RemoveDirectoryA("lb_dir_test");
1351 SetCurrentDirectoryA(curdir
);
1354 static HWND g_listBox
;
1355 static HWND g_label
;
1357 #define ID_TEST_LABEL 1001
1358 #define ID_TEST_LISTBOX 1002
1360 static BOOL
on_listbox_container_create (HWND hwnd
, LPCREATESTRUCTA lpcs
)
1362 g_label
= CreateWindowA(
1364 "Contents of static control before DlgDirList.",
1365 WS_CHILD
| WS_VISIBLE
,
1367 hwnd
, (HMENU
)ID_TEST_LABEL
, NULL
, 0);
1368 if (!g_label
) return FALSE
;
1369 g_listBox
= CreateWindowA(
1372 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| WS_BORDER
| WS_VSCROLL
,
1374 hwnd
, (HMENU
)ID_TEST_LISTBOX
, NULL
, 0);
1375 if (!g_listBox
) return FALSE
;
1380 static LRESULT CALLBACK
listbox_container_window_procA (
1381 HWND hwnd
, UINT uiMsg
, WPARAM wParam
, LPARAM lParam
)
1390 result
= on_listbox_container_create(hwnd
, (LPCREATESTRUCTA
) lParam
)
1394 result
= DefWindowProcA (hwnd
, uiMsg
, wParam
, lParam
);
1400 static BOOL
RegisterListboxWindowClass(HINSTANCE hInst
)
1407 cls
.hInstance
= hInst
;
1409 cls
.hCursor
= LoadCursorA (NULL
, (LPCSTR
)IDC_ARROW
);
1410 cls
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
1411 cls
.lpszMenuName
= NULL
;
1412 cls
.lpfnWndProc
= listbox_container_window_procA
;
1413 cls
.lpszClassName
= "ListboxContainerClass";
1414 if (!RegisterClassA (&cls
)) return FALSE
;
1419 static void test_listbox_dlgdir(void)
1424 int itemCount_allDirs
;
1425 int itemCount_justFiles
;
1426 int itemCount_justDrives
;
1428 char pathBuffer
[MAX_PATH
];
1429 char itemBuffer
[MAX_PATH
];
1430 char tempBuffer
[MAX_PATH
];
1435 file
= CreateFileA( "wtest1.tmp.c", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1436 ok(file
!= INVALID_HANDLE_VALUE
, "Error creating the test file: %d\n", GetLastError());
1437 CloseHandle( file
);
1439 /* NOTE: for this test to succeed, there must be no subdirectories
1440 under the current directory. In addition, there must be at least
1441 one file that fits the wildcard w*.c . Normally, the test
1442 directory itself satisfies both conditions.
1445 hInst
= GetModuleHandleA(0);
1446 if (!RegisterListboxWindowClass(hInst
)) assert(0);
1447 hWnd
= CreateWindowA("ListboxContainerClass", "ListboxContainerClass",
1448 WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
1449 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
1450 NULL
, NULL
, hInst
, 0);
1453 /* Test for standard usage */
1455 /* The following should be overwritten by the directory path */
1456 SendMessageA(g_label
, WM_SETTEXT
, 0, (LPARAM
)"default contents");
1458 /* This should list all the w*.c files in the test directory
1459 * As of this writing, this includes win.c, winstation.c, wsprintf.c
1461 strcpy(pathBuffer
, "w*.c");
1462 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, 0);
1463 ok (res
== 1, "DlgDirList(*.c, 0) returned %d - expected 1 - 0x%08x\n", res
, GetLastError());
1465 /* Path specification gets converted to uppercase */
1466 ok (!strcmp(pathBuffer
, "W*.C"),
1467 "expected conversion to uppercase, got %s\n", pathBuffer
);
1469 /* Loaded path should have overwritten the label text */
1470 SendMessageA(g_label
, WM_GETTEXT
, MAX_PATH
, (LPARAM
)pathBuffer
);
1471 trace("Static control after DlgDirList: %s\n", pathBuffer
);
1472 ok (strcmp("default contents", pathBuffer
), "DlgDirList() did not modify static control!\n");
1474 /* There should be some content in the listbox */
1475 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1476 ok (itemCount
> 0, "DlgDirList() did NOT fill the listbox!\n");
1477 itemCount_justFiles
= itemCount
;
1479 /* Every single item in the control should start with a w and end in .c */
1480 for (i
= 0; i
< itemCount
; i
++) {
1481 memset(pathBuffer
, 0, MAX_PATH
);
1482 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1483 p
= pathBuffer
+ strlen(pathBuffer
);
1484 ok(((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1485 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1486 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1489 /* Test behavior when no files match the wildcard */
1490 strcpy(pathBuffer
, BAD_EXTENSION
);
1491 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, 0);
1492 ok (res
== 1, "DlgDirList(%s, 0) returned %d expected 1\n", BAD_EXTENSION
, res
);
1494 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1495 ok (itemCount
== 0, "DlgDirList() DID fill the listbox!\n");
1497 /* Test DDL_DIRECTORY */
1498 strcpy(pathBuffer
, "w*.c");
1499 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1501 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY) failed - 0x%08x\n", GetLastError());
1503 /* There should be some content in the listbox. In particular, there should
1504 * be exactly more elements than before, since the directories should
1507 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1508 itemCount_allDirs
= itemCount
- itemCount_justFiles
;
1509 ok (itemCount
>= itemCount_justFiles
,
1510 "DlgDirList(DDL_DIRECTORY) filled with %d entries, expected > %d\n",
1511 itemCount
, itemCount_justFiles
);
1513 /* Every single item in the control should start with a w and end in .c,
1514 * except for the "[..]" string, which should appear exactly as it is.
1516 for (i
= 0; i
< itemCount
; i
++) {
1517 memset(pathBuffer
, 0, MAX_PATH
);
1518 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1519 p
= pathBuffer
+ strlen(pathBuffer
);
1520 ok( (pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']') ||
1521 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1522 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1523 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1526 /* Test behavior when no files match the wildcard */
1527 strcpy(pathBuffer
, BAD_EXTENSION
);
1528 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1530 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY) returned %d expected 1\n", BAD_EXTENSION
, res
);
1532 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1533 ok (itemCount
== itemCount_allDirs
,
1534 "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
1535 itemCount_allDirs
, itemCount
);
1536 for (i
= 0; i
< itemCount
; i
++) {
1537 memset(pathBuffer
, 0, MAX_PATH
);
1538 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1539 ok( pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']',
1540 "Element %d (%s) does not fit requested [...]\n", i
, pathBuffer
);
1544 /* Test DDL_DRIVES. At least on WinXP-SP2, this implies DDL_EXCLUSIVE */
1545 strcpy(pathBuffer
, "w*.c");
1546 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1548 ok (res
== 1, "DlgDirList(*.c, DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1550 /* There should be some content in the listbox. In particular, there should
1551 * be at least one element before, since the string "[-c-]" should
1552 * have been added. Depending on the user setting, more drives might have
1555 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1557 "DlgDirList(DDL_DRIVES) filled with %d entries, expected at least %d\n",
1559 itemCount_justDrives
= itemCount
;
1561 /* Every single item in the control should fit the format [-c-] */
1562 for (i
= 0; i
< itemCount
; i
++) {
1563 memset(pathBuffer
, 0, MAX_PATH
);
1565 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1566 ok( strlen(pathBuffer
) == 5, "Length of drive string is not 5\n" );
1567 ok( sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1, "Element %d (%s) does not fit [-X-]\n", i
, pathBuffer
);
1568 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1569 if (!(driveletter
>= 'a' && driveletter
<= 'z')) {
1570 /* Correct after invalid entry is found */
1571 trace("removing count of invalid entry %s\n", pathBuffer
);
1572 itemCount_justDrives
--;
1576 /* Test behavior when no files match the wildcard */
1577 strcpy(pathBuffer
, BAD_EXTENSION
);
1578 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1580 ok (res
== 1, "DlgDirList(%s, DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION
, res
);
1582 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1583 ok (itemCount
== itemCount_justDrives
, "DlgDirList() incorrectly filled the listbox!\n");
1586 /* Test DDL_DIRECTORY|DDL_DRIVES. This does *not* imply DDL_EXCLUSIVE */
1587 strcpy(pathBuffer
, "w*.c");
1588 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1589 DDL_DIRECTORY
|DDL_DRIVES
);
1590 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1592 /* There should be some content in the listbox. In particular, there should
1593 * be exactly the number of plain files, plus the number of mapped drives,
1596 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1597 ok (itemCount
== itemCount_justFiles
+ itemCount_justDrives
+ itemCount_allDirs
,
1598 "DlgDirList(DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1599 itemCount
, itemCount_justFiles
+ itemCount_justDrives
+ itemCount_allDirs
);
1601 /* Every single item in the control should start with a w and end in .c,
1602 * except for the "[..]" string, which should appear exactly as it is,
1603 * and the mapped drives in the format "[-X-]".
1605 for (i
= 0; i
< itemCount
; i
++) {
1606 memset(pathBuffer
, 0, MAX_PATH
);
1608 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1609 p
= pathBuffer
+ strlen(pathBuffer
);
1610 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1) {
1611 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1613 ok( (pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']') ||
1614 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1615 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1616 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1620 /* Test behavior when no files match the wildcard */
1621 strcpy(pathBuffer
, BAD_EXTENSION
);
1622 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1623 DDL_DIRECTORY
|DDL_DRIVES
);
1624 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION
, res
);
1626 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1627 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
1628 "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
1629 itemCount_justDrives
+ itemCount_allDirs
, itemCount
);
1633 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1634 strcpy(pathBuffer
, "w*.c");
1635 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1636 DDL_DIRECTORY
|DDL_EXCLUSIVE
);
1637 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_EXCLUSIVE) failed - 0x%08x\n", GetLastError());
1639 /* There should be exactly one element: "[..]" */
1640 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1641 ok (itemCount
== itemCount_allDirs
,
1642 "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1643 itemCount
, itemCount_allDirs
);
1645 if (itemCount
&& GetCurrentDirectoryA( MAX_PATH
, pathBuffer
) > 3) /* there's no [..] in drive root */
1647 memset(pathBuffer
, 0, MAX_PATH
);
1648 SendMessageA(g_listBox
, LB_GETTEXT
, 0, (LPARAM
)pathBuffer
);
1649 ok( !strcmp(pathBuffer
, "[..]"), "First (and only) element is not [..]\n");
1652 /* Test behavior when no files match the wildcard */
1653 strcpy(pathBuffer
, BAD_EXTENSION
);
1654 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1655 DDL_DIRECTORY
|DDL_EXCLUSIVE
);
1656 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION
, res
);
1658 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1659 ok (itemCount
== itemCount_allDirs
, "DlgDirList() incorrectly filled the listbox!\n");
1662 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1663 strcpy(pathBuffer
, "w*.c");
1664 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1665 DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
);
1666 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) failed - 0x%08x\n", GetLastError());
1668 /* There should be no plain files on the listbox */
1669 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1670 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
1671 "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1672 itemCount
, itemCount_justDrives
+ itemCount_allDirs
);
1674 for (i
= 0; i
< itemCount
; i
++) {
1675 memset(pathBuffer
, 0, MAX_PATH
);
1677 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1678 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1) {
1679 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1681 ok( pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']',
1682 "Element %d (%s) does not fit expected [...]\n", i
, pathBuffer
);
1686 /* Test behavior when no files match the wildcard */
1687 strcpy(pathBuffer
, BAD_EXTENSION
);
1688 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1689 DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
);
1690 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION
, res
);
1692 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1693 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
1694 "DlgDirList() incorrectly filled the listbox!\n");
1696 /* Now test DlgDirSelectEx() in normal operation */
1697 /* Fill with everything - drives, directory and all plain files. */
1698 strcpy(pathBuffer
, "*");
1699 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1700 DDL_DIRECTORY
|DDL_DRIVES
);
1701 ok (res
!= 0, "DlgDirList(*, DDL_DIRECTORY|DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1703 SendMessageA(g_listBox
, LB_SETCURSEL
, -1, 0); /* Unselect any current selection */
1704 memset(pathBuffer
, 0, MAX_PATH
);
1705 SetLastError(0xdeadbeef);
1706 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1707 ok (GetLastError() == 0xdeadbeef,
1708 "DlgDirSelectEx() with no selection modified last error code from 0xdeadbeef to 0x%08x\n",
1710 ok (res
== 0, "DlgDirSelectEx() with no selection returned %d, expected 0\n", res
);
1711 /* WinXP-SP2 leaves pathBuffer untouched, but Win98 fills it with garbage. */
1713 ok (strlen(pathBuffer) == 0, "DlgDirSelectEx() with no selection filled buffer with %s\n", pathBuffer);
1715 /* Test proper drive/dir/file recognition */
1716 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1717 for (i
= 0; i
< itemCount
; i
++) {
1718 memset(itemBuffer
, 0, MAX_PATH
);
1719 memset(pathBuffer
, 0, MAX_PATH
);
1720 memset(tempBuffer
, 0, MAX_PATH
);
1722 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)itemBuffer
);
1723 res
= SendMessageA(g_listBox
, LB_SETCURSEL
, i
, 0);
1724 ok (res
== i
, "SendMessageA(LB_SETCURSEL, %d) failed\n", i
);
1725 if (sscanf(itemBuffer
, "[-%c-]", &driveletter
) == 1) {
1726 /* Current item is a drive letter */
1727 SetLastError(0xdeadbeef);
1728 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1729 ok (GetLastError() == 0xdeadbeef,
1730 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1732 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1734 /* For drive letters, DlgDirSelectEx tacks on a colon */
1735 ok (pathBuffer
[0] == driveletter
&& pathBuffer
[1] == ':' && pathBuffer
[2] == '\0',
1736 "%d: got \"%s\" expected \"%c:\"\n", i
, pathBuffer
, driveletter
);
1737 } else if (itemBuffer
[0] == '[') {
1738 /* Current item is the parent directory */
1739 SetLastError(0xdeadbeef);
1740 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1741 ok (GetLastError() == 0xdeadbeef,
1742 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1744 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1746 /* For directories, DlgDirSelectEx tacks on a backslash */
1747 p
= pathBuffer
+ strlen(pathBuffer
);
1748 ok (*(p
-1) == '\\', "DlgDirSelectEx did NOT tack on a backslash to dir, got %s\n", pathBuffer
);
1750 tempBuffer
[0] = '[';
1751 lstrcpynA(tempBuffer
+ 1, pathBuffer
, strlen(pathBuffer
));
1752 strcat(tempBuffer
, "]");
1753 ok (!strcmp(tempBuffer
, itemBuffer
), "Formatted directory should be %s, got %s\n", tempBuffer
, itemBuffer
);
1755 /* Current item is a plain file */
1756 SetLastError(0xdeadbeef);
1757 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1758 ok (GetLastError() == 0xdeadbeef,
1759 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1761 ok(res
== 0, "DlgDirSelectEx() thinks %s (%s) is a drive/directory!\n", itemBuffer
, pathBuffer
);
1763 /* NOTE: WinXP tacks a period on all files that lack an extension. This affects
1764 * for example, "Makefile", which gets reported as "Makefile."
1766 strcpy(tempBuffer
, itemBuffer
);
1767 if (strchr(tempBuffer
, '.') == NULL
) strcat(tempBuffer
, ".");
1768 ok (!strcmp(pathBuffer
, tempBuffer
), "Formatted file should be %s, got %s\n", tempBuffer
, pathBuffer
);
1772 DeleteFileA( "wtest1.tmp.c" );
1774 /* Now test DlgDirSelectEx() in abnormal operation */
1775 /* Fill list with bogus entries, that look somewhat valid */
1776 SendMessageA(g_listBox
, LB_RESETCONTENT
, 0, 0);
1777 SendMessageA(g_listBox
, LB_ADDSTRING
, 0, (LPARAM
)"[notexist.dir]");
1778 SendMessageA(g_listBox
, LB_ADDSTRING
, 0, (LPARAM
)"notexist.fil");
1779 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1780 for (i
= 0; i
< itemCount
; i
++) {
1781 memset(itemBuffer
, 0, MAX_PATH
);
1782 memset(pathBuffer
, 0, MAX_PATH
);
1783 memset(tempBuffer
, 0, MAX_PATH
);
1785 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)itemBuffer
);
1786 res
= SendMessageA(g_listBox
, LB_SETCURSEL
, i
, 0);
1787 ok (res
== i
, "SendMessage(LB_SETCURSEL, %d) failed\n", i
);
1788 if (sscanf(itemBuffer
, "[-%c-]", &driveletter
) == 1) {
1789 /* Current item is a drive letter */
1790 SetLastError(0xdeadbeef);
1791 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1792 ok (GetLastError() == 0xdeadbeef,
1793 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1795 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1797 /* For drive letters, DlgDirSelectEx tacks on a colon */
1798 ok (pathBuffer
[0] == driveletter
&& pathBuffer
[1] == ':' && pathBuffer
[2] == '\0',
1799 "%d: got \"%s\" expected \"%c:\"\n", i
, pathBuffer
, driveletter
);
1800 } else if (itemBuffer
[0] == '[') {
1801 /* Current item is the parent directory */
1802 SetLastError(0xdeadbeef);
1803 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1804 ok (GetLastError() == 0xdeadbeef,
1805 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1807 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1809 /* For directories, DlgDirSelectEx tacks on a backslash */
1810 p
= pathBuffer
+ strlen(pathBuffer
);
1811 ok (*(p
-1) == '\\', "DlgDirSelectEx did NOT tack on a backslash to dir, got %s\n", pathBuffer
);
1813 tempBuffer
[0] = '[';
1814 lstrcpynA(tempBuffer
+ 1, pathBuffer
, strlen(pathBuffer
));
1815 strcat(tempBuffer
, "]");
1816 ok (!strcmp(tempBuffer
, itemBuffer
), "Formatted directory should be %s, got %s\n", tempBuffer
, itemBuffer
);
1818 /* Current item is a plain file */
1819 SetLastError(0xdeadbeef);
1820 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1821 ok (GetLastError() == 0xdeadbeef,
1822 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1824 ok(res
== 0, "DlgDirSelectEx() thinks %s (%s) is a drive/directory!\n", itemBuffer
, pathBuffer
);
1826 /* NOTE: WinXP and Win98 tack a period on all files that lack an extension.
1827 * This affects for example, "Makefile", which gets reported as "Makefile."
1829 strcpy(tempBuffer
, itemBuffer
);
1830 if (strchr(tempBuffer
, '.') == NULL
) strcat(tempBuffer
, ".");
1831 ok (!strcmp(pathBuffer
, tempBuffer
), "Formatted file should be %s, got %s\n", tempBuffer
, pathBuffer
);
1835 /* Test behavior when loading folders from root with and without wildcard */
1836 strcpy(pathBuffer
, "C:\\");
1837 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, 0, DDL_DIRECTORY
| DDL_EXCLUSIVE
);
1838 ok(res
|| broken(!res
) /* NT4/W2K */, "DlgDirList failed to list C:\\ folders\n");
1839 ok(!strcmp(pathBuffer
, "*") || broken(!res
) /* NT4/W2K */,
1840 "DlgDirList set the invalid path spec '%s', expected '*'\n", pathBuffer
);
1842 strcpy(pathBuffer
, "C:\\*");
1843 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, 0, DDL_DIRECTORY
| DDL_EXCLUSIVE
);
1844 ok(res
|| broken(!res
) /* NT4/W2K */, "DlgDirList failed to list C:\\* folders\n");
1845 ok(!strcmp(pathBuffer
, "*") || broken(!res
) /* NT4/W2K */,
1846 "DlgDirList set the invalid path spec '%s', expected '*'\n", pathBuffer
);
1848 /* Try loading files from an invalid folder */
1849 SetLastError(0xdeadbeef);
1850 strcpy(pathBuffer
, "C:\\INVALID$$DIR");
1851 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, 0, DDL_DIRECTORY
| DDL_EXCLUSIVE
);
1852 ok(!res
, "DlgDirList should have failed with 0 but %d was returned\n", res
);
1853 ok(GetLastError() == ERROR_NO_WILDCARD_CHARACTERS
,
1854 "GetLastError should return 0x589, got 0x%X\n",GetLastError());
1856 DestroyWindow(hWnd
);
1859 static void test_set_count( void )
1861 static const DWORD styles
[] =
1866 HWND parent
, listbox
;
1871 parent
= create_parent();
1872 listbox
= create_listbox( LBS_OWNERDRAWFIXED
| LBS_NODATA
| WS_CHILD
| WS_VISIBLE
, parent
);
1874 UpdateWindow( listbox
);
1875 GetUpdateRect( listbox
, &r
, TRUE
);
1876 ok( IsRectEmpty( &r
), "got non-empty rect\n");
1878 ret
= SendMessageA( listbox
, LB_SETCOUNT
, 100, 0 );
1879 ok( ret
== 0, "got %d\n", ret
);
1880 ret
= SendMessageA( listbox
, LB_GETCOUNT
, 0, 0 );
1881 ok( ret
== 100, "got %d\n", ret
);
1883 GetUpdateRect( listbox
, &r
, TRUE
);
1884 ok( !IsRectEmpty( &r
), "got empty rect\n");
1886 ValidateRect( listbox
, NULL
);
1887 GetUpdateRect( listbox
, &r
, TRUE
);
1888 ok( IsRectEmpty( &r
), "got non-empty rect\n");
1890 ret
= SendMessageA( listbox
, LB_SETCOUNT
, 99, 0 );
1891 ok( ret
== 0, "got %d\n", ret
);
1893 GetUpdateRect( listbox
, &r
, TRUE
);
1894 ok( !IsRectEmpty( &r
), "got empty rect\n");
1896 ret
= SendMessageA( listbox
, LB_SETCOUNT
, -5, 0 );
1897 ok( ret
== 0, "got %d\n", ret
);
1898 ret
= SendMessageA( listbox
, LB_GETCOUNT
, 0, 0 );
1899 ok( ret
== -5, "got %d\n", ret
);
1901 DestroyWindow( listbox
);
1903 for (i
= 0; i
< ARRAY_SIZE(styles
); ++i
)
1905 listbox
= create_listbox( styles
[i
] | WS_CHILD
| WS_VISIBLE
, parent
);
1907 SetLastError( 0xdeadbeef );
1908 ret
= SendMessageA( listbox
, LB_SETCOUNT
, 100, 0 );
1909 ok( ret
== LB_ERR
, "expected %d, got %d\n", LB_ERR
, ret
);
1910 ok( GetLastError() == ERROR_SETCOUNT_ON_BAD_LB
, "Unexpected error %d.\n", GetLastError() );
1912 DestroyWindow( listbox
);
1915 DestroyWindow( parent
);
1918 static DWORD (WINAPI
*pGetListBoxInfo
)(HWND
);
1919 static int lb_getlistboxinfo
;
1921 static LRESULT WINAPI
listbox_subclass_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1923 WNDPROC oldproc
= (WNDPROC
)GetWindowLongPtrA(hwnd
, GWLP_USERDATA
);
1925 if (message
== LB_GETLISTBOXINFO
)
1926 lb_getlistboxinfo
++;
1928 return CallWindowProcA(oldproc
, hwnd
, message
, wParam
, lParam
);
1931 static void test_GetListBoxInfo(void)
1933 HWND listbox
, parent
;
1937 pGetListBoxInfo
= (void*)GetProcAddress(GetModuleHandleA("user32.dll"), "GetListBoxInfo");
1939 if (!pGetListBoxInfo
)
1941 win_skip("GetListBoxInfo() not available\n");
1945 parent
= create_parent();
1946 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
, parent
);
1948 oldproc
= (WNDPROC
)SetWindowLongPtrA(listbox
, GWLP_WNDPROC
, (LONG_PTR
)listbox_subclass_proc
);
1949 SetWindowLongPtrA(listbox
, GWLP_USERDATA
, (LONG_PTR
)oldproc
);
1951 lb_getlistboxinfo
= 0;
1952 ret
= pGetListBoxInfo(listbox
);
1953 ok(ret
> 0, "got %d\n", ret
);
1955 ok(lb_getlistboxinfo
== 0, "got %d\n", lb_getlistboxinfo
);
1957 DestroyWindow(listbox
);
1958 DestroyWindow(parent
);
1961 static void test_init_storage( void )
1963 static const DWORD styles
[] =
1966 LBS_NODATA
| LBS_OWNERDRAWFIXED
,
1968 HWND parent
, listbox
;
1969 LONG ret
, items_size
;
1972 parent
= create_parent();
1973 for (i
= 0; i
< ARRAY_SIZE(styles
); i
++)
1975 listbox
= CreateWindowA("listbox", "TestList", styles
[i
] | WS_CHILD
,
1976 0, 0, 100, 100, parent
, (HMENU
)1, NULL
, 0);
1978 items_size
= SendMessageA(listbox
, LB_INITSTORAGE
, 100, 0);
1979 ok(items_size
>= 100, "expected at least 100, got %d\n", items_size
);
1981 ret
= SendMessageA(listbox
, LB_INITSTORAGE
, 0, 0);
1982 ok(ret
== items_size
, "expected %d, got %d\n", items_size
, ret
);
1984 /* it doesn't grow since the space was already reserved */
1985 ret
= SendMessageA(listbox
, LB_INITSTORAGE
, items_size
, 0);
1986 ok(ret
== items_size
, "expected %d, got %d\n", items_size
, ret
);
1988 /* it doesn't shrink the reserved space */
1989 ret
= SendMessageA(listbox
, LB_INITSTORAGE
, 42, 0);
1990 ok(ret
== items_size
, "expected %d, got %d\n", items_size
, ret
);
1992 /* now populate almost all of it so it's not reserved anymore */
1993 if (styles
[i
] & LBS_NODATA
)
1995 ret
= SendMessageA(listbox
, LB_SETCOUNT
, items_size
- 1, 0);
1996 ok(ret
== 0, "unexpected return value %d\n", ret
);
2000 for (j
= 0; j
< items_size
- 1; j
++)
2002 ret
= SendMessageA(listbox
, LB_INSERTSTRING
, -1, (LPARAM
)"");
2003 ok(ret
== j
, "expected %d, got %d\n", j
, ret
);
2007 /* we still have one more reserved slot, so it doesn't grow yet */
2008 ret
= SendMessageA(listbox
, LB_INITSTORAGE
, 1, 0);
2009 ok(ret
== items_size
, "expected %d, got %d\n", items_size
, ret
);
2011 /* fill the slot and check again, it should grow this time */
2012 ret
= SendMessageA(listbox
, LB_INSERTSTRING
, -1, (LPARAM
)"");
2013 ok(ret
== items_size
- 1, "expected %d, got %d\n", items_size
- 1, ret
);
2014 ret
= SendMessageA(listbox
, LB_INITSTORAGE
, 0, 0);
2015 ok(ret
== items_size
, "expected %d, got %d\n", items_size
, ret
);
2016 ret
= SendMessageA(listbox
, LB_INITSTORAGE
, 1, 0);
2017 ok(ret
> items_size
, "expected it to grow past %d, got %d\n", items_size
, ret
);
2019 DestroyWindow(listbox
);
2021 DestroyWindow(parent
);
2024 static void test_missing_lbuttonup( void )
2026 HWND listbox
, parent
, capture
;
2028 parent
= create_parent();
2029 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
, parent
);
2031 /* Send button down without a corresponding button up */
2032 SendMessageA(listbox
, WM_LBUTTONDOWN
, 0, MAKELPARAM(10,10));
2033 capture
= GetCapture();
2034 ok(capture
== listbox
, "got %p expected %p\n", capture
, listbox
);
2036 /* Capture is released and LBN_SELCHANGE sent during WM_KILLFOCUS */
2039 capture
= GetCapture();
2040 ok(capture
== NULL
, "got %p\n", capture
);
2041 ok(got_selchange
, "got %d\n", got_selchange
);
2043 DestroyWindow(listbox
);
2044 DestroyWindow(parent
);
2047 static void test_extents(void)
2049 HWND listbox
, parent
;
2054 parent
= create_parent();
2056 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
, parent
);
2058 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
2059 ok(res
== 0, "Got wrong initial horizontal extent: %u\n", res
);
2061 sinfo
.cbSize
= sizeof(sinfo
);
2062 sinfo
.fMask
= SIF_RANGE
;
2063 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
2064 ok(br
== TRUE
, "GetScrollInfo failed\n");
2065 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
2066 ok(sinfo
.nMax
== 100, "got wrong max: %u\n", sinfo
.nMax
);
2067 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
2068 "List box should not have a horizontal scroll bar\n");
2070 /* horizontal extent < width */
2071 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 64, 0);
2073 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
2074 ok(res
== 64, "Got wrong horizontal extent: %u\n", res
);
2076 sinfo
.cbSize
= sizeof(sinfo
);
2077 sinfo
.fMask
= SIF_RANGE
;
2078 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
2079 ok(br
== TRUE
, "GetScrollInfo failed\n");
2080 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
2081 ok(sinfo
.nMax
== 100, "got wrong max: %u\n", sinfo
.nMax
);
2082 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
2083 "List box should not have a horizontal scroll bar\n");
2085 /* horizontal extent > width */
2086 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 184, 0);
2088 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
2089 ok(res
== 184, "Got wrong horizontal extent: %u\n", res
);
2091 sinfo
.cbSize
= sizeof(sinfo
);
2092 sinfo
.fMask
= SIF_RANGE
;
2093 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
2094 ok(br
== TRUE
, "GetScrollInfo failed\n");
2095 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
2096 ok(sinfo
.nMax
== 100, "got wrong max: %u\n", sinfo
.nMax
);
2097 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
2098 "List box should not have a horizontal scroll bar\n");
2100 DestroyWindow(listbox
);
2103 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
| WS_HSCROLL
, parent
);
2105 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
2106 ok(res
== 0, "Got wrong initial horizontal extent: %u\n", res
);
2108 sinfo
.cbSize
= sizeof(sinfo
);
2109 sinfo
.fMask
= SIF_RANGE
;
2110 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
2111 ok(br
== TRUE
, "GetScrollInfo failed\n");
2112 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
2113 ok(sinfo
.nMax
== 100, "got wrong max: %u\n", sinfo
.nMax
);
2114 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
2115 "List box should not have a horizontal scroll bar\n");
2117 /* horizontal extent < width */
2118 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 64, 0);
2120 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
2121 ok(res
== 64, "Got wrong horizontal extent: %u\n", res
);
2123 sinfo
.cbSize
= sizeof(sinfo
);
2124 sinfo
.fMask
= SIF_RANGE
;
2125 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
2126 ok(br
== TRUE
, "GetScrollInfo failed\n");
2127 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
2128 ok(sinfo
.nMax
== 63, "got wrong max: %u\n", sinfo
.nMax
);
2129 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
2130 "List box should not have a horizontal scroll bar\n");
2132 /* horizontal extent > width */
2133 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 184, 0);
2135 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
2136 ok(res
== 184, "Got wrong horizontal extent: %u\n", res
);
2138 sinfo
.cbSize
= sizeof(sinfo
);
2139 sinfo
.fMask
= SIF_RANGE
;
2140 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
2141 ok(br
== TRUE
, "GetScrollInfo failed\n");
2142 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
2143 ok(sinfo
.nMax
== 183, "got wrong max: %u\n", sinfo
.nMax
);
2144 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
2145 "List box should have a horizontal scroll bar\n");
2147 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 0, 0);
2149 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
2150 ok(res
== 0, "Got wrong horizontal extent: %u\n", res
);
2152 sinfo
.cbSize
= sizeof(sinfo
);
2153 sinfo
.fMask
= SIF_RANGE
;
2154 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
2155 ok(br
== TRUE
, "GetScrollInfo failed\n");
2156 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
2157 ok(sinfo
.nMax
== 0, "got wrong max: %u\n", sinfo
.nMax
);
2158 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
2159 "List box should not have a horizontal scroll bar\n");
2161 DestroyWindow(listbox
);
2164 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
| WS_HSCROLL
| LBS_DISABLENOSCROLL
, parent
);
2166 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
2167 ok(res
== 0, "Got wrong initial horizontal extent: %u\n", res
);
2169 sinfo
.cbSize
= sizeof(sinfo
);
2170 sinfo
.fMask
= SIF_RANGE
;
2171 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
2172 ok(br
== TRUE
, "GetScrollInfo failed\n");
2173 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
2174 ok(sinfo
.nMax
== 0, "got wrong max: %u\n", sinfo
.nMax
);
2175 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
2176 "List box should have a horizontal scroll bar\n");
2178 /* horizontal extent < width */
2179 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 64, 0);
2181 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
2182 ok(res
== 64, "Got wrong horizontal extent: %u\n", res
);
2184 sinfo
.cbSize
= sizeof(sinfo
);
2185 sinfo
.fMask
= SIF_RANGE
;
2186 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
2187 ok(br
== TRUE
, "GetScrollInfo failed\n");
2188 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
2189 ok(sinfo
.nMax
== 63, "got wrong max: %u\n", sinfo
.nMax
);
2190 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
2191 "List box should have a horizontal scroll bar\n");
2193 /* horizontal extent > width */
2194 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 184, 0);
2196 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
2197 ok(res
== 184, "Got wrong horizontal extent: %u\n", res
);
2199 sinfo
.cbSize
= sizeof(sinfo
);
2200 sinfo
.fMask
= SIF_RANGE
;
2201 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
2202 ok(br
== TRUE
, "GetScrollInfo failed\n");
2203 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
2204 ok(sinfo
.nMax
== 183, "got wrong max: %u\n", sinfo
.nMax
);
2205 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
2206 "List box should have a horizontal scroll bar\n");
2208 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 0, 0);
2210 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
2211 ok(res
== 0, "Got wrong horizontal extent: %u\n", res
);
2213 sinfo
.cbSize
= sizeof(sinfo
);
2214 sinfo
.fMask
= SIF_RANGE
;
2215 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
2216 ok(br
== TRUE
, "GetScrollInfo failed\n");
2217 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
2218 ok(sinfo
.nMax
== 0, "got wrong max: %u\n", sinfo
.nMax
);
2219 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
2220 "List box should have a horizontal scroll bar\n");
2222 DestroyWindow(listbox
);
2224 DestroyWindow(parent
);
2227 static void test_WM_MEASUREITEM(void)
2229 HWND parent
, listbox
;
2232 parent
= create_parent();
2233 listbox
= create_listbox(WS_CHILD
| LBS_OWNERDRAWVARIABLE
, parent
);
2235 data
= SendMessageA(listbox
, LB_GETITEMDATA
, 0, 0);
2236 ok(data
== (LRESULT
)strings
[0], "data = %08lx, expected %p\n", data
, strings
[0]);
2237 DestroyWindow(parent
);
2239 parent
= create_parent();
2240 listbox
= create_listbox(WS_CHILD
| LBS_OWNERDRAWVARIABLE
| LBS_HASSTRINGS
, parent
);
2242 data
= SendMessageA(listbox
, LB_GETITEMDATA
, 0, 0);
2243 ok(!data
, "data = %08lx\n", data
);
2244 DestroyWindow(parent
);
2247 static void test_LBS_NODATA(void)
2249 static const DWORD invalid_styles
[] =
2252 LBS_OWNERDRAWVARIABLE
,
2255 LBS_OWNERDRAWFIXED
| LBS_SORT
,
2256 LBS_OWNERDRAWFIXED
| LBS_HASSTRINGS
,
2258 static const UINT invalid_idx
[] = { -2, 2 };
2259 static const UINT valid_idx
[] = { 0, 1 };
2260 static const ULONG_PTR zero_data
;
2261 HWND listbox
, parent
;
2266 listbox
= CreateWindowA("listbox", "TestList", LBS_NODATA
| LBS_OWNERDRAWFIXED
| WS_VISIBLE
,
2267 0, 0, 100, 100, NULL
, NULL
, NULL
, 0);
2268 ok(listbox
!= NULL
, "Failed to create ListBox window.\n");
2270 ret
= SendMessageA(listbox
, LB_INSERTSTRING
, -1, 0);
2271 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
2272 ret
= SendMessageA(listbox
, LB_INSERTSTRING
, -1, 0);
2273 ok(ret
== 1, "Unexpected return value %d.\n", ret
);
2274 ret
= SendMessageA(listbox
, LB_GETCOUNT
, 0, 0);
2275 ok(ret
== 2, "Unexpected return value %d.\n", ret
);
2277 /* Invalid indices. */
2278 for (i
= 0; i
< ARRAY_SIZE(invalid_idx
); ++i
)
2280 ret
= SendMessageA(listbox
, LB_SETITEMDATA
, invalid_idx
[i
], 42);
2281 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2282 ret
= SendMessageA(listbox
, LB_GETTEXTLEN
, invalid_idx
[i
], 0);
2283 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2286 ret
= SendMessageA(listbox
, LB_GETTEXT
, invalid_idx
[i
], (LPARAM
)&data
);
2287 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2289 ret
= SendMessageA(listbox
, LB_GETITEMDATA
, invalid_idx
[i
], 0);
2290 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2293 /* Valid indices. */
2294 for (i
= 0; i
< ARRAY_SIZE(valid_idx
); ++i
)
2296 ret
= SendMessageA(listbox
, LB_SETITEMDATA
, valid_idx
[i
], 42);
2297 ok(ret
== TRUE
, "Unexpected return value %d.\n", ret
);
2298 ret
= SendMessageA(listbox
, LB_GETTEXTLEN
, valid_idx
[i
], 0);
2299 ok(ret
== sizeof(data
), "Unexpected return value %d.\n", ret
);
2301 memset(&data
, 0xee, sizeof(data
));
2302 ret
= SendMessageA(listbox
, LB_GETTEXT
, valid_idx
[i
], (LPARAM
)&data
);
2303 ok(ret
== sizeof(data
), "Unexpected return value %d.\n", ret
);
2304 ok(!memcmp(&data
, &zero_data
, sizeof(data
)), "Unexpected item data.\n");
2306 ret
= SendMessageA(listbox
, LB_GETITEMDATA
, valid_idx
[i
], 0);
2307 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
2310 /* More messages that don't work with LBS_NODATA. */
2311 SetLastError(0xdeadbeef);
2312 ret
= SendMessageA(listbox
, LB_FINDSTRING
, 1, 0);
2313 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2314 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError should return 0x57, got 0x%X\n", GetLastError());
2315 SetLastError(0xdeadbeef);
2316 ret
= SendMessageA(listbox
, LB_FINDSTRING
, 1, 42);
2317 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2318 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError should return 0x57, got 0x%X\n", GetLastError());
2319 SetLastError(0xdeadbeef);
2320 ret
= SendMessageA(listbox
, LB_FINDSTRINGEXACT
, 1, 0);
2321 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2322 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError should return 0x57, got 0x%X\n", GetLastError());
2323 SetLastError(0xdeadbeef);
2324 ret
= SendMessageA(listbox
, LB_FINDSTRINGEXACT
, 1, 42);
2325 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2326 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError should return 0x57, got 0x%X\n", GetLastError());
2327 SetLastError(0xdeadbeef);
2328 ret
= SendMessageA(listbox
, LB_SELECTSTRING
, 1, 0);
2329 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2330 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError should return 0x57, got 0x%X\n", GetLastError());
2331 SetLastError(0xdeadbeef);
2332 ret
= SendMessageA(listbox
, LB_SELECTSTRING
, 1, 42);
2333 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2334 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError should return 0x57, got 0x%X\n", GetLastError());
2336 DestroyWindow(listbox
);
2338 /* Invalid window style combinations. */
2339 parent
= create_parent();
2340 ok(parent
!= NULL
, "Failed to create parent window.\n");
2342 for (i
= 0; i
< ARRAY_SIZE(invalid_styles
); ++i
)
2346 listbox
= CreateWindowA("listbox", "TestList", LBS_NODATA
| WS_CHILD
| invalid_styles
[i
],
2347 0, 0, 100, 100, parent
, (HMENU
)1, NULL
, 0);
2348 ok(listbox
!= NULL
, "Failed to create a listbox.\n");
2350 style
= GetWindowLongA(listbox
, GWL_STYLE
);
2351 ok((style
& invalid_styles
[i
]) == invalid_styles
[i
], "%u: unexpected window styles %#x.\n", i
, style
);
2352 ret
= SendMessageA(listbox
, LB_SETCOUNT
, 100, 0);
2353 ok(ret
== LB_ERR
, "%u: unexpected return value %d.\n", i
, ret
);
2354 DestroyWindow(listbox
);
2357 DestroyWindow(parent
);
2362 const struct listbox_test SS
=
2364 {{LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
2365 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
2366 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
2367 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
2368 /* {selected, anchor, caret, selcount}{TODO fields} */
2369 const struct listbox_test SS_NS
=
2370 {{LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
2371 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
2372 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
2373 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
2374 const struct listbox_test MS
=
2375 {{ 0, LB_ERR
, 0, 0}, {0,0,0,0},
2376 { 1, 1, 1, 1}, {0,0,0,0},
2377 { 2, 1, 2, 1}, {0,0,0,0},
2378 { 0, LB_ERR
, 0, 2}, {0,0,0,0}};
2379 const struct listbox_test MS_NS
=
2380 {{LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
2381 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
2382 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
2383 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
2384 const struct listbox_test ES
=
2385 {{ 0, LB_ERR
, 0, 0}, {0,0,0,0},
2386 { 1, 1, 1, 1}, {0,0,0,0},
2387 { 2, 2, 2, 1}, {0,0,0,0},
2388 { 0, LB_ERR
, 0, 2}, {0,0,0,0}};
2389 const struct listbox_test ES_NS
=
2390 {{LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
2391 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
2392 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
2393 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
2394 const struct listbox_test EMS
=
2395 {{ 0, LB_ERR
, 0, 0}, {0,0,0,0},
2396 { 1, 1, 1, 1}, {0,0,0,0},
2397 { 2, 2, 2, 1}, {0,0,0,0},
2398 { 0, LB_ERR
, 0, 2}, {0,0,0,0}};
2399 const struct listbox_test EMS_NS
=
2400 {{LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
2401 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
2402 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
2403 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
2405 trace (" Testing single selection...\n");
2407 trace (" ... with NOSEL\n");
2408 check (LBS_NOSEL
, SS_NS
);
2409 trace (" ... LBS_NODATA variant ...\n");
2410 check (LBS_NODATA
| LBS_OWNERDRAWFIXED
, SS
);
2411 trace (" ... with NOSEL\n");
2412 check (LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_NOSEL
, SS_NS
);
2414 trace (" Testing multiple selection...\n");
2415 check (LBS_MULTIPLESEL
, MS
);
2416 trace (" ... with NOSEL\n");
2417 check (LBS_MULTIPLESEL
| LBS_NOSEL
, MS_NS
);
2418 trace (" ... LBS_NODATA variant ...\n");
2419 check (LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_MULTIPLESEL
, MS
);
2420 trace (" ... with NOSEL\n");
2421 check (LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_MULTIPLESEL
| LBS_NOSEL
, MS_NS
);
2423 trace (" Testing extended selection...\n");
2424 check (LBS_EXTENDEDSEL
, ES
);
2425 trace (" ... with NOSEL\n");
2426 check (LBS_EXTENDEDSEL
| LBS_NOSEL
, ES_NS
);
2427 trace (" ... LBS_NODATA variant ...\n");
2428 check (LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_EXTENDEDSEL
, ES
);
2429 trace (" ... with NOSEL\n");
2430 check (LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_EXTENDEDSEL
| LBS_NOSEL
, ES_NS
);
2432 trace (" Testing extended and multiple selection...\n");
2433 check (LBS_EXTENDEDSEL
| LBS_MULTIPLESEL
, EMS
);
2434 trace (" ... with NOSEL\n");
2435 check (LBS_EXTENDEDSEL
| LBS_MULTIPLESEL
| LBS_NOSEL
, EMS_NS
);
2436 trace (" ... LBS_NODATA variant ...\n");
2437 check (LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_EXTENDEDSEL
| LBS_MULTIPLESEL
, EMS
);
2438 trace (" ... with NOSEL\n");
2439 check (LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_EXTENDEDSEL
| LBS_MULTIPLESEL
| LBS_NOSEL
, EMS_NS
);
2441 check_item_height();
2443 test_LB_SELITEMRANGE();
2444 test_LB_SETCURSEL();
2445 test_listbox_height();
2446 test_changing_selection_styles();
2447 test_itemfrompoint();
2448 test_listbox_item_data();
2449 test_listbox_LB_DIR();
2450 test_listbox_dlgdir();
2452 test_init_storage();
2453 test_GetListBoxInfo();
2454 test_missing_lbuttonup();
2456 test_WM_MEASUREITEM();