d3d11/tests: Add test for shaders interstage interface.
[wine.git] / dlls / user32 / tests / listbox.c
blob91d4675f839ce0312f7149e0801afdf69494b0c9
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
20 #include <assert.h>
21 #include <stdarg.h>
22 #include <stdio.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wingdi.h"
27 #include "winuser.h"
28 #include "winnls.h"
30 #include "wine/test.h"
32 #ifdef VISIBLE
33 #define WAIT Sleep (1000)
34 #define REDRAW RedrawWindow (handle, NULL, 0, RDW_UPDATENOW)
35 #else
36 #define WAIT
37 #define REDRAW
38 #endif
40 static const char * const strings[4] = {
41 "First added",
42 "Second added",
43 "Third added",
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 HWND
50 create_listbox (DWORD add_style, HWND parent)
52 HWND handle;
53 INT_PTR ctl_id=0;
54 if (parent)
55 ctl_id=1;
56 handle=CreateWindowA("LISTBOX", "TestList",
57 (LBS_STANDARD & ~LBS_SORT) | add_style,
58 0, 0, 100, 100,
59 parent, (HMENU)ctl_id, NULL, 0);
61 assert (handle);
62 SendMessageA(handle, LB_ADDSTRING, 0, (LPARAM) strings[0]);
63 SendMessageA(handle, LB_ADDSTRING, 0, (LPARAM) strings[1]);
64 SendMessageA(handle, LB_ADDSTRING, 0, (LPARAM) strings[2]);
65 SendMessageA(handle, LB_ADDSTRING, 0, (LPARAM) strings[3]);
67 #ifdef VISIBLE
68 ShowWindow (handle, SW_SHOW);
69 #endif
70 REDRAW;
72 return handle;
75 struct listbox_prop {
76 DWORD add_style;
79 struct listbox_stat {
80 int selected, anchor, caret, selcount;
83 struct listbox_test {
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;
91 static void
92 listbox_query (HWND handle, struct listbox_stat *results)
94 results->selected = SendMessageA(handle, LB_GETCURSEL, 0, 0);
95 results->anchor = SendMessageA(handle, LB_GETANCHORINDEX, 0, 0);
96 results->caret = SendMessageA(handle, LB_GETCARETINDEX, 0, 0);
97 results->selcount = SendMessageA(handle, LB_GETSELCOUNT, 0, 0);
100 static void
101 buttonpress (HWND handle, WORD x, WORD y)
103 LPARAM lp=x+(y<<16);
105 WAIT;
106 SendMessageA(handle, WM_LBUTTONDOWN, MK_LBUTTON, lp);
107 SendMessageA(handle, WM_LBUTTONUP, 0, lp);
108 REDRAW;
111 static void
112 keypress (HWND handle, WPARAM keycode, BYTE scancode, BOOL extended)
114 LPARAM lp=1+(scancode<<16)+(extended?KEYEVENTF_EXTENDEDKEY:0);
116 WAIT;
117 SendMessageA(handle, WM_KEYDOWN, keycode, lp);
118 SendMessageA(handle, WM_KEYUP , keycode, lp | 0xc000000);
119 REDRAW;
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, \
125 t.s.f, got.f)
127 #define listbox_todo_field_ok(t, s, f, got) \
128 todo_wine_if (t.s##_todo.f) { listbox_field_ok(t, s, f, got); }
130 #define listbox_ok(t, s, got) \
131 listbox_todo_field_ok(t, s, selected, got); \
132 listbox_todo_field_ok(t, s, anchor, got); \
133 listbox_todo_field_ok(t, s, caret, got); \
134 listbox_todo_field_ok(t, s, selcount, got)
136 static void
137 check (const struct listbox_test test)
139 struct listbox_stat answer;
140 HWND hLB=create_listbox (test.prop.add_style, 0);
141 RECT second_item;
142 int i;
143 int res;
145 listbox_query (hLB, &answer);
146 listbox_ok (test, init, answer);
148 SendMessageA(hLB, LB_GETITEMRECT, 1, (LPARAM) &second_item);
149 buttonpress(hLB, (WORD)second_item.left, (WORD)second_item.top);
151 listbox_query (hLB, &answer);
152 listbox_ok (test, click, answer);
154 keypress (hLB, VK_DOWN, 0x50, TRUE);
156 listbox_query (hLB, &answer);
157 listbox_ok (test, step, answer);
159 DestroyWindow (hLB);
160 hLB=create_listbox (test.prop.add_style, 0);
162 SendMessageA(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(1, 2));
163 listbox_query (hLB, &answer);
164 listbox_ok (test, sel, answer);
166 for (i=0;i<4;i++) {
167 DWORD size = SendMessageA(hLB, LB_GETTEXTLEN, i, 0);
168 CHAR *txt;
169 WCHAR *txtw;
170 int resA, resW;
172 txt = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, size+1);
173 resA=SendMessageA(hLB, LB_GETTEXT, i, (LPARAM)txt);
174 ok(!strcmp (txt, strings[i]), "returned string for item %d does not match %s vs %s\n", i, txt, strings[i]);
176 txtw = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, 2*size+2);
177 resW=SendMessageW(hLB, LB_GETTEXT, i, (LPARAM)txtw);
178 if (resA != resW) {
179 trace("SendMessageW(LB_GETTEXT) not supported on this platform (resA=%d resW=%d), skipping...\n",
180 resA, resW);
181 } else {
182 WideCharToMultiByte( CP_ACP, 0, txtw, -1, txt, size, NULL, NULL );
183 ok(!strcmp (txt, strings[i]), "returned string for item %d does not match %s vs %s\n", i, txt, strings[i]);
186 HeapFree (GetProcessHeap(), 0, txtw);
187 HeapFree (GetProcessHeap(), 0, txt);
190 /* Confirm the count of items, and that an invalid delete does not remove anything */
191 res = SendMessageA(hLB, LB_GETCOUNT, 0, 0);
192 ok((res==4), "Expected 4 items, got %d\n", res);
193 res = SendMessageA(hLB, LB_DELETESTRING, -1, 0);
194 ok((res==LB_ERR), "Expected LB_ERR items, got %d\n", res);
195 res = SendMessageA(hLB, LB_DELETESTRING, 4, 0);
196 ok((res==LB_ERR), "Expected LB_ERR items, got %d\n", res);
197 res = SendMessageA(hLB, LB_GETCOUNT, 0, 0);
198 ok((res==4), "Expected 4 items, got %d\n", res);
200 WAIT;
201 DestroyWindow (hLB);
204 static void check_item_height(void)
206 HWND hLB;
207 HDC hdc;
208 HFONT font;
209 TEXTMETRICA tm;
210 INT itemHeight;
212 hLB = create_listbox (0, 0);
213 ok ((hdc = GetDCEx( hLB, 0, DCX_CACHE )) != 0, "Can't get hdc\n");
214 ok ((font = GetCurrentObject(hdc, OBJ_FONT)) != 0, "Can't get the current font\n");
215 ok (GetTextMetricsA( hdc, &tm ), "Can't read font metrics\n");
216 ReleaseDC( hLB, hdc);
218 ok (SendMessageA(hLB, WM_SETFONT, (WPARAM)font, 0) == 0, "Can't set font\n");
220 itemHeight = SendMessageA(hLB, LB_GETITEMHEIGHT, 0, 0);
221 ok (itemHeight == tm.tmHeight, "Item height wrong, got %d, expecting %d\n", itemHeight, tm.tmHeight);
223 DestroyWindow (hLB);
225 hLB = CreateWindowA("LISTBOX", "TestList", LBS_OWNERDRAWVARIABLE,
226 0, 0, 100, 100, NULL, NULL, NULL, 0);
227 itemHeight = SendMessageA(hLB, LB_GETITEMHEIGHT, 0, 0);
228 ok(itemHeight == tm.tmHeight, "itemHeight %d\n", itemHeight);
229 itemHeight = SendMessageA(hLB, LB_GETITEMHEIGHT, 5, 0);
230 ok(itemHeight == tm.tmHeight, "itemHeight %d\n", itemHeight);
231 itemHeight = SendMessageA(hLB, LB_GETITEMHEIGHT, -5, 0);
232 ok(itemHeight == tm.tmHeight, "itemHeight %d\n", itemHeight);
233 DestroyWindow (hLB);
236 static int got_selchange;
238 static LRESULT WINAPI main_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
240 switch (msg)
242 case WM_DRAWITEM:
244 RECT rc_item, rc_client, rc_clip;
245 DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lparam;
247 trace("%p WM_DRAWITEM %08lx %08lx\n", hwnd, wparam, lparam);
249 ok(wparam == dis->CtlID, "got wParam=%08lx instead of %08x\n",
250 wparam, dis->CtlID);
251 ok(dis->CtlType == ODT_LISTBOX, "wrong CtlType %04x\n", dis->CtlType);
253 GetClientRect(dis->hwndItem, &rc_client);
254 trace("hwndItem %p client rect %s\n", dis->hwndItem, wine_dbgstr_rect(&rc_client));
255 GetClipBox(dis->hDC, &rc_clip);
256 trace("clip rect %s\n", wine_dbgstr_rect(&rc_clip));
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 %s\n", wine_dbgstr_rect(&dis->rcItem));
262 SendMessageA(dis->hwndItem, LB_GETITEMRECT, dis->itemID, (LPARAM)&rc_item);
263 trace("item rect %s\n", wine_dbgstr_rect(&rc_item));
264 ok(EqualRect(&dis->rcItem, &rc_item), "item rects are not equal\n");
266 break;
269 case WM_COMMAND:
270 if (HIWORD( wparam ) == LBN_SELCHANGE) got_selchange++;
271 break;
273 default:
274 break;
277 return DefWindowProcA(hwnd, msg, wparam, lparam);
280 static HWND create_parent( void )
282 WNDCLASSA cls;
283 HWND parent;
284 static ATOM class;
286 if (!class)
288 cls.style = 0;
289 cls.lpfnWndProc = main_window_proc;
290 cls.cbClsExtra = 0;
291 cls.cbWndExtra = 0;
292 cls.hInstance = GetModuleHandleA(NULL);
293 cls.hIcon = 0;
294 cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
295 cls.hbrBackground = GetStockObject(WHITE_BRUSH);
296 cls.lpszMenuName = NULL;
297 cls.lpszClassName = "main_window_class";
298 class = RegisterClassA( &cls );
301 parent = CreateWindowExA(0, "main_window_class", NULL,
302 WS_POPUP | WS_VISIBLE,
303 100, 100, 400, 400,
304 GetDesktopWindow(), 0,
305 GetModuleHandleA(NULL), NULL);
306 return parent;
309 static void test_ownerdraw(void)
311 HWND parent, hLB;
312 INT ret;
313 RECT rc;
315 parent = create_parent();
316 assert(parent);
318 hLB = create_listbox(LBS_OWNERDRAWFIXED | WS_CHILD | WS_VISIBLE, parent);
319 assert(hLB);
321 SetForegroundWindow(hLB);
322 UpdateWindow(hLB);
324 /* make height short enough */
325 SendMessageA(hLB, LB_GETITEMRECT, 0, (LPARAM)&rc);
326 SetWindowPos(hLB, 0, 0, 0, 100, rc.bottom - rc.top + 1,
327 SWP_NOZORDER | SWP_NOMOVE);
329 /* make 0 item invisible */
330 SendMessageA(hLB, LB_SETTOPINDEX, 1, 0);
331 ret = SendMessageA(hLB, LB_GETTOPINDEX, 0, 0);
332 ok(ret == 1, "wrong top index %d\n", ret);
334 SendMessageA(hLB, LB_GETITEMRECT, 0, (LPARAM)&rc);
335 trace("item 0 rect %s\n", wine_dbgstr_rect(&rc));
336 ok(!IsRectEmpty(&rc), "empty item rect\n");
337 ok(rc.top < 0, "rc.top is not negative (%d)\n", rc.top);
339 DestroyWindow(hLB);
340 DestroyWindow(parent);
343 #define listbox_test_query(exp, got) \
344 ok(exp.selected == got.selected, "expected selected %d, got %d\n", exp.selected, got.selected); \
345 ok(exp.anchor == got.anchor, "expected anchor %d, got %d\n", exp.anchor, got.anchor); \
346 ok(exp.caret == got.caret, "expected caret %d, got %d\n", exp.caret, got.caret); \
347 ok(exp.selcount == got.selcount, "expected selcount %d, got %d\n", exp.selcount, got.selcount);
349 static void test_LB_SELITEMRANGE(void)
351 static const struct listbox_stat test_nosel = { 0, LB_ERR, 0, 0 };
352 static const struct listbox_stat test_1 = { 0, LB_ERR, 0, 2 };
353 static const struct listbox_stat test_2 = { 0, LB_ERR, 0, 3 };
354 static const struct listbox_stat test_3 = { 0, LB_ERR, 0, 4 };
355 HWND hLB;
356 struct listbox_stat answer;
357 INT ret;
359 trace("testing LB_SELITEMRANGE\n");
361 hLB = create_listbox(LBS_EXTENDEDSEL, 0);
362 assert(hLB);
364 listbox_query(hLB, &answer);
365 listbox_test_query(test_nosel, answer);
367 ret = SendMessageA(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(1, 2));
368 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
369 listbox_query(hLB, &answer);
370 listbox_test_query(test_1, answer);
372 SendMessageA(hLB, LB_SETSEL, FALSE, -1);
373 listbox_query(hLB, &answer);
374 listbox_test_query(test_nosel, answer);
376 ret = SendMessageA(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(0, 4));
377 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
378 listbox_query(hLB, &answer);
379 listbox_test_query(test_3, answer);
381 SendMessageA(hLB, LB_SETSEL, FALSE, -1);
382 listbox_query(hLB, &answer);
383 listbox_test_query(test_nosel, answer);
385 ret = SendMessageA(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(-5, 5));
386 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
387 listbox_query(hLB, &answer);
388 listbox_test_query(test_nosel, answer);
390 SendMessageA(hLB, LB_SETSEL, FALSE, -1);
391 listbox_query(hLB, &answer);
392 listbox_test_query(test_nosel, answer);
394 ret = SendMessageA(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(2, 10));
395 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
396 listbox_query(hLB, &answer);
397 listbox_test_query(test_1, answer);
399 SendMessageA(hLB, LB_SETSEL, FALSE, -1);
400 listbox_query(hLB, &answer);
401 listbox_test_query(test_nosel, answer);
403 ret = SendMessageA(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(4, 10));
404 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
405 listbox_query(hLB, &answer);
406 listbox_test_query(test_nosel, answer);
408 SendMessageA(hLB, LB_SETSEL, FALSE, -1);
409 listbox_query(hLB, &answer);
410 listbox_test_query(test_nosel, answer);
412 ret = SendMessageA(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(10, 1));
413 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
414 listbox_query(hLB, &answer);
415 listbox_test_query(test_2, answer);
417 SendMessageA(hLB, LB_SETSEL, FALSE, -1);
418 listbox_query(hLB, &answer);
419 listbox_test_query(test_nosel, answer);
421 ret = SendMessageA(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(1, -1));
422 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
423 listbox_query(hLB, &answer);
424 listbox_test_query(test_2, answer);
426 DestroyWindow(hLB);
429 static void test_LB_SETCURSEL(void)
431 HWND parent, hLB;
432 INT ret;
434 trace("testing LB_SETCURSEL\n");
436 parent = create_parent();
437 assert(parent);
439 hLB = create_listbox(LBS_NOINTEGRALHEIGHT | WS_CHILD, parent);
440 assert(hLB);
442 SendMessageA(hLB, LB_SETITEMHEIGHT, 0, 32);
444 ret = SendMessageA(hLB, LB_SETCURSEL, 2, 0);
445 ok(ret == 2, "LB_SETCURSEL returned %d instead of 2\n", ret);
446 ret = GetScrollPos(hLB, SB_VERT);
447 ok(ret == 0, "expected vscroll 0, got %d\n", ret);
449 ret = SendMessageA(hLB, LB_SETCURSEL, 3, 0);
450 ok(ret == 3, "LB_SETCURSEL returned %d instead of 3\n", ret);
451 ret = GetScrollPos(hLB, SB_VERT);
452 ok(ret == 1, "expected vscroll 1, got %d\n", ret);
454 DestroyWindow(hLB);
457 static void test_listbox_height(void)
459 HWND hList;
460 int r, id;
462 hList = CreateWindowA( "ListBox", "list test", 0,
463 1, 1, 600, 100, NULL, NULL, NULL, NULL );
464 ok( hList != NULL, "failed to create listbox\n");
466 id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi");
467 ok( id == 0, "item id wrong\n");
469 r = SendMessageA( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 20, 0 ));
470 ok( r == 0, "send message failed\n");
472 r = SendMessageA(hList, LB_GETITEMHEIGHT, 0, 0 );
473 ok( r == 20, "height wrong\n");
475 r = SendMessageA( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 0, 30 ));
476 ok( r == -1, "send message failed\n");
478 r = SendMessageA(hList, LB_GETITEMHEIGHT, 0, 0 );
479 ok( r == 20, "height wrong\n");
481 r = SendMessageA( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 0x100, 0 ));
482 ok( r == -1, "send message failed\n");
484 r = SendMessageA(hList, LB_GETITEMHEIGHT, 0, 0 );
485 ok( r == 20, "height wrong\n");
487 r = SendMessageA( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 0xff, 0 ));
488 ok( r == 0, "send message failed\n");
490 r = SendMessageA(hList, LB_GETITEMHEIGHT, 0, 0 );
491 ok( r == 0xff, "height wrong\n");
493 DestroyWindow( hList );
496 static void test_itemfrompoint(void)
498 /* WS_POPUP is required in order to have a more accurate size calculation (
499 without caption). LBS_NOINTEGRALHEIGHT is required in order to test
500 behavior of partially-displayed item.
502 HWND hList = CreateWindowA( "ListBox", "list test",
503 WS_VISIBLE|WS_POPUP|LBS_NOINTEGRALHEIGHT,
504 1, 1, 600, 100, NULL, NULL, NULL, NULL );
505 ULONG r, id;
506 RECT rc;
508 /* For an empty listbox win2k returns 0x1ffff, win98 returns 0x10000, nt4 returns 0xffffffff */
509 r = SendMessageA(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
510 ok( r == 0x1ffff || r == 0x10000 || r == 0xffffffff, "ret %x\n", r );
512 r = SendMessageA(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( 700, 30 ));
513 ok( r == 0x1ffff || r == 0x10000 || r == 0xffffffff, "ret %x\n", r );
515 r = SendMessageA(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( 30, 300 ));
516 ok( r == 0x1ffff || r == 0x10000 || r == 0xffffffff, "ret %x\n", r );
518 id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi");
519 ok( id == 0, "item id wrong\n");
520 id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi1");
521 ok( id == 1, "item id wrong\n");
523 r = SendMessageA(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
524 ok( r == 0x1, "ret %x\n", r );
526 r = SendMessageA(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 601 ));
527 ok( r == 0x10001 || broken(r == 1), /* nt4 */
528 "ret %x\n", r );
530 /* Resize control so that below assertions about sizes are valid */
531 r = SendMessageA( hList, LB_GETITEMRECT, 0, (LPARAM)&rc);
532 ok( r == 1, "ret %x\n", r);
533 r = MoveWindow(hList, 1, 1, 600, (rc.bottom - rc.top + 1) * 9 / 2, TRUE);
534 ok( r != 0, "ret %x\n", r);
536 id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi2");
537 ok( id == 2, "item id wrong\n");
538 id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi3");
539 ok( id == 3, "item id wrong\n");
540 id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi4");
541 ok( id == 4, "item id wrong\n");
542 id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi5");
543 ok( id == 5, "item id wrong\n");
544 id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi6");
545 ok( id == 6, "item id wrong\n");
546 id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi7");
547 ok( id == 7, "item id wrong\n");
549 /* Set the listbox up so that id 1 is at the top, this leaves 5
550 partially visible at the bottom and 6, 7 are invisible */
552 SendMessageA( hList, LB_SETTOPINDEX, 1, 0);
553 r = SendMessageA( hList, LB_GETTOPINDEX, 0, 0);
554 ok( r == 1, "top %d\n", r);
556 r = SendMessageA( hList, LB_GETITEMRECT, 5, (LPARAM)&rc);
557 ok( r == 1, "ret %x\n", r);
558 r = SendMessageA( hList, LB_GETITEMRECT, 6, (LPARAM)&rc);
559 ok( r == 0, "ret %x\n", r);
561 r = SendMessageA( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(/* x */ 10, /* y */ 10) );
562 ok( r == 1, "ret %x\n", r);
564 r = SendMessageA( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(1000, 10) );
565 ok( r == 0x10001 || broken(r == 1), /* nt4 */
566 "ret %x\n", r );
568 r = SendMessageA( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, -10) );
569 ok( r == 0x10001 || broken(r == 1), /* nt4 */
570 "ret %x\n", r );
572 r = SendMessageA( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, 100) );
573 ok( r == 0x10005 || broken(r == 5), /* nt4 */
574 "item %x\n", r );
576 r = SendMessageA( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, 200) );
577 ok( r == 0x10005 || broken(r == 5), /* nt4 */
578 "item %x\n", r );
580 DestroyWindow( hList );
583 static void test_listbox_item_data(void)
585 HWND hList;
586 int r, id;
588 hList = CreateWindowA( "ListBox", "list test", 0,
589 1, 1, 600, 100, NULL, NULL, NULL, NULL );
590 ok( hList != NULL, "failed to create listbox\n");
592 id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi");
593 ok( id == 0, "item id wrong\n");
595 r = SendMessageA( hList, LB_SETITEMDATA, 0, MAKELPARAM( 20, 0 ));
596 ok(r == TRUE, "LB_SETITEMDATA returned %d instead of TRUE\n", r);
598 r = SendMessageA( hList, LB_GETITEMDATA, 0, 0);
599 ok( r == 20, "get item data failed\n");
601 DestroyWindow( hList );
604 static void test_listbox_LB_DIR(void)
606 HWND hList;
607 int res, itemCount;
608 int itemCount_justFiles;
609 int itemCount_justDrives;
610 int itemCount_allFiles;
611 int itemCount_allDirs;
612 int i;
613 char pathBuffer[MAX_PATH];
614 char * p;
615 char driveletter;
616 const char *wildcard = "*";
617 HANDLE file;
619 file = CreateFileA( "wtest1.tmp.c", GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL );
620 ok(file != INVALID_HANDLE_VALUE, "Error creating the test file: %d\n", GetLastError());
621 CloseHandle( file );
623 /* NOTE: for this test to succeed, there must be no subdirectories
624 under the current directory. In addition, there must be at least
625 one file that fits the wildcard w*.c . Normally, the test
626 directory itself satisfies both conditions.
628 hList = CreateWindowA( "ListBox", "list test", WS_VISIBLE|WS_POPUP,
629 1, 1, 600, 100, NULL, NULL, NULL, NULL );
630 assert(hList);
632 /* Test for standard usage */
634 /* This should list all the files in the test directory. */
635 strcpy(pathBuffer, wildcard);
636 SendMessageA(hList, LB_RESETCONTENT, 0, 0);
637 res = SendMessageA(hList, LB_DIR, 0, (LPARAM)pathBuffer);
638 if (res == -1) /* "*" wildcard doesn't work on win9x */
640 wildcard = "*.*";
641 strcpy(pathBuffer, wildcard);
642 res = SendMessageA(hList, LB_DIR, 0, (LPARAM)pathBuffer);
644 ok (res >= 0, "SendMessage(LB_DIR, 0, *) failed - 0x%08x\n", GetLastError());
646 /* There should be some content in the listbox */
647 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
648 ok (itemCount > 0, "SendMessage(LB_DIR) did NOT fill the listbox!\n");
649 itemCount_allFiles = itemCount;
650 ok(res + 1 == itemCount,
651 "SendMessage(LB_DIR, 0, *) returned incorrect index (expected %d got %d)!\n",
652 itemCount - 1, res);
654 /* This tests behavior when no files match the wildcard */
655 strcpy(pathBuffer, BAD_EXTENSION);
656 SendMessageA(hList, LB_RESETCONTENT, 0, 0);
657 res = SendMessageA(hList, LB_DIR, 0, (LPARAM)pathBuffer);
658 ok (res == -1, "SendMessage(LB_DIR, 0, %s) returned %d, expected -1\n", BAD_EXTENSION, res);
660 /* There should be NO content in the listbox */
661 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
662 ok (itemCount == 0, "SendMessage(LB_DIR) DID fill the listbox!\n");
665 /* This should list all the w*.c files in the test directory
666 * As of this writing, this includes win.c, winstation.c, wsprintf.c
668 strcpy(pathBuffer, "w*.c");
669 SendMessageA(hList, LB_RESETCONTENT, 0, 0);
670 res = SendMessageA(hList, LB_DIR, 0, (LPARAM)pathBuffer);
671 ok (res >= 0, "SendMessage(LB_DIR, 0, w*.c) failed - 0x%08x\n", GetLastError());
673 /* Path specification does NOT converted to uppercase */
674 ok (!strcmp(pathBuffer, "w*.c"),
675 "expected no change to pathBuffer, got %s\n", pathBuffer);
677 /* There should be some content in the listbox */
678 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
679 ok (itemCount > 0, "SendMessage(LB_DIR) did NOT fill the listbox!\n");
680 itemCount_justFiles = itemCount;
681 ok(res + 1 == itemCount,
682 "SendMessage(LB_DIR, 0, w*.c) returned incorrect index (expected %d got %d)!\n",
683 itemCount - 1, res);
685 /* Every single item in the control should start with a w and end in .c */
686 for (i = 0; i < itemCount; i++) {
687 memset(pathBuffer, 0, MAX_PATH);
688 SendMessageA(hList, LB_GETTEXT, i, (LPARAM)pathBuffer);
689 p = pathBuffer + strlen(pathBuffer);
690 ok(((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
691 (*(p-1) == 'c' || *(p-1) == 'C') &&
692 (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
695 /* Test DDL_DIRECTORY */
696 strcpy(pathBuffer, wildcard);
697 SendMessageA(hList, LB_RESETCONTENT, 0, 0);
698 res = SendMessageA(hList, LB_DIR, DDL_DIRECTORY, (LPARAM)pathBuffer);
699 ok (res > 0, "SendMessage(LB_DIR, DDL_DIRECTORY, *) failed - 0x%08x\n", GetLastError());
701 /* There should be some content in the listbox.
702 * All files plus "[..]"
704 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
705 itemCount_allDirs = itemCount - itemCount_allFiles;
706 ok (itemCount > itemCount_allFiles,
707 "SendMessage(LB_DIR, DDL_DIRECTORY, *) filled with %d entries, expected > %d\n",
708 itemCount, itemCount_allFiles);
709 ok(res + 1 == itemCount,
710 "SendMessage(LB_DIR, DDL_DIRECTORY, *) returned incorrect index (expected %d got %d)!\n",
711 itemCount - 1, res);
713 /* This tests behavior when no files match the wildcard */
714 strcpy(pathBuffer, BAD_EXTENSION);
715 SendMessageA(hList, LB_RESETCONTENT, 0, 0);
716 res = SendMessageA(hList, LB_DIR, DDL_DIRECTORY, (LPARAM)pathBuffer);
717 ok (res == -1, "SendMessage(LB_DIR, DDL_DIRECTORY, %s) returned %d, expected -1\n", BAD_EXTENSION, res);
719 /* There should be NO content in the listbox */
720 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
721 ok (itemCount == 0, "SendMessage(LB_DIR) DID fill the listbox!\n");
724 /* Test DDL_DIRECTORY */
725 strcpy(pathBuffer, "w*.c");
726 SendMessageA(hList, LB_RESETCONTENT, 0, 0);
727 res = SendMessageA(hList, LB_DIR, DDL_DIRECTORY, (LPARAM)pathBuffer);
728 ok (res >= 0, "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) failed - 0x%08x\n", GetLastError());
730 /* There should be some content in the listbox. Since the parent directory does not
731 * fit w*.c, there should be exactly the same number of items as without DDL_DIRECTORY
733 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
734 ok (itemCount == itemCount_justFiles,
735 "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) filled with %d entries, expected %d\n",
736 itemCount, itemCount_justFiles);
737 ok(res + 1 == itemCount,
738 "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) returned incorrect index (expected %d got %d)!\n",
739 itemCount - 1, res);
741 /* Every single item in the control should start with a w and end in .c. */
742 for (i = 0; i < itemCount; i++) {
743 memset(pathBuffer, 0, MAX_PATH);
744 SendMessageA(hList, LB_GETTEXT, i, (LPARAM)pathBuffer);
745 p = pathBuffer + strlen(pathBuffer);
747 ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
748 (*(p-1) == 'c' || *(p-1) == 'C') &&
749 (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
753 /* Test DDL_DRIVES|DDL_EXCLUSIVE */
754 strcpy(pathBuffer, wildcard);
755 SendMessageA(hList, LB_RESETCONTENT, 0, 0);
756 res = SendMessageA(hList, LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, (LPARAM)pathBuffer);
757 ok (res >= 0, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) failed - 0x%08x\n", GetLastError());
759 /* There should be some content in the listbox. In particular, there should
760 * be at least one element before, since the string "[-c-]" should
761 * have been added. Depending on the user setting, more drives might have
762 * been added.
764 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
765 ok (itemCount >= 1,
766 "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) filled with %d entries, expected at least %d\n",
767 itemCount, 1);
768 itemCount_justDrives = itemCount;
769 ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) returned incorrect index!\n");
771 /* Every single item in the control should fit the format [-c-] */
772 for (i = 0; i < itemCount; i++) {
773 memset(pathBuffer, 0, MAX_PATH);
774 driveletter = '\0';
775 SendMessageA(hList, LB_GETTEXT, i, (LPARAM)pathBuffer);
776 ok( strlen(pathBuffer) == 5, "Length of drive string is not 5\n" );
777 ok( sscanf(pathBuffer, "[-%c-]", &driveletter) == 1, "Element %d (%s) does not fit [-X-]\n", i, pathBuffer);
778 ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
779 if (!(driveletter >= 'a' && driveletter <= 'z')) {
780 /* Correct after invalid entry is found */
781 trace("removing count of invalid entry %s\n", pathBuffer);
782 itemCount_justDrives--;
786 /* This tests behavior when no files match the wildcard */
787 strcpy(pathBuffer, BAD_EXTENSION);
788 SendMessageA(hList, LB_RESETCONTENT, 0, 0);
789 res = SendMessageA(hList, LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, (LPARAM)pathBuffer);
790 ok (res == itemCount_justDrives -1, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
791 BAD_EXTENSION, res, itemCount_justDrives -1);
793 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
794 ok (itemCount == itemCount_justDrives, "SendMessage(LB_DIR) returned %d expected %d\n",
795 itemCount, itemCount_justDrives);
797 trace("Files with w*.c: %d Mapped drives: %d Directories: 1\n",
798 itemCount_justFiles, itemCount_justDrives);
800 /* Test DDL_DRIVES. */
801 strcpy(pathBuffer, wildcard);
802 SendMessageA(hList, LB_RESETCONTENT, 0, 0);
803 res = SendMessageA(hList, LB_DIR, DDL_DRIVES, (LPARAM)pathBuffer);
804 ok (res > 0, "SendMessage(LB_DIR, DDL_DRIVES, *) failed - 0x%08x\n", GetLastError());
806 /* There should be some content in the listbox. In particular, there should
807 * be at least one element before, since the string "[-c-]" should
808 * have been added. Depending on the user setting, more drives might have
809 * been added.
811 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
812 ok (itemCount == itemCount_justDrives + itemCount_allFiles,
813 "SendMessage(LB_DIR, DDL_DRIVES, *) filled with %d entries, expected %d\n",
814 itemCount, itemCount_justDrives + itemCount_allFiles);
815 ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DRIVES, *) returned incorrect index!\n");
817 /* This tests behavior when no files match the wildcard */
818 strcpy(pathBuffer, BAD_EXTENSION);
819 SendMessageA(hList, LB_RESETCONTENT, 0, 0);
820 res = SendMessageA(hList, LB_DIR, DDL_DRIVES, (LPARAM)pathBuffer);
821 ok (res == itemCount_justDrives -1, "SendMessage(LB_DIR, DDL_DRIVES, %s) returned %d, expected %d\n",
822 BAD_EXTENSION, res, itemCount_justDrives -1);
824 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
825 ok (itemCount == res + 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount, res + 1);
828 /* Test DDL_DRIVES. */
829 strcpy(pathBuffer, "w*.c");
830 SendMessageA(hList, LB_RESETCONTENT, 0, 0);
831 res = SendMessageA(hList, LB_DIR, DDL_DRIVES, (LPARAM)pathBuffer);
832 ok (res > 0, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) failed - 0x%08x\n", GetLastError());
834 /* There should be some content in the listbox. In particular, there should
835 * be at least one element before, since the string "[-c-]" should
836 * have been added. Depending on the user setting, more drives might have
837 * been added.
839 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
840 ok (itemCount == itemCount_justDrives + itemCount_justFiles,
841 "SendMessage(LB_DIR, DDL_DRIVES, w*.c) filled with %d entries, expected %d\n",
842 itemCount, itemCount_justDrives + itemCount_justFiles);
843 ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) returned incorrect index!\n");
845 /* Every single item in the control should fit the format [-c-], or w*.c */
846 for (i = 0; i < itemCount; i++) {
847 memset(pathBuffer, 0, MAX_PATH);
848 driveletter = '\0';
849 SendMessageA(hList, LB_GETTEXT, i, (LPARAM)pathBuffer);
850 p = pathBuffer + strlen(pathBuffer);
851 if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1) {
852 ok( strlen(pathBuffer) == 5, "Length of drive string is not 5\n" );
853 ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
854 } else {
856 ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
857 (*(p-1) == 'c' || *(p-1) == 'C') &&
858 (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
863 /* Test DDL_DIRECTORY|DDL_DRIVES. This does *not* imply DDL_EXCLUSIVE */
864 strcpy(pathBuffer, wildcard);
865 SendMessageA(hList, LB_RESETCONTENT, 0, 0);
866 res = SendMessageA(hList, LB_DIR, DDL_DIRECTORY|DDL_DRIVES, (LPARAM)pathBuffer);
867 ok (res > 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, *) failed - 0x%08x\n", GetLastError());
869 /* There should be some content in the listbox. In particular, there should
870 * be exactly the number of plain files, plus the number of mapped drives.
872 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
873 ok (itemCount == itemCount_allFiles + itemCount_justDrives + itemCount_allDirs,
874 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
875 itemCount, itemCount_allFiles + itemCount_justDrives + itemCount_allDirs);
876 ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
878 /* Every single item in the control should start with a w and end in .c,
879 * except for the "[..]" string, which should appear exactly as it is,
880 * and the mapped drives in the format "[-X-]".
882 for (i = 0; i < itemCount; i++) {
883 memset(pathBuffer, 0, MAX_PATH);
884 driveletter = '\0';
885 SendMessageA(hList, LB_GETTEXT, i, (LPARAM)pathBuffer);
886 if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1) {
887 ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
891 /* This tests behavior when no files match the wildcard */
892 strcpy(pathBuffer, BAD_EXTENSION);
893 SendMessageA(hList, LB_RESETCONTENT, 0, 0);
894 res = SendMessageA(hList, LB_DIR, DDL_DIRECTORY|DDL_DRIVES, (LPARAM)pathBuffer);
895 ok (res == itemCount_justDrives -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, %s) returned %d, expected %d\n",
896 BAD_EXTENSION, res, itemCount_justDrives -1);
898 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
899 ok (itemCount == res + 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount, res + 1);
903 /* Test DDL_DIRECTORY|DDL_DRIVES. */
904 strcpy(pathBuffer, "w*.c");
905 SendMessageA(hList, LB_RESETCONTENT, 0, 0);
906 res = SendMessageA(hList, LB_DIR, DDL_DIRECTORY|DDL_DRIVES, (LPARAM)pathBuffer);
907 ok (res > 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) failed - 0x%08x\n", GetLastError());
909 /* There should be some content in the listbox. In particular, there should
910 * be exactly the number of plain files, plus the number of mapped drives.
912 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
913 ok (itemCount == itemCount_justFiles + itemCount_justDrives,
914 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
915 itemCount, itemCount_justFiles + itemCount_justDrives);
916 ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
918 /* Every single item in the control should start with a w and end in .c,
919 * except the mapped drives in the format "[-X-]". The "[..]" directory
920 * should not appear.
922 for (i = 0; i < itemCount; i++) {
923 memset(pathBuffer, 0, MAX_PATH);
924 driveletter = '\0';
925 SendMessageA(hList, LB_GETTEXT, i, (LPARAM)pathBuffer);
926 p = pathBuffer + strlen(pathBuffer);
927 if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1) {
928 ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
929 } else {
931 ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
932 (*(p-1) == 'c' || *(p-1) == 'C') &&
933 (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
937 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
938 strcpy(pathBuffer, wildcard);
939 SendMessageA(hList, LB_RESETCONTENT, 0, 0);
940 res = SendMessageA(hList, LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, (LPARAM)pathBuffer);
941 ok (res != -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) failed err %u\n", GetLastError());
943 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
944 ok (itemCount == itemCount_allDirs,
945 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
946 itemCount, itemCount_allDirs);
947 ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) returned incorrect index!\n");
949 if (itemCount && GetCurrentDirectoryA( MAX_PATH, pathBuffer ) > 3) /* there's no [..] in drive root */
951 memset(pathBuffer, 0, MAX_PATH);
952 SendMessageA(hList, LB_GETTEXT, 0, (LPARAM)pathBuffer);
953 ok( !strcmp(pathBuffer, "[..]"), "First element is not [..]\n");
956 /* This tests behavior when no files match the wildcard */
957 strcpy(pathBuffer, BAD_EXTENSION);
958 SendMessageA(hList, LB_RESETCONTENT, 0, 0);
959 res = SendMessageA(hList, LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, (LPARAM)pathBuffer);
960 ok (res == -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
961 BAD_EXTENSION, res, -1);
963 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
964 ok (itemCount == res + 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount, res + 1);
967 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
968 strcpy(pathBuffer, "w*.c");
969 SendMessageA(hList, LB_RESETCONTENT, 0, 0);
970 res = SendMessageA(hList, LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, (LPARAM)pathBuffer);
971 ok (res == LB_ERR, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, w*.c) returned %d expected %d\n", res, LB_ERR);
973 /* There should be no elements, since "[..]" does not fit w*.c */
974 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
975 ok (itemCount == 0,
976 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
977 itemCount, 0);
979 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
980 strcpy(pathBuffer, wildcard);
981 SendMessageA(hList, LB_RESETCONTENT, 0, 0);
982 res = SendMessageA(hList, LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, (LPARAM)pathBuffer);
983 ok (res > 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
985 /* There should be no plain files on the listbox */
986 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
987 ok (itemCount == itemCount_justDrives + itemCount_allDirs,
988 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
989 itemCount, itemCount_justDrives + itemCount_allDirs);
990 ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
992 for (i = 0; i < itemCount; i++) {
993 memset(pathBuffer, 0, MAX_PATH);
994 driveletter = '\0';
995 SendMessageA(hList, LB_GETTEXT, i, (LPARAM)pathBuffer);
996 if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1) {
997 ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
998 } else {
999 ok( pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']',
1000 "Element %d (%s) does not fit expected [...]\n", i, pathBuffer);
1004 /* This tests behavior when no files match the wildcard */
1005 strcpy(pathBuffer, BAD_EXTENSION);
1006 SendMessageA(hList, LB_RESETCONTENT, 0, 0);
1007 res = SendMessageA(hList, LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, (LPARAM)pathBuffer);
1008 ok (res == itemCount_justDrives -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1009 BAD_EXTENSION, res, itemCount_justDrives -1);
1011 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1012 ok (itemCount == res + 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount, res + 1);
1014 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1015 strcpy(pathBuffer, "w*.c");
1016 SendMessageA(hList, LB_RESETCONTENT, 0, 0);
1017 res = SendMessageA(hList, LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, (LPARAM)pathBuffer);
1018 ok (res >= 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
1020 /* There should be no plain files on the listbox, and no [..], since it does not fit w*.c */
1021 itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1022 ok (itemCount == itemCount_justDrives,
1023 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1024 itemCount, itemCount_justDrives);
1025 ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
1027 for (i = 0; i < itemCount; i++) {
1028 memset(pathBuffer, 0, MAX_PATH);
1029 driveletter = '\0';
1030 SendMessageA(hList, LB_GETTEXT, i, (LPARAM)pathBuffer);
1031 ok (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1, "Element %d (%s) does not fit [-X-]\n", i, pathBuffer);
1032 ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1034 DestroyWindow(hList);
1036 DeleteFileA( "wtest1.tmp.c" );
1039 static HWND g_listBox;
1040 static HWND g_label;
1042 #define ID_TEST_LABEL 1001
1043 #define ID_TEST_LISTBOX 1002
1045 static BOOL on_listbox_container_create (HWND hwnd, LPCREATESTRUCTA lpcs)
1047 g_label = CreateWindowA(
1048 "Static",
1049 "Contents of static control before DlgDirList.",
1050 WS_CHILD | WS_VISIBLE,
1051 10, 10, 512, 32,
1052 hwnd, (HMENU)ID_TEST_LABEL, NULL, 0);
1053 if (!g_label) return FALSE;
1054 g_listBox = CreateWindowA(
1055 "ListBox",
1056 "DlgDirList test",
1057 WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | WS_VSCROLL,
1058 10, 60, 256, 256,
1059 hwnd, (HMENU)ID_TEST_LISTBOX, NULL, 0);
1060 if (!g_listBox) return FALSE;
1062 return TRUE;
1065 static LRESULT CALLBACK listbox_container_window_procA (
1066 HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
1068 LRESULT result = 0;
1070 switch (uiMsg) {
1071 case WM_DESTROY:
1072 PostQuitMessage(0);
1073 break;
1074 case WM_CREATE:
1075 result = on_listbox_container_create(hwnd, (LPCREATESTRUCTA) lParam)
1076 ? 0 : (LRESULT)-1;
1077 break;
1078 default:
1079 result = DefWindowProcA (hwnd, uiMsg, wParam, lParam);
1080 break;
1082 return result;
1085 static BOOL RegisterListboxWindowClass(HINSTANCE hInst)
1087 WNDCLASSA cls;
1089 cls.style = 0;
1090 cls.cbClsExtra = 0;
1091 cls.cbWndExtra = 0;
1092 cls.hInstance = hInst;
1093 cls.hIcon = NULL;
1094 cls.hCursor = LoadCursorA (NULL, (LPCSTR)IDC_ARROW);
1095 cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
1096 cls.lpszMenuName = NULL;
1097 cls.lpfnWndProc = listbox_container_window_procA;
1098 cls.lpszClassName = "ListboxContainerClass";
1099 if (!RegisterClassA (&cls)) return FALSE;
1101 return TRUE;
1104 static void test_listbox_dlgdir(void)
1106 HINSTANCE hInst;
1107 HWND hWnd;
1108 int res, itemCount;
1109 int itemCount_allDirs;
1110 int itemCount_justFiles;
1111 int itemCount_justDrives;
1112 int i;
1113 char pathBuffer[MAX_PATH];
1114 char itemBuffer[MAX_PATH];
1115 char tempBuffer[MAX_PATH];
1116 char * p;
1117 char driveletter;
1118 HANDLE file;
1120 file = CreateFileA( "wtest1.tmp.c", GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL );
1121 ok(file != INVALID_HANDLE_VALUE, "Error creating the test file: %d\n", GetLastError());
1122 CloseHandle( file );
1124 /* NOTE: for this test to succeed, there must be no subdirectories
1125 under the current directory. In addition, there must be at least
1126 one file that fits the wildcard w*.c . Normally, the test
1127 directory itself satisfies both conditions.
1130 hInst = GetModuleHandleA(0);
1131 if (!RegisterListboxWindowClass(hInst)) assert(0);
1132 hWnd = CreateWindowA("ListboxContainerClass", "ListboxContainerClass",
1133 WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1134 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
1135 NULL, NULL, hInst, 0);
1136 assert(hWnd);
1138 /* Test for standard usage */
1140 /* The following should be overwritten by the directory path */
1141 SendMessageA(g_label, WM_SETTEXT, 0, (LPARAM)"default contents");
1143 /* This should list all the w*.c files in the test directory
1144 * As of this writing, this includes win.c, winstation.c, wsprintf.c
1146 strcpy(pathBuffer, "w*.c");
1147 res = DlgDirListA(hWnd, pathBuffer, ID_TEST_LISTBOX, ID_TEST_LABEL, 0);
1148 ok (res == 1, "DlgDirList(*.c, 0) returned %d - expected 1 - 0x%08x\n", res, GetLastError());
1150 /* Path specification gets converted to uppercase */
1151 ok (!strcmp(pathBuffer, "W*.C"),
1152 "expected conversion to uppercase, got %s\n", pathBuffer);
1154 /* Loaded path should have overwritten the label text */
1155 SendMessageA(g_label, WM_GETTEXT, MAX_PATH, (LPARAM)pathBuffer);
1156 trace("Static control after DlgDirList: %s\n", pathBuffer);
1157 ok (strcmp("default contents", pathBuffer), "DlgDirList() did not modify static control!\n");
1159 /* There should be some content in the listbox */
1160 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1161 ok (itemCount > 0, "DlgDirList() did NOT fill the listbox!\n");
1162 itemCount_justFiles = itemCount;
1164 /* Every single item in the control should start with a w and end in .c */
1165 for (i = 0; i < itemCount; i++) {
1166 memset(pathBuffer, 0, MAX_PATH);
1167 SendMessageA(g_listBox, LB_GETTEXT, i, (LPARAM)pathBuffer);
1168 p = pathBuffer + strlen(pathBuffer);
1169 ok(((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1170 (*(p-1) == 'c' || *(p-1) == 'C') &&
1171 (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1174 /* Test behavior when no files match the wildcard */
1175 strcpy(pathBuffer, BAD_EXTENSION);
1176 res = DlgDirListA(hWnd, pathBuffer, ID_TEST_LISTBOX, ID_TEST_LABEL, 0);
1177 ok (res == 1, "DlgDirList(%s, 0) returned %d expected 1\n", BAD_EXTENSION, res);
1179 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1180 ok (itemCount == 0, "DlgDirList() DID fill the listbox!\n");
1182 /* Test DDL_DIRECTORY */
1183 strcpy(pathBuffer, "w*.c");
1184 res = DlgDirListA(hWnd, pathBuffer, ID_TEST_LISTBOX, ID_TEST_LABEL,
1185 DDL_DIRECTORY);
1186 ok (res == 1, "DlgDirList(*.c, DDL_DIRECTORY) failed - 0x%08x\n", GetLastError());
1188 /* There should be some content in the listbox. In particular, there should
1189 * be exactly more elements than before, since the directories should
1190 * have been added.
1192 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1193 itemCount_allDirs = itemCount - itemCount_justFiles;
1194 ok (itemCount >= itemCount_justFiles,
1195 "DlgDirList(DDL_DIRECTORY) filled with %d entries, expected > %d\n",
1196 itemCount, itemCount_justFiles);
1198 /* Every single item in the control should start with a w and end in .c,
1199 * except for the "[..]" string, which should appear exactly as it is.
1201 for (i = 0; i < itemCount; i++) {
1202 memset(pathBuffer, 0, MAX_PATH);
1203 SendMessageA(g_listBox, LB_GETTEXT, i, (LPARAM)pathBuffer);
1204 p = pathBuffer + strlen(pathBuffer);
1205 ok( (pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']') ||
1206 ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1207 (*(p-1) == 'c' || *(p-1) == 'C') &&
1208 (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1211 /* Test behavior when no files match the wildcard */
1212 strcpy(pathBuffer, BAD_EXTENSION);
1213 res = DlgDirListA(hWnd, pathBuffer, ID_TEST_LISTBOX, ID_TEST_LABEL,
1214 DDL_DIRECTORY);
1215 ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY) returned %d expected 1\n", BAD_EXTENSION, res);
1217 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1218 ok (itemCount == itemCount_allDirs,
1219 "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
1220 itemCount_allDirs, itemCount);
1221 for (i = 0; i < itemCount; i++) {
1222 memset(pathBuffer, 0, MAX_PATH);
1223 SendMessageA(g_listBox, LB_GETTEXT, i, (LPARAM)pathBuffer);
1224 ok( pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']',
1225 "Element %d (%s) does not fit requested [...]\n", i, pathBuffer);
1229 /* Test DDL_DRIVES. At least on WinXP-SP2, this implies DDL_EXCLUSIVE */
1230 strcpy(pathBuffer, "w*.c");
1231 res = DlgDirListA(hWnd, pathBuffer, ID_TEST_LISTBOX, ID_TEST_LABEL,
1232 DDL_DRIVES);
1233 ok (res == 1, "DlgDirList(*.c, DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1235 /* There should be some content in the listbox. In particular, there should
1236 * be at least one element before, since the string "[-c-]" should
1237 * have been added. Depending on the user setting, more drives might have
1238 * been added.
1240 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1241 ok (itemCount >= 1,
1242 "DlgDirList(DDL_DRIVES) filled with %d entries, expected at least %d\n",
1243 itemCount, 1);
1244 itemCount_justDrives = itemCount;
1246 /* Every single item in the control should fit the format [-c-] */
1247 for (i = 0; i < itemCount; i++) {
1248 memset(pathBuffer, 0, MAX_PATH);
1249 driveletter = '\0';
1250 SendMessageA(g_listBox, LB_GETTEXT, i, (LPARAM)pathBuffer);
1251 ok( strlen(pathBuffer) == 5, "Length of drive string is not 5\n" );
1252 ok( sscanf(pathBuffer, "[-%c-]", &driveletter) == 1, "Element %d (%s) does not fit [-X-]\n", i, pathBuffer);
1253 ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1254 if (!(driveletter >= 'a' && driveletter <= 'z')) {
1255 /* Correct after invalid entry is found */
1256 trace("removing count of invalid entry %s\n", pathBuffer);
1257 itemCount_justDrives--;
1261 /* Test behavior when no files match the wildcard */
1262 strcpy(pathBuffer, BAD_EXTENSION);
1263 res = DlgDirListA(hWnd, pathBuffer, ID_TEST_LISTBOX, ID_TEST_LABEL,
1264 DDL_DRIVES);
1265 ok (res == 1, "DlgDirList(%s, DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION, res);
1267 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1268 ok (itemCount == itemCount_justDrives, "DlgDirList() incorrectly filled the listbox!\n");
1271 /* Test DDL_DIRECTORY|DDL_DRIVES. This does *not* imply DDL_EXCLUSIVE */
1272 strcpy(pathBuffer, "w*.c");
1273 res = DlgDirListA(hWnd, pathBuffer, ID_TEST_LISTBOX, ID_TEST_LABEL,
1274 DDL_DIRECTORY|DDL_DRIVES);
1275 ok (res == 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1277 /* There should be some content in the listbox. In particular, there should
1278 * be exactly the number of plain files, plus the number of mapped drives,
1279 * plus one "[..]"
1281 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1282 ok (itemCount == itemCount_justFiles + itemCount_justDrives + itemCount_allDirs,
1283 "DlgDirList(DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1284 itemCount, itemCount_justFiles + itemCount_justDrives + itemCount_allDirs);
1286 /* Every single item in the control should start with a w and end in .c,
1287 * except for the "[..]" string, which should appear exactly as it is,
1288 * and the mapped drives in the format "[-X-]".
1290 for (i = 0; i < itemCount; i++) {
1291 memset(pathBuffer, 0, MAX_PATH);
1292 driveletter = '\0';
1293 SendMessageA(g_listBox, LB_GETTEXT, i, (LPARAM)pathBuffer);
1294 p = pathBuffer + strlen(pathBuffer);
1295 if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1) {
1296 ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1297 } else {
1298 ok( (pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']') ||
1299 ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1300 (*(p-1) == 'c' || *(p-1) == 'C') &&
1301 (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1305 /* Test behavior when no files match the wildcard */
1306 strcpy(pathBuffer, BAD_EXTENSION);
1307 res = DlgDirListA(hWnd, pathBuffer, ID_TEST_LISTBOX, ID_TEST_LABEL,
1308 DDL_DIRECTORY|DDL_DRIVES);
1309 ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION, res);
1311 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1312 ok (itemCount == itemCount_justDrives + itemCount_allDirs,
1313 "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
1314 itemCount_justDrives + itemCount_allDirs, itemCount);
1318 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1319 strcpy(pathBuffer, "w*.c");
1320 res = DlgDirListA(hWnd, pathBuffer, ID_TEST_LISTBOX, ID_TEST_LABEL,
1321 DDL_DIRECTORY|DDL_EXCLUSIVE);
1322 ok (res == 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_EXCLUSIVE) failed - 0x%08x\n", GetLastError());
1324 /* There should be exactly one element: "[..]" */
1325 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1326 ok (itemCount == itemCount_allDirs,
1327 "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1328 itemCount, itemCount_allDirs);
1330 if (itemCount && GetCurrentDirectoryA( MAX_PATH, pathBuffer ) > 3) /* there's no [..] in drive root */
1332 memset(pathBuffer, 0, MAX_PATH);
1333 SendMessageA(g_listBox, LB_GETTEXT, 0, (LPARAM)pathBuffer);
1334 ok( !strcmp(pathBuffer, "[..]"), "First (and only) element is not [..]\n");
1337 /* Test behavior when no files match the wildcard */
1338 strcpy(pathBuffer, BAD_EXTENSION);
1339 res = DlgDirListA(hWnd, pathBuffer, ID_TEST_LISTBOX, ID_TEST_LABEL,
1340 DDL_DIRECTORY|DDL_EXCLUSIVE);
1341 ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION, res);
1343 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1344 ok (itemCount == itemCount_allDirs, "DlgDirList() incorrectly filled the listbox!\n");
1347 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1348 strcpy(pathBuffer, "w*.c");
1349 res = DlgDirListA(hWnd, pathBuffer, ID_TEST_LISTBOX, ID_TEST_LABEL,
1350 DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE);
1351 ok (res == 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) failed - 0x%08x\n", GetLastError());
1353 /* There should be no plain files on the listbox */
1354 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1355 ok (itemCount == itemCount_justDrives + itemCount_allDirs,
1356 "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1357 itemCount, itemCount_justDrives + itemCount_allDirs);
1359 for (i = 0; i < itemCount; i++) {
1360 memset(pathBuffer, 0, MAX_PATH);
1361 driveletter = '\0';
1362 SendMessageA(g_listBox, LB_GETTEXT, i, (LPARAM)pathBuffer);
1363 if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1) {
1364 ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1365 } else {
1366 ok( pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']',
1367 "Element %d (%s) does not fit expected [...]\n", i, pathBuffer);
1371 /* Test behavior when no files match the wildcard */
1372 strcpy(pathBuffer, BAD_EXTENSION);
1373 res = DlgDirListA(hWnd, pathBuffer, ID_TEST_LISTBOX, ID_TEST_LABEL,
1374 DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE);
1375 ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION, res);
1377 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1378 ok (itemCount == itemCount_justDrives + itemCount_allDirs,
1379 "DlgDirList() incorrectly filled the listbox!\n");
1381 /* Now test DlgDirSelectEx() in normal operation */
1382 /* Fill with everything - drives, directory and all plain files. */
1383 strcpy(pathBuffer, "*");
1384 res = DlgDirListA(hWnd, pathBuffer, ID_TEST_LISTBOX, ID_TEST_LABEL,
1385 DDL_DIRECTORY|DDL_DRIVES);
1386 ok (res != 0, "DlgDirList(*, DDL_DIRECTORY|DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1388 SendMessageA(g_listBox, LB_SETCURSEL, -1, 0); /* Unselect any current selection */
1389 memset(pathBuffer, 0, MAX_PATH);
1390 SetLastError(0xdeadbeef);
1391 res = DlgDirSelectExA(hWnd, pathBuffer, MAX_PATH, ID_TEST_LISTBOX);
1392 ok (GetLastError() == 0xdeadbeef,
1393 "DlgDirSelectEx() with no selection modified last error code from 0xdeadbeef to 0x%08x\n",
1394 GetLastError());
1395 ok (res == 0, "DlgDirSelectEx() with no selection returned %d, expected 0\n", res);
1396 /* WinXP-SP2 leaves pathBuffer untouched, but Win98 fills it with garbage. */
1398 ok (strlen(pathBuffer) == 0, "DlgDirSelectEx() with no selection filled buffer with %s\n", pathBuffer);
1400 /* Test proper drive/dir/file recognition */
1401 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1402 for (i = 0; i < itemCount; i++) {
1403 memset(itemBuffer, 0, MAX_PATH);
1404 memset(pathBuffer, 0, MAX_PATH);
1405 memset(tempBuffer, 0, MAX_PATH);
1406 driveletter = '\0';
1407 SendMessageA(g_listBox, LB_GETTEXT, i, (LPARAM)itemBuffer);
1408 res = SendMessageA(g_listBox, LB_SETCURSEL, i, 0);
1409 ok (res == i, "SendMessageA(LB_SETCURSEL, %d) failed\n", i);
1410 if (sscanf(itemBuffer, "[-%c-]", &driveletter) == 1) {
1411 /* Current item is a drive letter */
1412 SetLastError(0xdeadbeef);
1413 res = DlgDirSelectExA(hWnd, pathBuffer, MAX_PATH, ID_TEST_LISTBOX);
1414 ok (GetLastError() == 0xdeadbeef,
1415 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1416 i, GetLastError());
1417 ok(res == 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer, pathBuffer);
1419 /* For drive letters, DlgDirSelectEx tacks on a colon */
1420 ok (pathBuffer[0] == driveletter && pathBuffer[1] == ':' && pathBuffer[2] == '\0',
1421 "%d: got \"%s\" expected \"%c:\"\n", i, pathBuffer, driveletter);
1422 } else if (itemBuffer[0] == '[') {
1423 /* Current item is the parent directory */
1424 SetLastError(0xdeadbeef);
1425 res = DlgDirSelectExA(hWnd, pathBuffer, MAX_PATH, ID_TEST_LISTBOX);
1426 ok (GetLastError() == 0xdeadbeef,
1427 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1428 i, GetLastError());
1429 ok(res == 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer, pathBuffer);
1431 /* For directories, DlgDirSelectEx tacks on a backslash */
1432 p = pathBuffer + strlen(pathBuffer);
1433 ok (*(p-1) == '\\', "DlgDirSelectEx did NOT tack on a backslash to dir, got %s\n", pathBuffer);
1435 tempBuffer[0] = '[';
1436 lstrcpynA(tempBuffer + 1, pathBuffer, strlen(pathBuffer));
1437 strcat(tempBuffer, "]");
1438 ok (!strcmp(tempBuffer, itemBuffer), "Formatted directory should be %s, got %s\n", tempBuffer, itemBuffer);
1439 } else {
1440 /* Current item is a plain file */
1441 SetLastError(0xdeadbeef);
1442 res = DlgDirSelectExA(hWnd, pathBuffer, MAX_PATH, ID_TEST_LISTBOX);
1443 ok (GetLastError() == 0xdeadbeef,
1444 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1445 i, GetLastError());
1446 ok(res == 0, "DlgDirSelectEx() thinks %s (%s) is a drive/directory!\n", itemBuffer, pathBuffer);
1448 /* NOTE: WinXP tacks a period on all files that lack an extension. This affects
1449 * for example, "Makefile", which gets reported as "Makefile."
1451 strcpy(tempBuffer, itemBuffer);
1452 if (strchr(tempBuffer, '.') == NULL) strcat(tempBuffer, ".");
1453 ok (!strcmp(pathBuffer, tempBuffer), "Formatted file should be %s, got %s\n", tempBuffer, pathBuffer);
1457 DeleteFileA( "wtest1.tmp.c" );
1459 /* Now test DlgDirSelectEx() in abnormal operation */
1460 /* Fill list with bogus entries, that look somewhat valid */
1461 SendMessageA(g_listBox, LB_RESETCONTENT, 0, 0);
1462 SendMessageA(g_listBox, LB_ADDSTRING, 0, (LPARAM)"[notexist.dir]");
1463 SendMessageA(g_listBox, LB_ADDSTRING, 0, (LPARAM)"notexist.fil");
1464 itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1465 for (i = 0; i < itemCount; i++) {
1466 memset(itemBuffer, 0, MAX_PATH);
1467 memset(pathBuffer, 0, MAX_PATH);
1468 memset(tempBuffer, 0, MAX_PATH);
1469 driveletter = '\0';
1470 SendMessageA(g_listBox, LB_GETTEXT, i, (LPARAM)itemBuffer);
1471 res = SendMessageA(g_listBox, LB_SETCURSEL, i, 0);
1472 ok (res == i, "SendMessage(LB_SETCURSEL, %d) failed\n", i);
1473 if (sscanf(itemBuffer, "[-%c-]", &driveletter) == 1) {
1474 /* Current item is a drive letter */
1475 SetLastError(0xdeadbeef);
1476 res = DlgDirSelectExA(hWnd, pathBuffer, MAX_PATH, ID_TEST_LISTBOX);
1477 ok (GetLastError() == 0xdeadbeef,
1478 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1479 i, GetLastError());
1480 ok(res == 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer, pathBuffer);
1482 /* For drive letters, DlgDirSelectEx tacks on a colon */
1483 ok (pathBuffer[0] == driveletter && pathBuffer[1] == ':' && pathBuffer[2] == '\0',
1484 "%d: got \"%s\" expected \"%c:\"\n", i, pathBuffer, driveletter);
1485 } else if (itemBuffer[0] == '[') {
1486 /* Current item is the parent directory */
1487 SetLastError(0xdeadbeef);
1488 res = DlgDirSelectExA(hWnd, pathBuffer, MAX_PATH, ID_TEST_LISTBOX);
1489 ok (GetLastError() == 0xdeadbeef,
1490 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1491 i, GetLastError());
1492 ok(res == 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer, pathBuffer);
1494 /* For directories, DlgDirSelectEx tacks on a backslash */
1495 p = pathBuffer + strlen(pathBuffer);
1496 ok (*(p-1) == '\\', "DlgDirSelectEx did NOT tack on a backslash to dir, got %s\n", pathBuffer);
1498 tempBuffer[0] = '[';
1499 lstrcpynA(tempBuffer + 1, pathBuffer, strlen(pathBuffer));
1500 strcat(tempBuffer, "]");
1501 ok (!strcmp(tempBuffer, itemBuffer), "Formatted directory should be %s, got %s\n", tempBuffer, itemBuffer);
1502 } else {
1503 /* Current item is a plain file */
1504 SetLastError(0xdeadbeef);
1505 res = DlgDirSelectExA(hWnd, pathBuffer, MAX_PATH, ID_TEST_LISTBOX);
1506 ok (GetLastError() == 0xdeadbeef,
1507 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1508 i, GetLastError());
1509 ok(res == 0, "DlgDirSelectEx() thinks %s (%s) is a drive/directory!\n", itemBuffer, pathBuffer);
1511 /* NOTE: WinXP and Win98 tack a period on all files that lack an extension.
1512 * This affects for example, "Makefile", which gets reported as "Makefile."
1514 strcpy(tempBuffer, itemBuffer);
1515 if (strchr(tempBuffer, '.') == NULL) strcat(tempBuffer, ".");
1516 ok (!strcmp(pathBuffer, tempBuffer), "Formatted file should be %s, got %s\n", tempBuffer, pathBuffer);
1520 /* Test behavior when loading folders from root with and without wildcard */
1521 strcpy(pathBuffer, "C:\\");
1522 res = DlgDirListA(hWnd, pathBuffer, ID_TEST_LISTBOX, 0, DDL_DIRECTORY | DDL_EXCLUSIVE);
1523 ok(res || broken(!res) /* NT4/W2K */, "DlgDirList failed to list C:\\ folders\n");
1524 todo_wine ok(!strcmp(pathBuffer, "*") || broken(!res) /* NT4/W2K */,
1525 "DlgDirList set the invalid path spec '%s', expected '*'\n", pathBuffer);
1527 strcpy(pathBuffer, "C:\\*");
1528 res = DlgDirListA(hWnd, pathBuffer, ID_TEST_LISTBOX, 0, DDL_DIRECTORY | DDL_EXCLUSIVE);
1529 ok(res || broken(!res) /* NT4/W2K */, "DlgDirList failed to list C:\\* folders\n");
1530 ok(!strcmp(pathBuffer, "*") || broken(!res) /* NT4/W2K */,
1531 "DlgDirList set the invalid path spec '%s', expected '*'\n", pathBuffer);
1533 /* Try loading files from an invalid folder */
1534 SetLastError(0xdeadbeef);
1535 strcpy(pathBuffer, "C:\\INVALID$$DIR");
1536 res = DlgDirListA(hWnd, pathBuffer, ID_TEST_LISTBOX, 0, DDL_DIRECTORY | DDL_EXCLUSIVE);
1537 todo_wine ok(!res, "DlgDirList should have failed with 0 but %d was returned\n", res);
1538 todo_wine ok(GetLastError() == ERROR_NO_WILDCARD_CHARACTERS,
1539 "GetLastError should return 0x589, got 0x%X\n",GetLastError());
1541 DestroyWindow(hWnd);
1544 static void test_set_count( void )
1546 HWND parent, listbox;
1547 LONG ret;
1548 RECT r;
1550 parent = create_parent();
1551 listbox = create_listbox( LBS_OWNERDRAWFIXED | LBS_NODATA | WS_CHILD | WS_VISIBLE, parent );
1553 UpdateWindow( listbox );
1554 GetUpdateRect( listbox, &r, TRUE );
1555 ok( IsRectEmpty( &r ), "got non-empty rect\n");
1557 ret = SendMessageA( listbox, LB_SETCOUNT, 100, 0 );
1558 ok( ret == 0, "got %d\n", ret );
1559 ret = SendMessageA( listbox, LB_GETCOUNT, 0, 0 );
1560 ok( ret == 100, "got %d\n", ret );
1562 GetUpdateRect( listbox, &r, TRUE );
1563 ok( !IsRectEmpty( &r ), "got empty rect\n");
1565 ValidateRect( listbox, NULL );
1566 GetUpdateRect( listbox, &r, TRUE );
1567 ok( IsRectEmpty( &r ), "got non-empty rect\n");
1569 ret = SendMessageA( listbox, LB_SETCOUNT, 99, 0 );
1570 ok( ret == 0, "got %d\n", ret );
1572 GetUpdateRect( listbox, &r, TRUE );
1573 ok( !IsRectEmpty( &r ), "got empty rect\n");
1575 DestroyWindow( listbox );
1576 DestroyWindow( parent );
1579 static DWORD (WINAPI *pGetListBoxInfo)(HWND);
1580 static int lb_getlistboxinfo;
1582 static LRESULT WINAPI listbox_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
1584 WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
1586 if (message == LB_GETLISTBOXINFO)
1587 lb_getlistboxinfo++;
1589 return CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
1592 static void test_GetListBoxInfo(void)
1594 HWND listbox, parent;
1595 WNDPROC oldproc;
1596 DWORD ret;
1598 pGetListBoxInfo = (void*)GetProcAddress(GetModuleHandleA("user32.dll"), "GetListBoxInfo");
1600 if (!pGetListBoxInfo)
1602 win_skip("GetListBoxInfo() not available\n");
1603 return;
1606 parent = create_parent();
1607 listbox = create_listbox(WS_CHILD | WS_VISIBLE, parent);
1609 oldproc = (WNDPROC)SetWindowLongPtrA(listbox, GWLP_WNDPROC, (LONG_PTR)listbox_subclass_proc);
1610 SetWindowLongPtrA(listbox, GWLP_USERDATA, (LONG_PTR)oldproc);
1612 lb_getlistboxinfo = 0;
1613 ret = pGetListBoxInfo(listbox);
1614 ok(ret > 0, "got %d\n", ret);
1615 todo_wine
1616 ok(lb_getlistboxinfo == 0, "got %d\n", lb_getlistboxinfo);
1618 DestroyWindow(listbox);
1619 DestroyWindow(parent);
1622 static void test_missing_lbuttonup( void )
1624 HWND listbox, parent, capture;
1626 parent = create_parent();
1627 listbox = create_listbox(WS_CHILD | WS_VISIBLE, parent);
1629 /* Send button down without a corresponding button up */
1630 SendMessageA(listbox, WM_LBUTTONDOWN, 0, MAKELPARAM(10,10));
1631 capture = GetCapture();
1632 ok(capture == listbox, "got %p expected %p\n", capture, listbox);
1634 /* Capture is released and LBN_SELCHANGE sent during WM_KILLFOCUS */
1635 got_selchange = 0;
1636 SetFocus(NULL);
1637 capture = GetCapture();
1638 ok(capture == NULL, "got %p\n", capture);
1639 ok(got_selchange, "got %d\n", got_selchange);
1641 DestroyWindow(listbox);
1642 DestroyWindow(parent);
1645 static void test_extents(void)
1647 HWND listbox, parent;
1648 DWORD res;
1649 SCROLLINFO sinfo;
1650 BOOL br;
1652 parent = create_parent();
1654 listbox = create_listbox(WS_CHILD | WS_VISIBLE, parent);
1656 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
1657 ok(res == 0, "Got wrong initial horizontal extent: %u\n", res);
1659 sinfo.cbSize = sizeof(sinfo);
1660 sinfo.fMask = SIF_RANGE;
1661 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
1662 ok(br == TRUE, "GetScrollInfo failed\n");
1663 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
1664 ok(sinfo.nMax == 100, "got wrong max: %u\n", sinfo.nMax);
1665 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
1666 "List box should not have a horizontal scroll bar\n");
1668 /* horizontal extent < width */
1669 SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 64, 0);
1671 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
1672 ok(res == 64, "Got wrong horizontal extent: %u\n", res);
1674 sinfo.cbSize = sizeof(sinfo);
1675 sinfo.fMask = SIF_RANGE;
1676 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
1677 ok(br == TRUE, "GetScrollInfo failed\n");
1678 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
1679 ok(sinfo.nMax == 100, "got wrong max: %u\n", sinfo.nMax);
1680 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
1681 "List box should not have a horizontal scroll bar\n");
1683 /* horizontal extent > width */
1684 SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 184, 0);
1686 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
1687 ok(res == 184, "Got wrong horizontal extent: %u\n", res);
1689 sinfo.cbSize = sizeof(sinfo);
1690 sinfo.fMask = SIF_RANGE;
1691 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
1692 ok(br == TRUE, "GetScrollInfo failed\n");
1693 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
1694 ok(sinfo.nMax == 100, "got wrong max: %u\n", sinfo.nMax);
1695 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
1696 "List box should not have a horizontal scroll bar\n");
1698 DestroyWindow(listbox);
1701 listbox = create_listbox(WS_CHILD | WS_VISIBLE | WS_HSCROLL, parent);
1703 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
1704 ok(res == 0, "Got wrong initial horizontal extent: %u\n", res);
1706 sinfo.cbSize = sizeof(sinfo);
1707 sinfo.fMask = SIF_RANGE;
1708 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
1709 ok(br == TRUE, "GetScrollInfo failed\n");
1710 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
1711 ok(sinfo.nMax == 100, "got wrong max: %u\n", sinfo.nMax);
1712 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
1713 "List box should not have a horizontal scroll bar\n");
1715 /* horizontal extent < width */
1716 SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 64, 0);
1718 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
1719 ok(res == 64, "Got wrong horizontal extent: %u\n", res);
1721 sinfo.cbSize = sizeof(sinfo);
1722 sinfo.fMask = SIF_RANGE;
1723 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
1724 ok(br == TRUE, "GetScrollInfo failed\n");
1725 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
1726 ok(sinfo.nMax == 63, "got wrong max: %u\n", sinfo.nMax);
1727 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
1728 "List box should not have a horizontal scroll bar\n");
1730 /* horizontal extent > width */
1731 SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 184, 0);
1733 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
1734 ok(res == 184, "Got wrong horizontal extent: %u\n", res);
1736 sinfo.cbSize = sizeof(sinfo);
1737 sinfo.fMask = SIF_RANGE;
1738 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
1739 ok(br == TRUE, "GetScrollInfo failed\n");
1740 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
1741 ok(sinfo.nMax == 183, "got wrong max: %u\n", sinfo.nMax);
1742 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) != 0,
1743 "List box should have a horizontal scroll bar\n");
1745 SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 0, 0);
1747 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
1748 ok(res == 0, "Got wrong horizontal extent: %u\n", res);
1750 sinfo.cbSize = sizeof(sinfo);
1751 sinfo.fMask = SIF_RANGE;
1752 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
1753 ok(br == TRUE, "GetScrollInfo failed\n");
1754 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
1755 ok(sinfo.nMax == 0, "got wrong max: %u\n", sinfo.nMax);
1756 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
1757 "List box should not have a horizontal scroll bar\n");
1759 DestroyWindow(listbox);
1762 listbox = create_listbox(WS_CHILD | WS_VISIBLE | WS_HSCROLL | LBS_DISABLENOSCROLL, parent);
1764 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
1765 ok(res == 0, "Got wrong initial horizontal extent: %u\n", res);
1767 sinfo.cbSize = sizeof(sinfo);
1768 sinfo.fMask = SIF_RANGE;
1769 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
1770 ok(br == TRUE, "GetScrollInfo failed\n");
1771 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
1772 ok(sinfo.nMax == 0, "got wrong max: %u\n", sinfo.nMax);
1773 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) != 0,
1774 "List box should have a horizontal scroll bar\n");
1776 /* horizontal extent < width */
1777 SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 64, 0);
1779 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
1780 ok(res == 64, "Got wrong horizontal extent: %u\n", res);
1782 sinfo.cbSize = sizeof(sinfo);
1783 sinfo.fMask = SIF_RANGE;
1784 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
1785 ok(br == TRUE, "GetScrollInfo failed\n");
1786 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
1787 ok(sinfo.nMax == 63, "got wrong max: %u\n", sinfo.nMax);
1788 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) != 0,
1789 "List box should have a horizontal scroll bar\n");
1791 /* horizontal extent > width */
1792 SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 184, 0);
1794 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
1795 ok(res == 184, "Got wrong horizontal extent: %u\n", res);
1797 sinfo.cbSize = sizeof(sinfo);
1798 sinfo.fMask = SIF_RANGE;
1799 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
1800 ok(br == TRUE, "GetScrollInfo failed\n");
1801 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
1802 ok(sinfo.nMax == 183, "got wrong max: %u\n", sinfo.nMax);
1803 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) != 0,
1804 "List box should have a horizontal scroll bar\n");
1806 SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 0, 0);
1808 res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
1809 ok(res == 0, "Got wrong horizontal extent: %u\n", res);
1811 sinfo.cbSize = sizeof(sinfo);
1812 sinfo.fMask = SIF_RANGE;
1813 br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
1814 ok(br == TRUE, "GetScrollInfo failed\n");
1815 ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
1816 ok(sinfo.nMax == 0, "got wrong max: %u\n", sinfo.nMax);
1817 ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) != 0,
1818 "List box should have a horizontal scroll bar\n");
1820 DestroyWindow(listbox);
1822 DestroyWindow(parent);
1825 START_TEST(listbox)
1827 const struct listbox_test SS =
1828 /* {add_style} */
1829 {{0},
1830 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
1831 { 1, 1, 1, LB_ERR}, {0,0,0,0},
1832 { 2, 2, 2, LB_ERR}, {0,0,0,0},
1833 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
1834 /* {selected, anchor, caret, selcount}{TODO fields} */
1835 const struct listbox_test SS_NS =
1836 {{LBS_NOSEL},
1837 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
1838 { 1, 1, 1, LB_ERR}, {0,0,0,0},
1839 { 2, 2, 2, LB_ERR}, {0,0,0,0},
1840 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
1841 const struct listbox_test MS =
1842 {{LBS_MULTIPLESEL},
1843 { 0, LB_ERR, 0, 0}, {0,0,0,0},
1844 { 1, 1, 1, 1}, {0,0,0,0},
1845 { 2, 1, 2, 1}, {0,0,0,0},
1846 { 0, LB_ERR, 0, 2}, {0,0,0,0}};
1847 const struct listbox_test MS_NS =
1848 {{LBS_MULTIPLESEL | LBS_NOSEL},
1849 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
1850 { 1, 1, 1, LB_ERR}, {0,0,0,0},
1851 { 2, 2, 2, LB_ERR}, {0,0,0,0},
1852 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
1853 const struct listbox_test ES =
1854 {{LBS_EXTENDEDSEL},
1855 { 0, LB_ERR, 0, 0}, {0,0,0,0},
1856 { 1, 1, 1, 1}, {0,0,0,0},
1857 { 2, 2, 2, 1}, {0,0,0,0},
1858 { 0, LB_ERR, 0, 2}, {0,0,0,0}};
1859 const struct listbox_test ES_NS =
1860 {{LBS_EXTENDEDSEL | LBS_NOSEL},
1861 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
1862 { 1, 1, 1, LB_ERR}, {0,0,0,0},
1863 { 2, 2, 2, LB_ERR}, {0,0,0,0},
1864 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
1865 const struct listbox_test EMS =
1866 {{LBS_EXTENDEDSEL | LBS_MULTIPLESEL},
1867 { 0, LB_ERR, 0, 0}, {0,0,0,0},
1868 { 1, 1, 1, 1}, {0,0,0,0},
1869 { 2, 2, 2, 1}, {0,0,0,0},
1870 { 0, LB_ERR, 0, 2}, {0,0,0,0}};
1871 const struct listbox_test EMS_NS =
1872 {{LBS_EXTENDEDSEL | LBS_MULTIPLESEL | LBS_NOSEL},
1873 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
1874 { 1, 1, 1, LB_ERR}, {0,0,0,0},
1875 { 2, 2, 2, LB_ERR}, {0,0,0,0},
1876 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
1878 trace (" Testing single selection...\n");
1879 check (SS);
1880 trace (" ... with NOSEL\n");
1881 check (SS_NS);
1882 trace (" Testing multiple selection...\n");
1883 check (MS);
1884 trace (" ... with NOSEL\n");
1885 check (MS_NS);
1886 trace (" Testing extended selection...\n");
1887 check (ES);
1888 trace (" ... with NOSEL\n");
1889 check (ES_NS);
1890 trace (" Testing extended and multiple selection...\n");
1891 check (EMS);
1892 trace (" ... with NOSEL\n");
1893 check (EMS_NS);
1895 check_item_height();
1896 test_ownerdraw();
1897 test_LB_SELITEMRANGE();
1898 test_LB_SETCURSEL();
1899 test_listbox_height();
1900 test_itemfrompoint();
1901 test_listbox_item_data();
1902 test_listbox_LB_DIR();
1903 test_listbox_dlgdir();
1904 test_set_count();
1905 test_GetListBoxInfo();
1906 test_missing_lbuttonup();
1907 test_extents();