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
);
436 DestroyWindow(parent
);
439 #define listbox_test_query(exp, got) \
440 ok(exp.selected == got.selected, "expected selected %d, got %d\n", exp.selected, got.selected); \
441 ok(exp.anchor == got.anchor, "expected anchor %d, got %d\n", exp.anchor, got.anchor); \
442 ok(exp.caret == got.caret, "expected caret %d, got %d\n", exp.caret, got.caret); \
443 ok(exp.selcount == got.selcount, "expected selcount %d, got %d\n", exp.selcount, got.selcount);
445 static void test_LB_SELITEMRANGE(void)
447 static const struct listbox_stat test_nosel
= { 0, LB_ERR
, 0, 0 };
448 static const struct listbox_stat test_1
= { 0, LB_ERR
, 0, 2 };
449 static const struct listbox_stat test_2
= { 0, LB_ERR
, 0, 3 };
450 static const struct listbox_stat test_3
= { 0, LB_ERR
, 0, 4 };
451 struct listbox_stat answer
;
455 hLB
= create_listbox(LBS_EXTENDEDSEL
, 0);
456 ok(hLB
!= NULL
, "Failed to create listbox window.\n");
458 listbox_query(hLB
, &answer
);
459 listbox_test_query(test_nosel
, answer
);
461 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(1, 2));
462 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
463 listbox_query(hLB
, &answer
);
464 listbox_test_query(test_1
, answer
);
466 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
467 listbox_query(hLB
, &answer
);
468 listbox_test_query(test_nosel
, answer
);
470 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(0, 4));
471 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
472 listbox_query(hLB
, &answer
);
473 listbox_test_query(test_3
, answer
);
475 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
476 listbox_query(hLB
, &answer
);
477 listbox_test_query(test_nosel
, answer
);
479 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(-5, 5));
480 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
481 listbox_query(hLB
, &answer
);
482 listbox_test_query(test_nosel
, answer
);
484 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
485 listbox_query(hLB
, &answer
);
486 listbox_test_query(test_nosel
, answer
);
488 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(2, 10));
489 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
490 listbox_query(hLB
, &answer
);
491 listbox_test_query(test_1
, answer
);
493 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
494 listbox_query(hLB
, &answer
);
495 listbox_test_query(test_nosel
, answer
);
497 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(4, 10));
498 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
499 listbox_query(hLB
, &answer
);
500 listbox_test_query(test_nosel
, answer
);
502 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
503 listbox_query(hLB
, &answer
);
504 listbox_test_query(test_nosel
, answer
);
506 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(10, 1));
507 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
508 listbox_query(hLB
, &answer
);
509 listbox_test_query(test_2
, answer
);
511 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
512 listbox_query(hLB
, &answer
);
513 listbox_test_query(test_nosel
, answer
);
515 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(1, -1));
516 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
517 listbox_query(hLB
, &answer
);
518 listbox_test_query(test_2
, answer
);
523 static void test_LB_SETCURSEL(void)
528 parent
= create_parent();
529 ok(parent
!= NULL
, "Failed to create parent window.\n");
531 hLB
= create_listbox(LBS_NOINTEGRALHEIGHT
| WS_CHILD
, parent
);
532 ok(hLB
!= NULL
, "Failed to create listbox.\n");
534 SendMessageA(hLB
, LB_SETITEMHEIGHT
, 0, 32);
536 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 2, 0);
537 ok(ret
== 2, "LB_SETCURSEL returned %d instead of 2\n", ret
);
538 ret
= GetScrollPos(hLB
, SB_VERT
);
539 ok(ret
== 0, "expected vscroll 0, got %d\n", ret
);
541 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 3, 0);
542 ok(ret
== 3, "LB_SETCURSEL returned %d instead of 3\n", ret
);
543 ret
= GetScrollPos(hLB
, SB_VERT
);
544 ok(ret
== 1, "expected vscroll 1, got %d\n", ret
);
549 static void test_listbox_height(void)
554 hList
= CreateWindowA( WC_LISTBOXA
, "list test", 0,
555 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
556 ok( hList
!= NULL
, "failed to create listbox\n");
558 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi");
559 ok( id
== 0, "item id wrong\n");
561 r
= SendMessageA( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 20, 0 ));
562 ok( r
== 0, "send message failed\n");
564 r
= SendMessageA(hList
, LB_GETITEMHEIGHT
, 0, 0 );
565 ok( r
== 20, "height wrong\n");
567 r
= SendMessageA( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 0, 30 ));
568 ok( r
== -1, "send message failed\n");
570 r
= SendMessageA(hList
, LB_GETITEMHEIGHT
, 0, 0 );
571 ok( r
== 20, "height wrong\n");
573 r
= SendMessageA( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 256, 0 ));
574 ok( r
== -1, "Failed to set item height, %d.\n", r
);
576 r
= SendMessageA(hList
, LB_GETITEMHEIGHT
, 0, 0 );
577 ok( r
== 20, "Unexpected item height %d.\n", r
);
579 r
= SendMessageA( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 0xff, 0 ));
580 ok( r
== 0, "send message failed\n");
582 r
= SendMessageA(hList
, LB_GETITEMHEIGHT
, 0, 0 );
583 ok( r
== 0xff, "height wrong\n");
585 DestroyWindow( hList
);
588 static void test_itemfrompoint(void)
590 /* WS_POPUP is required in order to have a more accurate size calculation (
591 without caption). LBS_NOINTEGRALHEIGHT is required in order to test
592 behavior of partially-displayed item.
594 HWND hList
= CreateWindowA( WC_LISTBOXA
, "list test",
595 WS_VISIBLE
|WS_POPUP
|LBS_NOINTEGRALHEIGHT
,
596 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
600 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
601 ok( r
== MAKELPARAM(0xffff, 1), "Unexpected ret value %#x.\n", r
);
603 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( 700, 30 ));
604 ok( r
== MAKELPARAM(0xffff, 1), "Unexpected ret value %#x.\n", r
);
606 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( 30, 300 ));
607 ok( r
== MAKELPARAM(0xffff, 1), "Unexpected ret value %#x.\n", r
);
609 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi");
610 ok( id
== 0, "item id wrong\n");
611 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi1");
612 ok( id
== 1, "item id wrong\n");
614 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
615 ok( r
== 0x1, "ret %x\n", r
);
617 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( /* x */ 30, /* y */ 601 ));
618 ok( r
== MAKELPARAM(1, 1), "Unexpected ret value %#x.\n", r
);
620 /* Resize control so that below assertions about sizes are valid */
621 r
= SendMessageA( hList
, LB_GETITEMRECT
, 0, (LPARAM
)&rc
);
622 ok( r
== 1, "ret %x\n", r
);
623 r
= MoveWindow(hList
, 1, 1, 600, (rc
.bottom
- rc
.top
+ 1) * 9 / 2, TRUE
);
624 ok( r
!= 0, "ret %x\n", r
);
626 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi2");
627 ok( id
== 2, "item id wrong\n");
628 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi3");
629 ok( id
== 3, "item id wrong\n");
630 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi4");
631 ok( id
== 4, "item id wrong\n");
632 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi5");
633 ok( id
== 5, "item id wrong\n");
634 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi6");
635 ok( id
== 6, "item id wrong\n");
636 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi7");
637 ok( id
== 7, "item id wrong\n");
639 /* Set the listbox up so that id 1 is at the top, this leaves 5
640 partially visible at the bottom and 6, 7 are invisible */
642 SendMessageA( hList
, LB_SETTOPINDEX
, 1, 0);
643 r
= SendMessageA( hList
, LB_GETTOPINDEX
, 0, 0);
644 ok( r
== 1, "top %d\n", r
);
646 r
= SendMessageA( hList
, LB_GETITEMRECT
, 5, (LPARAM
)&rc
);
647 ok( r
== 1, "ret %x\n", r
);
648 r
= SendMessageA( hList
, LB_GETITEMRECT
, 6, (LPARAM
)&rc
);
649 ok( r
== 0, "ret %x\n", r
);
651 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(/* x */ 10, /* y */ 10) );
652 ok( r
== 1, "ret %x\n", r
);
654 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(1000, 10) );
655 ok( r
== 0x10001, "ret %x\n", r
);
657 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(10, -10) );
658 ok( r
== 0x10001, "ret %x\n", r
);
660 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(10, 100) );
661 ok( r
== 0x10005, "item %x\n", r
);
663 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(10, 200) );
664 ok( r
== 0x10005, "item %x\n", r
);
666 DestroyWindow( hList
);
669 static void test_listbox_item_data(void)
674 hList
= CreateWindowA( WC_LISTBOXA
, "list test", 0,
675 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
676 ok( hList
!= NULL
, "failed to create listbox\n");
678 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi");
679 ok( id
== 0, "item id wrong\n");
681 r
= SendMessageA( hList
, LB_SETITEMDATA
, 0, MAKELPARAM( 20, 0 ));
682 ok(r
== TRUE
, "LB_SETITEMDATA returned %d instead of TRUE\n", r
);
684 r
= SendMessageA( hList
, LB_GETITEMDATA
, 0, 0);
685 ok( r
== 20, "get item data failed\n");
687 DestroyWindow( hList
);
690 static void test_listbox_LB_DIR(void)
694 int itemCount_justFiles
;
695 int itemCount_justDrives
;
696 int itemCount_allFiles
;
697 int itemCount_allDirs
;
699 char pathBuffer
[MAX_PATH
];
702 const char *wildcard
= "*";
705 file
= CreateFileA( "wtest1.tmp.c", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, FILE_ATTRIBUTE_NORMAL
, NULL
);
706 ok(file
!= INVALID_HANDLE_VALUE
, "Error creating the test file: %d\n", GetLastError());
709 /* NOTE: for this test to succeed, there must be no subdirectories
710 under the current directory. In addition, there must be at least
711 one file that fits the wildcard w*.c . Normally, the test
712 directory itself satisfies both conditions.
714 hList
= CreateWindowA( WC_LISTBOXA
, "list test", WS_VISIBLE
|WS_POPUP
,
715 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
716 ok(hList
!= NULL
, "Failed to create listbox window.\n");
718 /* Test for standard usage */
720 /* This should list all the files in the test directory. */
721 strcpy(pathBuffer
, wildcard
);
722 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
723 res
= SendMessageA(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
724 if (res
== -1) /* "*" wildcard doesn't work on win9x */
727 strcpy(pathBuffer
, wildcard
);
728 res
= SendMessageA(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
730 ok (res
>= 0, "SendMessage(LB_DIR, 0, *) failed - 0x%08x\n", GetLastError());
732 /* There should be some content in the listbox */
733 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
734 ok (itemCount
> 0, "SendMessage(LB_DIR) did NOT fill the listbox!\n");
735 itemCount_allFiles
= itemCount
;
736 ok(res
+ 1 == itemCount
,
737 "SendMessage(LB_DIR, 0, *) returned incorrect index (expected %d got %d)!\n",
740 /* This tests behavior when no files match the wildcard */
741 strcpy(pathBuffer
, BAD_EXTENSION
);
742 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
743 res
= SendMessageA(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
744 ok (res
== -1, "SendMessage(LB_DIR, 0, %s) returned %d, expected -1\n", BAD_EXTENSION
, res
);
746 /* There should be NO content in the listbox */
747 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
748 ok (itemCount
== 0, "SendMessage(LB_DIR) DID fill the listbox!\n");
751 /* This should list all the w*.c files in the test directory
752 * As of this writing, this includes win.c, winstation.c, wsprintf.c
754 strcpy(pathBuffer
, "w*.c");
755 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
756 res
= SendMessageA(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
757 ok (res
>= 0, "SendMessage(LB_DIR, 0, w*.c) failed - 0x%08x\n", GetLastError());
759 /* Path specification does NOT converted to uppercase */
760 ok (!strcmp(pathBuffer
, "w*.c"),
761 "expected no change to pathBuffer, got %s\n", pathBuffer
);
763 /* There should be some content in the listbox */
764 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
765 ok (itemCount
> 0, "SendMessage(LB_DIR) did NOT fill the listbox!\n");
766 itemCount_justFiles
= itemCount
;
767 ok(res
+ 1 == itemCount
,
768 "SendMessage(LB_DIR, 0, w*.c) returned incorrect index (expected %d got %d)!\n",
771 /* Every single item in the control should start with a w and end in .c */
772 for (i
= 0; i
< itemCount
; i
++)
774 memset(pathBuffer
, 0, MAX_PATH
);
775 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
776 p
= pathBuffer
+ strlen(pathBuffer
);
777 ok(((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
778 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
779 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
782 /* Test DDL_DIRECTORY */
783 strcpy(pathBuffer
, wildcard
);
784 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
785 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
, (LPARAM
)pathBuffer
);
786 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY, *) failed - 0x%08x\n", GetLastError());
788 /* There should be some content in the listbox.
789 * All files plus "[..]"
791 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
792 itemCount_allDirs
= itemCount
- itemCount_allFiles
;
793 ok (itemCount
>= itemCount_allFiles
,
794 "SendMessage(LB_DIR, DDL_DIRECTORY, *) filled with %d entries, expected > %d\n",
795 itemCount
, itemCount_allFiles
);
796 ok(res
+ 1 == itemCount
,
797 "SendMessage(LB_DIR, DDL_DIRECTORY, *) returned incorrect index (expected %d got %d)!\n",
800 /* This tests behavior when no files match the wildcard */
801 strcpy(pathBuffer
, BAD_EXTENSION
);
802 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
803 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
, (LPARAM
)pathBuffer
);
804 ok (res
== -1, "SendMessage(LB_DIR, DDL_DIRECTORY, %s) returned %d, expected -1\n", BAD_EXTENSION
, res
);
806 /* There should be NO content in the listbox */
807 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
808 ok (itemCount
== 0, "SendMessage(LB_DIR) DID fill the listbox!\n");
810 /* Test DDL_DIRECTORY */
811 strcpy(pathBuffer
, "w*.c");
812 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
813 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
, (LPARAM
)pathBuffer
);
814 ok (res
>= 0, "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) failed - 0x%08x\n", GetLastError());
816 /* There should be some content in the listbox. Since the parent directory does not
817 * fit w*.c, there should be exactly the same number of items as without DDL_DIRECTORY
819 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
820 ok (itemCount
== itemCount_justFiles
,
821 "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) filled with %d entries, expected %d\n",
822 itemCount
, itemCount_justFiles
);
823 ok(res
+ 1 == itemCount
,
824 "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) returned incorrect index (expected %d got %d)!\n",
827 /* Every single item in the control should start with a w and end in .c. */
828 for (i
= 0; i
< itemCount
; i
++)
830 memset(pathBuffer
, 0, MAX_PATH
);
831 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
832 p
= pathBuffer
+ strlen(pathBuffer
);
834 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
835 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
836 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
839 /* Test DDL_DRIVES|DDL_EXCLUSIVE */
840 strcpy(pathBuffer
, wildcard
);
841 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
842 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
843 ok (res
>= 0, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) failed - 0x%08x\n", GetLastError());
845 /* There should be some content in the listbox. In particular, there should
846 * be at least one element before, since the string "[-c-]" should
847 * have been added. Depending on the user setting, more drives might have
850 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
852 "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) filled with %d entries, expected at least %d\n",
854 itemCount_justDrives
= itemCount
;
855 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) returned incorrect index!\n");
857 /* Every single item in the control should fit the format [-c-] */
858 for (i
= 0; i
< itemCount
; i
++)
860 memset(pathBuffer
, 0, MAX_PATH
);
862 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
863 ok( strlen(pathBuffer
) == 5, "Length of drive string is not 5\n" );
864 ok( sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1, "Element %d (%s) does not fit [-X-]\n", i
, pathBuffer
);
865 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
866 if (!(driveletter
>= 'a' && driveletter
<= 'z'))
868 /* Correct after invalid entry is found */
869 itemCount_justDrives
--;
873 /* This tests behavior when no files match the wildcard */
874 strcpy(pathBuffer
, BAD_EXTENSION
);
875 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
876 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
877 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
878 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
880 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
881 ok (itemCount
== itemCount_justDrives
, "SendMessage(LB_DIR) returned %d expected %d\n",
882 itemCount
, itemCount_justDrives
);
884 /* Test DDL_DRIVES. */
885 strcpy(pathBuffer
, wildcard
);
886 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
887 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
, (LPARAM
)pathBuffer
);
888 ok (res
> 0, "SendMessage(LB_DIR, DDL_DRIVES, *) failed - 0x%08x\n", GetLastError());
890 /* There should be some content in the listbox. In particular, there should
891 * be at least one element before, since the string "[-c-]" should
892 * have been added. Depending on the user setting, more drives might have
895 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
896 ok (itemCount
== itemCount_justDrives
+ itemCount_allFiles
,
897 "SendMessage(LB_DIR, DDL_DRIVES, *) filled with %d entries, expected %d\n",
898 itemCount
, itemCount_justDrives
+ itemCount_allFiles
);
899 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DRIVES, *) returned incorrect index!\n");
901 /* This tests behavior when no files match the wildcard */
902 strcpy(pathBuffer
, BAD_EXTENSION
);
903 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
904 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
, (LPARAM
)pathBuffer
);
905 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DRIVES, %s) returned %d, expected %d\n",
906 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
908 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
909 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
911 /* Test DDL_DRIVES. */
912 strcpy(pathBuffer
, "w*.c");
913 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
914 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
, (LPARAM
)pathBuffer
);
915 ok (res
> 0, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) failed - 0x%08x\n", GetLastError());
917 /* There should be some content in the listbox. In particular, there should
918 * be at least one element before, since the string "[-c-]" should
919 * have been added. Depending on the user setting, more drives might have
922 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
923 ok (itemCount
== itemCount_justDrives
+ itemCount_justFiles
,
924 "SendMessage(LB_DIR, DDL_DRIVES, w*.c) filled with %d entries, expected %d\n",
925 itemCount
, itemCount_justDrives
+ itemCount_justFiles
);
926 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) returned incorrect index!\n");
928 /* Every single item in the control should fit the format [-c-], or w*.c */
929 for (i
= 0; i
< itemCount
; i
++)
931 memset(pathBuffer
, 0, MAX_PATH
);
933 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
934 p
= pathBuffer
+ strlen(pathBuffer
);
935 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1)
937 ok( strlen(pathBuffer
) == 5, "Length of drive string is not 5\n" );
938 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
943 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
944 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
945 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
949 /* Test DDL_DIRECTORY|DDL_DRIVES. This does *not* imply DDL_EXCLUSIVE */
950 strcpy(pathBuffer
, wildcard
);
951 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
952 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
, (LPARAM
)pathBuffer
);
953 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, *) failed - 0x%08x\n", GetLastError());
955 /* There should be some content in the listbox. In particular, there should
956 * be exactly the number of plain files, plus the number of mapped drives.
958 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
959 ok (itemCount
== itemCount_allFiles
+ itemCount_justDrives
+ itemCount_allDirs
,
960 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
961 itemCount
, itemCount_allFiles
+ itemCount_justDrives
+ itemCount_allDirs
);
962 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
964 /* Every single item in the control should start with a w and end in .c,
965 * except for the "[..]" string, which should appear exactly as it is,
966 * and the mapped drives in the format "[-X-]".
968 for (i
= 0; i
< itemCount
; i
++)
970 memset(pathBuffer
, 0, MAX_PATH
);
972 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
973 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1)
974 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
977 /* This tests behavior when no files match the wildcard */
978 strcpy(pathBuffer
, BAD_EXTENSION
);
979 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
980 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
, (LPARAM
)pathBuffer
);
981 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, %s) returned %d, expected %d\n",
982 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
984 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
985 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
987 /* Test DDL_DIRECTORY|DDL_DRIVES. */
988 strcpy(pathBuffer
, "w*.c");
989 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
990 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
, (LPARAM
)pathBuffer
);
991 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) failed - 0x%08x\n", GetLastError());
993 /* There should be some content in the listbox. In particular, there should
994 * be exactly the number of plain files, plus the number of mapped drives.
996 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
997 ok (itemCount
== itemCount_justFiles
+ itemCount_justDrives
,
998 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
999 itemCount
, itemCount_justFiles
+ itemCount_justDrives
);
1000 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
1002 /* Every single item in the control should start with a w and end in .c,
1003 * except the mapped drives in the format "[-X-]". The "[..]" directory
1004 * should not appear.
1006 for (i
= 0; i
< itemCount
; i
++)
1008 memset(pathBuffer
, 0, MAX_PATH
);
1010 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1011 p
= pathBuffer
+ strlen(pathBuffer
);
1012 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1)
1013 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1016 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1017 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1018 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1021 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1022 strcpy(pathBuffer
, wildcard
);
1023 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1024 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1025 ok (res
!= -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) failed err %u\n",
1028 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1029 ok (itemCount
== itemCount_allDirs
,
1030 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1031 itemCount
, itemCount_allDirs
);
1032 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) returned incorrect index!\n");
1034 if (itemCount
&& GetCurrentDirectoryA( MAX_PATH
, pathBuffer
) > 3) /* there's no [..] in drive root */
1036 memset(pathBuffer
, 0, MAX_PATH
);
1037 SendMessageA(hList
, LB_GETTEXT
, 0, (LPARAM
)pathBuffer
);
1038 ok( !strcmp(pathBuffer
, "[..]"), "First element is not [..]\n");
1041 /* This tests behavior when no files match the wildcard */
1042 strcpy(pathBuffer
, BAD_EXTENSION
);
1043 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1044 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1045 ok (res
== -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1046 BAD_EXTENSION
, res
, -1);
1048 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1049 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
1052 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1053 strcpy(pathBuffer
, "w*.c");
1054 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1055 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1056 ok (res
== LB_ERR
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, w*.c) returned %d expected %d\n", res
, LB_ERR
);
1058 /* There should be no elements, since "[..]" does not fit w*.c */
1059 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1061 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1064 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1065 strcpy(pathBuffer
, wildcard
);
1066 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1067 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1068 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
1070 /* There should be no plain files on the listbox */
1071 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1072 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
1073 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1074 itemCount
, itemCount_justDrives
+ itemCount_allDirs
);
1075 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
1077 for (i
= 0; i
< itemCount
; i
++)
1079 memset(pathBuffer
, 0, MAX_PATH
);
1081 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1082 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1)
1083 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1085 ok( pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']',
1086 "Element %d (%s) does not fit expected [...]\n", i
, pathBuffer
);
1089 /* This tests behavior when no files match the wildcard */
1090 strcpy(pathBuffer
, BAD_EXTENSION
);
1091 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1092 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1093 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1094 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
1096 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1097 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
1099 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1100 strcpy(pathBuffer
, "w*.c");
1101 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1102 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1103 ok (res
>= 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
1105 /* There should be no plain files on the listbox, and no [..], since it does not fit w*.c */
1106 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1107 ok (itemCount
== itemCount_justDrives
,
1108 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1109 itemCount
, itemCount_justDrives
);
1110 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
1112 for (i
= 0; i
< itemCount
; i
++)
1114 memset(pathBuffer
, 0, MAX_PATH
);
1116 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1117 ok (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1, "Element %d (%s) does not fit [-X-]\n", i
, pathBuffer
);
1118 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1120 DestroyWindow(hList
);
1122 DeleteFileA( "wtest1.tmp.c" );
1125 static HWND g_listBox
;
1126 static HWND g_label
;
1128 #define ID_TEST_LABEL 1001
1129 #define ID_TEST_LISTBOX 1002
1131 static BOOL
on_listbox_container_create(HWND hwnd
, CREATESTRUCTA
*lpcs
)
1133 g_label
= CreateWindowA(WC_STATICA
, "Contents of static control before DlgDirList.",
1134 WS_CHILD
| WS_VISIBLE
, 10, 10, 512, 32, hwnd
, (HMENU
)ID_TEST_LABEL
, NULL
, 0);
1135 if (!g_label
) return FALSE
;
1137 g_listBox
= CreateWindowA(WC_LISTBOXA
, "DlgDirList test",
1138 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| WS_BORDER
| WS_VSCROLL
, 10, 60, 256, 256,
1139 hwnd
, (HMENU
)ID_TEST_LISTBOX
, NULL
, 0);
1140 if (!g_listBox
) return FALSE
;
1145 static LRESULT CALLBACK
listbox_container_window_procA(HWND hwnd
, UINT uiMsg
, WPARAM wParam
, LPARAM lParam
)
1155 result
= on_listbox_container_create(hwnd
, (CREATESTRUCTA
*)lParam
) ? 0 : (LRESULT
)-1;
1158 result
= DefWindowProcA(hwnd
, uiMsg
, wParam
, lParam
);
1164 static BOOL
RegisterListboxWindowClass(HINSTANCE hInst
)
1171 cls
.hInstance
= hInst
;
1173 cls
.hCursor
= LoadCursorA (NULL
, (LPCSTR
)IDC_ARROW
);
1174 cls
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
1175 cls
.lpszMenuName
= NULL
;
1176 cls
.lpfnWndProc
= listbox_container_window_procA
;
1177 cls
.lpszClassName
= "ListboxContainerClass";
1178 if (!RegisterClassA (&cls
)) return FALSE
;
1183 static void test_listbox_dlgdir(void)
1188 int itemCount_allDirs
;
1189 int itemCount_justFiles
;
1190 int itemCount_justDrives
;
1192 char pathBuffer
[MAX_PATH
];
1193 char itemBuffer
[MAX_PATH
];
1194 char tempBuffer
[MAX_PATH
];
1200 file
= CreateFileA( "wtest1.tmp.c", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1201 ok(file
!= INVALID_HANDLE_VALUE
, "Error creating the test file: %d\n", GetLastError());
1202 CloseHandle( file
);
1204 /* NOTE: for this test to succeed, there must be no subdirectories
1205 under the current directory. In addition, there must be at least
1206 one file that fits the wildcard w*.c . Normally, the test
1207 directory itself satisfies both conditions.
1210 hInst
= GetModuleHandleA(0);
1211 ret
= RegisterListboxWindowClass(hInst
);
1212 ok(ret
, "Failed to register test class.\n");
1214 hWnd
= CreateWindowA("ListboxContainerClass", "ListboxContainerClass",
1215 WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
1216 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
1217 NULL
, NULL
, hInst
, 0);
1218 ok(hWnd
!= NULL
, "Failed to create container window.\n");
1220 /* Test for standard usage */
1222 /* The following should be overwritten by the directory path */
1223 SendMessageA(g_label
, WM_SETTEXT
, 0, (LPARAM
)"default contents");
1225 /* This should list all the w*.c files in the test directory
1226 * As of this writing, this includes win.c, winstation.c, wsprintf.c
1228 strcpy(pathBuffer
, "w*.c");
1229 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, 0);
1230 ok (res
== 1, "DlgDirList(*.c, 0) returned %d - expected 1 - 0x%08x\n", res
, GetLastError());
1232 /* Path specification gets converted to uppercase */
1233 ok (!strcmp(pathBuffer
, "W*.C"),
1234 "expected conversion to uppercase, got %s\n", pathBuffer
);
1236 /* Loaded path should have overwritten the label text */
1237 SendMessageA(g_label
, WM_GETTEXT
, MAX_PATH
, (LPARAM
)pathBuffer
);
1238 ok (strcmp("default contents", pathBuffer
), "DlgDirList() did not modify static control!\n");
1240 /* There should be some content in the listbox */
1241 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1242 ok (itemCount
> 0, "DlgDirList() did NOT fill the listbox!\n");
1243 itemCount_justFiles
= itemCount
;
1245 /* Every single item in the control should start with a w and end in .c */
1246 for (i
= 0; i
< itemCount
; i
++)
1248 memset(pathBuffer
, 0, MAX_PATH
);
1249 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1250 p
= pathBuffer
+ strlen(pathBuffer
);
1251 ok(((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1252 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1253 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1256 /* Test behavior when no files match the wildcard */
1257 strcpy(pathBuffer
, BAD_EXTENSION
);
1258 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, 0);
1259 ok (res
== 1, "DlgDirList(%s, 0) returned %d expected 1\n", BAD_EXTENSION
, res
);
1261 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1262 ok (itemCount
== 0, "DlgDirList() DID fill the listbox!\n");
1264 /* Test DDL_DIRECTORY */
1265 strcpy(pathBuffer
, "w*.c");
1266 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
);
1267 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY) failed - 0x%08x\n", GetLastError());
1269 /* There should be some content in the listbox. In particular, there should
1270 * be exactly more elements than before, since the directories should
1273 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1274 itemCount_allDirs
= itemCount
- itemCount_justFiles
;
1275 ok (itemCount
>= itemCount_justFiles
, "DlgDirList(DDL_DIRECTORY) filled with %d entries, expected > %d\n",
1276 itemCount
, itemCount_justFiles
);
1278 /* Every single item in the control should start with a w and end in .c,
1279 * except for the "[..]" string, which should appear exactly as it is.
1281 for (i
= 0; i
< itemCount
; i
++)
1283 memset(pathBuffer
, 0, MAX_PATH
);
1284 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1285 p
= pathBuffer
+ strlen(pathBuffer
);
1286 ok( (pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']') ||
1287 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1288 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1289 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1292 /* Test behavior when no files match the wildcard */
1293 strcpy(pathBuffer
, BAD_EXTENSION
);
1294 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
);
1295 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY) returned %d expected 1\n", BAD_EXTENSION
, res
);
1297 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1298 ok (itemCount
== itemCount_allDirs
, "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
1299 itemCount_allDirs
, itemCount
);
1300 for (i
= 0; i
< itemCount
; i
++)
1302 memset(pathBuffer
, 0, MAX_PATH
);
1303 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1304 ok( pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']',
1305 "Element %d (%s) does not fit requested [...]\n", i
, pathBuffer
);
1308 /* Test DDL_DRIVES. At least on WinXP-SP2, this implies DDL_EXCLUSIVE */
1309 strcpy(pathBuffer
, "w*.c");
1310 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DRIVES
);
1311 ok (res
== 1, "DlgDirList(*.c, DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1313 /* There should be some content in the listbox. In particular, there should
1314 * be at least one element before, since the string "[-c-]" should
1315 * have been added. Depending on the user setting, more drives might have
1318 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1320 "DlgDirList(DDL_DRIVES) filled with %d entries, expected at least %d\n",
1322 itemCount_justDrives
= itemCount
;
1324 /* Every single item in the control should fit the format [-c-] */
1325 for (i
= 0; i
< itemCount
; i
++)
1327 memset(pathBuffer
, 0, MAX_PATH
);
1329 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1330 ok( strlen(pathBuffer
) == 5, "Length of drive string is not 5\n" );
1331 ok( sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1, "Element %d (%s) does not fit [-X-]\n", i
, pathBuffer
);
1332 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1333 if (!(driveletter
>= 'a' && driveletter
<= 'z')) {
1334 /* Correct after invalid entry is found */
1335 trace("removing count of invalid entry %s\n", pathBuffer
);
1336 itemCount_justDrives
--;
1340 /* Test behavior when no files match the wildcard */
1341 strcpy(pathBuffer
, BAD_EXTENSION
);
1342 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DRIVES
);
1343 ok (res
== 1, "DlgDirList(%s, DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION
, res
);
1345 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1346 ok (itemCount
== itemCount_justDrives
, "DlgDirList() incorrectly filled the listbox!\n");
1348 /* Test DDL_DIRECTORY|DDL_DRIVES. This does *not* imply DDL_EXCLUSIVE */
1349 strcpy(pathBuffer
, "w*.c");
1350 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_DRIVES
);
1351 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1353 /* There should be some content in the listbox. In particular, there should
1354 * be exactly the number of plain files, plus the number of mapped drives,
1357 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1358 ok (itemCount
== itemCount_justFiles
+ itemCount_justDrives
+ itemCount_allDirs
,
1359 "DlgDirList(DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1360 itemCount
, itemCount_justFiles
+ itemCount_justDrives
+ itemCount_allDirs
);
1362 /* Every single item in the control should start with a w and end in .c,
1363 * except for the "[..]" string, which should appear exactly as it is,
1364 * and the mapped drives in the format "[-X-]".
1366 for (i
= 0; i
< itemCount
; i
++)
1368 memset(pathBuffer
, 0, MAX_PATH
);
1370 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1371 p
= pathBuffer
+ strlen(pathBuffer
);
1372 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1)
1373 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1375 ok( (pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']') ||
1376 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1377 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1378 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1381 /* Test behavior when no files match the wildcard */
1382 strcpy(pathBuffer
, BAD_EXTENSION
);
1383 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_DRIVES
);
1384 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION
, res
);
1386 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1387 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
1388 "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
1389 itemCount_justDrives
+ itemCount_allDirs
, itemCount
);
1391 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1392 strcpy(pathBuffer
, "w*.c");
1393 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_EXCLUSIVE
);
1394 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_EXCLUSIVE) failed - 0x%08x\n", GetLastError());
1396 /* There should be exactly one element: "[..]" */
1397 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1398 ok (itemCount
== itemCount_allDirs
,
1399 "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1400 itemCount
, itemCount_allDirs
);
1402 if (itemCount
&& GetCurrentDirectoryA( MAX_PATH
, pathBuffer
) > 3) /* there's no [..] in drive root */
1404 memset(pathBuffer
, 0, MAX_PATH
);
1405 SendMessageA(g_listBox
, LB_GETTEXT
, 0, (LPARAM
)pathBuffer
);
1406 ok( !strcmp(pathBuffer
, "[..]"), "First (and only) element is not [..]\n");
1409 /* Test behavior when no files match the wildcard */
1410 strcpy(pathBuffer
, BAD_EXTENSION
);
1411 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_EXCLUSIVE
);
1412 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION
, res
);
1414 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1415 ok (itemCount
== itemCount_allDirs
, "DlgDirList() incorrectly filled the listbox!\n");
1417 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1418 strcpy(pathBuffer
, "w*.c");
1419 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
);
1420 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) failed - 0x%08x\n", GetLastError());
1422 /* There should be no plain files on the listbox */
1423 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1424 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
1425 "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1426 itemCount
, itemCount_justDrives
+ itemCount_allDirs
);
1428 for (i
= 0; i
< itemCount
; i
++)
1430 memset(pathBuffer
, 0, MAX_PATH
);
1432 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1433 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1)
1434 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1436 ok( pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']',
1437 "Element %d (%s) does not fit expected [...]\n", i
, pathBuffer
);
1440 /* Test behavior when no files match the wildcard */
1441 strcpy(pathBuffer
, BAD_EXTENSION
);
1442 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
);
1443 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION
, res
);
1445 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1446 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
, "DlgDirList() incorrectly filled the listbox!\n");
1448 /* Now test DlgDirSelectEx() in normal operation */
1449 /* Fill with everything - drives, directory and all plain files. */
1450 strcpy(pathBuffer
, "*");
1451 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_DRIVES
);
1452 ok (res
!= 0, "DlgDirList(*, DDL_DIRECTORY|DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1454 SendMessageA(g_listBox
, LB_SETCURSEL
, -1, 0); /* Unselect any current selection */
1455 memset(pathBuffer
, 0, MAX_PATH
);
1456 SetLastError(0xdeadbeef);
1457 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1458 ok (GetLastError() == 0xdeadbeef,
1459 "DlgDirSelectEx() with no selection modified last error code from 0xdeadbeef to 0x%08x\n",
1461 ok (res
== 0, "DlgDirSelectEx() with no selection returned %d, expected 0\n", res
);
1462 /* WinXP-SP2 leaves pathBuffer untouched, but Win98 fills it with garbage. */
1464 ok (strlen(pathBuffer) == 0, "DlgDirSelectEx() with no selection filled buffer with %s\n", pathBuffer);
1466 /* Test proper drive/dir/file recognition */
1467 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1468 for (i
= 0; i
< itemCount
; i
++)
1470 memset(itemBuffer
, 0, MAX_PATH
);
1471 memset(pathBuffer
, 0, MAX_PATH
);
1472 memset(tempBuffer
, 0, MAX_PATH
);
1474 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)itemBuffer
);
1475 res
= SendMessageA(g_listBox
, LB_SETCURSEL
, i
, 0);
1476 ok (res
== i
, "SendMessageA(LB_SETCURSEL, %d) failed\n", i
);
1477 if (sscanf(itemBuffer
, "[-%c-]", &driveletter
) == 1)
1479 /* Current item is a drive letter */
1480 SetLastError(0xdeadbeef);
1481 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1482 ok (GetLastError() == 0xdeadbeef,
1483 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1485 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1487 /* For drive letters, DlgDirSelectEx tacks on a colon */
1488 ok (pathBuffer
[0] == driveletter
&& pathBuffer
[1] == ':' && pathBuffer
[2] == '\0',
1489 "%d: got \"%s\" expected \"%c:\"\n", i
, pathBuffer
, driveletter
);
1491 else if (itemBuffer
[0] == '[')
1493 /* Current item is the parent directory */
1494 SetLastError(0xdeadbeef);
1495 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1496 ok (GetLastError() == 0xdeadbeef,
1497 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1499 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1501 /* For directories, DlgDirSelectEx tacks on a backslash */
1502 p
= pathBuffer
+ strlen(pathBuffer
);
1503 ok (*(p
-1) == '\\', "DlgDirSelectEx did NOT tack on a backslash to dir, got %s\n", pathBuffer
);
1505 tempBuffer
[0] = '[';
1506 lstrcpynA(tempBuffer
+ 1, pathBuffer
, strlen(pathBuffer
));
1507 strcat(tempBuffer
, "]");
1508 ok (!strcmp(tempBuffer
, itemBuffer
), "Formatted directory should be %s, got %s\n", tempBuffer
, itemBuffer
);
1512 /* Current item is a plain file */
1513 SetLastError(0xdeadbeef);
1514 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1515 ok (GetLastError() == 0xdeadbeef,
1516 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1518 ok(res
== 0, "DlgDirSelectEx() thinks %s (%s) is a drive/directory!\n", itemBuffer
, pathBuffer
);
1520 /* NOTE: WinXP tacks a period on all files that lack an extension. This affects
1521 * for example, "Makefile", which gets reported as "Makefile."
1523 strcpy(tempBuffer
, itemBuffer
);
1524 if (strchr(tempBuffer
, '.') == NULL
) strcat(tempBuffer
, ".");
1525 ok (!strcmp(pathBuffer
, tempBuffer
), "Formatted file should be %s, got %s\n", tempBuffer
, pathBuffer
);
1529 DeleteFileA( "wtest1.tmp.c" );
1531 /* Now test DlgDirSelectEx() in abnormal operation */
1532 /* Fill list with bogus entries, that look somewhat valid */
1533 SendMessageA(g_listBox
, LB_RESETCONTENT
, 0, 0);
1534 SendMessageA(g_listBox
, LB_ADDSTRING
, 0, (LPARAM
)"[notexist.dir]");
1535 SendMessageA(g_listBox
, LB_ADDSTRING
, 0, (LPARAM
)"notexist.fil");
1536 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1537 for (i
= 0; i
< itemCount
; i
++)
1539 memset(itemBuffer
, 0, MAX_PATH
);
1540 memset(pathBuffer
, 0, MAX_PATH
);
1541 memset(tempBuffer
, 0, MAX_PATH
);
1543 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)itemBuffer
);
1544 res
= SendMessageA(g_listBox
, LB_SETCURSEL
, i
, 0);
1545 ok (res
== i
, "SendMessage(LB_SETCURSEL, %d) failed\n", i
);
1546 if (sscanf(itemBuffer
, "[-%c-]", &driveletter
) == 1)
1548 /* Current item is a drive letter */
1549 SetLastError(0xdeadbeef);
1550 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1551 ok (GetLastError() == 0xdeadbeef,
1552 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1554 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1556 /* For drive letters, DlgDirSelectEx tacks on a colon */
1557 ok (pathBuffer
[0] == driveletter
&& pathBuffer
[1] == ':' && pathBuffer
[2] == '\0',
1558 "%d: got \"%s\" expected \"%c:\"\n", i
, pathBuffer
, driveletter
);
1560 else if (itemBuffer
[0] == '[')
1562 /* Current item is the parent directory */
1563 SetLastError(0xdeadbeef);
1564 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1565 ok (GetLastError() == 0xdeadbeef,
1566 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1568 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1570 /* For directories, DlgDirSelectEx tacks on a backslash */
1571 p
= pathBuffer
+ strlen(pathBuffer
);
1572 ok (*(p
-1) == '\\', "DlgDirSelectEx did NOT tack on a backslash to dir, got %s\n", pathBuffer
);
1574 tempBuffer
[0] = '[';
1575 lstrcpynA(tempBuffer
+ 1, pathBuffer
, strlen(pathBuffer
));
1576 strcat(tempBuffer
, "]");
1577 ok (!strcmp(tempBuffer
, itemBuffer
), "Formatted directory should be %s, got %s\n", tempBuffer
, itemBuffer
);
1581 /* Current item is a plain file */
1582 SetLastError(0xdeadbeef);
1583 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1584 ok (GetLastError() == 0xdeadbeef,
1585 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1587 ok(res
== 0, "DlgDirSelectEx() thinks %s (%s) is a drive/directory!\n", itemBuffer
, pathBuffer
);
1589 /* NOTE: WinXP and Win98 tack a period on all files that lack an extension.
1590 * This affects for example, "Makefile", which gets reported as "Makefile."
1592 strcpy(tempBuffer
, itemBuffer
);
1593 if (strchr(tempBuffer
, '.') == NULL
) strcat(tempBuffer
, ".");
1594 ok (!strcmp(pathBuffer
, tempBuffer
), "Formatted file should be %s, got %s\n", tempBuffer
, pathBuffer
);
1598 /* Test behavior when loading folders from root with and without wildcard */
1599 strcpy(pathBuffer
, "C:\\");
1600 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, 0, DDL_DIRECTORY
| DDL_EXCLUSIVE
);
1601 ok(res
, "DlgDirList failed to list C:\\ folders\n");
1602 todo_wine
ok(!strcmp(pathBuffer
, "*"), "DlgDirList set the invalid path spec '%s', expected '*'\n", pathBuffer
);
1604 strcpy(pathBuffer
, "C:\\*");
1605 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, 0, DDL_DIRECTORY
| DDL_EXCLUSIVE
);
1606 ok(res
, "DlgDirList failed to list C:\\* folders\n");
1607 ok(!strcmp(pathBuffer
, "*"), "DlgDirList set the invalid path spec '%s', expected '*'\n", pathBuffer
);
1609 /* Try loading files from an invalid folder */
1610 SetLastError(0xdeadbeef);
1611 strcpy(pathBuffer
, "C:\\INVALID$$DIR");
1612 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, 0, DDL_DIRECTORY
| DDL_EXCLUSIVE
);
1613 todo_wine
ok(!res
, "DlgDirList should have failed with 0 but %d was returned\n", res
);
1614 todo_wine
ok(GetLastError() == ERROR_NO_WILDCARD_CHARACTERS
,
1615 "GetLastError should return 0x589, got 0x%X\n",GetLastError());
1617 DestroyWindow(hWnd
);
1620 static void test_set_count( void )
1622 HWND parent
, listbox
;
1626 parent
= create_parent();
1627 listbox
= create_listbox( LBS_OWNERDRAWFIXED
| LBS_NODATA
| WS_CHILD
| WS_VISIBLE
, parent
);
1629 UpdateWindow( listbox
);
1630 GetUpdateRect( listbox
, &r
, TRUE
);
1631 ok( IsRectEmpty( &r
), "got non-empty rect\n");
1633 ret
= SendMessageA( listbox
, LB_SETCOUNT
, 100, 0 );
1634 ok( ret
== 0, "got %d\n", ret
);
1635 ret
= SendMessageA( listbox
, LB_GETCOUNT
, 0, 0 );
1636 ok( ret
== 100, "got %d\n", ret
);
1638 GetUpdateRect( listbox
, &r
, TRUE
);
1639 ok( !IsRectEmpty( &r
), "got empty rect\n");
1641 ValidateRect( listbox
, NULL
);
1642 GetUpdateRect( listbox
, &r
, TRUE
);
1643 ok( IsRectEmpty( &r
), "got non-empty rect\n");
1645 ret
= SendMessageA( listbox
, LB_SETCOUNT
, 99, 0 );
1646 ok( ret
== 0, "got %d\n", ret
);
1648 GetUpdateRect( listbox
, &r
, TRUE
);
1649 ok( !IsRectEmpty( &r
), "got empty rect\n");
1651 DestroyWindow( listbox
);
1652 DestroyWindow( parent
);
1655 static int lb_getlistboxinfo
;
1657 static LRESULT WINAPI
listbox_subclass_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1659 WNDPROC oldproc
= (WNDPROC
)GetWindowLongPtrA(hwnd
, GWLP_USERDATA
);
1661 if (message
== LB_GETLISTBOXINFO
)
1662 lb_getlistboxinfo
++;
1664 return CallWindowProcA(oldproc
, hwnd
, message
, wParam
, lParam
);
1667 static void test_GetListBoxInfo(void)
1669 HWND listbox
, parent
;
1673 parent
= create_parent();
1674 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
, parent
);
1676 oldproc
= (WNDPROC
)SetWindowLongPtrA(listbox
, GWLP_WNDPROC
, (LONG_PTR
)listbox_subclass_proc
);
1677 SetWindowLongPtrA(listbox
, GWLP_USERDATA
, (LONG_PTR
)oldproc
);
1679 lb_getlistboxinfo
= 0;
1680 ret
= GetListBoxInfo(listbox
);
1681 ok(ret
> 0, "got %d\n", ret
);
1682 ok(lb_getlistboxinfo
== 1, "got %d\n", lb_getlistboxinfo
);
1684 DestroyWindow(listbox
);
1685 DestroyWindow(parent
);
1688 static void test_missing_lbuttonup(void)
1690 HWND listbox
, parent
, capture
;
1692 parent
= create_parent();
1693 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
, parent
);
1695 /* Send button down without a corresponding button up */
1696 SendMessageA(listbox
, WM_LBUTTONDOWN
, 0, MAKELPARAM(10, 10));
1697 capture
= GetCapture();
1698 ok(capture
== listbox
, "got %p expected %p\n", capture
, listbox
);
1700 /* Capture is released and LBN_SELCHANGE sent during WM_KILLFOCUS */
1703 capture
= GetCapture();
1704 ok(capture
== NULL
, "got %p\n", capture
);
1705 ok(got_selchange
, "got %d\n", got_selchange
);
1707 DestroyWindow(listbox
);
1708 DestroyWindow(parent
);
1711 static void test_extents(void)
1713 HWND listbox
, parent
;
1718 parent
= create_parent();
1720 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
, parent
);
1722 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1723 ok(res
== 0, "Got wrong initial horizontal extent: %u\n", res
);
1725 sinfo
.cbSize
= sizeof(sinfo
);
1726 sinfo
.fMask
= SIF_RANGE
;
1727 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1728 ok(br
== TRUE
, "GetScrollInfo failed\n");
1729 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1730 ok(sinfo
.nMax
== 100, "got wrong max: %u\n", sinfo
.nMax
);
1731 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1732 "List box should not have a horizontal scroll bar\n");
1734 /* horizontal extent < width */
1735 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 64, 0);
1737 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1738 ok(res
== 64, "Got wrong horizontal extent: %u\n", res
);
1740 sinfo
.cbSize
= sizeof(sinfo
);
1741 sinfo
.fMask
= SIF_RANGE
;
1742 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1743 ok(br
== TRUE
, "GetScrollInfo failed\n");
1744 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1745 ok(sinfo
.nMax
== 100, "got wrong max: %u\n", sinfo
.nMax
);
1746 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1747 "List box should not have a horizontal scroll bar\n");
1749 /* horizontal extent > width */
1750 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 184, 0);
1752 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1753 ok(res
== 184, "Got wrong horizontal extent: %u\n", res
);
1755 sinfo
.cbSize
= sizeof(sinfo
);
1756 sinfo
.fMask
= SIF_RANGE
;
1757 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1758 ok(br
== TRUE
, "GetScrollInfo failed\n");
1759 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1760 ok(sinfo
.nMax
== 100, "got wrong max: %u\n", sinfo
.nMax
);
1761 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1762 "List box should not have a horizontal scroll bar\n");
1764 DestroyWindow(listbox
);
1766 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
| WS_HSCROLL
, parent
);
1768 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1769 ok(res
== 0, "Got wrong initial horizontal extent: %u\n", res
);
1771 sinfo
.cbSize
= sizeof(sinfo
);
1772 sinfo
.fMask
= SIF_RANGE
;
1773 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1774 ok(br
== TRUE
, "GetScrollInfo failed\n");
1775 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1776 ok(sinfo
.nMax
== 100, "got wrong max: %u\n", sinfo
.nMax
);
1777 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1778 "List box should not have a horizontal scroll bar\n");
1780 /* horizontal extent < width */
1781 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 64, 0);
1783 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1784 ok(res
== 64, "Got wrong horizontal extent: %u\n", res
);
1786 sinfo
.cbSize
= sizeof(sinfo
);
1787 sinfo
.fMask
= SIF_RANGE
;
1788 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1789 ok(br
== TRUE
, "GetScrollInfo failed\n");
1790 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1791 ok(sinfo
.nMax
== 63, "got wrong max: %u\n", sinfo
.nMax
);
1792 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1793 "List box should not have a horizontal scroll bar\n");
1795 /* horizontal extent > width */
1796 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 184, 0);
1798 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1799 ok(res
== 184, "Got wrong horizontal extent: %u\n", res
);
1801 sinfo
.cbSize
= sizeof(sinfo
);
1802 sinfo
.fMask
= SIF_RANGE
;
1803 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1804 ok(br
== TRUE
, "GetScrollInfo failed\n");
1805 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1806 ok(sinfo
.nMax
== 183, "got wrong max: %u\n", sinfo
.nMax
);
1807 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
1808 "List box should have a horizontal scroll bar\n");
1810 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 0, 0);
1812 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1813 ok(res
== 0, "Got wrong horizontal extent: %u\n", res
);
1815 sinfo
.cbSize
= sizeof(sinfo
);
1816 sinfo
.fMask
= SIF_RANGE
;
1817 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1818 ok(br
== TRUE
, "GetScrollInfo failed\n");
1819 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1820 ok(sinfo
.nMax
== 0, "got wrong max: %u\n", sinfo
.nMax
);
1821 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1822 "List box should not have a horizontal scroll bar\n");
1824 DestroyWindow(listbox
);
1827 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
| WS_HSCROLL
| LBS_DISABLENOSCROLL
, parent
);
1829 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1830 ok(res
== 0, "Got wrong initial horizontal extent: %u\n", res
);
1832 sinfo
.cbSize
= sizeof(sinfo
);
1833 sinfo
.fMask
= SIF_RANGE
;
1834 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1835 ok(br
== TRUE
, "GetScrollInfo failed\n");
1836 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1837 ok(sinfo
.nMax
== 0, "got wrong max: %u\n", sinfo
.nMax
);
1838 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
1839 "List box should have a horizontal scroll bar\n");
1841 /* horizontal extent < width */
1842 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 64, 0);
1844 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1845 ok(res
== 64, "Got wrong horizontal extent: %u\n", res
);
1847 sinfo
.cbSize
= sizeof(sinfo
);
1848 sinfo
.fMask
= SIF_RANGE
;
1849 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1850 ok(br
== TRUE
, "GetScrollInfo failed\n");
1851 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1852 ok(sinfo
.nMax
== 63, "got wrong max: %u\n", sinfo
.nMax
);
1853 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
1854 "List box should have a horizontal scroll bar\n");
1856 /* horizontal extent > width */
1857 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 184, 0);
1859 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1860 ok(res
== 184, "Got wrong horizontal extent: %u\n", res
);
1862 sinfo
.cbSize
= sizeof(sinfo
);
1863 sinfo
.fMask
= SIF_RANGE
;
1864 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1865 ok(br
== TRUE
, "GetScrollInfo failed\n");
1866 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1867 ok(sinfo
.nMax
== 183, "got wrong max: %u\n", sinfo
.nMax
);
1868 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
1869 "List box should have a horizontal scroll bar\n");
1871 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 0, 0);
1873 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1874 ok(res
== 0, "Got wrong horizontal extent: %u\n", res
);
1876 sinfo
.cbSize
= sizeof(sinfo
);
1877 sinfo
.fMask
= SIF_RANGE
;
1878 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1879 ok(br
== TRUE
, "GetScrollInfo failed\n");
1880 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1881 ok(sinfo
.nMax
== 0, "got wrong max: %u\n", sinfo
.nMax
);
1882 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
1883 "List box should have a horizontal scroll bar\n");
1885 DestroyWindow(listbox
);
1887 DestroyWindow(parent
);
1890 static void test_listbox(void)
1892 static const struct listbox_test SS
=
1895 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
1896 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
1897 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
1898 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
1900 /* {selected, anchor, caret, selcount}{TODO fields} */
1901 static const struct listbox_test SS_NS
=
1903 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
1904 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
1905 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
1906 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
1908 static const struct listbox_test MS
=
1910 { 0, LB_ERR
, 0, 0}, {0,0,0,0},
1911 { 1, 1, 1, 1}, {0,0,0,0},
1912 { 2, 1, 2, 1}, {0,0,0,0},
1913 { 0, LB_ERR
, 0, 2}, {0,0,0,0}};
1915 static const struct listbox_test MS_NS
=
1916 {{LBS_MULTIPLESEL
| LBS_NOSEL
},
1917 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
1918 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
1919 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
1920 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
1922 static const struct listbox_test ES
=
1924 { 0, LB_ERR
, 0, 0}, {0,0,0,0},
1925 { 1, 1, 1, 1}, {0,0,0,0},
1926 { 2, 2, 2, 1}, {0,0,0,0},
1927 { 0, LB_ERR
, 0, 2}, {0,0,0,0}};
1929 static const struct listbox_test ES_NS
=
1930 {{LBS_EXTENDEDSEL
| LBS_NOSEL
},
1931 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
1932 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
1933 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
1934 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
1936 static const struct listbox_test EMS
=
1937 {{LBS_EXTENDEDSEL
| LBS_MULTIPLESEL
},
1938 { 0, LB_ERR
, 0, 0}, {0,0,0,0},
1939 { 1, 1, 1, 1}, {0,0,0,0},
1940 { 2, 2, 2, 1}, {0,0,0,0},
1941 { 0, LB_ERR
, 0, 2}, {0,0,0,0}};
1943 static const struct listbox_test EMS_NS
=
1944 {{LBS_EXTENDEDSEL
| LBS_MULTIPLESEL
| LBS_NOSEL
},
1945 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
1946 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
1947 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
1948 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
1960 static const struct message lb_addstring_ownerdraw_parent_seq
[] =
1962 { WM_MEASUREITEM
, sent
|wparam
|lparam
, 0x1012, 0xf30604ed },
1963 { WM_MEASUREITEM
, sent
|wparam
|lparam
, 0x1112, 0xf30604ee },
1964 { WM_MEASUREITEM
, sent
|wparam
|lparam
, 0x1212, 0xf30604ef },
1968 static const struct message lb_addstring_sort_parent_seq
[] =
1970 { WM_MEASUREITEM
, sent
|wparam
|lparam
, 0x1012, 0xf30604ed },
1971 { WM_COMPAREITEM
, sent
|wparam
|lparam
, 0xf30604ed, 0xf30604ee },
1972 { WM_MEASUREITEM
, sent
|wparam
|lparam
, 0x1112, 0xf30604ee },
1973 { WM_COMPAREITEM
, sent
|wparam
|lparam
, 0xf30604ed, 0xf30604ef },
1974 { WM_COMPAREITEM
, sent
|wparam
|lparam
, 0xf30604ee, 0xf30604ef },
1975 { WM_MEASUREITEM
, sent
|wparam
|lparam
, 0x1212, 0xf30604ef },
1979 static const struct message empty_seq
[] =
1984 static void test_WM_MEASUREITEM(void)
1986 HWND parent
, listbox
;
1989 parent
= create_parent();
1990 listbox
= create_listbox(WS_CHILD
| LBS_OWNERDRAWVARIABLE
, parent
);
1992 data
= SendMessageA(listbox
, LB_GETITEMDATA
, 0, 0);
1993 ok(data
== (LRESULT
)strings
[0], "data = %08lx, expected %p\n", data
, strings
[0]);
1994 DestroyWindow(parent
);
1996 parent
= create_parent();
1997 listbox
= create_listbox(WS_CHILD
| LBS_OWNERDRAWVARIABLE
| LBS_HASSTRINGS
, parent
);
1999 data
= SendMessageA(listbox
, LB_GETITEMDATA
, 0, 0);
2000 ok(!data
, "data = %08lx\n", data
);
2002 /* LBS_HASSTRINGS */
2003 parent
= create_parent();
2004 listbox
= CreateWindowExA(WS_EX_NOPARENTNOTIFY
, WC_LISTBOXA
, NULL
,
2005 WS_CHILD
| LBS_NOTIFY
| LBS_OWNERDRAWVARIABLE
| LBS_HASSTRINGS
| WS_VISIBLE
,
2006 10, 10, 80, 80, parent
, (HMENU
)ID_LISTBOX
, 0, NULL
);
2008 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
2010 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 0");
2011 ok(ret
== 0, "expected 0, got %ld\n", ret
);
2012 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 1");
2013 ok(ret
== 1, "expected 1, got %ld\n", ret
);
2014 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 2");
2015 ok(ret
== 2, "expected 2, got %ld\n", ret
);
2017 ok_sequence(sequences
, PARENT_SEQ_INDEX
, lb_addstring_ownerdraw_parent_seq
,
2018 "LB_ADDSTRING (LBS_HASSTRINGS, ownerdraw)", FALSE
);
2019 DestroyWindow(listbox
);
2021 /* LBS_SORT, no LBS_HASSTRINGS */
2022 listbox
= CreateWindowExA(WS_EX_NOPARENTNOTIFY
, WC_LISTBOXA
, NULL
,
2023 WS_CHILD
| LBS_NOTIFY
| LBS_OWNERDRAWVARIABLE
| LBS_SORT
| WS_VISIBLE
,
2024 10, 10, 80, 80, parent
, (HMENU
)ID_LISTBOX
, 0, NULL
);
2026 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
2028 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 0");
2029 ok(ret
== 0, "expected 0, got %ld\n", ret
);
2030 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 1");
2031 ok(ret
== 1, "expected 1, got %ld\n", ret
);
2032 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 2");
2033 ok(ret
== 2, "expected 2, got %ld\n", ret
);
2035 ok_sequence(sequences
, PARENT_SEQ_INDEX
, lb_addstring_sort_parent_seq
, "LB_ADDSTRING (LBS_SORT)", TRUE
);
2036 DestroyWindow(listbox
);
2038 /* LBS_HASSTRINGS */
2039 listbox
= CreateWindowExA(WS_EX_NOPARENTNOTIFY
, WC_LISTBOXA
, NULL
,
2040 WS_CHILD
| LBS_NOTIFY
| LBS_HASSTRINGS
| WS_VISIBLE
,
2041 10, 10, 80, 80, parent
, (HMENU
)ID_LISTBOX
, 0, NULL
);
2043 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
2045 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 2");
2046 ok(ret
== 0, "expected 0, got %ld\n", ret
);
2047 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 0");
2048 ok(ret
== 1, "expected 1, got %ld\n", ret
);
2049 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 1");
2050 ok(ret
== 2, "expected 2, got %ld\n", ret
);
2052 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_seq
, "LB_ADDSTRING (LBS_HASSTRINGS)", FALSE
);
2053 DestroyWindow(listbox
);
2055 /* LBS_HASSTRINGS, LBS_SORT */
2056 listbox
= CreateWindowExA(WS_EX_NOPARENTNOTIFY
, WC_LISTBOXA
, NULL
,
2057 WS_CHILD
| LBS_NOTIFY
| LBS_HASSTRINGS
| LBS_SORT
| WS_VISIBLE
,
2058 10, 10, 80, 80, parent
, (HMENU
)ID_LISTBOX
, 0, NULL
);
2060 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
2062 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 2");
2063 ok(ret
== 0, "expected 0, got %ld\n", ret
);
2064 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 0");
2065 ok(ret
== 0, "expected 0, got %ld\n", ret
);
2066 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 1");
2067 ok(ret
== 1, "expected 1, got %ld\n", ret
);
2069 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_seq
, "LB_ADDSTRING (LBS_HASSTRINGS, LBS_SORT)", FALSE
);
2070 DestroyWindow(listbox
);
2072 DestroyWindow(parent
);
2077 ULONG_PTR ctx_cookie
;
2080 if (!load_v6_module(&ctx_cookie
, &hCtx
))
2083 init_msg_sequences(sequences
, NUM_MSG_SEQUENCES
);
2088 test_LB_SELITEMRANGE();
2089 test_LB_SETCURSEL();
2090 test_listbox_height();
2091 test_itemfrompoint();
2092 test_listbox_item_data();
2093 test_listbox_LB_DIR();
2094 test_listbox_dlgdir();
2096 test_GetListBoxInfo();
2097 test_missing_lbuttonup();
2099 test_WM_MEASUREITEM();
2101 unload_v6_module(ctx_cookie
, hCtx
);