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/heap.h"
31 #include "wine/test.h"
41 static struct msg_sequence
*sequences
[NUM_MSG_SEQUENCES
];
43 /* encoded MEASUREITEMSTRUCT into a WPARAM */
57 } MEASURE_ITEM_STRUCT
;
59 static unsigned hash_Ly_W(const WCHAR
*str
)
64 hash
= hash
* 1664525u + (unsigned char)(*str
) + 1013904223u;
69 static unsigned hash_Ly(const char *str
)
74 hash
= hash
* 1664525u + (unsigned char)(*str
) + 1013904223u;
79 static const char * const strings
[4] = {
83 "Fourth added which is very long because at some time we only had a 256 byte character buffer and "
84 "that was overflowing in one of those applications that had a common dialog file open box and tried "
85 "to add a 300 characters long custom filter string which of course the code did not like and crashed. "
86 "Just make sure this string is longer than 256 characters."
89 static const char BAD_EXTENSION
[] = "*.badtxt";
93 static HWND
create_listbox(DWORD add_style
, HWND parent
)
101 handle
= CreateWindowA(WC_LISTBOXA
, "TestList", (LBS_STANDARD
& ~LBS_SORT
) | add_style
, 0, 0, 100, 100,
102 parent
, (HMENU
)ctl_id
, NULL
, 0);
103 ok(handle
!= NULL
, "Failed to create listbox window.\n");
105 SendMessageA(handle
, LB_ADDSTRING
, 0, (LPARAM
) strings
[0]);
106 SendMessageA(handle
, LB_ADDSTRING
, 0, (LPARAM
) strings
[1]);
107 SendMessageA(handle
, LB_ADDSTRING
, 0, (LPARAM
) strings
[2]);
108 SendMessageA(handle
, LB_ADDSTRING
, 0, (LPARAM
) strings
[3]);
120 int selected
, anchor
, caret
, selcount
;
125 struct listbox_prop prop
;
126 struct listbox_stat init
, init_todo
;
127 struct listbox_stat click
, click_todo
;
128 struct listbox_stat step
, step_todo
;
129 struct listbox_stat sel
, sel_todo
;
132 static void listbox_query(HWND handle
, struct listbox_stat
*results
)
134 results
->selected
= SendMessageA(handle
, LB_GETCURSEL
, 0, 0);
135 results
->anchor
= SendMessageA(handle
, LB_GETANCHORINDEX
, 0, 0);
136 results
->caret
= SendMessageA(handle
, LB_GETCARETINDEX
, 0, 0);
137 results
->selcount
= SendMessageA(handle
, LB_GETSELCOUNT
, 0, 0);
140 static void buttonpress(HWND handle
, WORD x
, WORD y
)
142 LPARAM lp
= x
+ (y
<< 16);
144 SendMessageA(handle
, WM_LBUTTONDOWN
, MK_LBUTTON
, lp
);
145 SendMessageA(handle
, WM_LBUTTONUP
, 0, lp
);
148 static void keypress(HWND handle
, WPARAM keycode
, BYTE scancode
, BOOL extended
)
150 LPARAM lp
= 1 + (scancode
<< 16) + (extended
? KEYEVENTF_EXTENDEDKEY
: 0);
152 SendMessageA(handle
, WM_KEYDOWN
, keycode
, lp
);
153 SendMessageA(handle
, WM_KEYUP
, keycode
, lp
| 0xc000000);
156 #define listbox_field_ok(t, s, f, got) \
157 ok (t.s.f==got.f, "style %#x, step " #s ", field " #f \
158 ": expected %d, got %d\n", (unsigned int)t.prop.add_style, \
161 #define listbox_todo_field_ok(t, s, f, got) \
162 todo_wine_if (t.s##_todo.f) { listbox_field_ok(t, s, f, got); }
164 #define listbox_ok(t, s, got) \
165 listbox_todo_field_ok(t, s, selected, got); \
166 listbox_todo_field_ok(t, s, anchor, got); \
167 listbox_todo_field_ok(t, s, caret, got); \
168 listbox_todo_field_ok(t, s, selcount, got)
170 static void run_test(const struct listbox_test test
)
172 struct listbox_stat answer
;
173 HWND hLB
=create_listbox (test
.prop
.add_style
, 0);
177 listbox_query (hLB
, &answer
);
178 listbox_ok (test
, init
, answer
);
180 SendMessageA(hLB
, LB_GETITEMRECT
, 1, (LPARAM
) &second_item
);
181 buttonpress(hLB
, (WORD
)second_item
.left
, (WORD
)second_item
.top
);
183 listbox_query(hLB
, &answer
);
184 listbox_ok(test
, click
, answer
);
186 keypress(hLB
, VK_DOWN
, 0x50, TRUE
);
188 listbox_query(hLB
, &answer
);
189 listbox_ok(test
, step
, answer
);
193 hLB
= create_listbox(test
.prop
.add_style
, 0);
195 SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(1, 2));
196 listbox_query(hLB
, &answer
);
197 listbox_ok(test
, sel
, answer
);
199 for (i
= 0; i
< 4; i
++)
201 DWORD size
= SendMessageA(hLB
, LB_GETTEXTLEN
, i
, 0);
206 txt
= heap_alloc_zero(size
+ 1);
207 resA
= SendMessageA(hLB
, LB_GETTEXT
, i
, (LPARAM
)txt
);
208 ok(!strcmp(txt
, strings
[i
]), "returned string for item %d does not match %s vs %s\n", i
, txt
, strings
[i
]);
210 txtw
= heap_alloc_zero((size
+ 1) * sizeof(*txtw
));
211 resW
= SendMessageW(hLB
, LB_GETTEXT
, i
, (LPARAM
)txtw
);
213 trace("SendMessageW(LB_GETTEXT) not supported on this platform (resA=%d resW=%d), skipping...\n", resA
, resW
);
216 WideCharToMultiByte(CP_ACP
, 0, txtw
, -1, txt
, size
, NULL
, NULL
);
217 ok(!strcmp (txt
, strings
[i
]), "returned string for item %d does not match %s vs %s\n", i
, txt
, strings
[i
]);
224 /* Confirm the count of items, and that an invalid delete does not remove anything */
225 res
= SendMessageA(hLB
, LB_GETCOUNT
, 0, 0);
226 ok(res
== 4, "Expected 4 items, got %d\n", res
);
227 res
= SendMessageA(hLB
, LB_DELETESTRING
, -1, 0);
228 ok(res
== LB_ERR
, "Expected LB_ERR items, got %d\n", res
);
229 res
= SendMessageA(hLB
, LB_DELETESTRING
, 4, 0);
230 ok(res
== LB_ERR
, "Expected LB_ERR items, got %d\n", res
);
231 res
= SendMessageA(hLB
, LB_GETCOUNT
, 0, 0);
232 ok(res
== 4, "Expected 4 items, got %d\n", res
);
237 static void test_item_height(void)
245 hLB
= create_listbox (0, 0);
246 ok ((hdc
= GetDCEx( hLB
, 0, DCX_CACHE
)) != 0, "Can't get hdc\n");
247 ok ((font
= GetCurrentObject(hdc
, OBJ_FONT
)) != 0, "Can't get the current font\n");
248 ok (GetTextMetricsA( hdc
, &tm
), "Can't read font metrics\n");
249 ReleaseDC( hLB
, hdc
);
251 ok (SendMessageA(hLB
, WM_SETFONT
, (WPARAM
)font
, 0) == 0, "Can't set font\n");
253 itemHeight
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 0, 0);
254 ok (itemHeight
== tm
.tmHeight
, "Item height wrong, got %d, expecting %d\n", itemHeight
, tm
.tmHeight
);
258 hLB
= CreateWindowA(WC_LISTBOXA
, "TestList", LBS_OWNERDRAWVARIABLE
, 0, 0, 100, 100, NULL
, NULL
, NULL
, 0);
260 itemHeight
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 0, 0);
261 ok(itemHeight
> 0 && itemHeight
<= tm
.tmHeight
, "Unexpected item height %d, expected %d.\n",
262 itemHeight
, tm
.tmHeight
);
263 itemHeight
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 5, 0);
264 ok(itemHeight
> 0 && itemHeight
<= tm
.tmHeight
, "Unexpected item height %d, expected %d.\n",
265 itemHeight
, tm
.tmHeight
);
266 itemHeight
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, -5, 0);
267 ok(itemHeight
> 0 && itemHeight
<= tm
.tmHeight
, "Unexpected item height %d, expected %d.\n",
268 itemHeight
, tm
.tmHeight
);
273 static int got_selchange
;
275 static LRESULT WINAPI
main_window_proc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
277 static LONG defwndproc_counter
= 0;
278 struct message m
= { 0 };
282 m
.flags
= sent
|wparam
|lparam
;
283 if (defwndproc_counter
) m
.flags
|= defwinproc
;
291 MEASUREITEMSTRUCT
*mis
= (void *)lParam
;
292 BOOL is_unicode_data
= FALSE
;
293 MEASURE_ITEM_STRUCT mi
;
295 if (mis
->CtlType
== ODT_LISTBOX
)
297 HWND ctrl
= GetDlgItem(hwnd
, mis
->CtlID
);
298 is_unicode_data
= GetWindowLongA(ctrl
, GWL_STYLE
) & LBS_HASSTRINGS
;
302 mi
.u
.item
.CtlType
= mis
->CtlType
;
303 mi
.u
.item
.CtlID
= mis
->CtlID
;
304 mi
.u
.item
.itemID
= mis
->itemID
;
305 mi
.u
.item
.wParam
= wParam
;
309 m
.lParam
= mis
->itemData
? hash_Ly_W((const WCHAR
*)mis
->itemData
) : 0;
311 m
.lParam
= mis
->itemData
? hash_Ly((const char *)mis
->itemData
) : 0;
312 add_message(sequences
, PARENT_SEQ_INDEX
, &m
);
314 ok(wParam
== mis
->CtlID
, "got wParam=%08lx, expected %08x\n", wParam
, mis
->CtlID
);
315 ok(mis
->CtlType
== ODT_LISTBOX
, "mi->CtlType = %u\n", mis
->CtlType
);
316 ok(mis
->CtlID
== 1, "mi->CtlID = %u\n", mis
->CtlID
);
317 ok(mis
->itemHeight
, "mi->itemHeight = 0\n");
323 COMPAREITEMSTRUCT
*cis
= (COMPAREITEMSTRUCT
*)lParam
;
324 HWND ctrl
= GetDlgItem(hwnd
, cis
->CtlID
);
325 BOOL is_unicode_data
= TRUE
;
327 ok(wParam
== cis
->CtlID
, "expected %#x, got %#lx\n", cis
->CtlID
, wParam
);
328 ok(cis
->hwndItem
== ctrl
, "expected %p, got %p\n", ctrl
, cis
->hwndItem
);
329 ok((int)cis
->itemID1
>= 0, "expected >= 0, got %d\n", cis
->itemID1
);
330 ok((int)cis
->itemID2
== -1, "expected -1, got %d\n", cis
->itemID2
);
332 if (cis
->CtlType
== ODT_LISTBOX
)
333 is_unicode_data
= GetWindowLongA(ctrl
, GWL_STYLE
) & LBS_HASSTRINGS
;
337 m
.wParam
= cis
->itemData1
? hash_Ly_W((const WCHAR
*)cis
->itemData1
) : 0;
338 m
.lParam
= cis
->itemData2
? hash_Ly_W((const WCHAR
*)cis
->itemData2
) : 0;
342 m
.wParam
= cis
->itemData1
? hash_Ly((const char *)cis
->itemData1
) : 0;
343 m
.lParam
= cis
->itemData2
? hash_Ly((const char *)cis
->itemData2
) : 0;
345 add_message(sequences
, PARENT_SEQ_INDEX
, &m
);
350 RECT rc_item
, rc_client
, rc_clip
;
351 DRAWITEMSTRUCT
*dis
= (DRAWITEMSTRUCT
*)lParam
;
353 ok(wParam
== dis
->CtlID
, "got wParam=%08lx instead of %08x\n", wParam
, dis
->CtlID
);
354 ok(dis
->CtlType
== ODT_LISTBOX
, "wrong CtlType %04x\n", dis
->CtlType
);
356 GetClientRect(dis
->hwndItem
, &rc_client
);
357 GetClipBox(dis
->hDC
, &rc_clip
);
358 ok(EqualRect(&rc_client
, &rc_clip
) || IsRectEmpty(&rc_clip
),
359 "client rect of the listbox should be equal to the clip box,"
360 "or the clip box should be empty\n");
362 SendMessageA(dis
->hwndItem
, LB_GETITEMRECT
, dis
->itemID
, (LPARAM
)&rc_item
);
363 ok(EqualRect(&dis
->rcItem
, &rc_item
), "item rects are not equal\n");
369 if (HIWORD( wParam
) == LBN_SELCHANGE
) got_selchange
++;
376 defwndproc_counter
++;
377 ret
= DefWindowProcA(hwnd
, msg
, wParam
, lParam
);
378 defwndproc_counter
--;
380 return msg
== WM_COMPAREITEM
? -1 : ret
;
383 static HWND
create_parent( void )
391 cls
.lpfnWndProc
= main_window_proc
;
394 cls
.hInstance
= GetModuleHandleA(NULL
);
396 cls
.hCursor
= LoadCursorA(0, (LPCSTR
)IDC_ARROW
);
397 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
398 cls
.lpszMenuName
= NULL
;
399 cls
.lpszClassName
= "main_window_class";
400 class = RegisterClassA( &cls
);
403 return CreateWindowExA(0, "main_window_class", NULL
, WS_POPUP
| WS_VISIBLE
, 100, 100, 400, 400, GetDesktopWindow(),
404 0, GetModuleHandleA(NULL
), NULL
);
407 static void test_ownerdraw(void)
413 parent
= create_parent();
414 ok(parent
!= NULL
, "Failed to create parent window.\n");
416 hLB
= create_listbox(LBS_OWNERDRAWFIXED
| WS_CHILD
| WS_VISIBLE
, parent
);
417 ok(hLB
!= NULL
, "Failed to create listbox window.\n");
419 SetForegroundWindow(hLB
);
422 /* make height short enough */
423 SendMessageA(hLB
, LB_GETITEMRECT
, 0, (LPARAM
)&rc
);
424 SetWindowPos(hLB
, 0, 0, 0, 100, rc
.bottom
- rc
.top
+ 1, SWP_NOZORDER
| SWP_NOMOVE
);
426 /* make 0 item invisible */
427 SendMessageA(hLB
, LB_SETTOPINDEX
, 1, 0);
428 ret
= SendMessageA(hLB
, LB_GETTOPINDEX
, 0, 0);
429 ok(ret
== 1, "wrong top index %d\n", ret
);
431 SendMessageA(hLB
, LB_GETITEMRECT
, 0, (LPARAM
)&rc
);
432 ok(!IsRectEmpty(&rc
), "empty item rect\n");
433 ok(rc
.top
< 0, "rc.top is not negative (%d)\n", rc
.top
);
437 /* Both FIXED and VARIABLE, FIXED should override VARIABLE. */
438 hLB
= CreateWindowA(WC_LISTBOXA
, "TestList", LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
, 0, 0, 100, 100,
439 NULL
, NULL
, NULL
, 0);
440 ok(hLB
!= NULL
, "last error 0x%08x\n", GetLastError());
442 ret
= SendMessageA(hLB
, LB_INSERTSTRING
, -1, 0);
443 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
444 ret
= SendMessageA(hLB
, LB_INSERTSTRING
, -1, 0);
445 ok(ret
== 1, "Unexpected return value %d.\n", ret
);
447 ret
= SendMessageA(hLB
, LB_SETITEMHEIGHT
, 0, 13);
448 ok(ret
== LB_OKAY
, "Failed to set item height, %d.\n", ret
);
450 ret
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 0, 0);
451 ok(ret
== 13, "Unexpected item height %d.\n", ret
);
453 ret
= SendMessageA(hLB
, LB_SETITEMHEIGHT
, 1, 42);
454 ok(ret
== LB_OKAY
, "Failed to set item height, %d.\n", ret
);
456 ret
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 0, 0);
458 ok(ret
== 42, "Unexpected item height %d.\n", ret
);
460 ret
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 1, 0);
461 ok(ret
== 42, "Unexpected item height %d.\n", ret
);
465 DestroyWindow(parent
);
468 #define listbox_test_query(exp, got) \
469 ok(exp.selected == got.selected, "expected selected %d, got %d\n", exp.selected, got.selected); \
470 ok(exp.anchor == got.anchor, "expected anchor %d, got %d\n", exp.anchor, got.anchor); \
471 ok(exp.caret == got.caret, "expected caret %d, got %d\n", exp.caret, got.caret); \
472 ok(exp.selcount == got.selcount, "expected selcount %d, got %d\n", exp.selcount, got.selcount);
474 static void test_LB_SELITEMRANGE(void)
476 static const struct listbox_stat test_nosel
= { 0, LB_ERR
, 0, 0 };
477 static const struct listbox_stat test_1
= { 0, LB_ERR
, 0, 2 };
478 static const struct listbox_stat test_2
= { 0, LB_ERR
, 0, 3 };
479 static const struct listbox_stat test_3
= { 0, LB_ERR
, 0, 4 };
480 struct listbox_stat answer
;
484 hLB
= create_listbox(LBS_EXTENDEDSEL
, 0);
485 ok(hLB
!= NULL
, "Failed to create listbox window.\n");
487 listbox_query(hLB
, &answer
);
488 listbox_test_query(test_nosel
, answer
);
490 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(1, 2));
491 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
492 listbox_query(hLB
, &answer
);
493 listbox_test_query(test_1
, answer
);
495 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
496 listbox_query(hLB
, &answer
);
497 listbox_test_query(test_nosel
, answer
);
499 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(0, 4));
500 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
501 listbox_query(hLB
, &answer
);
502 listbox_test_query(test_3
, answer
);
504 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
505 listbox_query(hLB
, &answer
);
506 listbox_test_query(test_nosel
, answer
);
508 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(-5, 5));
509 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
510 listbox_query(hLB
, &answer
);
511 listbox_test_query(test_nosel
, answer
);
513 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
514 listbox_query(hLB
, &answer
);
515 listbox_test_query(test_nosel
, answer
);
517 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(2, 10));
518 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
519 listbox_query(hLB
, &answer
);
520 listbox_test_query(test_1
, answer
);
522 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
523 listbox_query(hLB
, &answer
);
524 listbox_test_query(test_nosel
, answer
);
526 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(4, 10));
527 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
528 listbox_query(hLB
, &answer
);
529 listbox_test_query(test_nosel
, answer
);
531 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
532 listbox_query(hLB
, &answer
);
533 listbox_test_query(test_nosel
, answer
);
535 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(10, 1));
536 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
537 listbox_query(hLB
, &answer
);
538 listbox_test_query(test_2
, answer
);
540 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
541 listbox_query(hLB
, &answer
);
542 listbox_test_query(test_nosel
, answer
);
544 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(1, -1));
545 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
546 listbox_query(hLB
, &answer
);
547 listbox_test_query(test_2
, answer
);
552 static void test_LB_SETCURSEL(void)
557 parent
= create_parent();
558 ok(parent
!= NULL
, "Failed to create parent window.\n");
560 hLB
= create_listbox(LBS_NOINTEGRALHEIGHT
| WS_CHILD
, parent
);
561 ok(hLB
!= NULL
, "Failed to create listbox.\n");
563 SendMessageA(hLB
, LB_SETITEMHEIGHT
, 0, 32);
565 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
566 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
568 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 2, 0);
569 ok(ret
== 2, "LB_SETCURSEL returned %d instead of 2\n", ret
);
570 ret
= GetScrollPos(hLB
, SB_VERT
);
571 ok(ret
== 0, "expected vscroll 0, got %d\n", ret
);
573 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
574 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
576 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 3, 0);
577 ok(ret
== 3, "LB_SETCURSEL returned %d instead of 3\n", ret
);
578 ret
= GetScrollPos(hLB
, SB_VERT
);
579 ok(ret
== 1, "expected vscroll 1, got %d\n", ret
);
581 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
582 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
586 hLB
= create_listbox(0, 0);
587 ok(hLB
!= NULL
, "Failed to create ListBox window.\n");
589 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 1, 0);
590 ok(ret
== 1, "Unexpected return value %d.\n", ret
);
592 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
593 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
597 /* LBS_EXTENDEDSEL */
598 hLB
= create_listbox(LBS_EXTENDEDSEL
, 0);
599 ok(hLB
!= NULL
, "Failed to create listbox.\n");
601 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
602 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
604 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 2, 0);
605 ok(ret
== -1, "LB_SETCURSEL returned %d instead of 2\n", ret
);
607 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
608 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
612 /* LBS_MULTIPLESEL */
613 hLB
= create_listbox(LBS_MULTIPLESEL
, 0);
614 ok(hLB
!= NULL
, "Failed to create listbox.\n");
616 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
617 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
619 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 2, 0);
620 ok(ret
== -1, "LB_SETCURSEL returned %d instead of 2\n", ret
);
622 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
623 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
628 static void test_LB_SETSEL(void)
633 /* LBS_EXTENDEDSEL */
634 list
= create_listbox(LBS_EXTENDEDSEL
, 0);
635 ok(list
!= NULL
, "Failed to create ListBox window.\n");
637 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
638 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
640 ret
= SendMessageA(list
, LB_SETSEL
, TRUE
, 0);
641 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
642 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
643 ok(ret
== 0, "Unexpected anchor index %d.\n", ret
);
645 ret
= SendMessageA(list
, LB_SETSEL
, TRUE
, 1);
646 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
647 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
648 ok(ret
== 1, "Unexpected anchor index %d.\n", ret
);
650 ret
= SendMessageA(list
, LB_SETSEL
, FALSE
, 1);
651 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
652 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
653 ok(ret
== 1, "Unexpected anchor index %d.\n", ret
);
657 /* LBS_MULTIPLESEL */
658 list
= create_listbox(LBS_MULTIPLESEL
, 0);
659 ok(list
!= NULL
, "Failed to create ListBox window.\n");
661 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
662 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
664 ret
= SendMessageA(list
, LB_SETSEL
, TRUE
, 0);
665 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
666 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
667 ok(ret
== 0, "Unexpected anchor index %d.\n", ret
);
669 ret
= SendMessageA(list
, LB_SETSEL
, TRUE
, 1);
670 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
671 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
672 ok(ret
== 1, "Unexpected anchor index %d.\n", ret
);
674 ret
= SendMessageA(list
, LB_SETSEL
, FALSE
, 1);
675 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
676 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
677 ok(ret
== 1, "Unexpected anchor index %d.\n", ret
);
682 static void test_listbox_height(void)
687 hList
= CreateWindowA( WC_LISTBOXA
, "list test", 0,
688 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
689 ok( hList
!= NULL
, "failed to create listbox\n");
691 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi");
692 ok( id
== 0, "item id wrong\n");
694 r
= SendMessageA( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 20, 0 ));
695 ok( r
== 0, "send message failed\n");
697 r
= SendMessageA(hList
, LB_GETITEMHEIGHT
, 0, 0 );
698 ok( r
== 20, "height wrong\n");
700 r
= SendMessageA( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 0, 30 ));
701 ok( r
== -1, "send message failed\n");
703 r
= SendMessageA(hList
, LB_GETITEMHEIGHT
, 0, 0 );
704 ok( r
== 20, "height wrong\n");
706 r
= SendMessageA( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 256, 0 ));
707 ok( r
== -1, "Failed to set item height, %d.\n", r
);
709 r
= SendMessageA(hList
, LB_GETITEMHEIGHT
, 0, 0 );
710 ok( r
== 20, "Unexpected item height %d.\n", r
);
712 r
= SendMessageA( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 0xff, 0 ));
713 ok( r
== 0, "send message failed\n");
715 r
= SendMessageA(hList
, LB_GETITEMHEIGHT
, 0, 0 );
716 ok( r
== 0xff, "height wrong\n");
718 DestroyWindow( hList
);
721 static void test_itemfrompoint(void)
723 /* WS_POPUP is required in order to have a more accurate size calculation (
724 without caption). LBS_NOINTEGRALHEIGHT is required in order to test
725 behavior of partially-displayed item.
727 HWND hList
= CreateWindowA( WC_LISTBOXA
, "list test",
728 WS_VISIBLE
|WS_POPUP
|LBS_NOINTEGRALHEIGHT
,
729 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
733 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
734 ok( r
== MAKELPARAM(0xffff, 1), "Unexpected ret value %#x.\n", r
);
736 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( 700, 30 ));
737 ok( r
== MAKELPARAM(0xffff, 1), "Unexpected ret value %#x.\n", r
);
739 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( 30, 300 ));
740 ok( r
== MAKELPARAM(0xffff, 1), "Unexpected ret value %#x.\n", r
);
742 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi");
743 ok( id
== 0, "item id wrong\n");
744 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi1");
745 ok( id
== 1, "item id wrong\n");
747 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
748 ok( r
== 0x1, "ret %x\n", r
);
750 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( /* x */ 30, /* y */ 601 ));
751 ok( r
== MAKELPARAM(1, 1), "Unexpected ret value %#x.\n", r
);
753 /* Resize control so that below assertions about sizes are valid */
754 r
= SendMessageA( hList
, LB_GETITEMRECT
, 0, (LPARAM
)&rc
);
755 ok( r
== 1, "ret %x\n", r
);
756 r
= MoveWindow(hList
, 1, 1, 600, (rc
.bottom
- rc
.top
+ 1) * 9 / 2, TRUE
);
757 ok( r
!= 0, "ret %x\n", r
);
759 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi2");
760 ok( id
== 2, "item id wrong\n");
761 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi3");
762 ok( id
== 3, "item id wrong\n");
763 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi4");
764 ok( id
== 4, "item id wrong\n");
765 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi5");
766 ok( id
== 5, "item id wrong\n");
767 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi6");
768 ok( id
== 6, "item id wrong\n");
769 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi7");
770 ok( id
== 7, "item id wrong\n");
772 /* Set the listbox up so that id 1 is at the top, this leaves 5
773 partially visible at the bottom and 6, 7 are invisible */
775 SendMessageA( hList
, LB_SETTOPINDEX
, 1, 0);
776 r
= SendMessageA( hList
, LB_GETTOPINDEX
, 0, 0);
777 ok( r
== 1, "top %d\n", r
);
779 r
= SendMessageA( hList
, LB_GETITEMRECT
, 5, (LPARAM
)&rc
);
780 ok( r
== 1, "ret %x\n", r
);
781 r
= SendMessageA( hList
, LB_GETITEMRECT
, 6, (LPARAM
)&rc
);
782 ok( r
== 0, "ret %x\n", r
);
784 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(/* x */ 10, /* y */ 10) );
785 ok( r
== 1, "ret %x\n", r
);
787 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(1000, 10) );
788 ok( r
== 0x10001, "ret %x\n", r
);
790 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(10, -10) );
791 ok( r
== 0x10001, "ret %x\n", r
);
793 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(10, 100) );
794 ok( r
== 0x10005, "item %x\n", r
);
796 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(10, 200) );
797 ok( r
== 0x10005, "item %x\n", r
);
799 DestroyWindow( hList
);
802 static void test_listbox_item_data(void)
807 hList
= CreateWindowA( WC_LISTBOXA
, "list test", 0,
808 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
809 ok( hList
!= NULL
, "failed to create listbox\n");
811 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi");
812 ok( id
== 0, "item id wrong\n");
814 r
= SendMessageA( hList
, LB_SETITEMDATA
, 0, MAKELPARAM( 20, 0 ));
815 ok(r
== TRUE
, "LB_SETITEMDATA returned %d instead of TRUE\n", r
);
817 r
= SendMessageA( hList
, LB_GETITEMDATA
, 0, 0);
818 ok( r
== 20, "get item data failed\n");
820 DestroyWindow( hList
);
823 static void test_listbox_LB_DIR(void)
825 char path
[MAX_PATH
], curdir
[MAX_PATH
];
828 int itemCount_justFiles
;
829 int itemCount_justDrives
;
830 int itemCount_allFiles
;
831 int itemCount_allDirs
;
833 char pathBuffer
[MAX_PATH
];
836 const char *wildcard
= "*";
840 GetCurrentDirectoryA(ARRAY_SIZE(curdir
), curdir
);
842 GetTempPathA(ARRAY_SIZE(path
), path
);
843 ret
= SetCurrentDirectoryA(path
);
844 ok(ret
, "Failed to set current directory.\n");
846 ret
= CreateDirectoryA("lb_dir_test", NULL
);
847 ok(ret
, "Failed to create test directory.\n");
849 file
= CreateFileA( "wtest1.tmp.c", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, FILE_ATTRIBUTE_NORMAL
, NULL
);
850 ok(file
!= INVALID_HANDLE_VALUE
, "Error creating the test file: %d\n", GetLastError());
853 /* NOTE: for this test to succeed, there must be no subdirectories
854 under the current directory. In addition, there must be at least
855 one file that fits the wildcard w*.c . Normally, the test
856 directory itself satisfies both conditions.
858 hList
= CreateWindowA( WC_LISTBOXA
, "list test", WS_VISIBLE
|WS_POPUP
,
859 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
860 ok(hList
!= NULL
, "Failed to create listbox window.\n");
862 /* Test for standard usage */
864 /* This should list all the files in the test directory. */
865 strcpy(pathBuffer
, wildcard
);
866 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
867 res
= SendMessageA(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
868 if (res
== -1) /* "*" wildcard doesn't work on win9x */
871 strcpy(pathBuffer
, wildcard
);
872 res
= SendMessageA(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
874 ok (res
>= 0, "SendMessage(LB_DIR, 0, *) failed - 0x%08x\n", GetLastError());
876 /* There should be some content in the listbox */
877 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
878 ok (itemCount
> 0, "SendMessage(LB_DIR) did NOT fill the listbox!\n");
879 itemCount_allFiles
= itemCount
;
880 ok(res
+ 1 == itemCount
,
881 "SendMessage(LB_DIR, 0, *) returned incorrect index (expected %d got %d)!\n",
884 /* This tests behavior when no files match the wildcard */
885 strcpy(pathBuffer
, BAD_EXTENSION
);
886 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
887 res
= SendMessageA(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
888 ok (res
== -1, "SendMessage(LB_DIR, 0, %s) returned %d, expected -1\n", BAD_EXTENSION
, res
);
890 /* There should be NO content in the listbox */
891 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
892 ok (itemCount
== 0, "SendMessage(LB_DIR) DID fill the listbox!\n");
895 /* This should list all the w*.c files in the test directory
896 * As of this writing, this includes win.c, winstation.c, wsprintf.c
898 strcpy(pathBuffer
, "w*.c");
899 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
900 res
= SendMessageA(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
901 ok (res
>= 0, "SendMessage(LB_DIR, 0, w*.c) failed - 0x%08x\n", GetLastError());
903 /* Path specification does NOT converted to uppercase */
904 ok (!strcmp(pathBuffer
, "w*.c"),
905 "expected no change to pathBuffer, got %s\n", pathBuffer
);
907 /* There should be some content in the listbox */
908 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
909 ok (itemCount
> 0, "SendMessage(LB_DIR) did NOT fill the listbox!\n");
910 itemCount_justFiles
= itemCount
;
911 ok(res
+ 1 == itemCount
,
912 "SendMessage(LB_DIR, 0, w*.c) returned incorrect index (expected %d got %d)!\n",
915 /* Every single item in the control should start with a w and end in .c */
916 for (i
= 0; i
< itemCount
; i
++)
918 memset(pathBuffer
, 0, MAX_PATH
);
919 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
920 p
= pathBuffer
+ strlen(pathBuffer
);
921 ok(((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
922 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
923 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
926 /* Test DDL_DIRECTORY */
927 strcpy(pathBuffer
, wildcard
);
928 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
929 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
, (LPARAM
)pathBuffer
);
930 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY, *) failed - 0x%08x\n", GetLastError());
932 /* There should be some content in the listbox.
933 * All files plus "[..]"
935 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
936 itemCount_allDirs
= itemCount
- itemCount_allFiles
;
937 ok (itemCount
>= itemCount_allFiles
,
938 "SendMessage(LB_DIR, DDL_DIRECTORY, *) filled with %d entries, expected > %d\n",
939 itemCount
, itemCount_allFiles
);
940 ok(res
+ 1 == itemCount
,
941 "SendMessage(LB_DIR, DDL_DIRECTORY, *) returned incorrect index (expected %d got %d)!\n",
944 /* This tests behavior when no files match the wildcard */
945 strcpy(pathBuffer
, BAD_EXTENSION
);
946 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
947 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
, (LPARAM
)pathBuffer
);
948 ok (res
== -1, "SendMessage(LB_DIR, DDL_DIRECTORY, %s) returned %d, expected -1\n", BAD_EXTENSION
, res
);
950 /* There should be NO content in the listbox */
951 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
952 ok (itemCount
== 0, "SendMessage(LB_DIR) DID fill the listbox!\n");
954 /* Test DDL_DIRECTORY */
955 strcpy(pathBuffer
, "w*.c");
956 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
957 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
, (LPARAM
)pathBuffer
);
958 ok (res
>= 0, "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) failed - 0x%08x\n", GetLastError());
960 /* There should be some content in the listbox. Since the parent directory does not
961 * fit w*.c, there should be exactly the same number of items as without DDL_DIRECTORY
963 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
964 ok (itemCount
== itemCount_justFiles
,
965 "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) filled with %d entries, expected %d\n",
966 itemCount
, itemCount_justFiles
);
967 ok(res
+ 1 == itemCount
,
968 "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) returned incorrect index (expected %d got %d)!\n",
971 /* Every single item in the control should start with a w and end in .c. */
972 for (i
= 0; i
< itemCount
; i
++)
974 memset(pathBuffer
, 0, MAX_PATH
);
975 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
976 p
= pathBuffer
+ strlen(pathBuffer
);
978 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
979 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
980 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
983 /* Test DDL_DRIVES|DDL_EXCLUSIVE */
984 strcpy(pathBuffer
, wildcard
);
985 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
986 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
987 ok (res
>= 0, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) failed - 0x%08x\n", GetLastError());
989 /* There should be some content in the listbox. In particular, there should
990 * be at least one element before, since the string "[-c-]" should
991 * have been added. Depending on the user setting, more drives might have
994 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
996 "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) filled with %d entries, expected at least %d\n",
998 itemCount_justDrives
= itemCount
;
999 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) returned incorrect index!\n");
1001 /* Every single item in the control should fit the format [-c-] */
1002 for (i
= 0; i
< itemCount
; i
++)
1004 memset(pathBuffer
, 0, MAX_PATH
);
1006 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1007 ok( strlen(pathBuffer
) == 5, "Length of drive string is not 5\n" );
1008 ok( sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1, "Element %d (%s) does not fit [-X-]\n", i
, pathBuffer
);
1009 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1010 if (!(driveletter
>= 'a' && driveletter
<= 'z'))
1012 /* Correct after invalid entry is found */
1013 itemCount_justDrives
--;
1017 /* This tests behavior when no files match the wildcard */
1018 strcpy(pathBuffer
, BAD_EXTENSION
);
1019 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1020 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1021 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1022 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
1024 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1025 ok (itemCount
== itemCount_justDrives
, "SendMessage(LB_DIR) returned %d expected %d\n",
1026 itemCount
, itemCount_justDrives
);
1028 /* Test DDL_DRIVES. */
1029 strcpy(pathBuffer
, wildcard
);
1030 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1031 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
, (LPARAM
)pathBuffer
);
1032 ok (res
> 0, "SendMessage(LB_DIR, DDL_DRIVES, *) failed - 0x%08x\n", GetLastError());
1034 /* There should be some content in the listbox. In particular, there should
1035 * be at least one element before, since the string "[-c-]" should
1036 * have been added. Depending on the user setting, more drives might have
1039 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1040 ok (itemCount
== itemCount_justDrives
+ itemCount_allFiles
,
1041 "SendMessage(LB_DIR, DDL_DRIVES, *) filled with %d entries, expected %d\n",
1042 itemCount
, itemCount_justDrives
+ itemCount_allFiles
);
1043 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DRIVES, *) returned incorrect index!\n");
1045 /* This tests behavior when no files match the wildcard */
1046 strcpy(pathBuffer
, BAD_EXTENSION
);
1047 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1048 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
, (LPARAM
)pathBuffer
);
1049 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DRIVES, %s) returned %d, expected %d\n",
1050 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
1052 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1053 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
1055 /* Test DDL_DRIVES. */
1056 strcpy(pathBuffer
, "w*.c");
1057 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1058 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
, (LPARAM
)pathBuffer
);
1059 ok (res
> 0, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) failed - 0x%08x\n", GetLastError());
1061 /* There should be some content in the listbox. In particular, there should
1062 * be at least one element before, since the string "[-c-]" should
1063 * have been added. Depending on the user setting, more drives might have
1066 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1067 ok (itemCount
== itemCount_justDrives
+ itemCount_justFiles
,
1068 "SendMessage(LB_DIR, DDL_DRIVES, w*.c) filled with %d entries, expected %d\n",
1069 itemCount
, itemCount_justDrives
+ itemCount_justFiles
);
1070 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) returned incorrect index!\n");
1072 /* Every single item in the control should fit the format [-c-], or w*.c */
1073 for (i
= 0; i
< itemCount
; i
++)
1075 memset(pathBuffer
, 0, MAX_PATH
);
1077 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1078 p
= pathBuffer
+ strlen(pathBuffer
);
1079 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1)
1081 ok( strlen(pathBuffer
) == 5, "Length of drive string is not 5\n" );
1082 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1087 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1088 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1089 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1093 /* Test DDL_DIRECTORY|DDL_DRIVES. This does *not* imply DDL_EXCLUSIVE */
1094 strcpy(pathBuffer
, wildcard
);
1095 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1096 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
, (LPARAM
)pathBuffer
);
1097 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, *) failed - 0x%08x\n", GetLastError());
1099 /* There should be some content in the listbox. In particular, there should
1100 * be exactly the number of plain files, plus the number of mapped drives.
1102 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1103 ok (itemCount
== itemCount_allFiles
+ itemCount_justDrives
+ itemCount_allDirs
,
1104 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1105 itemCount
, itemCount_allFiles
+ itemCount_justDrives
+ itemCount_allDirs
);
1106 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
1108 /* Every single item in the control should start with a w and end in .c,
1109 * except for the "[..]" string, which should appear exactly as it is,
1110 * and the mapped drives in the format "[-X-]".
1112 for (i
= 0; i
< itemCount
; i
++)
1114 memset(pathBuffer
, 0, MAX_PATH
);
1116 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1117 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1)
1118 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1121 /* This tests behavior when no files match the wildcard */
1122 strcpy(pathBuffer
, BAD_EXTENSION
);
1123 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1124 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
, (LPARAM
)pathBuffer
);
1125 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, %s) returned %d, expected %d\n",
1126 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
1128 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1129 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
1131 /* Test DDL_DIRECTORY|DDL_DRIVES. */
1132 strcpy(pathBuffer
, "w*.c");
1133 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1134 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
, (LPARAM
)pathBuffer
);
1135 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) failed - 0x%08x\n", GetLastError());
1137 /* There should be some content in the listbox. In particular, there should
1138 * be exactly the number of plain files, plus the number of mapped drives.
1140 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1141 ok (itemCount
== itemCount_justFiles
+ itemCount_justDrives
,
1142 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1143 itemCount
, itemCount_justFiles
+ itemCount_justDrives
);
1144 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
1146 /* Every single item in the control should start with a w and end in .c,
1147 * except the mapped drives in the format "[-X-]". The "[..]" directory
1148 * should not appear.
1150 for (i
= 0; i
< itemCount
; i
++)
1152 memset(pathBuffer
, 0, MAX_PATH
);
1154 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1155 p
= pathBuffer
+ strlen(pathBuffer
);
1156 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1)
1157 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1160 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1161 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1162 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1165 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1166 strcpy(pathBuffer
, wildcard
);
1167 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1168 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1169 ok (res
!= -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) failed err %u\n",
1172 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1173 ok (itemCount
== itemCount_allDirs
,
1174 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1175 itemCount
, itemCount_allDirs
);
1176 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) returned incorrect index!\n");
1180 memset(pathBuffer
, 0, MAX_PATH
);
1181 SendMessageA(hList
, LB_GETTEXT
, 0, (LPARAM
)pathBuffer
);
1182 ok( !strcmp(pathBuffer
, "[..]"), "First element is %s, not [..]\n", pathBuffer
);
1185 /* This tests behavior when no files match the wildcard */
1186 strcpy(pathBuffer
, BAD_EXTENSION
);
1187 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1188 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1189 ok (res
== -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1190 BAD_EXTENSION
, res
, -1);
1192 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1193 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
1196 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1197 strcpy(pathBuffer
, "w*.c");
1198 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1199 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1200 ok (res
== LB_ERR
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, w*.c) returned %d expected %d\n", res
, LB_ERR
);
1202 /* There should be no elements, since "[..]" does not fit w*.c */
1203 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1205 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1208 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1209 strcpy(pathBuffer
, wildcard
);
1210 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1211 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1212 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
1214 /* There should be no plain files on the listbox */
1215 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1216 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
1217 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1218 itemCount
, itemCount_justDrives
+ itemCount_allDirs
);
1219 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
1221 for (i
= 0; i
< itemCount
; i
++)
1223 memset(pathBuffer
, 0, MAX_PATH
);
1225 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1226 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1)
1227 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1229 ok( pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']',
1230 "Element %d (%s) does not fit expected [...]\n", i
, pathBuffer
);
1233 /* This tests behavior when no files match the wildcard */
1234 strcpy(pathBuffer
, BAD_EXTENSION
);
1235 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1236 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1237 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1238 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
1240 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1241 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
1243 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1244 strcpy(pathBuffer
, "w*.c");
1245 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1246 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1247 ok (res
>= 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
1249 /* There should be no plain files on the listbox, and no [..], since it does not fit w*.c */
1250 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1251 ok (itemCount
== itemCount_justDrives
,
1252 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1253 itemCount
, itemCount_justDrives
);
1254 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
1256 for (i
= 0; i
< itemCount
; i
++)
1258 memset(pathBuffer
, 0, MAX_PATH
);
1260 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1261 ok (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1, "Element %d (%s) does not fit [-X-]\n", i
, pathBuffer
);
1262 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1264 DestroyWindow(hList
);
1266 DeleteFileA( "wtest1.tmp.c" );
1267 RemoveDirectoryA("lb_dir_test");
1269 SetCurrentDirectoryA(curdir
);
1272 static HWND g_listBox
;
1273 static HWND g_label
;
1275 #define ID_TEST_LABEL 1001
1276 #define ID_TEST_LISTBOX 1002
1278 static BOOL
on_listbox_container_create(HWND hwnd
, CREATESTRUCTA
*lpcs
)
1280 g_label
= CreateWindowA(WC_STATICA
, "Contents of static control before DlgDirList.",
1281 WS_CHILD
| WS_VISIBLE
, 10, 10, 512, 32, hwnd
, (HMENU
)ID_TEST_LABEL
, NULL
, 0);
1282 if (!g_label
) return FALSE
;
1284 g_listBox
= CreateWindowA(WC_LISTBOXA
, "DlgDirList test",
1285 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| WS_BORDER
| WS_VSCROLL
, 10, 60, 256, 256,
1286 hwnd
, (HMENU
)ID_TEST_LISTBOX
, NULL
, 0);
1287 if (!g_listBox
) return FALSE
;
1292 static LRESULT CALLBACK
listbox_container_window_procA(HWND hwnd
, UINT uiMsg
, WPARAM wParam
, LPARAM lParam
)
1302 result
= on_listbox_container_create(hwnd
, (CREATESTRUCTA
*)lParam
) ? 0 : (LRESULT
)-1;
1305 result
= DefWindowProcA(hwnd
, uiMsg
, wParam
, lParam
);
1311 static BOOL
RegisterListboxWindowClass(HINSTANCE hInst
)
1318 cls
.hInstance
= hInst
;
1320 cls
.hCursor
= LoadCursorA (NULL
, (LPCSTR
)IDC_ARROW
);
1321 cls
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
1322 cls
.lpszMenuName
= NULL
;
1323 cls
.lpfnWndProc
= listbox_container_window_procA
;
1324 cls
.lpszClassName
= "ListboxContainerClass";
1325 if (!RegisterClassA (&cls
)) return FALSE
;
1330 static void test_listbox_dlgdir(void)
1335 int itemCount_allDirs
;
1336 int itemCount_justFiles
;
1337 int itemCount_justDrives
;
1339 char pathBuffer
[MAX_PATH
];
1340 char itemBuffer
[MAX_PATH
];
1341 char tempBuffer
[MAX_PATH
];
1347 file
= CreateFileA( "wtest1.tmp.c", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1348 ok(file
!= INVALID_HANDLE_VALUE
, "Error creating the test file: %d\n", GetLastError());
1349 CloseHandle( file
);
1351 /* NOTE: for this test to succeed, there must be no subdirectories
1352 under the current directory. In addition, there must be at least
1353 one file that fits the wildcard w*.c . Normally, the test
1354 directory itself satisfies both conditions.
1357 hInst
= GetModuleHandleA(0);
1358 ret
= RegisterListboxWindowClass(hInst
);
1359 ok(ret
, "Failed to register test class.\n");
1361 hWnd
= CreateWindowA("ListboxContainerClass", "ListboxContainerClass",
1362 WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
1363 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
1364 NULL
, NULL
, hInst
, 0);
1365 ok(hWnd
!= NULL
, "Failed to create container window.\n");
1367 /* Test for standard usage */
1369 /* The following should be overwritten by the directory path */
1370 SendMessageA(g_label
, WM_SETTEXT
, 0, (LPARAM
)"default contents");
1372 /* This should list all the w*.c files in the test directory
1373 * As of this writing, this includes win.c, winstation.c, wsprintf.c
1375 strcpy(pathBuffer
, "w*.c");
1376 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, 0);
1377 ok (res
== 1, "DlgDirList(*.c, 0) returned %d - expected 1 - 0x%08x\n", res
, GetLastError());
1379 /* Path specification gets converted to uppercase */
1380 ok (!strcmp(pathBuffer
, "W*.C"),
1381 "expected conversion to uppercase, got %s\n", pathBuffer
);
1383 /* Loaded path should have overwritten the label text */
1384 SendMessageA(g_label
, WM_GETTEXT
, MAX_PATH
, (LPARAM
)pathBuffer
);
1385 ok (strcmp("default contents", pathBuffer
), "DlgDirList() did not modify static control!\n");
1387 /* There should be some content in the listbox */
1388 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1389 ok (itemCount
> 0, "DlgDirList() did NOT fill the listbox!\n");
1390 itemCount_justFiles
= itemCount
;
1392 /* Every single item in the control should start with a w and end in .c */
1393 for (i
= 0; i
< itemCount
; i
++)
1395 memset(pathBuffer
, 0, MAX_PATH
);
1396 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1397 p
= pathBuffer
+ strlen(pathBuffer
);
1398 ok(((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1399 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1400 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1403 /* Test behavior when no files match the wildcard */
1404 strcpy(pathBuffer
, BAD_EXTENSION
);
1405 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, 0);
1406 ok (res
== 1, "DlgDirList(%s, 0) returned %d expected 1\n", BAD_EXTENSION
, res
);
1408 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1409 ok (itemCount
== 0, "DlgDirList() DID fill the listbox!\n");
1411 /* Test DDL_DIRECTORY */
1412 strcpy(pathBuffer
, "w*.c");
1413 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
);
1414 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY) failed - 0x%08x\n", GetLastError());
1416 /* There should be some content in the listbox. In particular, there should
1417 * be exactly more elements than before, since the directories should
1420 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1421 itemCount_allDirs
= itemCount
- itemCount_justFiles
;
1422 ok (itemCount
>= itemCount_justFiles
, "DlgDirList(DDL_DIRECTORY) filled with %d entries, expected > %d\n",
1423 itemCount
, itemCount_justFiles
);
1425 /* Every single item in the control should start with a w and end in .c,
1426 * except for the "[..]" string, which should appear exactly as it is.
1428 for (i
= 0; i
< itemCount
; i
++)
1430 memset(pathBuffer
, 0, MAX_PATH
);
1431 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1432 p
= pathBuffer
+ strlen(pathBuffer
);
1433 ok( (pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']') ||
1434 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1435 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1436 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1439 /* Test behavior when no files match the wildcard */
1440 strcpy(pathBuffer
, BAD_EXTENSION
);
1441 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
);
1442 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY) returned %d expected 1\n", BAD_EXTENSION
, res
);
1444 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1445 ok (itemCount
== itemCount_allDirs
, "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
1446 itemCount_allDirs
, itemCount
);
1447 for (i
= 0; i
< itemCount
; i
++)
1449 memset(pathBuffer
, 0, MAX_PATH
);
1450 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1451 ok( pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']',
1452 "Element %d (%s) does not fit requested [...]\n", i
, pathBuffer
);
1455 /* Test DDL_DRIVES. At least on WinXP-SP2, this implies DDL_EXCLUSIVE */
1456 strcpy(pathBuffer
, "w*.c");
1457 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DRIVES
);
1458 ok (res
== 1, "DlgDirList(*.c, DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1460 /* There should be some content in the listbox. In particular, there should
1461 * be at least one element before, since the string "[-c-]" should
1462 * have been added. Depending on the user setting, more drives might have
1465 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1467 "DlgDirList(DDL_DRIVES) filled with %d entries, expected at least %d\n",
1469 itemCount_justDrives
= itemCount
;
1471 /* Every single item in the control should fit the format [-c-] */
1472 for (i
= 0; i
< itemCount
; i
++)
1474 memset(pathBuffer
, 0, MAX_PATH
);
1476 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1477 ok( strlen(pathBuffer
) == 5, "Length of drive string is not 5\n" );
1478 ok( sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1, "Element %d (%s) does not fit [-X-]\n", i
, pathBuffer
);
1479 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1480 if (!(driveletter
>= 'a' && driveletter
<= 'z')) {
1481 /* Correct after invalid entry is found */
1482 trace("removing count of invalid entry %s\n", pathBuffer
);
1483 itemCount_justDrives
--;
1487 /* Test behavior when no files match the wildcard */
1488 strcpy(pathBuffer
, BAD_EXTENSION
);
1489 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DRIVES
);
1490 ok (res
== 1, "DlgDirList(%s, DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION
, res
);
1492 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1493 ok (itemCount
== itemCount_justDrives
, "DlgDirList() incorrectly filled the listbox!\n");
1495 /* Test DDL_DIRECTORY|DDL_DRIVES. This does *not* imply DDL_EXCLUSIVE */
1496 strcpy(pathBuffer
, "w*.c");
1497 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_DRIVES
);
1498 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1500 /* There should be some content in the listbox. In particular, there should
1501 * be exactly the number of plain files, plus the number of mapped drives,
1504 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1505 ok (itemCount
== itemCount_justFiles
+ itemCount_justDrives
+ itemCount_allDirs
,
1506 "DlgDirList(DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1507 itemCount
, itemCount_justFiles
+ itemCount_justDrives
+ itemCount_allDirs
);
1509 /* Every single item in the control should start with a w and end in .c,
1510 * except for the "[..]" string, which should appear exactly as it is,
1511 * and the mapped drives in the format "[-X-]".
1513 for (i
= 0; i
< itemCount
; i
++)
1515 memset(pathBuffer
, 0, MAX_PATH
);
1517 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1518 p
= pathBuffer
+ strlen(pathBuffer
);
1519 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1)
1520 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1522 ok( (pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']') ||
1523 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1524 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1525 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1528 /* Test behavior when no files match the wildcard */
1529 strcpy(pathBuffer
, BAD_EXTENSION
);
1530 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_DRIVES
);
1531 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION
, res
);
1533 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1534 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
1535 "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
1536 itemCount_justDrives
+ itemCount_allDirs
, itemCount
);
1538 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1539 strcpy(pathBuffer
, "w*.c");
1540 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_EXCLUSIVE
);
1541 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_EXCLUSIVE) failed - 0x%08x\n", GetLastError());
1543 /* There should be exactly one element: "[..]" */
1544 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1545 ok (itemCount
== itemCount_allDirs
,
1546 "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1547 itemCount
, itemCount_allDirs
);
1549 if (itemCount
&& GetCurrentDirectoryA( MAX_PATH
, pathBuffer
) > 3) /* there's no [..] in drive root */
1551 memset(pathBuffer
, 0, MAX_PATH
);
1552 SendMessageA(g_listBox
, LB_GETTEXT
, 0, (LPARAM
)pathBuffer
);
1553 ok( !strcmp(pathBuffer
, "[..]"), "First (and only) element is not [..]\n");
1556 /* Test behavior when no files match the wildcard */
1557 strcpy(pathBuffer
, BAD_EXTENSION
);
1558 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_EXCLUSIVE
);
1559 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION
, res
);
1561 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1562 ok (itemCount
== itemCount_allDirs
, "DlgDirList() incorrectly filled the listbox!\n");
1564 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1565 strcpy(pathBuffer
, "w*.c");
1566 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
);
1567 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) failed - 0x%08x\n", GetLastError());
1569 /* There should be no plain files on the listbox */
1570 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1571 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
1572 "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1573 itemCount
, itemCount_justDrives
+ itemCount_allDirs
);
1575 for (i
= 0; i
< itemCount
; i
++)
1577 memset(pathBuffer
, 0, MAX_PATH
);
1579 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1580 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1)
1581 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1583 ok( pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']',
1584 "Element %d (%s) does not fit expected [...]\n", i
, pathBuffer
);
1587 /* Test behavior when no files match the wildcard */
1588 strcpy(pathBuffer
, BAD_EXTENSION
);
1589 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
);
1590 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION
, res
);
1592 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1593 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
, "DlgDirList() incorrectly filled the listbox!\n");
1595 /* Now test DlgDirSelectEx() in normal operation */
1596 /* Fill with everything - drives, directory and all plain files. */
1597 strcpy(pathBuffer
, "*");
1598 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_DRIVES
);
1599 ok (res
!= 0, "DlgDirList(*, DDL_DIRECTORY|DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1601 SendMessageA(g_listBox
, LB_SETCURSEL
, -1, 0); /* Unselect any current selection */
1602 memset(pathBuffer
, 0, MAX_PATH
);
1603 SetLastError(0xdeadbeef);
1604 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1605 ok (GetLastError() == 0xdeadbeef,
1606 "DlgDirSelectEx() with no selection modified last error code from 0xdeadbeef to 0x%08x\n",
1608 ok (res
== 0, "DlgDirSelectEx() with no selection returned %d, expected 0\n", res
);
1609 /* WinXP-SP2 leaves pathBuffer untouched, but Win98 fills it with garbage. */
1611 ok (strlen(pathBuffer) == 0, "DlgDirSelectEx() with no selection filled buffer with %s\n", pathBuffer);
1613 /* Test proper drive/dir/file recognition */
1614 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1615 for (i
= 0; i
< itemCount
; i
++)
1617 memset(itemBuffer
, 0, MAX_PATH
);
1618 memset(pathBuffer
, 0, MAX_PATH
);
1619 memset(tempBuffer
, 0, MAX_PATH
);
1621 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)itemBuffer
);
1622 res
= SendMessageA(g_listBox
, LB_SETCURSEL
, i
, 0);
1623 ok (res
== i
, "SendMessageA(LB_SETCURSEL, %d) failed\n", i
);
1624 if (sscanf(itemBuffer
, "[-%c-]", &driveletter
) == 1)
1626 /* Current item is a drive letter */
1627 SetLastError(0xdeadbeef);
1628 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1629 ok (GetLastError() == 0xdeadbeef,
1630 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1632 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1634 /* For drive letters, DlgDirSelectEx tacks on a colon */
1635 ok (pathBuffer
[0] == driveletter
&& pathBuffer
[1] == ':' && pathBuffer
[2] == '\0',
1636 "%d: got \"%s\" expected \"%c:\"\n", i
, pathBuffer
, driveletter
);
1638 else if (itemBuffer
[0] == '[')
1640 /* Current item is the parent directory */
1641 SetLastError(0xdeadbeef);
1642 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1643 ok (GetLastError() == 0xdeadbeef,
1644 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1646 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1648 /* For directories, DlgDirSelectEx tacks on a backslash */
1649 p
= pathBuffer
+ strlen(pathBuffer
);
1650 ok (*(p
-1) == '\\', "DlgDirSelectEx did NOT tack on a backslash to dir, got %s\n", pathBuffer
);
1652 tempBuffer
[0] = '[';
1653 lstrcpynA(tempBuffer
+ 1, pathBuffer
, strlen(pathBuffer
));
1654 strcat(tempBuffer
, "]");
1655 ok (!strcmp(tempBuffer
, itemBuffer
), "Formatted directory should be %s, got %s\n", tempBuffer
, itemBuffer
);
1659 /* Current item is a plain file */
1660 SetLastError(0xdeadbeef);
1661 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1662 ok (GetLastError() == 0xdeadbeef,
1663 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1665 ok(res
== 0, "DlgDirSelectEx() thinks %s (%s) is a drive/directory!\n", itemBuffer
, pathBuffer
);
1667 /* NOTE: WinXP tacks a period on all files that lack an extension. This affects
1668 * for example, "Makefile", which gets reported as "Makefile."
1670 strcpy(tempBuffer
, itemBuffer
);
1671 if (strchr(tempBuffer
, '.') == NULL
) strcat(tempBuffer
, ".");
1672 ok (!strcmp(pathBuffer
, tempBuffer
), "Formatted file should be %s, got %s\n", tempBuffer
, pathBuffer
);
1676 DeleteFileA( "wtest1.tmp.c" );
1678 /* Now test DlgDirSelectEx() in abnormal operation */
1679 /* Fill list with bogus entries, that look somewhat valid */
1680 SendMessageA(g_listBox
, LB_RESETCONTENT
, 0, 0);
1681 SendMessageA(g_listBox
, LB_ADDSTRING
, 0, (LPARAM
)"[notexist.dir]");
1682 SendMessageA(g_listBox
, LB_ADDSTRING
, 0, (LPARAM
)"notexist.fil");
1683 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1684 for (i
= 0; i
< itemCount
; i
++)
1686 memset(itemBuffer
, 0, MAX_PATH
);
1687 memset(pathBuffer
, 0, MAX_PATH
);
1688 memset(tempBuffer
, 0, MAX_PATH
);
1690 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)itemBuffer
);
1691 res
= SendMessageA(g_listBox
, LB_SETCURSEL
, i
, 0);
1692 ok (res
== i
, "SendMessage(LB_SETCURSEL, %d) failed\n", i
);
1693 if (sscanf(itemBuffer
, "[-%c-]", &driveletter
) == 1)
1695 /* Current item is a drive letter */
1696 SetLastError(0xdeadbeef);
1697 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1698 ok (GetLastError() == 0xdeadbeef,
1699 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1701 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1703 /* For drive letters, DlgDirSelectEx tacks on a colon */
1704 ok (pathBuffer
[0] == driveletter
&& pathBuffer
[1] == ':' && pathBuffer
[2] == '\0',
1705 "%d: got \"%s\" expected \"%c:\"\n", i
, pathBuffer
, driveletter
);
1707 else if (itemBuffer
[0] == '[')
1709 /* Current item is the parent directory */
1710 SetLastError(0xdeadbeef);
1711 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1712 ok (GetLastError() == 0xdeadbeef,
1713 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1715 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1717 /* For directories, DlgDirSelectEx tacks on a backslash */
1718 p
= pathBuffer
+ strlen(pathBuffer
);
1719 ok (*(p
-1) == '\\', "DlgDirSelectEx did NOT tack on a backslash to dir, got %s\n", pathBuffer
);
1721 tempBuffer
[0] = '[';
1722 lstrcpynA(tempBuffer
+ 1, pathBuffer
, strlen(pathBuffer
));
1723 strcat(tempBuffer
, "]");
1724 ok (!strcmp(tempBuffer
, itemBuffer
), "Formatted directory should be %s, got %s\n", tempBuffer
, itemBuffer
);
1728 /* Current item is a plain file */
1729 SetLastError(0xdeadbeef);
1730 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1731 ok (GetLastError() == 0xdeadbeef,
1732 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1734 ok(res
== 0, "DlgDirSelectEx() thinks %s (%s) is a drive/directory!\n", itemBuffer
, pathBuffer
);
1736 /* NOTE: WinXP and Win98 tack a period on all files that lack an extension.
1737 * This affects for example, "Makefile", which gets reported as "Makefile."
1739 strcpy(tempBuffer
, itemBuffer
);
1740 if (strchr(tempBuffer
, '.') == NULL
) strcat(tempBuffer
, ".");
1741 ok (!strcmp(pathBuffer
, tempBuffer
), "Formatted file should be %s, got %s\n", tempBuffer
, pathBuffer
);
1745 /* Test behavior when loading folders from root with and without wildcard */
1746 strcpy(pathBuffer
, "C:\\");
1747 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, 0, DDL_DIRECTORY
| DDL_EXCLUSIVE
);
1748 ok(res
, "DlgDirList failed to list C:\\ folders\n");
1749 todo_wine
ok(!strcmp(pathBuffer
, "*"), "DlgDirList set the invalid path spec '%s', expected '*'\n", pathBuffer
);
1751 strcpy(pathBuffer
, "C:\\*");
1752 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, 0, DDL_DIRECTORY
| DDL_EXCLUSIVE
);
1753 ok(res
, "DlgDirList failed to list C:\\* folders\n");
1754 ok(!strcmp(pathBuffer
, "*"), "DlgDirList set the invalid path spec '%s', expected '*'\n", pathBuffer
);
1756 /* Try loading files from an invalid folder */
1757 SetLastError(0xdeadbeef);
1758 strcpy(pathBuffer
, "C:\\INVALID$$DIR");
1759 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, 0, DDL_DIRECTORY
| DDL_EXCLUSIVE
);
1760 todo_wine
ok(!res
, "DlgDirList should have failed with 0 but %d was returned\n", res
);
1761 todo_wine
ok(GetLastError() == ERROR_NO_WILDCARD_CHARACTERS
,
1762 "GetLastError should return 0x589, got 0x%X\n",GetLastError());
1764 DestroyWindow(hWnd
);
1767 static void test_set_count( void )
1769 static const DWORD styles
[] =
1774 HWND parent
, listbox
;
1779 parent
= create_parent();
1780 listbox
= create_listbox( LBS_OWNERDRAWFIXED
| LBS_NODATA
| WS_CHILD
| WS_VISIBLE
, parent
);
1782 UpdateWindow( listbox
);
1783 GetUpdateRect( listbox
, &r
, TRUE
);
1784 ok( IsRectEmpty( &r
), "got non-empty rect\n");
1786 ret
= SendMessageA( listbox
, LB_SETCOUNT
, 100, 0 );
1787 ok( ret
== 0, "got %d\n", ret
);
1788 ret
= SendMessageA( listbox
, LB_GETCOUNT
, 0, 0 );
1789 ok( ret
== 100, "got %d\n", ret
);
1791 GetUpdateRect( listbox
, &r
, TRUE
);
1792 ok( !IsRectEmpty( &r
), "got empty rect\n");
1794 ValidateRect( listbox
, NULL
);
1795 GetUpdateRect( listbox
, &r
, TRUE
);
1796 ok( IsRectEmpty( &r
), "got non-empty rect\n");
1798 ret
= SendMessageA( listbox
, LB_SETCOUNT
, 99, 0 );
1799 ok( ret
== 0, "got %d\n", ret
);
1801 GetUpdateRect( listbox
, &r
, TRUE
);
1802 ok( !IsRectEmpty( &r
), "got empty rect\n");
1804 DestroyWindow( listbox
);
1806 for (i
= 0; i
< ARRAY_SIZE(styles
); ++i
)
1808 listbox
= create_listbox( styles
[i
] | WS_CHILD
| WS_VISIBLE
, parent
);
1810 SetLastError( 0xdeadbeef );
1811 ret
= SendMessageA( listbox
, LB_SETCOUNT
, 100, 0 );
1812 todo_wine_if(i
== 0)
1813 ok( ret
== LB_ERR
, "expected %d, got %d\n", LB_ERR
, ret
);
1814 todo_wine_if(i
== 1)
1815 ok( GetLastError() == 0xdeadbeef, "Unexpected error %d.\n", GetLastError() );
1817 DestroyWindow( listbox
);
1820 DestroyWindow( parent
);
1823 static int lb_getlistboxinfo
;
1825 static LRESULT WINAPI
listbox_subclass_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1827 WNDPROC oldproc
= (WNDPROC
)GetWindowLongPtrA(hwnd
, GWLP_USERDATA
);
1829 if (message
== LB_GETLISTBOXINFO
)
1830 lb_getlistboxinfo
++;
1832 return CallWindowProcA(oldproc
, hwnd
, message
, wParam
, lParam
);
1835 static void test_GetListBoxInfo(void)
1837 HWND listbox
, parent
;
1841 parent
= create_parent();
1842 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
, parent
);
1844 oldproc
= (WNDPROC
)SetWindowLongPtrA(listbox
, GWLP_WNDPROC
, (LONG_PTR
)listbox_subclass_proc
);
1845 SetWindowLongPtrA(listbox
, GWLP_USERDATA
, (LONG_PTR
)oldproc
);
1847 lb_getlistboxinfo
= 0;
1848 ret
= GetListBoxInfo(listbox
);
1849 ok(ret
> 0, "got %d\n", ret
);
1850 ok(lb_getlistboxinfo
== 1, "got %d\n", lb_getlistboxinfo
);
1852 DestroyWindow(listbox
);
1853 DestroyWindow(parent
);
1856 static void test_missing_lbuttonup(void)
1858 HWND listbox
, parent
, capture
;
1860 parent
= create_parent();
1861 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
, parent
);
1863 /* Send button down without a corresponding button up */
1864 SendMessageA(listbox
, WM_LBUTTONDOWN
, 0, MAKELPARAM(10, 10));
1865 capture
= GetCapture();
1866 ok(capture
== listbox
, "got %p expected %p\n", capture
, listbox
);
1868 /* Capture is released and LBN_SELCHANGE sent during WM_KILLFOCUS */
1871 capture
= GetCapture();
1872 ok(capture
== NULL
, "got %p\n", capture
);
1873 ok(got_selchange
, "got %d\n", got_selchange
);
1875 DestroyWindow(listbox
);
1876 DestroyWindow(parent
);
1879 static void test_extents(void)
1881 HWND listbox
, parent
;
1886 parent
= create_parent();
1888 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
, parent
);
1890 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1891 ok(res
== 0, "Got wrong initial horizontal extent: %u\n", res
);
1893 sinfo
.cbSize
= sizeof(sinfo
);
1894 sinfo
.fMask
= SIF_RANGE
;
1895 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1896 ok(br
== TRUE
, "GetScrollInfo failed\n");
1897 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1898 ok(sinfo
.nMax
== 100, "got wrong max: %u\n", sinfo
.nMax
);
1899 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1900 "List box should not have a horizontal scroll bar\n");
1902 /* horizontal extent < width */
1903 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 64, 0);
1905 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1906 ok(res
== 64, "Got wrong horizontal extent: %u\n", res
);
1908 sinfo
.cbSize
= sizeof(sinfo
);
1909 sinfo
.fMask
= SIF_RANGE
;
1910 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1911 ok(br
== TRUE
, "GetScrollInfo failed\n");
1912 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1913 ok(sinfo
.nMax
== 100, "got wrong max: %u\n", sinfo
.nMax
);
1914 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1915 "List box should not have a horizontal scroll bar\n");
1917 /* horizontal extent > width */
1918 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 184, 0);
1920 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1921 ok(res
== 184, "Got wrong horizontal extent: %u\n", res
);
1923 sinfo
.cbSize
= sizeof(sinfo
);
1924 sinfo
.fMask
= SIF_RANGE
;
1925 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1926 ok(br
== TRUE
, "GetScrollInfo failed\n");
1927 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1928 ok(sinfo
.nMax
== 100, "got wrong max: %u\n", sinfo
.nMax
);
1929 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1930 "List box should not have a horizontal scroll bar\n");
1932 DestroyWindow(listbox
);
1934 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
| WS_HSCROLL
, parent
);
1936 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1937 ok(res
== 0, "Got wrong initial horizontal extent: %u\n", res
);
1939 sinfo
.cbSize
= sizeof(sinfo
);
1940 sinfo
.fMask
= SIF_RANGE
;
1941 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1942 ok(br
== TRUE
, "GetScrollInfo failed\n");
1943 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1944 ok(sinfo
.nMax
== 100, "got wrong max: %u\n", sinfo
.nMax
);
1945 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1946 "List box should not have a horizontal scroll bar\n");
1948 /* horizontal extent < width */
1949 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 64, 0);
1951 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1952 ok(res
== 64, "Got wrong horizontal extent: %u\n", res
);
1954 sinfo
.cbSize
= sizeof(sinfo
);
1955 sinfo
.fMask
= SIF_RANGE
;
1956 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1957 ok(br
== TRUE
, "GetScrollInfo failed\n");
1958 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1959 ok(sinfo
.nMax
== 63, "got wrong max: %u\n", sinfo
.nMax
);
1960 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1961 "List box should not have a horizontal scroll bar\n");
1963 /* horizontal extent > width */
1964 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 184, 0);
1966 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1967 ok(res
== 184, "Got wrong horizontal extent: %u\n", res
);
1969 sinfo
.cbSize
= sizeof(sinfo
);
1970 sinfo
.fMask
= SIF_RANGE
;
1971 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1972 ok(br
== TRUE
, "GetScrollInfo failed\n");
1973 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1974 ok(sinfo
.nMax
== 183, "got wrong max: %u\n", sinfo
.nMax
);
1975 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
1976 "List box should have a horizontal scroll bar\n");
1978 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 0, 0);
1980 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1981 ok(res
== 0, "Got wrong horizontal extent: %u\n", res
);
1983 sinfo
.cbSize
= sizeof(sinfo
);
1984 sinfo
.fMask
= SIF_RANGE
;
1985 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1986 ok(br
== TRUE
, "GetScrollInfo failed\n");
1987 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1988 ok(sinfo
.nMax
== 0, "got wrong max: %u\n", sinfo
.nMax
);
1989 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1990 "List box should not have a horizontal scroll bar\n");
1992 DestroyWindow(listbox
);
1995 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
| WS_HSCROLL
| LBS_DISABLENOSCROLL
, parent
);
1997 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1998 ok(res
== 0, "Got wrong initial horizontal extent: %u\n", res
);
2000 sinfo
.cbSize
= sizeof(sinfo
);
2001 sinfo
.fMask
= SIF_RANGE
;
2002 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
2003 ok(br
== TRUE
, "GetScrollInfo failed\n");
2004 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
2005 ok(sinfo
.nMax
== 0, "got wrong max: %u\n", sinfo
.nMax
);
2006 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
2007 "List box should have a horizontal scroll bar\n");
2009 /* horizontal extent < width */
2010 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 64, 0);
2012 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
2013 ok(res
== 64, "Got wrong horizontal extent: %u\n", res
);
2015 sinfo
.cbSize
= sizeof(sinfo
);
2016 sinfo
.fMask
= SIF_RANGE
;
2017 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
2018 ok(br
== TRUE
, "GetScrollInfo failed\n");
2019 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
2020 ok(sinfo
.nMax
== 63, "got wrong max: %u\n", sinfo
.nMax
);
2021 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
2022 "List box should have a horizontal scroll bar\n");
2024 /* horizontal extent > width */
2025 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 184, 0);
2027 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
2028 ok(res
== 184, "Got wrong horizontal extent: %u\n", res
);
2030 sinfo
.cbSize
= sizeof(sinfo
);
2031 sinfo
.fMask
= SIF_RANGE
;
2032 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
2033 ok(br
== TRUE
, "GetScrollInfo failed\n");
2034 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
2035 ok(sinfo
.nMax
== 183, "got wrong max: %u\n", sinfo
.nMax
);
2036 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
2037 "List box should have a horizontal scroll bar\n");
2039 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 0, 0);
2041 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
2042 ok(res
== 0, "Got wrong horizontal extent: %u\n", res
);
2044 sinfo
.cbSize
= sizeof(sinfo
);
2045 sinfo
.fMask
= SIF_RANGE
;
2046 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
2047 ok(br
== TRUE
, "GetScrollInfo failed\n");
2048 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
2049 ok(sinfo
.nMax
== 0, "got wrong max: %u\n", sinfo
.nMax
);
2050 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
2051 "List box should have a horizontal scroll bar\n");
2053 DestroyWindow(listbox
);
2055 DestroyWindow(parent
);
2058 static void test_listbox(void)
2060 static const struct listbox_test SS
=
2063 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
2064 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
2065 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
2066 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
2068 /* {selected, anchor, caret, selcount}{TODO fields} */
2069 static const struct listbox_test SS_NS
=
2071 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
2072 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
2073 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
2074 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
2076 static const struct listbox_test MS
=
2078 { 0, LB_ERR
, 0, 0}, {0,0,0,0},
2079 { 1, 1, 1, 1}, {0,0,0,0},
2080 { 2, 1, 2, 1}, {0,0,0,0},
2081 { 0, LB_ERR
, 0, 2}, {0,0,0,0}};
2083 static const struct listbox_test MS_NS
=
2084 {{LBS_MULTIPLESEL
| LBS_NOSEL
},
2085 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
2086 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
2087 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
2088 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
2090 static const struct listbox_test ES
=
2092 { 0, LB_ERR
, 0, 0}, {0,0,0,0},
2093 { 1, 1, 1, 1}, {0,0,0,0},
2094 { 2, 2, 2, 1}, {0,0,0,0},
2095 { 0, LB_ERR
, 0, 2}, {0,0,0,0}};
2097 static const struct listbox_test ES_NS
=
2098 {{LBS_EXTENDEDSEL
| LBS_NOSEL
},
2099 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
2100 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
2101 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
2102 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
2104 static const struct listbox_test EMS
=
2105 {{LBS_EXTENDEDSEL
| LBS_MULTIPLESEL
},
2106 { 0, LB_ERR
, 0, 0}, {0,0,0,0},
2107 { 1, 1, 1, 1}, {0,0,0,0},
2108 { 2, 2, 2, 1}, {0,0,0,0},
2109 { 0, LB_ERR
, 0, 2}, {0,0,0,0}};
2111 static const struct listbox_test EMS_NS
=
2112 {{LBS_EXTENDEDSEL
| LBS_MULTIPLESEL
| LBS_NOSEL
},
2113 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
2114 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
2115 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
2116 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
2128 static const struct message lb_addstring_ownerdraw_parent_seq
[] =
2130 { WM_MEASUREITEM
, sent
|wparam
|lparam
, 0x1012, 0xf30604ed },
2131 { WM_MEASUREITEM
, sent
|wparam
|lparam
, 0x1112, 0xf30604ee },
2132 { WM_MEASUREITEM
, sent
|wparam
|lparam
, 0x1212, 0xf30604ef },
2136 static const struct message lb_addstring_sort_parent_seq
[] =
2138 { WM_MEASUREITEM
, sent
|wparam
|lparam
, 0x1012, 0xf30604ed },
2139 { WM_COMPAREITEM
, sent
|wparam
|lparam
, 0xf30604ed, 0xf30604ee },
2140 { WM_MEASUREITEM
, sent
|wparam
|lparam
, 0x1112, 0xf30604ee },
2141 { WM_COMPAREITEM
, sent
|wparam
|lparam
, 0xf30604ed, 0xf30604ef },
2142 { WM_COMPAREITEM
, sent
|wparam
|lparam
, 0xf30604ee, 0xf30604ef },
2143 { WM_MEASUREITEM
, sent
|wparam
|lparam
, 0x1212, 0xf30604ef },
2147 static const struct message empty_seq
[] =
2152 static void test_WM_MEASUREITEM(void)
2154 HWND parent
, listbox
;
2157 parent
= create_parent();
2158 listbox
= create_listbox(WS_CHILD
| LBS_OWNERDRAWVARIABLE
, parent
);
2160 data
= SendMessageA(listbox
, LB_GETITEMDATA
, 0, 0);
2161 ok(data
== (LRESULT
)strings
[0], "data = %08lx, expected %p\n", data
, strings
[0]);
2162 DestroyWindow(parent
);
2164 parent
= create_parent();
2165 listbox
= create_listbox(WS_CHILD
| LBS_OWNERDRAWVARIABLE
| LBS_HASSTRINGS
, parent
);
2167 data
= SendMessageA(listbox
, LB_GETITEMDATA
, 0, 0);
2168 ok(!data
, "data = %08lx\n", data
);
2170 /* LBS_HASSTRINGS */
2171 parent
= create_parent();
2172 listbox
= CreateWindowExA(WS_EX_NOPARENTNOTIFY
, WC_LISTBOXA
, NULL
,
2173 WS_CHILD
| LBS_NOTIFY
| LBS_OWNERDRAWVARIABLE
| LBS_HASSTRINGS
| WS_VISIBLE
,
2174 10, 10, 80, 80, parent
, (HMENU
)ID_LISTBOX
, 0, NULL
);
2176 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
2178 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 0");
2179 ok(ret
== 0, "expected 0, got %ld\n", ret
);
2180 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 1");
2181 ok(ret
== 1, "expected 1, got %ld\n", ret
);
2182 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 2");
2183 ok(ret
== 2, "expected 2, got %ld\n", ret
);
2185 ok_sequence(sequences
, PARENT_SEQ_INDEX
, lb_addstring_ownerdraw_parent_seq
,
2186 "LB_ADDSTRING (LBS_HASSTRINGS, ownerdraw)", FALSE
);
2187 DestroyWindow(listbox
);
2189 /* LBS_SORT, no LBS_HASSTRINGS */
2190 listbox
= CreateWindowExA(WS_EX_NOPARENTNOTIFY
, WC_LISTBOXA
, NULL
,
2191 WS_CHILD
| LBS_NOTIFY
| LBS_OWNERDRAWVARIABLE
| LBS_SORT
| WS_VISIBLE
,
2192 10, 10, 80, 80, parent
, (HMENU
)ID_LISTBOX
, 0, NULL
);
2194 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
2196 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 0");
2197 ok(ret
== 0, "expected 0, got %ld\n", ret
);
2198 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 1");
2199 ok(ret
== 1, "expected 1, got %ld\n", ret
);
2200 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 2");
2201 ok(ret
== 2, "expected 2, got %ld\n", ret
);
2203 ok_sequence(sequences
, PARENT_SEQ_INDEX
, lb_addstring_sort_parent_seq
, "LB_ADDSTRING (LBS_SORT)", FALSE
);
2204 DestroyWindow(listbox
);
2206 /* LBS_HASSTRINGS */
2207 listbox
= CreateWindowExA(WS_EX_NOPARENTNOTIFY
, WC_LISTBOXA
, NULL
,
2208 WS_CHILD
| LBS_NOTIFY
| LBS_HASSTRINGS
| WS_VISIBLE
,
2209 10, 10, 80, 80, parent
, (HMENU
)ID_LISTBOX
, 0, NULL
);
2211 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
2213 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 2");
2214 ok(ret
== 0, "expected 0, got %ld\n", ret
);
2215 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 0");
2216 ok(ret
== 1, "expected 1, got %ld\n", ret
);
2217 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 1");
2218 ok(ret
== 2, "expected 2, got %ld\n", ret
);
2220 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_seq
, "LB_ADDSTRING (LBS_HASSTRINGS)", FALSE
);
2221 DestroyWindow(listbox
);
2223 /* LBS_HASSTRINGS, LBS_SORT */
2224 listbox
= CreateWindowExA(WS_EX_NOPARENTNOTIFY
, WC_LISTBOXA
, NULL
,
2225 WS_CHILD
| LBS_NOTIFY
| LBS_HASSTRINGS
| LBS_SORT
| WS_VISIBLE
,
2226 10, 10, 80, 80, parent
, (HMENU
)ID_LISTBOX
, 0, NULL
);
2228 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
2230 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 2");
2231 ok(ret
== 0, "expected 0, got %ld\n", ret
);
2232 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 0");
2233 ok(ret
== 0, "expected 0, got %ld\n", ret
);
2234 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 1");
2235 ok(ret
== 1, "expected 1, got %ld\n", ret
);
2237 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_seq
, "LB_ADDSTRING (LBS_HASSTRINGS, LBS_SORT)", FALSE
);
2238 DestroyWindow(listbox
);
2240 DestroyWindow(parent
);
2245 ULONG_PTR ctx_cookie
;
2248 if (!load_v6_module(&ctx_cookie
, &hCtx
))
2251 init_msg_sequences(sequences
, NUM_MSG_SEQUENCES
);
2256 test_LB_SELITEMRANGE();
2257 test_LB_SETCURSEL();
2258 test_listbox_height();
2259 test_itemfrompoint();
2260 test_listbox_item_data();
2261 test_listbox_LB_DIR();
2262 test_listbox_dlgdir();
2264 test_GetListBoxInfo();
2265 test_missing_lbuttonup();
2267 test_WM_MEASUREITEM();
2270 unload_v6_module(ctx_cookie
, hCtx
);