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";
50 create_listbox (DWORD add_style
, HWND parent
)
56 handle
=CreateWindow ("LISTBOX", "TestList",
57 (LBS_STANDARD
& ~LBS_SORT
) | add_style
,
59 parent
, (HMENU
)ctl_id
, NULL
, 0);
62 SendMessage (handle
, LB_ADDSTRING
, 0, (LPARAM
) strings
[0]);
63 SendMessage (handle
, LB_ADDSTRING
, 0, (LPARAM
) strings
[1]);
64 SendMessage (handle
, LB_ADDSTRING
, 0, (LPARAM
) strings
[2]);
65 SendMessage (handle
, LB_ADDSTRING
, 0, (LPARAM
) strings
[3]);
68 ShowWindow (handle
, SW_SHOW
);
80 int selected
, anchor
, caret
, selcount
;
84 struct listbox_prop prop
;
85 struct listbox_stat init
, init_todo
;
86 struct listbox_stat click
, click_todo
;
87 struct listbox_stat step
, step_todo
;
88 struct listbox_stat sel
, sel_todo
;
92 listbox_query (HWND handle
, struct listbox_stat
*results
)
94 results
->selected
= SendMessage (handle
, LB_GETCURSEL
, 0, 0);
95 results
->anchor
= SendMessage (handle
, LB_GETANCHORINDEX
, 0, 0);
96 results
->caret
= SendMessage (handle
, LB_GETCARETINDEX
, 0, 0);
97 results
->selcount
= SendMessage (handle
, LB_GETSELCOUNT
, 0, 0);
101 buttonpress (HWND handle
, WORD x
, WORD y
)
106 SendMessage (handle
, WM_LBUTTONDOWN
, MK_LBUTTON
, lp
);
107 SendMessage (handle
, WM_LBUTTONUP
, 0, lp
);
112 keypress (HWND handle
, WPARAM keycode
, BYTE scancode
, BOOL extended
)
114 LPARAM lp
=1+(scancode
<<16)+(extended
?KEYEVENTF_EXTENDEDKEY
:0);
117 SendMessage (handle
, WM_KEYDOWN
, keycode
, lp
);
118 SendMessage (handle
, WM_KEYUP
, keycode
, lp
| 0xc000000);
122 #define listbox_field_ok(t, s, f, got) \
123 ok (t.s.f==got.f, "style %#x, step " #s ", field " #f \
124 ": expected %d, got %d\n", (unsigned int)t.prop.add_style, \
127 #define listbox_todo_field_ok(t, s, f, got) \
128 if (t.s##_todo.f) todo_wine { listbox_field_ok(t, s, f, got); } \
129 else listbox_field_ok(t, s, f, got)
131 #define listbox_ok(t, s, got) \
132 listbox_todo_field_ok(t, s, selected, got); \
133 listbox_todo_field_ok(t, s, anchor, got); \
134 listbox_todo_field_ok(t, s, caret, got); \
135 listbox_todo_field_ok(t, s, selcount, got)
138 check (const struct listbox_test test
)
140 struct listbox_stat answer
;
141 HWND hLB
=create_listbox (test
.prop
.add_style
, 0);
146 listbox_query (hLB
, &answer
);
147 listbox_ok (test
, init
, answer
);
149 SendMessage (hLB
, LB_GETITEMRECT
, 1, (LPARAM
) &second_item
);
150 buttonpress(hLB
, (WORD
)second_item
.left
, (WORD
)second_item
.top
);
152 listbox_query (hLB
, &answer
);
153 listbox_ok (test
, click
, answer
);
155 keypress (hLB
, VK_DOWN
, 0x50, TRUE
);
157 listbox_query (hLB
, &answer
);
158 listbox_ok (test
, step
, answer
);
161 hLB
=create_listbox (test
.prop
.add_style
, 0);
163 SendMessage (hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(1, 2));
164 listbox_query (hLB
, &answer
);
165 listbox_ok (test
, sel
, answer
);
168 DWORD size
= SendMessage (hLB
, LB_GETTEXTLEN
, i
, 0);
173 txt
= HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY
, size
+1);
174 resA
=SendMessageA(hLB
, LB_GETTEXT
, i
, (LPARAM
)txt
);
175 ok(!strcmp (txt
, strings
[i
]), "returned string for item %d does not match %s vs %s\n", i
, txt
, strings
[i
]);
177 txtw
= HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY
, 2*size
+2);
178 resW
=SendMessageW(hLB
, LB_GETTEXT
, i
, (LPARAM
)txtw
);
180 trace("SendMessageW(LB_GETTEXT) not supported on this platform (resA=%d resW=%d), skipping...\n",
183 WideCharToMultiByte( CP_ACP
, 0, txtw
, -1, txt
, size
, NULL
, NULL
);
184 ok(!strcmp (txt
, strings
[i
]), "returned string for item %d does not match %s vs %s\n", i
, txt
, strings
[i
]);
187 HeapFree (GetProcessHeap(), 0, txtw
);
188 HeapFree (GetProcessHeap(), 0, txt
);
191 /* Confirm the count of items, and that an invalid delete does not remove anything */
192 res
= SendMessage (hLB
, LB_GETCOUNT
, 0, 0);
193 ok((res
==4), "Expected 4 items, got %d\n", res
);
194 res
= SendMessage (hLB
, LB_DELETESTRING
, -1, 0);
195 ok((res
==LB_ERR
), "Expected LB_ERR items, got %d\n", res
);
196 res
= SendMessage (hLB
, LB_DELETESTRING
, 4, 0);
197 ok((res
==LB_ERR
), "Expected LB_ERR items, got %d\n", res
);
198 res
= SendMessage (hLB
, LB_GETCOUNT
, 0, 0);
199 ok((res
==4), "Expected 4 items, got %d\n", res
);
205 static void check_item_height(void)
213 hLB
= create_listbox (0, 0);
214 ok ((hdc
= GetDCEx( hLB
, 0, DCX_CACHE
)) != 0, "Can't get hdc\n");
215 ok ((font
= GetCurrentObject(hdc
, OBJ_FONT
)) != 0, "Can't get the current font\n");
216 ok (GetTextMetrics( hdc
, &tm
), "Can't read font metrics\n");
217 ReleaseDC( hLB
, hdc
);
219 ok (SendMessage(hLB
, WM_SETFONT
, (WPARAM
)font
, 0) == 0, "Can't set font\n");
221 itemHeight
= SendMessage(hLB
, LB_GETITEMHEIGHT
, 0, 0);
222 ok (itemHeight
== tm
.tmHeight
, "Item height wrong, got %d, expecting %d\n", itemHeight
, tm
.tmHeight
);
226 hLB
= CreateWindow ("LISTBOX", "TestList", LBS_OWNERDRAWVARIABLE
,
227 0, 0, 100, 100, NULL
, NULL
, NULL
, 0);
228 itemHeight
= SendMessage(hLB
, LB_GETITEMHEIGHT
, 0, 0);
229 ok(itemHeight
== tm
.tmHeight
, "itemHeight %d\n", itemHeight
);
230 itemHeight
= SendMessage(hLB
, LB_GETITEMHEIGHT
, 5, 0);
231 ok(itemHeight
== tm
.tmHeight
, "itemHeight %d\n", itemHeight
);
232 itemHeight
= SendMessage(hLB
, LB_GETITEMHEIGHT
, -5, 0);
233 ok(itemHeight
== tm
.tmHeight
, "itemHeight %d\n", itemHeight
);
237 static LRESULT WINAPI
main_window_proc(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
243 RECT rc_item
, rc_client
, rc_clip
;
244 DRAWITEMSTRUCT
*dis
= (DRAWITEMSTRUCT
*)lparam
;
246 trace("%p WM_DRAWITEM %08lx %08lx\n", hwnd
, wparam
, lparam
);
248 ok(wparam
== dis
->CtlID
, "got wParam=%08lx instead of %08x\n",
250 ok(dis
->CtlType
== ODT_LISTBOX
, "wrong CtlType %04x\n", dis
->CtlType
);
252 GetClientRect(dis
->hwndItem
, &rc_client
);
253 trace("hwndItem %p client rect (%d,%d-%d,%d)\n", dis
->hwndItem
,
254 rc_client
.left
, rc_client
.top
, rc_client
.right
, rc_client
.bottom
);
255 GetClipBox(dis
->hDC
, &rc_clip
);
256 trace("clip rect (%d,%d-%d,%d)\n", rc_clip
.left
, rc_clip
.top
, rc_clip
.right
, rc_clip
.bottom
);
257 ok(EqualRect(&rc_client
, &rc_clip
) || IsRectEmpty(&rc_clip
),
258 "client rect of the listbox should be equal to the clip box,"
259 "or the clip box should be empty\n");
261 trace("rcItem (%d,%d-%d,%d)\n", dis
->rcItem
.left
, dis
->rcItem
.top
,
262 dis
->rcItem
.right
, dis
->rcItem
.bottom
);
263 SendMessage(dis
->hwndItem
, LB_GETITEMRECT
, dis
->itemID
, (LPARAM
)&rc_item
);
264 trace("item rect (%d,%d-%d,%d)\n", rc_item
.left
, rc_item
.top
, rc_item
.right
, rc_item
.bottom
);
265 ok(EqualRect(&dis
->rcItem
, &rc_item
), "item rects are not equal\n");
274 return DefWindowProc(hwnd
, msg
, wparam
, lparam
);
277 static void test_ownerdraw(void)
285 cls
.lpfnWndProc
= main_window_proc
;
288 cls
.hInstance
= GetModuleHandle(0);
290 cls
.hCursor
= LoadCursor(0, IDC_ARROW
);
291 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
292 cls
.lpszMenuName
= NULL
;
293 cls
.lpszClassName
= "main_window_class";
294 ok (RegisterClass(&cls
), "RegisterClass failed\n");
296 parent
= CreateWindowEx(0, "main_window_class", NULL
,
297 WS_POPUP
| WS_VISIBLE
,
299 GetDesktopWindow(), 0,
300 GetModuleHandle(0), NULL
);
303 hLB
= create_listbox(LBS_OWNERDRAWFIXED
| WS_CHILD
| WS_VISIBLE
, parent
);
306 SetForegroundWindow(hLB
);
309 /* make height short enough */
310 SendMessage(hLB
, LB_GETITEMRECT
, 0, (LPARAM
)&rc
);
311 SetWindowPos(hLB
, 0, 0, 0, 100, rc
.bottom
- rc
.top
+ 1,
312 SWP_NOZORDER
| SWP_NOMOVE
);
314 /* make 0 item invisible */
315 SendMessage(hLB
, LB_SETTOPINDEX
, 1, 0);
316 ret
= SendMessage(hLB
, LB_GETTOPINDEX
, 0, 0);
317 ok(ret
== 1, "wrong top index %d\n", ret
);
319 SendMessage(hLB
, LB_GETITEMRECT
, 0, (LPARAM
)&rc
);
320 trace("item 0 rect (%d,%d-%d,%d)\n", rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
321 ok(!IsRectEmpty(&rc
), "empty item rect\n");
322 ok(rc
.top
< 0, "rc.top is not negative (%d)\n", rc
.top
);
325 DestroyWindow(parent
);
328 #define listbox_test_query(exp, got) \
329 ok(exp.selected == got.selected, "expected selected %d, got %d\n", exp.selected, got.selected); \
330 ok(exp.anchor == got.anchor, "expected anchor %d, got %d\n", exp.anchor, got.anchor); \
331 ok(exp.caret == got.caret, "expected caret %d, got %d\n", exp.caret, got.caret); \
332 ok(exp.selcount == got.selcount, "expected selcount %d, got %d\n", exp.selcount, got.selcount);
334 static void test_selection(void)
336 static const struct listbox_stat test_nosel
= { 0, LB_ERR
, 0, 0 };
337 static const struct listbox_stat test_1
= { 0, LB_ERR
, 0, 2 };
338 static const struct listbox_stat test_2
= { 0, LB_ERR
, 0, 3 };
339 static const struct listbox_stat test_3
= { 0, LB_ERR
, 0, 4 };
341 struct listbox_stat answer
;
344 trace("testing LB_SELITEMRANGE\n");
346 hLB
= create_listbox(LBS_EXTENDEDSEL
, 0);
349 listbox_query(hLB
, &answer
);
350 listbox_test_query(test_nosel
, answer
);
352 ret
= SendMessage(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(1, 2));
353 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
354 listbox_query(hLB
, &answer
);
355 listbox_test_query(test_1
, answer
);
357 SendMessage(hLB
, LB_SETSEL
, FALSE
, -1);
358 listbox_query(hLB
, &answer
);
359 listbox_test_query(test_nosel
, answer
);
361 ret
= SendMessage(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(0, 4));
362 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
363 listbox_query(hLB
, &answer
);
364 listbox_test_query(test_3
, answer
);
366 SendMessage(hLB
, LB_SETSEL
, FALSE
, -1);
367 listbox_query(hLB
, &answer
);
368 listbox_test_query(test_nosel
, answer
);
370 ret
= SendMessage(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(-5, 5));
371 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
372 listbox_query(hLB
, &answer
);
373 listbox_test_query(test_nosel
, answer
);
375 SendMessage(hLB
, LB_SETSEL
, FALSE
, -1);
376 listbox_query(hLB
, &answer
);
377 listbox_test_query(test_nosel
, answer
);
379 ret
= SendMessage(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(2, 10));
380 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
381 listbox_query(hLB
, &answer
);
382 listbox_test_query(test_1
, answer
);
384 SendMessage(hLB
, LB_SETSEL
, FALSE
, -1);
385 listbox_query(hLB
, &answer
);
386 listbox_test_query(test_nosel
, answer
);
388 ret
= SendMessage(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(4, 10));
389 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
390 listbox_query(hLB
, &answer
);
391 listbox_test_query(test_nosel
, answer
);
393 SendMessage(hLB
, LB_SETSEL
, FALSE
, -1);
394 listbox_query(hLB
, &answer
);
395 listbox_test_query(test_nosel
, answer
);
397 ret
= SendMessage(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(10, 1));
398 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
399 listbox_query(hLB
, &answer
);
400 listbox_test_query(test_2
, answer
);
402 SendMessage(hLB
, LB_SETSEL
, FALSE
, -1);
403 listbox_query(hLB
, &answer
);
404 listbox_test_query(test_nosel
, answer
);
406 ret
= SendMessage(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(1, -1));
407 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
408 listbox_query(hLB
, &answer
);
409 listbox_test_query(test_2
, answer
);
414 static void test_listbox_height(void)
419 hList
= CreateWindow( "ListBox", "list test", 0,
420 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
421 ok( hList
!= NULL
, "failed to create listbox\n");
423 id
= SendMessage( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi");
424 ok( id
== 0, "item id wrong\n");
426 r
= SendMessage( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 20, 0 ));
427 ok( r
== 0, "send message failed\n");
429 r
= SendMessage(hList
, LB_GETITEMHEIGHT
, 0, 0 );
430 ok( r
== 20, "height wrong\n");
432 r
= SendMessage( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 0, 30 ));
433 ok( r
== -1, "send message failed\n");
435 r
= SendMessage(hList
, LB_GETITEMHEIGHT
, 0, 0 );
436 ok( r
== 20, "height wrong\n");
438 r
= SendMessage( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 0x100, 0 ));
439 ok( r
== -1, "send message failed\n");
441 r
= SendMessage(hList
, LB_GETITEMHEIGHT
, 0, 0 );
442 ok( r
== 20, "height wrong\n");
444 r
= SendMessage( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 0xff, 0 ));
445 ok( r
== 0, "send message failed\n");
447 r
= SendMessage(hList
, LB_GETITEMHEIGHT
, 0, 0 );
448 ok( r
== 0xff, "height wrong\n");
450 DestroyWindow( hList
);
453 static void test_itemfrompoint(void)
455 /* WS_POPUP is required in order to have a more accurate size calculation (
456 without caption). LBS_NOINTEGRALHEIGHT is required in order to test
457 behavior of partially-displayed item.
459 HWND hList
= CreateWindow( "ListBox", "list test",
460 WS_VISIBLE
|WS_POPUP
|LBS_NOINTEGRALHEIGHT
,
461 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
465 /* For an empty listbox win2k returns 0x1ffff, win98 returns 0x10000, nt4 returns 0xffffffff */
466 r
= SendMessage(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
467 ok( r
== 0x1ffff || r
== 0x10000 || r
== 0xffffffff, "ret %x\n", r
);
469 r
= SendMessage(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( 700, 30 ));
470 ok( r
== 0x1ffff || r
== 0x10000 || r
== 0xffffffff, "ret %x\n", r
);
472 r
= SendMessage(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( 30, 300 ));
473 ok( r
== 0x1ffff || r
== 0x10000 || r
== 0xffffffff, "ret %x\n", r
);
475 id
= SendMessage( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi");
476 ok( id
== 0, "item id wrong\n");
477 id
= SendMessage( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi1");
478 ok( id
== 1, "item id wrong\n");
480 r
= SendMessage(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
481 ok( r
== 0x1, "ret %x\n", r
);
483 r
= SendMessage(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( /* x */ 30, /* y */ 601 ));
484 ok( r
== 0x10001 || broken(r
== 1), /* nt4 */
487 /* Resize control so that below assertions about sizes are valid */
488 r
= SendMessage( hList
, LB_GETITEMRECT
, 0, (LPARAM
)&rc
);
489 ok( r
== 1, "ret %x\n", r
);
490 r
= MoveWindow(hList
, 1, 1, 600, (rc
.bottom
- rc
.top
+ 1) * 9 / 2, TRUE
);
491 ok( r
!= 0, "ret %x\n", r
);
493 id
= SendMessage( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi2");
494 ok( id
== 2, "item id wrong\n");
495 id
= SendMessage( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi3");
496 ok( id
== 3, "item id wrong\n");
497 id
= SendMessage( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi4");
498 ok( id
== 4, "item id wrong\n");
499 id
= SendMessage( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi5");
500 ok( id
== 5, "item id wrong\n");
501 id
= SendMessage( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi6");
502 ok( id
== 6, "item id wrong\n");
503 id
= SendMessage( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi7");
504 ok( id
== 7, "item id wrong\n");
506 /* Set the listbox up so that id 1 is at the top, this leaves 5
507 partially visible at the bottom and 6, 7 are invisible */
509 SendMessage( hList
, LB_SETTOPINDEX
, 1, 0);
510 r
= SendMessage( hList
, LB_GETTOPINDEX
, 0, 0);
511 ok( r
== 1, "top %d\n", r
);
513 r
= SendMessage( hList
, LB_GETITEMRECT
, 5, (LPARAM
)&rc
);
514 ok( r
== 1, "ret %x\n", r
);
515 r
= SendMessage( hList
, LB_GETITEMRECT
, 6, (LPARAM
)&rc
);
516 ok( r
== 0, "ret %x\n", r
);
518 r
= SendMessage( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(/* x */ 10, /* y */ 10) );
519 ok( r
== 1, "ret %x\n", r
);
521 r
= SendMessage( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(1000, 10) );
522 ok( r
== 0x10001 || broken(r
== 1), /* nt4 */
525 r
= SendMessage( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(10, -10) );
526 ok( r
== 0x10001 || broken(r
== 1), /* nt4 */
529 r
= SendMessage( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(10, 100) );
530 ok( r
== 0x10005 || broken(r
== 5), /* nt4 */
533 r
= SendMessage( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(10, 200) );
534 ok( r
== 0x10005 || broken(r
== 5), /* nt4 */
537 DestroyWindow( hList
);
540 static void test_listbox_item_data(void)
545 hList
= CreateWindow( "ListBox", "list test", 0,
546 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
547 ok( hList
!= NULL
, "failed to create listbox\n");
549 id
= SendMessage( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi");
550 ok( id
== 0, "item id wrong\n");
552 r
= SendMessage( hList
, LB_SETITEMDATA
, 0, MAKELPARAM( 20, 0 ));
553 ok(r
== TRUE
, "LB_SETITEMDATA returned %d instead of TRUE\n", r
);
555 r
= SendMessage( hList
, LB_GETITEMDATA
, 0, 0);
556 ok( r
== 20, "get item data failed\n");
558 DestroyWindow( hList
);
561 static void test_listbox_LB_DIR(void)
565 int itemCount_justFiles
;
566 int itemCount_justDrives
;
567 int itemCount_allFiles
;
568 int itemCount_allDirs
;
570 char pathBuffer
[MAX_PATH
];
573 const char *wildcard
= "*";
576 file
= CreateFileA( "wtest1.tmp.c", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, FILE_ATTRIBUTE_NORMAL
, NULL
);
577 ok(file
!= INVALID_HANDLE_VALUE
, "Error creating the test file: %d\n", GetLastError());
580 /* NOTE: for this test to succeed, there must be no subdirectories
581 under the current directory. In addition, there must be at least
582 one file that fits the wildcard w*.c . Normally, the test
583 directory itself satisfies both conditions.
585 hList
= CreateWindow( "ListBox", "list test", WS_VISIBLE
|WS_POPUP
,
586 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
589 /* Test for standard usage */
591 /* This should list all the files in the test directory. */
592 strcpy(pathBuffer
, wildcard
);
593 SendMessage(hList
, LB_RESETCONTENT
, 0, 0);
594 res
= SendMessage(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
595 if (res
== -1) /* "*" wildcard doesn't work on win9x */
598 strcpy(pathBuffer
, wildcard
);
599 res
= SendMessage(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
601 ok (res
>= 0, "SendMessage(LB_DIR, 0, *) failed - 0x%08x\n", GetLastError());
603 /* There should be some content in the listbox */
604 itemCount
= SendMessage(hList
, LB_GETCOUNT
, 0, 0);
605 ok (itemCount
> 0, "SendMessage(LB_DIR) did NOT fill the listbox!\n");
606 itemCount_allFiles
= itemCount
;
607 ok(res
+ 1 == itemCount
,
608 "SendMessage(LB_DIR, 0, *) returned incorrect index (expected %d got %d)!\n",
611 /* This tests behavior when no files match the wildcard */
612 strcpy(pathBuffer
, BAD_EXTENSION
);
613 SendMessage(hList
, LB_RESETCONTENT
, 0, 0);
614 res
= SendMessage(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
615 ok (res
== -1, "SendMessage(LB_DIR, 0, %s) returned %d, expected -1\n", BAD_EXTENSION
, res
);
617 /* There should be NO content in the listbox */
618 itemCount
= SendMessage(hList
, LB_GETCOUNT
, 0, 0);
619 ok (itemCount
== 0, "SendMessage(LB_DIR) DID fill the listbox!\n");
622 /* This should list all the w*.c files in the test directory
623 * As of this writing, this includes win.c, winstation.c, wsprintf.c
625 strcpy(pathBuffer
, "w*.c");
626 SendMessage(hList
, LB_RESETCONTENT
, 0, 0);
627 res
= SendMessage(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
628 ok (res
>= 0, "SendMessage(LB_DIR, 0, w*.c) failed - 0x%08x\n", GetLastError());
630 /* Path specification does NOT converted to uppercase */
631 ok (!strcmp(pathBuffer
, "w*.c"),
632 "expected no change to pathBuffer, got %s\n", pathBuffer
);
634 /* There should be some content in the listbox */
635 itemCount
= SendMessage(hList
, LB_GETCOUNT
, 0, 0);
636 ok (itemCount
> 0, "SendMessage(LB_DIR) did NOT fill the listbox!\n");
637 itemCount_justFiles
= itemCount
;
638 ok(res
+ 1 == itemCount
,
639 "SendMessage(LB_DIR, 0, w*.c) returned incorrect index (expected %d got %d)!\n",
642 /* Every single item in the control should start with a w and end in .c */
643 for (i
= 0; i
< itemCount
; i
++) {
644 memset(pathBuffer
, 0, MAX_PATH
);
645 SendMessage(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
646 p
= pathBuffer
+ strlen(pathBuffer
);
647 ok(((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
648 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
649 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
652 /* Test DDL_DIRECTORY */
653 strcpy(pathBuffer
, wildcard
);
654 SendMessage(hList
, LB_RESETCONTENT
, 0, 0);
655 res
= SendMessage(hList
, LB_DIR
, DDL_DIRECTORY
, (LPARAM
)pathBuffer
);
656 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY, *) failed - 0x%08x\n", GetLastError());
658 /* There should be some content in the listbox.
659 * All files plus "[..]"
661 itemCount
= SendMessage(hList
, LB_GETCOUNT
, 0, 0);
662 itemCount_allDirs
= itemCount
- itemCount_allFiles
;
663 ok (itemCount
> itemCount_allFiles
,
664 "SendMessage(LB_DIR, DDL_DIRECTORY, *) filled with %d entries, expected > %d\n",
665 itemCount
, itemCount_allFiles
);
666 ok(res
+ 1 == itemCount
,
667 "SendMessage(LB_DIR, DDL_DIRECTORY, *) returned incorrect index (expected %d got %d)!\n",
670 /* This tests behavior when no files match the wildcard */
671 strcpy(pathBuffer
, BAD_EXTENSION
);
672 SendMessage(hList
, LB_RESETCONTENT
, 0, 0);
673 res
= SendMessage(hList
, LB_DIR
, DDL_DIRECTORY
, (LPARAM
)pathBuffer
);
674 ok (res
== -1, "SendMessage(LB_DIR, DDL_DIRECTORY, %s) returned %d, expected -1\n", BAD_EXTENSION
, res
);
676 /* There should be NO content in the listbox */
677 itemCount
= SendMessage(hList
, LB_GETCOUNT
, 0, 0);
678 ok (itemCount
== 0, "SendMessage(LB_DIR) DID fill the listbox!\n");
681 /* Test DDL_DIRECTORY */
682 strcpy(pathBuffer
, "w*.c");
683 SendMessage(hList
, LB_RESETCONTENT
, 0, 0);
684 res
= SendMessage(hList
, LB_DIR
, DDL_DIRECTORY
, (LPARAM
)pathBuffer
);
685 ok (res
>= 0, "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) failed - 0x%08x\n", GetLastError());
687 /* There should be some content in the listbox. Since the parent directory does not
688 * fit w*.c, there should be exactly the same number of items as without DDL_DIRECTORY
690 itemCount
= SendMessage(hList
, LB_GETCOUNT
, 0, 0);
691 ok (itemCount
== itemCount_justFiles
,
692 "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) filled with %d entries, expected %d\n",
693 itemCount
, itemCount_justFiles
);
694 ok(res
+ 1 == itemCount
,
695 "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) returned incorrect index (expected %d got %d)!\n",
698 /* Every single item in the control should start with a w and end in .c. */
699 for (i
= 0; i
< itemCount
; i
++) {
700 memset(pathBuffer
, 0, MAX_PATH
);
701 SendMessage(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
702 p
= pathBuffer
+ strlen(pathBuffer
);
704 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
705 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
706 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
710 /* Test DDL_DRIVES|DDL_EXCLUSIVE */
711 strcpy(pathBuffer
, wildcard
);
712 SendMessage(hList
, LB_RESETCONTENT
, 0, 0);
713 res
= SendMessage(hList
, LB_DIR
, DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
714 ok (res
>= 0, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) failed - 0x%08x\n", GetLastError());
716 /* There should be some content in the listbox. In particular, there should
717 * be at least one element before, since the string "[-c-]" should
718 * have been added. Depending on the user setting, more drives might have
721 itemCount
= SendMessage(hList
, LB_GETCOUNT
, 0, 0);
723 "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) filled with %d entries, expected at least %d\n",
725 itemCount_justDrives
= itemCount
;
726 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) returned incorrect index!\n");
728 /* Every single item in the control should fit the format [-c-] */
729 for (i
= 0; i
< itemCount
; i
++) {
730 memset(pathBuffer
, 0, MAX_PATH
);
732 SendMessage(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
733 ok( strlen(pathBuffer
) == 5, "Length of drive string is not 5\n" );
734 ok( sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1, "Element %d (%s) does not fit [-X-]\n", i
, pathBuffer
);
735 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
736 if (!(driveletter
>= 'a' && driveletter
<= 'z')) {
737 /* Correct after invalid entry is found */
738 trace("removing count of invalid entry %s\n", pathBuffer
);
739 itemCount_justDrives
--;
743 /* This tests behavior when no files match the wildcard */
744 strcpy(pathBuffer
, BAD_EXTENSION
);
745 SendMessage(hList
, LB_RESETCONTENT
, 0, 0);
746 res
= SendMessage(hList
, LB_DIR
, DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
747 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
748 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
750 itemCount
= SendMessage(hList
, LB_GETCOUNT
, 0, 0);
751 ok (itemCount
== itemCount_justDrives
, "SendMessage(LB_DIR) returned %d expected %d\n",
752 itemCount
, itemCount_justDrives
);
754 trace("Files with w*.c: %d Mapped drives: %d Directories: 1\n",
755 itemCount_justFiles
, itemCount_justDrives
);
757 /* Test DDL_DRIVES. */
758 strcpy(pathBuffer
, wildcard
);
759 SendMessage(hList
, LB_RESETCONTENT
, 0, 0);
760 res
= SendMessage(hList
, LB_DIR
, DDL_DRIVES
, (LPARAM
)pathBuffer
);
761 ok (res
> 0, "SendMessage(LB_DIR, DDL_DRIVES, *) failed - 0x%08x\n", GetLastError());
763 /* There should be some content in the listbox. In particular, there should
764 * be at least one element before, since the string "[-c-]" should
765 * have been added. Depending on the user setting, more drives might have
768 itemCount
= SendMessage(hList
, LB_GETCOUNT
, 0, 0);
769 ok (itemCount
== itemCount_justDrives
+ itemCount_allFiles
,
770 "SendMessage(LB_DIR, DDL_DRIVES, *) filled with %d entries, expected %d\n",
771 itemCount
, itemCount_justDrives
+ itemCount_allFiles
);
772 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DRIVES, *) returned incorrect index!\n");
774 /* This tests behavior when no files match the wildcard */
775 strcpy(pathBuffer
, BAD_EXTENSION
);
776 SendMessage(hList
, LB_RESETCONTENT
, 0, 0);
777 res
= SendMessage(hList
, LB_DIR
, DDL_DRIVES
, (LPARAM
)pathBuffer
);
778 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DRIVES, %s) returned %d, expected %d\n",
779 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
781 itemCount
= SendMessage(hList
, LB_GETCOUNT
, 0, 0);
782 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
785 /* Test DDL_DRIVES. */
786 strcpy(pathBuffer
, "w*.c");
787 SendMessage(hList
, LB_RESETCONTENT
, 0, 0);
788 res
= SendMessage(hList
, LB_DIR
, DDL_DRIVES
, (LPARAM
)pathBuffer
);
789 ok (res
> 0, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) failed - 0x%08x\n", GetLastError());
791 /* There should be some content in the listbox. In particular, there should
792 * be at least one element before, since the string "[-c-]" should
793 * have been added. Depending on the user setting, more drives might have
796 itemCount
= SendMessage(hList
, LB_GETCOUNT
, 0, 0);
797 ok (itemCount
== itemCount_justDrives
+ itemCount_justFiles
,
798 "SendMessage(LB_DIR, DDL_DRIVES, w*.c) filled with %d entries, expected %d\n",
799 itemCount
, itemCount_justDrives
+ itemCount_justFiles
);
800 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) returned incorrect index!\n");
802 /* Every single item in the control should fit the format [-c-], or w*.c */
803 for (i
= 0; i
< itemCount
; i
++) {
804 memset(pathBuffer
, 0, MAX_PATH
);
806 SendMessage(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
807 p
= pathBuffer
+ strlen(pathBuffer
);
808 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1) {
809 ok( strlen(pathBuffer
) == 5, "Length of drive string is not 5\n" );
810 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
813 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
814 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
815 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
820 /* Test DDL_DIRECTORY|DDL_DRIVES. This does *not* imply DDL_EXCLUSIVE */
821 strcpy(pathBuffer
, wildcard
);
822 SendMessage(hList
, LB_RESETCONTENT
, 0, 0);
823 res
= SendMessage(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
, (LPARAM
)pathBuffer
);
824 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, *) failed - 0x%08x\n", GetLastError());
826 /* There should be some content in the listbox. In particular, there should
827 * be exactly the number of plain files, plus the number of mapped drives.
829 itemCount
= SendMessage(hList
, LB_GETCOUNT
, 0, 0);
830 ok (itemCount
== itemCount_allFiles
+ itemCount_justDrives
+ itemCount_allDirs
,
831 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
832 itemCount
, itemCount_allFiles
+ itemCount_justDrives
+ itemCount_allDirs
);
833 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
835 /* Every single item in the control should start with a w and end in .c,
836 * except for the "[..]" string, which should appear exactly as it is,
837 * and the mapped drives in the format "[-X-]".
839 for (i
= 0; i
< itemCount
; i
++) {
840 memset(pathBuffer
, 0, MAX_PATH
);
842 SendMessage(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
843 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1) {
844 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
848 /* This tests behavior when no files match the wildcard */
849 strcpy(pathBuffer
, BAD_EXTENSION
);
850 SendMessage(hList
, LB_RESETCONTENT
, 0, 0);
851 res
= SendMessage(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
, (LPARAM
)pathBuffer
);
852 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, %s) returned %d, expected %d\n",
853 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
855 itemCount
= SendMessage(hList
, LB_GETCOUNT
, 0, 0);
856 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
860 /* Test DDL_DIRECTORY|DDL_DRIVES. */
861 strcpy(pathBuffer
, "w*.c");
862 SendMessage(hList
, LB_RESETCONTENT
, 0, 0);
863 res
= SendMessage(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
, (LPARAM
)pathBuffer
);
864 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) failed - 0x%08x\n", GetLastError());
866 /* There should be some content in the listbox. In particular, there should
867 * be exactly the number of plain files, plus the number of mapped drives.
869 itemCount
= SendMessage(hList
, LB_GETCOUNT
, 0, 0);
870 ok (itemCount
== itemCount_justFiles
+ itemCount_justDrives
,
871 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
872 itemCount
, itemCount_justFiles
+ itemCount_justDrives
);
873 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
875 /* Every single item in the control should start with a w and end in .c,
876 * except the mapped drives in the format "[-X-]". The "[..]" directory
879 for (i
= 0; i
< itemCount
; i
++) {
880 memset(pathBuffer
, 0, MAX_PATH
);
882 SendMessage(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
883 p
= pathBuffer
+ strlen(pathBuffer
);
884 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1) {
885 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
888 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
889 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
890 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
894 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
895 strcpy(pathBuffer
, wildcard
);
896 SendMessage(hList
, LB_RESETCONTENT
, 0, 0);
897 res
= SendMessage(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
898 ok (res
!= -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) failed err %u\n", GetLastError());
900 itemCount
= SendMessage(hList
, LB_GETCOUNT
, 0, 0);
901 ok (itemCount
== itemCount_allDirs
,
902 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
903 itemCount
, itemCount_allDirs
);
904 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) returned incorrect index!\n");
906 if (itemCount
&& GetCurrentDirectoryA( MAX_PATH
, pathBuffer
) > 3) /* there's no [..] in drive root */
908 memset(pathBuffer
, 0, MAX_PATH
);
909 SendMessage(hList
, LB_GETTEXT
, 0, (LPARAM
)pathBuffer
);
910 ok( !strcmp(pathBuffer
, "[..]"), "First element is not [..]\n");
913 /* This tests behavior when no files match the wildcard */
914 strcpy(pathBuffer
, BAD_EXTENSION
);
915 SendMessage(hList
, LB_RESETCONTENT
, 0, 0);
916 res
= SendMessage(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
917 ok (res
== -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
918 BAD_EXTENSION
, res
, -1);
920 itemCount
= SendMessage(hList
, LB_GETCOUNT
, 0, 0);
921 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
924 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
925 strcpy(pathBuffer
, "w*.c");
926 SendMessage(hList
, LB_RESETCONTENT
, 0, 0);
927 res
= SendMessage(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
928 ok (res
== LB_ERR
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, w*.c) returned %d expected %d\n", res
, LB_ERR
);
930 /* There should be no elements, since "[..]" does not fit w*.c */
931 itemCount
= SendMessage(hList
, LB_GETCOUNT
, 0, 0);
933 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
936 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
937 strcpy(pathBuffer
, wildcard
);
938 SendMessage(hList
, LB_RESETCONTENT
, 0, 0);
939 res
= SendMessage(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
940 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
942 /* There should be no plain files on the listbox */
943 itemCount
= SendMessage(hList
, LB_GETCOUNT
, 0, 0);
944 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
945 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
946 itemCount
, itemCount_justDrives
+ itemCount_allDirs
);
947 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
949 for (i
= 0; i
< itemCount
; i
++) {
950 memset(pathBuffer
, 0, MAX_PATH
);
952 SendMessage(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
953 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1) {
954 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
956 ok( pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']',
957 "Element %d (%s) does not fit expected [...]\n", i
, pathBuffer
);
961 /* This tests behavior when no files match the wildcard */
962 strcpy(pathBuffer
, BAD_EXTENSION
);
963 SendMessage(hList
, LB_RESETCONTENT
, 0, 0);
964 res
= SendMessage(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
965 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
966 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
968 itemCount
= SendMessage(hList
, LB_GETCOUNT
, 0, 0);
969 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
971 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
972 strcpy(pathBuffer
, "w*.c");
973 SendMessage(hList
, LB_RESETCONTENT
, 0, 0);
974 res
= SendMessage(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
975 ok (res
>= 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
977 /* There should be no plain files on the listbox, and no [..], since it does not fit w*.c */
978 itemCount
= SendMessage(hList
, LB_GETCOUNT
, 0, 0);
979 ok (itemCount
== itemCount_justDrives
,
980 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
981 itemCount
, itemCount_justDrives
);
982 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
984 for (i
= 0; i
< itemCount
; i
++) {
985 memset(pathBuffer
, 0, MAX_PATH
);
987 SendMessage(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
988 ok (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1, "Element %d (%s) does not fit [-X-]\n", i
, pathBuffer
);
989 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
991 DestroyWindow(hList
);
993 DeleteFileA( "wtest1.tmp.c" );
996 static HWND g_listBox
;
999 #define ID_TEST_LABEL 1001
1000 #define ID_TEST_LISTBOX 1002
1002 static BOOL
on_listbox_container_create (HWND hwnd
, LPCREATESTRUCT lpcs
)
1004 g_label
= CreateWindow(
1006 "Contents of static control before DlgDirList.",
1007 WS_CHILD
| WS_VISIBLE
,
1009 hwnd
, (HMENU
)ID_TEST_LABEL
, NULL
, 0);
1010 if (!g_label
) return FALSE
;
1011 g_listBox
= CreateWindow(
1014 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| WS_BORDER
| WS_VSCROLL
,
1016 hwnd
, (HMENU
)ID_TEST_LISTBOX
, NULL
, 0);
1017 if (!g_listBox
) return FALSE
;
1022 static LRESULT CALLBACK
listbox_container_window_procA (
1023 HWND hwnd
, UINT uiMsg
, WPARAM wParam
, LPARAM lParam
)
1032 result
= on_listbox_container_create(hwnd
, (LPCREATESTRUCTA
) lParam
)
1036 result
= DefWindowProcA (hwnd
, uiMsg
, wParam
, lParam
);
1042 static BOOL
RegisterListboxWindowClass(HINSTANCE hInst
)
1049 cls
.hInstance
= hInst
;
1051 cls
.hCursor
= LoadCursorA (NULL
, IDC_ARROW
);
1052 cls
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
1053 cls
.lpszMenuName
= NULL
;
1054 cls
.lpfnWndProc
= listbox_container_window_procA
;
1055 cls
.lpszClassName
= "ListboxContainerClass";
1056 if (!RegisterClassA (&cls
)) return FALSE
;
1061 static void test_listbox_dlgdir(void)
1066 int itemCount_allDirs
;
1067 int itemCount_justFiles
;
1068 int itemCount_justDrives
;
1070 char pathBuffer
[MAX_PATH
];
1071 char itemBuffer
[MAX_PATH
];
1072 char tempBuffer
[MAX_PATH
];
1077 file
= CreateFileA( "wtest1.tmp.c", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1078 ok(file
!= INVALID_HANDLE_VALUE
, "Error creating the test file: %d\n", GetLastError());
1079 CloseHandle( file
);
1081 /* NOTE: for this test to succeed, there must be no subdirectories
1082 under the current directory. In addition, there must be at least
1083 one file that fits the wildcard w*.c . Normally, the test
1084 directory itself satisfies both conditions.
1087 hInst
= GetModuleHandleA(0);
1088 if (!RegisterListboxWindowClass(hInst
)) assert(0);
1089 hWnd
= CreateWindow("ListboxContainerClass", "ListboxContainerClass",
1090 WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
1091 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
1092 NULL
, NULL
, hInst
, 0);
1095 /* Test for standard usage */
1097 /* The following should be overwritten by the directory path */
1098 SendMessage(g_label
, WM_SETTEXT
, 0, (LPARAM
)"default contents");
1100 /* This should list all the w*.c files in the test directory
1101 * As of this writing, this includes win.c, winstation.c, wsprintf.c
1103 strcpy(pathBuffer
, "w*.c");
1104 res
= DlgDirList(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, 0);
1105 ok (res
== 1, "DlgDirList(*.c, 0) returned %d - expected 1 - 0x%08x\n", res
, GetLastError());
1107 /* Path specification gets converted to uppercase */
1108 ok (!strcmp(pathBuffer
, "W*.C"),
1109 "expected conversion to uppercase, got %s\n", pathBuffer
);
1111 /* Loaded path should have overwritten the label text */
1112 SendMessage(g_label
, WM_GETTEXT
, MAX_PATH
, (LPARAM
)pathBuffer
);
1113 trace("Static control after DlgDirList: %s\n", pathBuffer
);
1114 ok (strcmp("default contents", pathBuffer
), "DlgDirList() did not modify static control!\n");
1116 /* There should be some content in the listbox */
1117 itemCount
= SendMessage(g_listBox
, LB_GETCOUNT
, 0, 0);
1118 ok (itemCount
> 0, "DlgDirList() did NOT fill the listbox!\n");
1119 itemCount_justFiles
= itemCount
;
1121 /* Every single item in the control should start with a w and end in .c */
1122 for (i
= 0; i
< itemCount
; i
++) {
1123 memset(pathBuffer
, 0, MAX_PATH
);
1124 SendMessage(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1125 p
= pathBuffer
+ strlen(pathBuffer
);
1126 ok(((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1127 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1128 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1131 /* Test behavior when no files match the wildcard */
1132 strcpy(pathBuffer
, BAD_EXTENSION
);
1133 res
= DlgDirList(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, 0);
1134 ok (res
== 1, "DlgDirList(%s, 0) returned %d expected 1\n", BAD_EXTENSION
, res
);
1136 itemCount
= SendMessage(g_listBox
, LB_GETCOUNT
, 0, 0);
1137 ok (itemCount
== 0, "DlgDirList() DID fill the listbox!\n");
1139 /* Test DDL_DIRECTORY */
1140 strcpy(pathBuffer
, "w*.c");
1141 res
= DlgDirList(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1143 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY) failed - 0x%08x\n", GetLastError());
1145 /* There should be some content in the listbox. In particular, there should
1146 * be exactly more elements than before, since the directories should
1149 itemCount
= SendMessage(g_listBox
, LB_GETCOUNT
, 0, 0);
1150 itemCount_allDirs
= itemCount
- itemCount_justFiles
;
1151 ok (itemCount
>= itemCount_justFiles
,
1152 "DlgDirList(DDL_DIRECTORY) filled with %d entries, expected > %d\n",
1153 itemCount
, itemCount_justFiles
);
1155 /* Every single item in the control should start with a w and end in .c,
1156 * except for the "[..]" string, which should appear exactly as it is.
1158 for (i
= 0; i
< itemCount
; i
++) {
1159 memset(pathBuffer
, 0, MAX_PATH
);
1160 SendMessage(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1161 p
= pathBuffer
+ strlen(pathBuffer
);
1162 ok( (pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']') ||
1163 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1164 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1165 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1168 /* Test behavior when no files match the wildcard */
1169 strcpy(pathBuffer
, BAD_EXTENSION
);
1170 res
= DlgDirList(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1172 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY) returned %d expected 1\n", BAD_EXTENSION
, res
);
1174 itemCount
= SendMessage(g_listBox
, LB_GETCOUNT
, 0, 0);
1175 ok (itemCount
== itemCount_allDirs
,
1176 "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
1177 itemCount_allDirs
, itemCount
);
1178 for (i
= 0; i
< itemCount
; i
++) {
1179 memset(pathBuffer
, 0, MAX_PATH
);
1180 SendMessage(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1181 ok( pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']',
1182 "Element %d (%s) does not fit requested [...]\n", i
, pathBuffer
);
1186 /* Test DDL_DRIVES. At least on WinXP-SP2, this implies DDL_EXCLUSIVE */
1187 strcpy(pathBuffer
, "w*.c");
1188 res
= DlgDirList(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1190 ok (res
== 1, "DlgDirList(*.c, DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1192 /* There should be some content in the listbox. In particular, there should
1193 * be at least one element before, since the string "[-c-]" should
1194 * have been added. Depending on the user setting, more drives might have
1197 itemCount
= SendMessage(g_listBox
, LB_GETCOUNT
, 0, 0);
1199 "DlgDirList(DDL_DRIVES) filled with %d entries, expected at least %d\n",
1201 itemCount_justDrives
= itemCount
;
1203 /* Every single item in the control should fit the format [-c-] */
1204 for (i
= 0; i
< itemCount
; i
++) {
1205 memset(pathBuffer
, 0, MAX_PATH
);
1207 SendMessage(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1208 ok( strlen(pathBuffer
) == 5, "Length of drive string is not 5\n" );
1209 ok( sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1, "Element %d (%s) does not fit [-X-]\n", i
, pathBuffer
);
1210 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1211 if (!(driveletter
>= 'a' && driveletter
<= 'z')) {
1212 /* Correct after invalid entry is found */
1213 trace("removing count of invalid entry %s\n", pathBuffer
);
1214 itemCount_justDrives
--;
1218 /* Test behavior when no files match the wildcard */
1219 strcpy(pathBuffer
, BAD_EXTENSION
);
1220 res
= DlgDirList(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1222 ok (res
== 1, "DlgDirList(%s, DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION
, res
);
1224 itemCount
= SendMessage(g_listBox
, LB_GETCOUNT
, 0, 0);
1225 ok (itemCount
== itemCount_justDrives
, "DlgDirList() incorrectly filled the listbox!\n");
1228 /* Test DDL_DIRECTORY|DDL_DRIVES. This does *not* imply DDL_EXCLUSIVE */
1229 strcpy(pathBuffer
, "w*.c");
1230 res
= DlgDirList(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1231 DDL_DIRECTORY
|DDL_DRIVES
);
1232 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1234 /* There should be some content in the listbox. In particular, there should
1235 * be exactly the number of plain files, plus the number of mapped drives,
1238 itemCount
= SendMessage(g_listBox
, LB_GETCOUNT
, 0, 0);
1239 ok (itemCount
== itemCount_justFiles
+ itemCount_justDrives
+ itemCount_allDirs
,
1240 "DlgDirList(DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1241 itemCount
, itemCount_justFiles
+ itemCount_justDrives
+ itemCount_allDirs
);
1243 /* Every single item in the control should start with a w and end in .c,
1244 * except for the "[..]" string, which should appear exactly as it is,
1245 * and the mapped drives in the format "[-X-]".
1247 for (i
= 0; i
< itemCount
; i
++) {
1248 memset(pathBuffer
, 0, MAX_PATH
);
1250 SendMessage(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1251 p
= pathBuffer
+ strlen(pathBuffer
);
1252 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1) {
1253 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1255 ok( (pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']') ||
1256 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1257 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1258 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1262 /* Test behavior when no files match the wildcard */
1263 strcpy(pathBuffer
, BAD_EXTENSION
);
1264 res
= DlgDirList(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1265 DDL_DIRECTORY
|DDL_DRIVES
);
1266 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION
, res
);
1268 itemCount
= SendMessage(g_listBox
, LB_GETCOUNT
, 0, 0);
1269 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
1270 "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
1271 itemCount_justDrives
+ itemCount_allDirs
, itemCount
);
1275 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1276 strcpy(pathBuffer
, "w*.c");
1277 res
= DlgDirList(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1278 DDL_DIRECTORY
|DDL_EXCLUSIVE
);
1279 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_EXCLUSIVE) failed - 0x%08x\n", GetLastError());
1281 /* There should be exactly one element: "[..]" */
1282 itemCount
= SendMessage(g_listBox
, LB_GETCOUNT
, 0, 0);
1283 ok (itemCount
== itemCount_allDirs
,
1284 "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1285 itemCount
, itemCount_allDirs
);
1287 if (itemCount
&& GetCurrentDirectoryA( MAX_PATH
, pathBuffer
) > 3) /* there's no [..] in drive root */
1289 memset(pathBuffer
, 0, MAX_PATH
);
1290 SendMessage(g_listBox
, LB_GETTEXT
, 0, (LPARAM
)pathBuffer
);
1291 ok( !strcmp(pathBuffer
, "[..]"), "First (and only) element is not [..]\n");
1294 /* Test behavior when no files match the wildcard */
1295 strcpy(pathBuffer
, BAD_EXTENSION
);
1296 res
= DlgDirList(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1297 DDL_DIRECTORY
|DDL_EXCLUSIVE
);
1298 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION
, res
);
1300 itemCount
= SendMessage(g_listBox
, LB_GETCOUNT
, 0, 0);
1301 ok (itemCount
== itemCount_allDirs
, "DlgDirList() incorrectly filled the listbox!\n");
1304 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1305 strcpy(pathBuffer
, "w*.c");
1306 res
= DlgDirList(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1307 DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
);
1308 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) failed - 0x%08x\n", GetLastError());
1310 /* There should be no plain files on the listbox */
1311 itemCount
= SendMessage(g_listBox
, LB_GETCOUNT
, 0, 0);
1312 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
1313 "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1314 itemCount
, itemCount_justDrives
+ itemCount_allDirs
);
1316 for (i
= 0; i
< itemCount
; i
++) {
1317 memset(pathBuffer
, 0, MAX_PATH
);
1319 SendMessage(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1320 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1) {
1321 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1323 ok( pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']',
1324 "Element %d (%s) does not fit expected [...]\n", i
, pathBuffer
);
1328 /* Test behavior when no files match the wildcard */
1329 strcpy(pathBuffer
, BAD_EXTENSION
);
1330 res
= DlgDirList(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1331 DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
);
1332 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION
, res
);
1334 itemCount
= SendMessage(g_listBox
, LB_GETCOUNT
, 0, 0);
1335 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
1336 "DlgDirList() incorrectly filled the listbox!\n");
1338 /* Now test DlgDirSelectEx() in normal operation */
1339 /* Fill with everything - drives, directory and all plain files. */
1340 strcpy(pathBuffer
, "*");
1341 res
= DlgDirList(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
,
1342 DDL_DIRECTORY
|DDL_DRIVES
);
1343 ok (res
!= 0, "DlgDirList(*, DDL_DIRECTORY|DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1345 SendMessage(g_listBox
, LB_SETCURSEL
, -1, 0); /* Unselect any current selection */
1346 memset(pathBuffer
, 0, MAX_PATH
);
1347 SetLastError(0xdeadbeef);
1348 res
= DlgDirSelectEx(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1349 ok (GetLastError() == 0xdeadbeef,
1350 "DlgDirSelectEx() with no selection modified last error code from 0xdeadbeef to 0x%08x\n",
1352 ok (res
== 0, "DlgDirSelectEx() with no selection returned %d, expected 0\n", res
);
1353 /* WinXP-SP2 leaves pathBuffer untouched, but Win98 fills it with garbage. */
1355 ok (strlen(pathBuffer) == 0, "DlgDirSelectEx() with no selection filled buffer with %s\n", pathBuffer);
1357 /* Test proper drive/dir/file recognition */
1358 itemCount
= SendMessage(g_listBox
, LB_GETCOUNT
, 0, 0);
1359 for (i
= 0; i
< itemCount
; i
++) {
1360 memset(itemBuffer
, 0, MAX_PATH
);
1361 memset(pathBuffer
, 0, MAX_PATH
);
1362 memset(tempBuffer
, 0, MAX_PATH
);
1364 SendMessage(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)itemBuffer
);
1365 res
= SendMessage(g_listBox
, LB_SETCURSEL
, i
, 0);
1366 ok (res
== i
, "SendMessage(LB_SETCURSEL, %d) failed\n", i
);
1367 if (sscanf(itemBuffer
, "[-%c-]", &driveletter
) == 1) {
1368 /* Current item is a drive letter */
1369 SetLastError(0xdeadbeef);
1370 res
= DlgDirSelectEx(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1371 ok (GetLastError() == 0xdeadbeef,
1372 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1374 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1376 /* For drive letters, DlgDirSelectEx tacks on a colon */
1377 ok (pathBuffer
[0] == driveletter
&& pathBuffer
[1] == ':' && pathBuffer
[2] == '\0',
1378 "%d: got \"%s\" expected \"%c:\"\n", i
, pathBuffer
, driveletter
);
1379 } else if (itemBuffer
[0] == '[') {
1380 /* Current item is the parent directory */
1381 SetLastError(0xdeadbeef);
1382 res
= DlgDirSelectEx(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1383 ok (GetLastError() == 0xdeadbeef,
1384 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1386 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1388 /* For directories, DlgDirSelectEx tacks on a backslash */
1389 p
= pathBuffer
+ strlen(pathBuffer
);
1390 ok (*(p
-1) == '\\', "DlgDirSelectEx did NOT tack on a backslash to dir, got %s\n", pathBuffer
);
1392 tempBuffer
[0] = '[';
1393 strncpy(tempBuffer
+ 1, pathBuffer
, strlen(pathBuffer
) - 1);
1394 strcat(tempBuffer
, "]");
1395 ok (!strcmp(tempBuffer
, itemBuffer
), "Formatted directory should be %s, got %s\n", tempBuffer
, itemBuffer
);
1397 /* Current item is a plain file */
1398 SetLastError(0xdeadbeef);
1399 res
= DlgDirSelectEx(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1400 ok (GetLastError() == 0xdeadbeef,
1401 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1403 ok(res
== 0, "DlgDirSelectEx() thinks %s (%s) is a drive/directory!\n", itemBuffer
, pathBuffer
);
1405 /* NOTE: WinXP tacks a period on all files that lack an extension. This affects
1406 * for example, "Makefile", which gets reported as "Makefile."
1408 strcpy(tempBuffer
, itemBuffer
);
1409 if (strchr(tempBuffer
, '.') == NULL
) strcat(tempBuffer
, ".");
1410 ok (!strcmp(pathBuffer
, tempBuffer
), "Formatted file should be %s, got %s\n", tempBuffer
, pathBuffer
);
1414 DeleteFileA( "wtest1.tmp.c" );
1416 /* Now test DlgDirSelectEx() in abnormal operation */
1417 /* Fill list with bogus entries, that look somewhat valid */
1418 SendMessage(g_listBox
, LB_RESETCONTENT
, 0, 0);
1419 SendMessage(g_listBox
, LB_ADDSTRING
, 0, (LPARAM
)"[notexist.dir]");
1420 SendMessage(g_listBox
, LB_ADDSTRING
, 0, (LPARAM
)"notexist.fil");
1421 itemCount
= SendMessage(g_listBox
, LB_GETCOUNT
, 0, 0);
1422 for (i
= 0; i
< itemCount
; i
++) {
1423 memset(itemBuffer
, 0, MAX_PATH
);
1424 memset(pathBuffer
, 0, MAX_PATH
);
1425 memset(tempBuffer
, 0, MAX_PATH
);
1427 SendMessage(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)itemBuffer
);
1428 res
= SendMessage(g_listBox
, LB_SETCURSEL
, i
, 0);
1429 ok (res
== i
, "SendMessage(LB_SETCURSEL, %d) failed\n", i
);
1430 if (sscanf(itemBuffer
, "[-%c-]", &driveletter
) == 1) {
1431 /* Current item is a drive letter */
1432 SetLastError(0xdeadbeef);
1433 res
= DlgDirSelectEx(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1434 ok (GetLastError() == 0xdeadbeef,
1435 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1437 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1439 /* For drive letters, DlgDirSelectEx tacks on a colon */
1440 ok (pathBuffer
[0] == driveletter
&& pathBuffer
[1] == ':' && pathBuffer
[2] == '\0',
1441 "%d: got \"%s\" expected \"%c:\"\n", i
, pathBuffer
, driveletter
);
1442 } else if (itemBuffer
[0] == '[') {
1443 /* Current item is the parent directory */
1444 SetLastError(0xdeadbeef);
1445 res
= DlgDirSelectEx(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1446 ok (GetLastError() == 0xdeadbeef,
1447 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1449 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1451 /* For directories, DlgDirSelectEx tacks on a backslash */
1452 p
= pathBuffer
+ strlen(pathBuffer
);
1453 ok (*(p
-1) == '\\', "DlgDirSelectEx did NOT tack on a backslash to dir, got %s\n", pathBuffer
);
1455 tempBuffer
[0] = '[';
1456 strncpy(tempBuffer
+ 1, pathBuffer
, strlen(pathBuffer
) - 1);
1457 strcat(tempBuffer
, "]");
1458 ok (!strcmp(tempBuffer
, itemBuffer
), "Formatted directory should be %s, got %s\n", tempBuffer
, itemBuffer
);
1460 /* Current item is a plain file */
1461 SetLastError(0xdeadbeef);
1462 res
= DlgDirSelectEx(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1463 ok (GetLastError() == 0xdeadbeef,
1464 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1466 ok(res
== 0, "DlgDirSelectEx() thinks %s (%s) is a drive/directory!\n", itemBuffer
, pathBuffer
);
1468 /* NOTE: WinXP and Win98 tack a period on all files that lack an extension.
1469 * This affects for example, "Makefile", which gets reported as "Makefile."
1471 strcpy(tempBuffer
, itemBuffer
);
1472 if (strchr(tempBuffer
, '.') == NULL
) strcat(tempBuffer
, ".");
1473 ok (!strcmp(pathBuffer
, tempBuffer
), "Formatted file should be %s, got %s\n", tempBuffer
, pathBuffer
);
1477 /* Test behavior when loading folders from root with and without wildcard */
1478 strcpy(pathBuffer
, "C:\\");
1479 res
= DlgDirList(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, 0, DDL_DIRECTORY
| DDL_EXCLUSIVE
);
1480 ok(res
|| broken(!res
) /* NT4/W2K */, "DlgDirList failed to list C:\\ folders\n");
1481 todo_wine
ok(!strcmp(pathBuffer
, "*") || broken(!res
) /* NT4/W2K */,
1482 "DlgDirList set the invalid path spec '%s', expected '*'\n", pathBuffer
);
1484 strcpy(pathBuffer
, "C:\\*");
1485 res
= DlgDirList(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, 0, DDL_DIRECTORY
| DDL_EXCLUSIVE
);
1486 ok(res
|| broken(!res
) /* NT4/W2K */, "DlgDirList failed to list C:\\* folders\n");
1487 ok(!strcmp(pathBuffer
, "*") || broken(!res
) /* NT4/W2K */,
1488 "DlgDirList set the invalid path spec '%s', expected '*'\n", pathBuffer
);
1490 /* Try loading files from an invalid folder */
1491 SetLastError(0xdeadbeef);
1492 strcpy(pathBuffer
, "C:\\INVALID$$DIR");
1493 res
= DlgDirList(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, 0, DDL_DIRECTORY
| DDL_EXCLUSIVE
);
1494 todo_wine
ok(!res
, "DlgDirList should have failed with 0 but %d was returned\n", res
);
1495 todo_wine
ok(GetLastError() == ERROR_NO_WILDCARD_CHARACTERS
,
1496 "GetLastError should return 0x589, got 0x%X\n",GetLastError());
1498 DestroyWindow(hWnd
);
1503 const struct listbox_test SS
=
1506 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
1507 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
1508 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
1509 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
1510 /* {selected, anchor, caret, selcount}{TODO fields} */
1511 const struct listbox_test SS_NS
=
1513 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
1514 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
1515 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
1516 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
1517 const struct listbox_test MS
=
1519 { 0, LB_ERR
, 0, 0}, {0,0,0,0},
1520 { 1, 1, 1, 1}, {0,0,0,0},
1521 { 2, 1, 2, 1}, {0,0,0,0},
1522 { 0, LB_ERR
, 0, 2}, {0,0,0,0}};
1523 const struct listbox_test MS_NS
=
1524 {{LBS_MULTIPLESEL
| LBS_NOSEL
},
1525 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
1526 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
1527 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
1528 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
1529 const struct listbox_test ES
=
1531 { 0, LB_ERR
, 0, 0}, {0,0,0,0},
1532 { 1, 1, 1, 1}, {0,0,0,0},
1533 { 2, 2, 2, 1}, {0,0,0,0},
1534 { 0, LB_ERR
, 0, 2}, {0,0,0,0}};
1535 const struct listbox_test ES_NS
=
1536 {{LBS_EXTENDEDSEL
| LBS_NOSEL
},
1537 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
1538 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
1539 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
1540 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
1541 const struct listbox_test EMS
=
1542 {{LBS_EXTENDEDSEL
| LBS_MULTIPLESEL
},
1543 { 0, LB_ERR
, 0, 0}, {0,0,0,0},
1544 { 1, 1, 1, 1}, {0,0,0,0},
1545 { 2, 2, 2, 1}, {0,0,0,0},
1546 { 0, LB_ERR
, 0, 2}, {0,0,0,0}};
1547 const struct listbox_test EMS_NS
=
1548 {{LBS_EXTENDEDSEL
| LBS_MULTIPLESEL
| LBS_NOSEL
},
1549 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
1550 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
1551 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
1552 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
1554 trace (" Testing single selection...\n");
1556 trace (" ... with NOSEL\n");
1558 trace (" Testing multiple selection...\n");
1560 trace (" ... with NOSEL\n");
1562 trace (" Testing extended selection...\n");
1564 trace (" ... with NOSEL\n");
1566 trace (" Testing extended and multiple selection...\n");
1568 trace (" ... with NOSEL\n");
1571 check_item_height();
1574 test_listbox_height();
1575 test_itemfrompoint();
1576 test_listbox_item_data();
1577 test_listbox_LB_DIR();
1578 test_listbox_dlgdir();