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_stat init
, init_todo
;
126 struct listbox_stat click
, click_todo
;
127 struct listbox_stat step
, step_todo
;
128 struct listbox_stat sel
, sel_todo
;
131 static void listbox_query(HWND handle
, struct listbox_stat
*results
)
133 results
->selected
= SendMessageA(handle
, LB_GETCURSEL
, 0, 0);
134 results
->anchor
= SendMessageA(handle
, LB_GETANCHORINDEX
, 0, 0);
135 results
->caret
= SendMessageA(handle
, LB_GETCARETINDEX
, 0, 0);
136 results
->selcount
= SendMessageA(handle
, LB_GETSELCOUNT
, 0, 0);
139 static void buttonpress(HWND handle
, WORD x
, WORD y
)
141 LPARAM lp
= x
+ (y
<< 16);
143 SendMessageA(handle
, WM_LBUTTONDOWN
, MK_LBUTTON
, lp
);
144 SendMessageA(handle
, WM_LBUTTONUP
, 0, lp
);
147 static void keypress(HWND handle
, WPARAM keycode
, BYTE scancode
, BOOL extended
)
149 LPARAM lp
= 1 + (scancode
<< 16) + (extended
? KEYEVENTF_EXTENDEDKEY
: 0);
151 SendMessageA(handle
, WM_KEYDOWN
, keycode
, lp
);
152 SendMessageA(handle
, WM_KEYUP
, keycode
, lp
| 0xc000000);
155 #define listbox_field_ok(t, s, f, got) \
156 ok (t.s.f==got.f, "style %#x, step " #s ", field " #f \
157 ": expected %d, got %d\n", style, t.s.f, got.f)
159 #define listbox_todo_field_ok(t, s, f, got) \
160 todo_wine_if (t.s##_todo.f) { listbox_field_ok(t, s, f, got); }
162 #define listbox_ok(t, s, got) \
163 listbox_todo_field_ok(t, s, selected, got); \
164 listbox_todo_field_ok(t, s, anchor, got); \
165 listbox_todo_field_ok(t, s, caret, got); \
166 listbox_todo_field_ok(t, s, selcount, got)
168 static void run_test(DWORD style
, const struct listbox_test test
)
170 struct listbox_stat answer
;
175 hLB
= create_listbox (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(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 && !(style
& LBS_NODATA
); 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
);
212 ok(resA
== resW
, "Unexpected text length.\n");
213 WideCharToMultiByte(CP_ACP
, 0, txtw
, -1, txt
, size
, NULL
, NULL
);
214 ok(!strcmp (txt
, strings
[i
]), "Unexpected string for item %d, %s vs %s.\n", i
, txt
, strings
[i
]);
220 /* Confirm the count of items, and that an invalid delete does not remove anything */
221 res
= SendMessageA(hLB
, LB_GETCOUNT
, 0, 0);
222 ok(res
== 4, "Expected 4 items, got %d\n", res
);
223 res
= SendMessageA(hLB
, LB_DELETESTRING
, -1, 0);
224 ok(res
== LB_ERR
, "Expected LB_ERR items, got %d\n", res
);
225 res
= SendMessageA(hLB
, LB_DELETESTRING
, 4, 0);
226 ok(res
== LB_ERR
, "Expected LB_ERR items, got %d\n", res
);
227 res
= SendMessageA(hLB
, LB_GETCOUNT
, 0, 0);
228 ok(res
== 4, "Expected 4 items, got %d\n", res
);
233 static void test_item_height(void)
241 hLB
= create_listbox (0, 0);
242 ok ((hdc
= GetDCEx( hLB
, 0, DCX_CACHE
)) != 0, "Can't get hdc\n");
243 ok ((font
= GetCurrentObject(hdc
, OBJ_FONT
)) != 0, "Can't get the current font\n");
244 ok (GetTextMetricsA( hdc
, &tm
), "Can't read font metrics\n");
245 ReleaseDC( hLB
, hdc
);
247 ok (SendMessageA(hLB
, WM_SETFONT
, (WPARAM
)font
, 0) == 0, "Can't set font\n");
249 itemHeight
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 0, 0);
250 ok (itemHeight
== tm
.tmHeight
, "Item height wrong, got %d, expecting %d\n", itemHeight
, tm
.tmHeight
);
254 hLB
= CreateWindowA(WC_LISTBOXA
, "TestList", LBS_OWNERDRAWVARIABLE
, 0, 0, 100, 100, NULL
, NULL
, NULL
, 0);
256 itemHeight
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 0, 0);
257 ok(itemHeight
> 0 && itemHeight
<= tm
.tmHeight
, "Unexpected item height %d, expected %d.\n",
258 itemHeight
, tm
.tmHeight
);
259 itemHeight
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 5, 0);
260 ok(itemHeight
> 0 && itemHeight
<= tm
.tmHeight
, "Unexpected item height %d, expected %d.\n",
261 itemHeight
, tm
.tmHeight
);
262 itemHeight
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, -5, 0);
263 ok(itemHeight
> 0 && itemHeight
<= tm
.tmHeight
, "Unexpected item height %d, expected %d.\n",
264 itemHeight
, tm
.tmHeight
);
269 static int got_selchange
;
271 static LRESULT WINAPI
main_window_proc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
273 static LONG defwndproc_counter
= 0;
274 struct message m
= { 0 };
278 m
.flags
= sent
|wparam
|lparam
;
279 if (defwndproc_counter
) m
.flags
|= defwinproc
;
287 MEASUREITEMSTRUCT
*mis
= (void *)lParam
;
288 BOOL is_unicode_data
= FALSE
;
289 MEASURE_ITEM_STRUCT mi
;
291 if (mis
->CtlType
== ODT_LISTBOX
)
293 HWND ctrl
= GetDlgItem(hwnd
, mis
->CtlID
);
294 is_unicode_data
= GetWindowLongA(ctrl
, GWL_STYLE
) & LBS_HASSTRINGS
;
298 mi
.u
.item
.CtlType
= mis
->CtlType
;
299 mi
.u
.item
.CtlID
= mis
->CtlID
;
300 mi
.u
.item
.itemID
= mis
->itemID
;
301 mi
.u
.item
.wParam
= wParam
;
305 m
.lParam
= mis
->itemData
? hash_Ly_W((const WCHAR
*)mis
->itemData
) : 0;
307 m
.lParam
= mis
->itemData
? hash_Ly((const char *)mis
->itemData
) : 0;
308 add_message(sequences
, PARENT_SEQ_INDEX
, &m
);
310 ok(wParam
== mis
->CtlID
, "got wParam=%08lx, expected %08x\n", wParam
, mis
->CtlID
);
311 ok(mis
->CtlType
== ODT_LISTBOX
, "mi->CtlType = %u\n", mis
->CtlType
);
312 ok(mis
->CtlID
== 1, "mi->CtlID = %u\n", mis
->CtlID
);
313 ok(mis
->itemHeight
, "mi->itemHeight = 0\n");
319 COMPAREITEMSTRUCT
*cis
= (COMPAREITEMSTRUCT
*)lParam
;
320 HWND ctrl
= GetDlgItem(hwnd
, cis
->CtlID
);
321 BOOL is_unicode_data
= TRUE
;
323 ok(wParam
== cis
->CtlID
, "expected %#x, got %#lx\n", cis
->CtlID
, wParam
);
324 ok(cis
->hwndItem
== ctrl
, "expected %p, got %p\n", ctrl
, cis
->hwndItem
);
325 ok((int)cis
->itemID1
>= 0, "expected >= 0, got %d\n", cis
->itemID1
);
326 ok((int)cis
->itemID2
== -1, "expected -1, got %d\n", cis
->itemID2
);
328 if (cis
->CtlType
== ODT_LISTBOX
)
329 is_unicode_data
= GetWindowLongA(ctrl
, GWL_STYLE
) & LBS_HASSTRINGS
;
333 m
.wParam
= cis
->itemData1
? hash_Ly_W((const WCHAR
*)cis
->itemData1
) : 0;
334 m
.lParam
= cis
->itemData2
? hash_Ly_W((const WCHAR
*)cis
->itemData2
) : 0;
338 m
.wParam
= cis
->itemData1
? hash_Ly((const char *)cis
->itemData1
) : 0;
339 m
.lParam
= cis
->itemData2
? hash_Ly((const char *)cis
->itemData2
) : 0;
341 add_message(sequences
, PARENT_SEQ_INDEX
, &m
);
346 RECT rc_item
, rc_client
, rc_clip
;
347 DRAWITEMSTRUCT
*dis
= (DRAWITEMSTRUCT
*)lParam
;
349 ok(wParam
== dis
->CtlID
, "got wParam=%08lx instead of %08x\n", wParam
, dis
->CtlID
);
350 ok(dis
->CtlType
== ODT_LISTBOX
, "wrong CtlType %04x\n", dis
->CtlType
);
352 GetClientRect(dis
->hwndItem
, &rc_client
);
353 GetClipBox(dis
->hDC
, &rc_clip
);
354 ok(EqualRect(&rc_client
, &rc_clip
) || IsRectEmpty(&rc_clip
),
355 "client rect of the listbox should be equal to the clip box,"
356 "or the clip box should be empty\n");
358 SendMessageA(dis
->hwndItem
, LB_GETITEMRECT
, dis
->itemID
, (LPARAM
)&rc_item
);
359 ok(EqualRect(&dis
->rcItem
, &rc_item
), "item rects are not equal\n");
365 if (HIWORD( wParam
) == LBN_SELCHANGE
) got_selchange
++;
372 defwndproc_counter
++;
373 ret
= DefWindowProcA(hwnd
, msg
, wParam
, lParam
);
374 defwndproc_counter
--;
376 return msg
== WM_COMPAREITEM
? -1 : ret
;
379 static HWND
create_parent( void )
387 cls
.lpfnWndProc
= main_window_proc
;
390 cls
.hInstance
= GetModuleHandleA(NULL
);
392 cls
.hCursor
= LoadCursorA(0, (LPCSTR
)IDC_ARROW
);
393 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
394 cls
.lpszMenuName
= NULL
;
395 cls
.lpszClassName
= "main_window_class";
396 class = RegisterClassA( &cls
);
399 return CreateWindowExA(0, "main_window_class", NULL
, WS_POPUP
| WS_VISIBLE
, 100, 100, 400, 400, GetDesktopWindow(),
400 0, GetModuleHandleA(NULL
), NULL
);
403 static void test_ownerdraw(void)
409 parent
= create_parent();
410 ok(parent
!= NULL
, "Failed to create parent window.\n");
412 hLB
= create_listbox(LBS_OWNERDRAWFIXED
| WS_CHILD
| WS_VISIBLE
, parent
);
413 ok(hLB
!= NULL
, "Failed to create listbox window.\n");
415 SetForegroundWindow(hLB
);
418 /* make height short enough */
419 SendMessageA(hLB
, LB_GETITEMRECT
, 0, (LPARAM
)&rc
);
420 SetWindowPos(hLB
, 0, 0, 0, 100, rc
.bottom
- rc
.top
+ 1, SWP_NOZORDER
| SWP_NOMOVE
);
422 /* make 0 item invisible */
423 SendMessageA(hLB
, LB_SETTOPINDEX
, 1, 0);
424 ret
= SendMessageA(hLB
, LB_GETTOPINDEX
, 0, 0);
425 ok(ret
== 1, "wrong top index %d\n", ret
);
427 SendMessageA(hLB
, LB_GETITEMRECT
, 0, (LPARAM
)&rc
);
428 ok(!IsRectEmpty(&rc
), "empty item rect\n");
429 ok(rc
.top
< 0, "rc.top is not negative (%d)\n", rc
.top
);
433 /* Both FIXED and VARIABLE, FIXED should override VARIABLE. */
434 hLB
= CreateWindowA(WC_LISTBOXA
, "TestList", LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
, 0, 0, 100, 100,
435 NULL
, NULL
, NULL
, 0);
436 ok(hLB
!= NULL
, "last error 0x%08x\n", GetLastError());
438 ret
= SendMessageA(hLB
, LB_INSERTSTRING
, -1, 0);
439 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
440 ret
= SendMessageA(hLB
, LB_INSERTSTRING
, -1, 0);
441 ok(ret
== 1, "Unexpected return value %d.\n", ret
);
443 ret
= SendMessageA(hLB
, LB_SETITEMHEIGHT
, 0, 13);
444 ok(ret
== LB_OKAY
, "Failed to set item height, %d.\n", ret
);
446 ret
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 0, 0);
447 ok(ret
== 13, "Unexpected item height %d.\n", ret
);
449 ret
= SendMessageA(hLB
, LB_SETITEMHEIGHT
, 1, 42);
450 ok(ret
== LB_OKAY
, "Failed to set item height, %d.\n", ret
);
452 ret
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 0, 0);
454 ok(ret
== 42, "Unexpected item height %d.\n", ret
);
456 ret
= SendMessageA(hLB
, LB_GETITEMHEIGHT
, 1, 0);
457 ok(ret
== 42, "Unexpected item height %d.\n", ret
);
461 DestroyWindow(parent
);
464 #define listbox_test_query(exp, got) \
465 ok(exp.selected == got.selected, "expected selected %d, got %d\n", exp.selected, got.selected); \
466 ok(exp.anchor == got.anchor, "expected anchor %d, got %d\n", exp.anchor, got.anchor); \
467 ok(exp.caret == got.caret, "expected caret %d, got %d\n", exp.caret, got.caret); \
468 ok(exp.selcount == got.selcount, "expected selcount %d, got %d\n", exp.selcount, got.selcount);
470 static void test_LB_SELITEMRANGE(void)
472 static const struct listbox_stat test_nosel
= { 0, LB_ERR
, 0, 0 };
473 static const struct listbox_stat test_1
= { 0, LB_ERR
, 0, 2 };
474 static const struct listbox_stat test_2
= { 0, LB_ERR
, 0, 3 };
475 static const struct listbox_stat test_3
= { 0, LB_ERR
, 0, 4 };
476 struct listbox_stat answer
;
480 hLB
= create_listbox(LBS_EXTENDEDSEL
, 0);
481 ok(hLB
!= NULL
, "Failed to create listbox window.\n");
483 listbox_query(hLB
, &answer
);
484 listbox_test_query(test_nosel
, answer
);
486 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(1, 2));
487 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
488 listbox_query(hLB
, &answer
);
489 listbox_test_query(test_1
, answer
);
491 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
492 listbox_query(hLB
, &answer
);
493 listbox_test_query(test_nosel
, answer
);
495 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(0, 4));
496 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
497 listbox_query(hLB
, &answer
);
498 listbox_test_query(test_3
, answer
);
500 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
501 listbox_query(hLB
, &answer
);
502 listbox_test_query(test_nosel
, answer
);
504 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(-5, 5));
505 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
506 listbox_query(hLB
, &answer
);
507 listbox_test_query(test_nosel
, answer
);
509 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
510 listbox_query(hLB
, &answer
);
511 listbox_test_query(test_nosel
, answer
);
513 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(2, 10));
514 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
515 listbox_query(hLB
, &answer
);
516 listbox_test_query(test_1
, answer
);
518 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
519 listbox_query(hLB
, &answer
);
520 listbox_test_query(test_nosel
, answer
);
522 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(4, 10));
523 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
524 listbox_query(hLB
, &answer
);
525 listbox_test_query(test_nosel
, answer
);
527 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
528 listbox_query(hLB
, &answer
);
529 listbox_test_query(test_nosel
, answer
);
531 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(10, 1));
532 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
533 listbox_query(hLB
, &answer
);
534 listbox_test_query(test_2
, answer
);
536 SendMessageA(hLB
, LB_SETSEL
, FALSE
, -1);
537 listbox_query(hLB
, &answer
);
538 listbox_test_query(test_nosel
, answer
);
540 ret
= SendMessageA(hLB
, LB_SELITEMRANGE
, TRUE
, MAKELPARAM(1, -1));
541 ok(ret
== LB_OKAY
, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret
);
542 listbox_query(hLB
, &answer
);
543 listbox_test_query(test_2
, answer
);
548 static void test_LB_SETCURSEL(void)
553 parent
= create_parent();
554 ok(parent
!= NULL
, "Failed to create parent window.\n");
556 hLB
= create_listbox(LBS_NOINTEGRALHEIGHT
| WS_CHILD
, parent
);
557 ok(hLB
!= NULL
, "Failed to create listbox.\n");
559 SendMessageA(hLB
, LB_SETITEMHEIGHT
, 0, 32);
561 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
562 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
564 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 2, 0);
565 ok(ret
== 2, "LB_SETCURSEL returned %d instead of 2\n", ret
);
566 ret
= GetScrollPos(hLB
, SB_VERT
);
567 ok(ret
== 0, "expected vscroll 0, got %d\n", ret
);
569 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
570 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
572 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 3, 0);
573 ok(ret
== 3, "LB_SETCURSEL returned %d instead of 3\n", ret
);
574 ret
= GetScrollPos(hLB
, SB_VERT
);
575 ok(ret
== 1, "expected vscroll 1, got %d\n", ret
);
577 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
578 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
582 hLB
= create_listbox(0, 0);
583 ok(hLB
!= NULL
, "Failed to create ListBox window.\n");
585 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 1, 0);
586 ok(ret
== 1, "Unexpected return value %d.\n", ret
);
588 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
589 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
593 /* LBS_EXTENDEDSEL */
594 hLB
= create_listbox(LBS_EXTENDEDSEL
, 0);
595 ok(hLB
!= NULL
, "Failed to create listbox.\n");
597 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
598 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
600 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 2, 0);
601 ok(ret
== -1, "LB_SETCURSEL returned %d instead of 2\n", ret
);
603 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
604 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
608 /* LBS_MULTIPLESEL */
609 hLB
= create_listbox(LBS_MULTIPLESEL
, 0);
610 ok(hLB
!= NULL
, "Failed to create listbox.\n");
612 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
613 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
615 ret
= SendMessageA(hLB
, LB_SETCURSEL
, 2, 0);
616 ok(ret
== -1, "LB_SETCURSEL returned %d instead of 2\n", ret
);
618 ret
= SendMessageA(hLB
, LB_GETANCHORINDEX
, 0, 0);
619 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
624 static void test_LB_SETSEL(void)
629 /* LBS_EXTENDEDSEL */
630 list
= create_listbox(LBS_EXTENDEDSEL
, 0);
631 ok(list
!= NULL
, "Failed to create ListBox window.\n");
633 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
634 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
636 ret
= SendMessageA(list
, LB_SETSEL
, TRUE
, 0);
637 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
638 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
639 ok(ret
== 0, "Unexpected anchor index %d.\n", ret
);
641 ret
= SendMessageA(list
, LB_SETSEL
, TRUE
, 1);
642 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
643 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
644 ok(ret
== 1, "Unexpected anchor index %d.\n", ret
);
646 ret
= SendMessageA(list
, LB_SETSEL
, FALSE
, 1);
647 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
648 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
649 ok(ret
== 1, "Unexpected anchor index %d.\n", ret
);
653 /* LBS_MULTIPLESEL */
654 list
= create_listbox(LBS_MULTIPLESEL
, 0);
655 ok(list
!= NULL
, "Failed to create ListBox window.\n");
657 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
658 ok(ret
== -1, "Unexpected anchor index %d.\n", ret
);
660 ret
= SendMessageA(list
, LB_SETSEL
, TRUE
, 0);
661 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
662 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
663 ok(ret
== 0, "Unexpected anchor index %d.\n", ret
);
665 ret
= SendMessageA(list
, LB_SETSEL
, TRUE
, 1);
666 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
667 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
668 ok(ret
== 1, "Unexpected anchor index %d.\n", ret
);
670 ret
= SendMessageA(list
, LB_SETSEL
, FALSE
, 1);
671 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
672 ret
= SendMessageA(list
, LB_GETANCHORINDEX
, 0, 0);
673 ok(ret
== 1, "Unexpected anchor index %d.\n", ret
);
678 static void test_listbox_height(void)
683 hList
= CreateWindowA( WC_LISTBOXA
, "list test", 0,
684 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
685 ok( hList
!= NULL
, "failed to create listbox\n");
687 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi");
688 ok( id
== 0, "item id wrong\n");
690 r
= SendMessageA( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 20, 0 ));
691 ok( r
== 0, "send message failed\n");
693 r
= SendMessageA(hList
, LB_GETITEMHEIGHT
, 0, 0 );
694 ok( r
== 20, "height wrong\n");
696 r
= SendMessageA( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 0, 30 ));
697 ok( r
== -1, "send message failed\n");
699 r
= SendMessageA(hList
, LB_GETITEMHEIGHT
, 0, 0 );
700 ok( r
== 20, "height wrong\n");
702 r
= SendMessageA( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 256, 0 ));
703 ok( r
== -1, "Failed to set item height, %d.\n", r
);
705 r
= SendMessageA(hList
, LB_GETITEMHEIGHT
, 0, 0 );
706 ok( r
== 20, "Unexpected item height %d.\n", r
);
708 r
= SendMessageA( hList
, LB_SETITEMHEIGHT
, 0, MAKELPARAM( 0xff, 0 ));
709 ok( r
== 0, "send message failed\n");
711 r
= SendMessageA(hList
, LB_GETITEMHEIGHT
, 0, 0 );
712 ok( r
== 0xff, "height wrong\n");
714 DestroyWindow( hList
);
717 static void test_itemfrompoint(void)
719 /* WS_POPUP is required in order to have a more accurate size calculation (
720 without caption). LBS_NOINTEGRALHEIGHT is required in order to test
721 behavior of partially-displayed item.
723 HWND hList
= CreateWindowA( WC_LISTBOXA
, "list test",
724 WS_VISIBLE
|WS_POPUP
|LBS_NOINTEGRALHEIGHT
,
725 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
729 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
730 ok( r
== MAKELPARAM(0xffff, 1), "Unexpected ret value %#x.\n", r
);
732 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( 700, 30 ));
733 ok( r
== MAKELPARAM(0xffff, 1), "Unexpected ret value %#x.\n", r
);
735 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( 30, 300 ));
736 ok( r
== MAKELPARAM(0xffff, 1), "Unexpected ret value %#x.\n", r
);
738 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi");
739 ok( id
== 0, "item id wrong\n");
740 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi1");
741 ok( id
== 1, "item id wrong\n");
743 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
744 ok( r
== 0x1, "ret %x\n", r
);
746 r
= SendMessageA(hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM( /* x */ 30, /* y */ 601 ));
747 ok( r
== MAKELPARAM(1, 1), "Unexpected ret value %#x.\n", r
);
749 /* Resize control so that below assertions about sizes are valid */
750 r
= SendMessageA( hList
, LB_GETITEMRECT
, 0, (LPARAM
)&rc
);
751 ok( r
== 1, "ret %x\n", r
);
752 r
= MoveWindow(hList
, 1, 1, 600, (rc
.bottom
- rc
.top
+ 1) * 9 / 2, TRUE
);
753 ok( r
!= 0, "ret %x\n", r
);
755 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi2");
756 ok( id
== 2, "item id wrong\n");
757 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi3");
758 ok( id
== 3, "item id wrong\n");
759 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi4");
760 ok( id
== 4, "item id wrong\n");
761 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi5");
762 ok( id
== 5, "item id wrong\n");
763 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi6");
764 ok( id
== 6, "item id wrong\n");
765 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi7");
766 ok( id
== 7, "item id wrong\n");
768 /* Set the listbox up so that id 1 is at the top, this leaves 5
769 partially visible at the bottom and 6, 7 are invisible */
771 SendMessageA( hList
, LB_SETTOPINDEX
, 1, 0);
772 r
= SendMessageA( hList
, LB_GETTOPINDEX
, 0, 0);
773 ok( r
== 1, "top %d\n", r
);
775 r
= SendMessageA( hList
, LB_GETITEMRECT
, 5, (LPARAM
)&rc
);
776 ok( r
== 1, "ret %x\n", r
);
777 r
= SendMessageA( hList
, LB_GETITEMRECT
, 6, (LPARAM
)&rc
);
778 ok( r
== 0, "ret %x\n", r
);
780 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(/* x */ 10, /* y */ 10) );
781 ok( r
== 1, "ret %x\n", r
);
783 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(1000, 10) );
784 ok( r
== 0x10001, "ret %x\n", r
);
786 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(10, -10) );
787 ok( r
== 0x10001, "ret %x\n", r
);
789 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(10, 100) );
790 ok( r
== 0x10005, "item %x\n", r
);
792 r
= SendMessageA( hList
, LB_ITEMFROMPOINT
, 0, MAKELPARAM(10, 200) );
793 ok( r
== 0x10005, "item %x\n", r
);
795 DestroyWindow( hList
);
798 static void test_listbox_item_data(void)
803 hList
= CreateWindowA( WC_LISTBOXA
, "list test", 0,
804 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
805 ok( hList
!= NULL
, "failed to create listbox\n");
807 id
= SendMessageA( hList
, LB_ADDSTRING
, 0, (LPARAM
) "hi");
808 ok( id
== 0, "item id wrong\n");
810 r
= SendMessageA( hList
, LB_SETITEMDATA
, 0, MAKELPARAM( 20, 0 ));
811 ok(r
== TRUE
, "LB_SETITEMDATA returned %d instead of TRUE\n", r
);
813 r
= SendMessageA( hList
, LB_GETITEMDATA
, 0, 0);
814 ok( r
== 20, "get item data failed\n");
816 DestroyWindow( hList
);
819 static void test_listbox_LB_DIR(void)
821 char path
[MAX_PATH
], curdir
[MAX_PATH
];
824 int itemCount_justFiles
;
825 int itemCount_justDrives
;
826 int itemCount_allFiles
;
827 int itemCount_allDirs
;
829 char pathBuffer
[MAX_PATH
];
832 const char *wildcard
= "*";
836 GetCurrentDirectoryA(ARRAY_SIZE(curdir
), curdir
);
838 GetTempPathA(ARRAY_SIZE(path
), path
);
839 ret
= SetCurrentDirectoryA(path
);
840 ok(ret
, "Failed to set current directory.\n");
842 ret
= CreateDirectoryA("lb_dir_test", NULL
);
843 ok(ret
, "Failed to create test directory.\n");
845 file
= CreateFileA( "wtest1.tmp.c", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, FILE_ATTRIBUTE_NORMAL
, NULL
);
846 ok(file
!= INVALID_HANDLE_VALUE
, "Error creating the test file: %d\n", GetLastError());
849 /* NOTE: for this test to succeed, there must be no subdirectories
850 under the current directory. In addition, there must be at least
851 one file that fits the wildcard w*.c . Normally, the test
852 directory itself satisfies both conditions.
854 hList
= CreateWindowA( WC_LISTBOXA
, "list test", WS_VISIBLE
|WS_POPUP
,
855 1, 1, 600, 100, NULL
, NULL
, NULL
, NULL
);
856 ok(hList
!= NULL
, "Failed to create listbox window.\n");
858 /* Test for standard usage */
860 /* This should list all the files in the test directory. */
861 strcpy(pathBuffer
, wildcard
);
862 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
863 res
= SendMessageA(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
864 if (res
== -1) /* "*" wildcard doesn't work on win9x */
867 strcpy(pathBuffer
, wildcard
);
868 res
= SendMessageA(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
870 ok (res
>= 0, "SendMessage(LB_DIR, 0, *) failed - 0x%08x\n", GetLastError());
872 /* There should be some content in the listbox */
873 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
874 ok (itemCount
> 0, "SendMessage(LB_DIR) did NOT fill the listbox!\n");
875 itemCount_allFiles
= itemCount
;
876 ok(res
+ 1 == itemCount
,
877 "SendMessage(LB_DIR, 0, *) returned incorrect index (expected %d got %d)!\n",
880 /* This tests behavior when no files match the wildcard */
881 strcpy(pathBuffer
, BAD_EXTENSION
);
882 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
883 res
= SendMessageA(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
884 ok (res
== -1, "SendMessage(LB_DIR, 0, %s) returned %d, expected -1\n", BAD_EXTENSION
, res
);
886 /* There should be NO content in the listbox */
887 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
888 ok (itemCount
== 0, "SendMessage(LB_DIR) DID fill the listbox!\n");
891 /* This should list all the w*.c files in the test directory
892 * As of this writing, this includes win.c, winstation.c, wsprintf.c
894 strcpy(pathBuffer
, "w*.c");
895 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
896 res
= SendMessageA(hList
, LB_DIR
, 0, (LPARAM
)pathBuffer
);
897 ok (res
>= 0, "SendMessage(LB_DIR, 0, w*.c) failed - 0x%08x\n", GetLastError());
899 /* Path specification does NOT converted to uppercase */
900 ok (!strcmp(pathBuffer
, "w*.c"),
901 "expected no change to pathBuffer, got %s\n", pathBuffer
);
903 /* There should be some content in the listbox */
904 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
905 ok (itemCount
> 0, "SendMessage(LB_DIR) did NOT fill the listbox!\n");
906 itemCount_justFiles
= itemCount
;
907 ok(res
+ 1 == itemCount
,
908 "SendMessage(LB_DIR, 0, w*.c) returned incorrect index (expected %d got %d)!\n",
911 /* Every single item in the control should start with a w and end in .c */
912 for (i
= 0; i
< itemCount
; i
++)
914 memset(pathBuffer
, 0, MAX_PATH
);
915 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
916 p
= pathBuffer
+ strlen(pathBuffer
);
917 ok(((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
918 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
919 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
922 /* Test DDL_DIRECTORY */
923 strcpy(pathBuffer
, wildcard
);
924 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
925 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
, (LPARAM
)pathBuffer
);
926 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY, *) failed - 0x%08x\n", GetLastError());
928 /* There should be some content in the listbox.
929 * All files plus "[..]"
931 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
932 itemCount_allDirs
= itemCount
- itemCount_allFiles
;
933 ok (itemCount
>= itemCount_allFiles
,
934 "SendMessage(LB_DIR, DDL_DIRECTORY, *) filled with %d entries, expected > %d\n",
935 itemCount
, itemCount_allFiles
);
936 ok(res
+ 1 == itemCount
,
937 "SendMessage(LB_DIR, DDL_DIRECTORY, *) returned incorrect index (expected %d got %d)!\n",
940 /* This tests behavior when no files match the wildcard */
941 strcpy(pathBuffer
, BAD_EXTENSION
);
942 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
943 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
, (LPARAM
)pathBuffer
);
944 ok (res
== -1, "SendMessage(LB_DIR, DDL_DIRECTORY, %s) returned %d, expected -1\n", BAD_EXTENSION
, res
);
946 /* There should be NO content in the listbox */
947 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
948 ok (itemCount
== 0, "SendMessage(LB_DIR) DID fill the listbox!\n");
950 /* Test DDL_DIRECTORY */
951 strcpy(pathBuffer
, "w*.c");
952 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
953 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
, (LPARAM
)pathBuffer
);
954 ok (res
>= 0, "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) failed - 0x%08x\n", GetLastError());
956 /* There should be some content in the listbox. Since the parent directory does not
957 * fit w*.c, there should be exactly the same number of items as without DDL_DIRECTORY
959 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
960 ok (itemCount
== itemCount_justFiles
,
961 "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) filled with %d entries, expected %d\n",
962 itemCount
, itemCount_justFiles
);
963 ok(res
+ 1 == itemCount
,
964 "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) returned incorrect index (expected %d got %d)!\n",
967 /* Every single item in the control should start with a w and end in .c. */
968 for (i
= 0; i
< itemCount
; i
++)
970 memset(pathBuffer
, 0, MAX_PATH
);
971 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
972 p
= pathBuffer
+ strlen(pathBuffer
);
974 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
975 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
976 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
979 /* Test DDL_DRIVES|DDL_EXCLUSIVE */
980 strcpy(pathBuffer
, wildcard
);
981 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
982 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
983 ok (res
>= 0, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) failed - 0x%08x\n", GetLastError());
985 /* There should be some content in the listbox. In particular, there should
986 * be at least one element before, since the string "[-c-]" should
987 * have been added. Depending on the user setting, more drives might have
990 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
992 "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) filled with %d entries, expected at least %d\n",
994 itemCount_justDrives
= itemCount
;
995 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) returned incorrect index!\n");
997 /* Every single item in the control should fit the format [-c-] */
998 for (i
= 0; i
< itemCount
; i
++)
1000 memset(pathBuffer
, 0, MAX_PATH
);
1002 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1003 ok( strlen(pathBuffer
) == 5, "Length of drive string is not 5\n" );
1004 ok( sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1, "Element %d (%s) does not fit [-X-]\n", i
, pathBuffer
);
1005 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1006 if (!(driveletter
>= 'a' && driveletter
<= 'z'))
1008 /* Correct after invalid entry is found */
1009 itemCount_justDrives
--;
1013 /* This tests behavior when no files match the wildcard */
1014 strcpy(pathBuffer
, BAD_EXTENSION
);
1015 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1016 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1017 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1018 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
1020 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1021 ok (itemCount
== itemCount_justDrives
, "SendMessage(LB_DIR) returned %d expected %d\n",
1022 itemCount
, itemCount_justDrives
);
1024 /* Test DDL_DRIVES. */
1025 strcpy(pathBuffer
, wildcard
);
1026 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1027 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
, (LPARAM
)pathBuffer
);
1028 ok (res
> 0, "SendMessage(LB_DIR, DDL_DRIVES, *) failed - 0x%08x\n", GetLastError());
1030 /* There should be some content in the listbox. In particular, there should
1031 * be at least one element before, since the string "[-c-]" should
1032 * have been added. Depending on the user setting, more drives might have
1035 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1036 ok (itemCount
== itemCount_justDrives
+ itemCount_allFiles
,
1037 "SendMessage(LB_DIR, DDL_DRIVES, *) filled with %d entries, expected %d\n",
1038 itemCount
, itemCount_justDrives
+ itemCount_allFiles
);
1039 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DRIVES, *) returned incorrect index!\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_DRIVES
, (LPARAM
)pathBuffer
);
1045 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DRIVES, %s) returned %d, expected %d\n",
1046 BAD_EXTENSION
, res
, itemCount_justDrives
-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);
1051 /* Test DDL_DRIVES. */
1052 strcpy(pathBuffer
, "w*.c");
1053 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1054 res
= SendMessageA(hList
, LB_DIR
, DDL_DRIVES
, (LPARAM
)pathBuffer
);
1055 ok (res
> 0, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) failed - 0x%08x\n", GetLastError());
1057 /* There should be some content in the listbox. In particular, there should
1058 * be at least one element before, since the string "[-c-]" should
1059 * have been added. Depending on the user setting, more drives might have
1062 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1063 ok (itemCount
== itemCount_justDrives
+ itemCount_justFiles
,
1064 "SendMessage(LB_DIR, DDL_DRIVES, w*.c) filled with %d entries, expected %d\n",
1065 itemCount
, itemCount_justDrives
+ itemCount_justFiles
);
1066 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) returned incorrect index!\n");
1068 /* Every single item in the control should fit the format [-c-], or w*.c */
1069 for (i
= 0; i
< itemCount
; i
++)
1071 memset(pathBuffer
, 0, MAX_PATH
);
1073 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1074 p
= pathBuffer
+ strlen(pathBuffer
);
1075 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1)
1077 ok( strlen(pathBuffer
) == 5, "Length of drive string is not 5\n" );
1078 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1083 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1084 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1085 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1089 /* Test DDL_DIRECTORY|DDL_DRIVES. This does *not* imply DDL_EXCLUSIVE */
1090 strcpy(pathBuffer
, wildcard
);
1091 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1092 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
, (LPARAM
)pathBuffer
);
1093 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, *) failed - 0x%08x\n", GetLastError());
1095 /* There should be some content in the listbox. In particular, there should
1096 * be exactly the number of plain files, plus the number of mapped drives.
1098 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1099 ok (itemCount
== itemCount_allFiles
+ itemCount_justDrives
+ itemCount_allDirs
,
1100 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1101 itemCount
, itemCount_allFiles
+ itemCount_justDrives
+ itemCount_allDirs
);
1102 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
1104 /* Every single item in the control should start with a w and end in .c,
1105 * except for the "[..]" string, which should appear exactly as it is,
1106 * and the mapped drives in the format "[-X-]".
1108 for (i
= 0; i
< itemCount
; i
++)
1110 memset(pathBuffer
, 0, MAX_PATH
);
1112 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1113 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1)
1114 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1117 /* This tests behavior when no files match the wildcard */
1118 strcpy(pathBuffer
, BAD_EXTENSION
);
1119 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1120 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
, (LPARAM
)pathBuffer
);
1121 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, %s) returned %d, expected %d\n",
1122 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
1124 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1125 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
1127 /* Test DDL_DIRECTORY|DDL_DRIVES. */
1128 strcpy(pathBuffer
, "w*.c");
1129 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1130 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
, (LPARAM
)pathBuffer
);
1131 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) failed - 0x%08x\n", GetLastError());
1133 /* There should be some content in the listbox. In particular, there should
1134 * be exactly the number of plain files, plus the number of mapped drives.
1136 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1137 ok (itemCount
== itemCount_justFiles
+ itemCount_justDrives
,
1138 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1139 itemCount
, itemCount_justFiles
+ itemCount_justDrives
);
1140 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
1142 /* Every single item in the control should start with a w and end in .c,
1143 * except the mapped drives in the format "[-X-]". The "[..]" directory
1144 * should not appear.
1146 for (i
= 0; i
< itemCount
; i
++)
1148 memset(pathBuffer
, 0, MAX_PATH
);
1150 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1151 p
= pathBuffer
+ strlen(pathBuffer
);
1152 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1)
1153 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1156 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1157 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1158 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1161 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1162 strcpy(pathBuffer
, wildcard
);
1163 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1164 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1165 ok (res
!= -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) failed err %u\n",
1168 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1169 ok (itemCount
== itemCount_allDirs
,
1170 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1171 itemCount
, itemCount_allDirs
);
1172 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) returned incorrect index!\n");
1176 memset(pathBuffer
, 0, MAX_PATH
);
1177 SendMessageA(hList
, LB_GETTEXT
, 0, (LPARAM
)pathBuffer
);
1178 ok( !strcmp(pathBuffer
, "[..]"), "First element is %s, not [..]\n", pathBuffer
);
1181 /* This tests behavior when no files match the wildcard */
1182 strcpy(pathBuffer
, BAD_EXTENSION
);
1183 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1184 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1185 ok (res
== -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1186 BAD_EXTENSION
, res
, -1);
1188 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1189 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
1192 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1193 strcpy(pathBuffer
, "w*.c");
1194 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1195 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1196 ok (res
== LB_ERR
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, w*.c) returned %d expected %d\n", res
, LB_ERR
);
1198 /* There should be no elements, since "[..]" does not fit w*.c */
1199 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1201 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1204 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1205 strcpy(pathBuffer
, wildcard
);
1206 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1207 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1208 ok (res
> 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
1210 /* There should be no plain files on the listbox */
1211 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1212 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
1213 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1214 itemCount
, itemCount_justDrives
+ itemCount_allDirs
);
1215 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
1217 for (i
= 0; i
< itemCount
; i
++)
1219 memset(pathBuffer
, 0, MAX_PATH
);
1221 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1222 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1)
1223 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1225 ok( pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']',
1226 "Element %d (%s) does not fit expected [...]\n", i
, pathBuffer
);
1229 /* This tests behavior when no files match the wildcard */
1230 strcpy(pathBuffer
, BAD_EXTENSION
);
1231 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1232 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1233 ok (res
== itemCount_justDrives
-1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1234 BAD_EXTENSION
, res
, itemCount_justDrives
-1);
1236 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1237 ok (itemCount
== res
+ 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount
, res
+ 1);
1239 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1240 strcpy(pathBuffer
, "w*.c");
1241 SendMessageA(hList
, LB_RESETCONTENT
, 0, 0);
1242 res
= SendMessageA(hList
, LB_DIR
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
, (LPARAM
)pathBuffer
);
1243 ok (res
>= 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
1245 /* There should be no plain files on the listbox, and no [..], since it does not fit w*.c */
1246 itemCount
= SendMessageA(hList
, LB_GETCOUNT
, 0, 0);
1247 ok (itemCount
== itemCount_justDrives
,
1248 "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1249 itemCount
, itemCount_justDrives
);
1250 ok(res
+ 1 == itemCount
, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
1252 for (i
= 0; i
< itemCount
; i
++)
1254 memset(pathBuffer
, 0, MAX_PATH
);
1256 SendMessageA(hList
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1257 ok (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1, "Element %d (%s) does not fit [-X-]\n", i
, pathBuffer
);
1258 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1260 DestroyWindow(hList
);
1262 DeleteFileA( "wtest1.tmp.c" );
1263 RemoveDirectoryA("lb_dir_test");
1265 SetCurrentDirectoryA(curdir
);
1268 static HWND g_listBox
;
1269 static HWND g_label
;
1271 #define ID_TEST_LABEL 1001
1272 #define ID_TEST_LISTBOX 1002
1274 static BOOL
on_listbox_container_create(HWND hwnd
, CREATESTRUCTA
*lpcs
)
1276 g_label
= CreateWindowA(WC_STATICA
, "Contents of static control before DlgDirList.",
1277 WS_CHILD
| WS_VISIBLE
, 10, 10, 512, 32, hwnd
, (HMENU
)ID_TEST_LABEL
, NULL
, 0);
1278 if (!g_label
) return FALSE
;
1280 g_listBox
= CreateWindowA(WC_LISTBOXA
, "DlgDirList test",
1281 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| WS_BORDER
| WS_VSCROLL
, 10, 60, 256, 256,
1282 hwnd
, (HMENU
)ID_TEST_LISTBOX
, NULL
, 0);
1283 if (!g_listBox
) return FALSE
;
1288 static LRESULT CALLBACK
listbox_container_window_procA(HWND hwnd
, UINT uiMsg
, WPARAM wParam
, LPARAM lParam
)
1298 result
= on_listbox_container_create(hwnd
, (CREATESTRUCTA
*)lParam
) ? 0 : (LRESULT
)-1;
1301 result
= DefWindowProcA(hwnd
, uiMsg
, wParam
, lParam
);
1307 static BOOL
RegisterListboxWindowClass(HINSTANCE hInst
)
1314 cls
.hInstance
= hInst
;
1316 cls
.hCursor
= LoadCursorA (NULL
, (LPCSTR
)IDC_ARROW
);
1317 cls
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
1318 cls
.lpszMenuName
= NULL
;
1319 cls
.lpfnWndProc
= listbox_container_window_procA
;
1320 cls
.lpszClassName
= "ListboxContainerClass";
1321 if (!RegisterClassA (&cls
)) return FALSE
;
1326 static void test_listbox_dlgdir(void)
1331 int itemCount_allDirs
;
1332 int itemCount_justFiles
;
1333 int itemCount_justDrives
;
1335 char pathBuffer
[MAX_PATH
];
1336 char itemBuffer
[MAX_PATH
];
1337 char tempBuffer
[MAX_PATH
];
1343 file
= CreateFileA( "wtest1.tmp.c", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1344 ok(file
!= INVALID_HANDLE_VALUE
, "Error creating the test file: %d\n", GetLastError());
1345 CloseHandle( file
);
1347 /* NOTE: for this test to succeed, there must be no subdirectories
1348 under the current directory. In addition, there must be at least
1349 one file that fits the wildcard w*.c . Normally, the test
1350 directory itself satisfies both conditions.
1353 hInst
= GetModuleHandleA(0);
1354 ret
= RegisterListboxWindowClass(hInst
);
1355 ok(ret
, "Failed to register test class.\n");
1357 hWnd
= CreateWindowA("ListboxContainerClass", "ListboxContainerClass",
1358 WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
1359 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
1360 NULL
, NULL
, hInst
, 0);
1361 ok(hWnd
!= NULL
, "Failed to create container window.\n");
1363 /* Test for standard usage */
1365 /* The following should be overwritten by the directory path */
1366 SendMessageA(g_label
, WM_SETTEXT
, 0, (LPARAM
)"default contents");
1368 /* This should list all the w*.c files in the test directory
1369 * As of this writing, this includes win.c, winstation.c, wsprintf.c
1371 strcpy(pathBuffer
, "w*.c");
1372 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, 0);
1373 ok (res
== 1, "DlgDirList(*.c, 0) returned %d - expected 1 - 0x%08x\n", res
, GetLastError());
1375 /* Path specification gets converted to uppercase */
1376 ok (!strcmp(pathBuffer
, "W*.C"),
1377 "expected conversion to uppercase, got %s\n", pathBuffer
);
1379 /* Loaded path should have overwritten the label text */
1380 SendMessageA(g_label
, WM_GETTEXT
, MAX_PATH
, (LPARAM
)pathBuffer
);
1381 ok (strcmp("default contents", pathBuffer
), "DlgDirList() did not modify static control!\n");
1383 /* There should be some content in the listbox */
1384 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1385 ok (itemCount
> 0, "DlgDirList() did NOT fill the listbox!\n");
1386 itemCount_justFiles
= itemCount
;
1388 /* Every single item in the control should start with a w and end in .c */
1389 for (i
= 0; i
< itemCount
; i
++)
1391 memset(pathBuffer
, 0, MAX_PATH
);
1392 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1393 p
= pathBuffer
+ strlen(pathBuffer
);
1394 ok(((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1395 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1396 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1399 /* Test behavior when no files match the wildcard */
1400 strcpy(pathBuffer
, BAD_EXTENSION
);
1401 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, 0);
1402 ok (res
== 1, "DlgDirList(%s, 0) returned %d expected 1\n", BAD_EXTENSION
, res
);
1404 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1405 ok (itemCount
== 0, "DlgDirList() DID fill the listbox!\n");
1407 /* Test DDL_DIRECTORY */
1408 strcpy(pathBuffer
, "w*.c");
1409 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
);
1410 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY) failed - 0x%08x\n", GetLastError());
1412 /* There should be some content in the listbox. In particular, there should
1413 * be exactly more elements than before, since the directories should
1416 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1417 itemCount_allDirs
= itemCount
- itemCount_justFiles
;
1418 ok (itemCount
>= itemCount_justFiles
, "DlgDirList(DDL_DIRECTORY) filled with %d entries, expected > %d\n",
1419 itemCount
, itemCount_justFiles
);
1421 /* Every single item in the control should start with a w and end in .c,
1422 * except for the "[..]" string, which should appear exactly as it is.
1424 for (i
= 0; i
< itemCount
; i
++)
1426 memset(pathBuffer
, 0, MAX_PATH
);
1427 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1428 p
= pathBuffer
+ strlen(pathBuffer
);
1429 ok( (pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']') ||
1430 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1431 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1432 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1435 /* Test behavior when no files match the wildcard */
1436 strcpy(pathBuffer
, BAD_EXTENSION
);
1437 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
);
1438 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY) returned %d expected 1\n", BAD_EXTENSION
, res
);
1440 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1441 ok (itemCount
== itemCount_allDirs
, "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
1442 itemCount_allDirs
, itemCount
);
1443 for (i
= 0; i
< itemCount
; i
++)
1445 memset(pathBuffer
, 0, MAX_PATH
);
1446 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1447 ok( pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']',
1448 "Element %d (%s) does not fit requested [...]\n", i
, pathBuffer
);
1451 /* Test DDL_DRIVES. At least on WinXP-SP2, this implies DDL_EXCLUSIVE */
1452 strcpy(pathBuffer
, "w*.c");
1453 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DRIVES
);
1454 ok (res
== 1, "DlgDirList(*.c, DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1456 /* There should be some content in the listbox. In particular, there should
1457 * be at least one element before, since the string "[-c-]" should
1458 * have been added. Depending on the user setting, more drives might have
1461 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1463 "DlgDirList(DDL_DRIVES) filled with %d entries, expected at least %d\n",
1465 itemCount_justDrives
= itemCount
;
1467 /* Every single item in the control should fit the format [-c-] */
1468 for (i
= 0; i
< itemCount
; i
++)
1470 memset(pathBuffer
, 0, MAX_PATH
);
1472 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1473 ok( strlen(pathBuffer
) == 5, "Length of drive string is not 5\n" );
1474 ok( sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1, "Element %d (%s) does not fit [-X-]\n", i
, pathBuffer
);
1475 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1476 if (!(driveletter
>= 'a' && driveletter
<= 'z')) {
1477 /* Correct after invalid entry is found */
1478 trace("removing count of invalid entry %s\n", pathBuffer
);
1479 itemCount_justDrives
--;
1483 /* Test behavior when no files match the wildcard */
1484 strcpy(pathBuffer
, BAD_EXTENSION
);
1485 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DRIVES
);
1486 ok (res
== 1, "DlgDirList(%s, DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION
, res
);
1488 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1489 ok (itemCount
== itemCount_justDrives
, "DlgDirList() incorrectly filled the listbox!\n");
1491 /* Test DDL_DIRECTORY|DDL_DRIVES. This does *not* imply DDL_EXCLUSIVE */
1492 strcpy(pathBuffer
, "w*.c");
1493 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_DRIVES
);
1494 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1496 /* There should be some content in the listbox. In particular, there should
1497 * be exactly the number of plain files, plus the number of mapped drives,
1500 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1501 ok (itemCount
== itemCount_justFiles
+ itemCount_justDrives
+ itemCount_allDirs
,
1502 "DlgDirList(DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1503 itemCount
, itemCount_justFiles
+ itemCount_justDrives
+ itemCount_allDirs
);
1505 /* Every single item in the control should start with a w and end in .c,
1506 * except for the "[..]" string, which should appear exactly as it is,
1507 * and the mapped drives in the format "[-X-]".
1509 for (i
= 0; i
< itemCount
; i
++)
1511 memset(pathBuffer
, 0, MAX_PATH
);
1513 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1514 p
= pathBuffer
+ strlen(pathBuffer
);
1515 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1)
1516 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1518 ok( (pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']') ||
1519 ((pathBuffer
[0] == 'w' || pathBuffer
[0] == 'W') &&
1520 (*(p
-1) == 'c' || *(p
-1) == 'C') &&
1521 (*(p
-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i
, pathBuffer
);
1524 /* Test behavior when no files match the wildcard */
1525 strcpy(pathBuffer
, BAD_EXTENSION
);
1526 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_DRIVES
);
1527 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION
, res
);
1529 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1530 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
1531 "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
1532 itemCount_justDrives
+ itemCount_allDirs
, itemCount
);
1534 /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1535 strcpy(pathBuffer
, "w*.c");
1536 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_EXCLUSIVE
);
1537 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_EXCLUSIVE) failed - 0x%08x\n", GetLastError());
1539 /* There should be exactly one element: "[..]" */
1540 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1541 ok (itemCount
== itemCount_allDirs
,
1542 "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1543 itemCount
, itemCount_allDirs
);
1545 if (itemCount
&& GetCurrentDirectoryA( MAX_PATH
, pathBuffer
) > 3) /* there's no [..] in drive root */
1547 memset(pathBuffer
, 0, MAX_PATH
);
1548 SendMessageA(g_listBox
, LB_GETTEXT
, 0, (LPARAM
)pathBuffer
);
1549 ok( !strcmp(pathBuffer
, "[..]"), "First (and only) element is not [..]\n");
1552 /* Test behavior when no files match the wildcard */
1553 strcpy(pathBuffer
, BAD_EXTENSION
);
1554 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_EXCLUSIVE
);
1555 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION
, res
);
1557 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1558 ok (itemCount
== itemCount_allDirs
, "DlgDirList() incorrectly filled the listbox!\n");
1560 /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1561 strcpy(pathBuffer
, "w*.c");
1562 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
);
1563 ok (res
== 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) failed - 0x%08x\n", GetLastError());
1565 /* There should be no plain files on the listbox */
1566 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1567 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
,
1568 "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1569 itemCount
, itemCount_justDrives
+ itemCount_allDirs
);
1571 for (i
= 0; i
< itemCount
; i
++)
1573 memset(pathBuffer
, 0, MAX_PATH
);
1575 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)pathBuffer
);
1576 if (sscanf(pathBuffer
, "[-%c-]", &driveletter
) == 1)
1577 ok( driveletter
>= 'a' && driveletter
<= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter
);
1579 ok( pathBuffer
[0] == '[' && pathBuffer
[strlen(pathBuffer
)-1] == ']',
1580 "Element %d (%s) does not fit expected [...]\n", i
, pathBuffer
);
1583 /* Test behavior when no files match the wildcard */
1584 strcpy(pathBuffer
, BAD_EXTENSION
);
1585 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_DRIVES
|DDL_EXCLUSIVE
);
1586 ok (res
== 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION
, res
);
1588 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1589 ok (itemCount
== itemCount_justDrives
+ itemCount_allDirs
, "DlgDirList() incorrectly filled the listbox!\n");
1591 /* Now test DlgDirSelectEx() in normal operation */
1592 /* Fill with everything - drives, directory and all plain files. */
1593 strcpy(pathBuffer
, "*");
1594 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, ID_TEST_LABEL
, DDL_DIRECTORY
|DDL_DRIVES
);
1595 ok (res
!= 0, "DlgDirList(*, DDL_DIRECTORY|DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1597 SendMessageA(g_listBox
, LB_SETCURSEL
, -1, 0); /* Unselect any current selection */
1598 memset(pathBuffer
, 0, MAX_PATH
);
1599 SetLastError(0xdeadbeef);
1600 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1601 ok (GetLastError() == 0xdeadbeef,
1602 "DlgDirSelectEx() with no selection modified last error code from 0xdeadbeef to 0x%08x\n",
1604 ok (res
== 0, "DlgDirSelectEx() with no selection returned %d, expected 0\n", res
);
1605 /* WinXP-SP2 leaves pathBuffer untouched, but Win98 fills it with garbage. */
1607 ok (strlen(pathBuffer) == 0, "DlgDirSelectEx() with no selection filled buffer with %s\n", pathBuffer);
1609 /* Test proper drive/dir/file recognition */
1610 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1611 for (i
= 0; i
< itemCount
; i
++)
1613 memset(itemBuffer
, 0, MAX_PATH
);
1614 memset(pathBuffer
, 0, MAX_PATH
);
1615 memset(tempBuffer
, 0, MAX_PATH
);
1617 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)itemBuffer
);
1618 res
= SendMessageA(g_listBox
, LB_SETCURSEL
, i
, 0);
1619 ok (res
== i
, "SendMessageA(LB_SETCURSEL, %d) failed\n", i
);
1620 if (sscanf(itemBuffer
, "[-%c-]", &driveletter
) == 1)
1622 /* Current item is a drive letter */
1623 SetLastError(0xdeadbeef);
1624 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1625 ok (GetLastError() == 0xdeadbeef,
1626 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1628 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1630 /* For drive letters, DlgDirSelectEx tacks on a colon */
1631 ok (pathBuffer
[0] == driveletter
&& pathBuffer
[1] == ':' && pathBuffer
[2] == '\0',
1632 "%d: got \"%s\" expected \"%c:\"\n", i
, pathBuffer
, driveletter
);
1634 else if (itemBuffer
[0] == '[')
1636 /* Current item is the parent directory */
1637 SetLastError(0xdeadbeef);
1638 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1639 ok (GetLastError() == 0xdeadbeef,
1640 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1642 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1644 /* For directories, DlgDirSelectEx tacks on a backslash */
1645 p
= pathBuffer
+ strlen(pathBuffer
);
1646 ok (*(p
-1) == '\\', "DlgDirSelectEx did NOT tack on a backslash to dir, got %s\n", pathBuffer
);
1648 tempBuffer
[0] = '[';
1649 lstrcpynA(tempBuffer
+ 1, pathBuffer
, strlen(pathBuffer
));
1650 strcat(tempBuffer
, "]");
1651 ok (!strcmp(tempBuffer
, itemBuffer
), "Formatted directory should be %s, got %s\n", tempBuffer
, itemBuffer
);
1655 /* Current item is a plain file */
1656 SetLastError(0xdeadbeef);
1657 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1658 ok (GetLastError() == 0xdeadbeef,
1659 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1661 ok(res
== 0, "DlgDirSelectEx() thinks %s (%s) is a drive/directory!\n", itemBuffer
, pathBuffer
);
1663 /* NOTE: WinXP tacks a period on all files that lack an extension. This affects
1664 * for example, "Makefile", which gets reported as "Makefile."
1666 strcpy(tempBuffer
, itemBuffer
);
1667 if (strchr(tempBuffer
, '.') == NULL
) strcat(tempBuffer
, ".");
1668 ok (!strcmp(pathBuffer
, tempBuffer
), "Formatted file should be %s, got %s\n", tempBuffer
, pathBuffer
);
1672 DeleteFileA( "wtest1.tmp.c" );
1674 /* Now test DlgDirSelectEx() in abnormal operation */
1675 /* Fill list with bogus entries, that look somewhat valid */
1676 SendMessageA(g_listBox
, LB_RESETCONTENT
, 0, 0);
1677 SendMessageA(g_listBox
, LB_ADDSTRING
, 0, (LPARAM
)"[notexist.dir]");
1678 SendMessageA(g_listBox
, LB_ADDSTRING
, 0, (LPARAM
)"notexist.fil");
1679 itemCount
= SendMessageA(g_listBox
, LB_GETCOUNT
, 0, 0);
1680 for (i
= 0; i
< itemCount
; i
++)
1682 memset(itemBuffer
, 0, MAX_PATH
);
1683 memset(pathBuffer
, 0, MAX_PATH
);
1684 memset(tempBuffer
, 0, MAX_PATH
);
1686 SendMessageA(g_listBox
, LB_GETTEXT
, i
, (LPARAM
)itemBuffer
);
1687 res
= SendMessageA(g_listBox
, LB_SETCURSEL
, i
, 0);
1688 ok (res
== i
, "SendMessage(LB_SETCURSEL, %d) failed\n", i
);
1689 if (sscanf(itemBuffer
, "[-%c-]", &driveletter
) == 1)
1691 /* Current item is a drive letter */
1692 SetLastError(0xdeadbeef);
1693 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1694 ok (GetLastError() == 0xdeadbeef,
1695 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1697 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1699 /* For drive letters, DlgDirSelectEx tacks on a colon */
1700 ok (pathBuffer
[0] == driveletter
&& pathBuffer
[1] == ':' && pathBuffer
[2] == '\0',
1701 "%d: got \"%s\" expected \"%c:\"\n", i
, pathBuffer
, driveletter
);
1703 else if (itemBuffer
[0] == '[')
1705 /* Current item is the parent directory */
1706 SetLastError(0xdeadbeef);
1707 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1708 ok (GetLastError() == 0xdeadbeef,
1709 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1711 ok(res
== 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer
, pathBuffer
);
1713 /* For directories, DlgDirSelectEx tacks on a backslash */
1714 p
= pathBuffer
+ strlen(pathBuffer
);
1715 ok (*(p
-1) == '\\', "DlgDirSelectEx did NOT tack on a backslash to dir, got %s\n", pathBuffer
);
1717 tempBuffer
[0] = '[';
1718 lstrcpynA(tempBuffer
+ 1, pathBuffer
, strlen(pathBuffer
));
1719 strcat(tempBuffer
, "]");
1720 ok (!strcmp(tempBuffer
, itemBuffer
), "Formatted directory should be %s, got %s\n", tempBuffer
, itemBuffer
);
1724 /* Current item is a plain file */
1725 SetLastError(0xdeadbeef);
1726 res
= DlgDirSelectExA(hWnd
, pathBuffer
, MAX_PATH
, ID_TEST_LISTBOX
);
1727 ok (GetLastError() == 0xdeadbeef,
1728 "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1730 ok(res
== 0, "DlgDirSelectEx() thinks %s (%s) is a drive/directory!\n", itemBuffer
, pathBuffer
);
1732 /* NOTE: WinXP and Win98 tack a period on all files that lack an extension.
1733 * This affects for example, "Makefile", which gets reported as "Makefile."
1735 strcpy(tempBuffer
, itemBuffer
);
1736 if (strchr(tempBuffer
, '.') == NULL
) strcat(tempBuffer
, ".");
1737 ok (!strcmp(pathBuffer
, tempBuffer
), "Formatted file should be %s, got %s\n", tempBuffer
, pathBuffer
);
1741 /* Test behavior when loading folders from root with and without wildcard */
1742 strcpy(pathBuffer
, "C:\\");
1743 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, 0, DDL_DIRECTORY
| DDL_EXCLUSIVE
);
1744 ok(res
, "DlgDirList failed to list C:\\ folders\n");
1745 todo_wine
ok(!strcmp(pathBuffer
, "*"), "DlgDirList set the invalid path spec '%s', expected '*'\n", pathBuffer
);
1747 strcpy(pathBuffer
, "C:\\*");
1748 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, 0, DDL_DIRECTORY
| DDL_EXCLUSIVE
);
1749 ok(res
, "DlgDirList failed to list C:\\* folders\n");
1750 ok(!strcmp(pathBuffer
, "*"), "DlgDirList set the invalid path spec '%s', expected '*'\n", pathBuffer
);
1752 /* Try loading files from an invalid folder */
1753 SetLastError(0xdeadbeef);
1754 strcpy(pathBuffer
, "C:\\INVALID$$DIR");
1755 res
= DlgDirListA(hWnd
, pathBuffer
, ID_TEST_LISTBOX
, 0, DDL_DIRECTORY
| DDL_EXCLUSIVE
);
1756 todo_wine
ok(!res
, "DlgDirList should have failed with 0 but %d was returned\n", res
);
1757 todo_wine
ok(GetLastError() == ERROR_NO_WILDCARD_CHARACTERS
,
1758 "GetLastError should return 0x589, got 0x%X\n",GetLastError());
1760 DestroyWindow(hWnd
);
1763 static void test_set_count( void )
1765 static const DWORD styles
[] =
1770 HWND parent
, listbox
;
1775 parent
= create_parent();
1776 listbox
= create_listbox( LBS_OWNERDRAWFIXED
| LBS_NODATA
| WS_CHILD
| WS_VISIBLE
, parent
);
1778 UpdateWindow( listbox
);
1779 GetUpdateRect( listbox
, &r
, TRUE
);
1780 ok( IsRectEmpty( &r
), "got non-empty rect\n");
1782 ret
= SendMessageA( listbox
, LB_SETCOUNT
, 100, 0 );
1783 ok( ret
== 0, "got %d\n", ret
);
1784 ret
= SendMessageA( listbox
, LB_GETCOUNT
, 0, 0 );
1785 ok( ret
== 100, "got %d\n", ret
);
1787 GetUpdateRect( listbox
, &r
, TRUE
);
1788 ok( !IsRectEmpty( &r
), "got empty rect\n");
1790 ValidateRect( listbox
, NULL
);
1791 GetUpdateRect( listbox
, &r
, TRUE
);
1792 ok( IsRectEmpty( &r
), "got non-empty rect\n");
1794 ret
= SendMessageA( listbox
, LB_SETCOUNT
, 99, 0 );
1795 ok( ret
== 0, "got %d\n", ret
);
1797 GetUpdateRect( listbox
, &r
, TRUE
);
1798 ok( !IsRectEmpty( &r
), "got empty rect\n");
1800 DestroyWindow( listbox
);
1802 for (i
= 0; i
< ARRAY_SIZE(styles
); ++i
)
1804 listbox
= create_listbox( styles
[i
] | WS_CHILD
| WS_VISIBLE
, parent
);
1806 SetLastError( 0xdeadbeef );
1807 ret
= SendMessageA( listbox
, LB_SETCOUNT
, 100, 0 );
1808 todo_wine_if(i
== 0)
1809 ok( ret
== LB_ERR
, "expected %d, got %d\n", LB_ERR
, ret
);
1810 todo_wine_if(i
== 1)
1811 ok( GetLastError() == 0xdeadbeef, "Unexpected error %d.\n", GetLastError() );
1813 DestroyWindow( listbox
);
1816 DestroyWindow( parent
);
1819 static int lb_getlistboxinfo
;
1821 static LRESULT WINAPI
listbox_subclass_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1823 WNDPROC oldproc
= (WNDPROC
)GetWindowLongPtrA(hwnd
, GWLP_USERDATA
);
1825 if (message
== LB_GETLISTBOXINFO
)
1826 lb_getlistboxinfo
++;
1828 return CallWindowProcA(oldproc
, hwnd
, message
, wParam
, lParam
);
1831 static void test_GetListBoxInfo(void)
1833 HWND listbox
, parent
;
1837 parent
= create_parent();
1838 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
, parent
);
1840 oldproc
= (WNDPROC
)SetWindowLongPtrA(listbox
, GWLP_WNDPROC
, (LONG_PTR
)listbox_subclass_proc
);
1841 SetWindowLongPtrA(listbox
, GWLP_USERDATA
, (LONG_PTR
)oldproc
);
1843 lb_getlistboxinfo
= 0;
1844 ret
= GetListBoxInfo(listbox
);
1845 ok(ret
> 0, "got %d\n", ret
);
1846 ok(lb_getlistboxinfo
== 1, "got %d\n", lb_getlistboxinfo
);
1848 DestroyWindow(listbox
);
1849 DestroyWindow(parent
);
1852 static void test_missing_lbuttonup(void)
1854 HWND listbox
, parent
, capture
;
1856 parent
= create_parent();
1857 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
, parent
);
1859 /* Send button down without a corresponding button up */
1860 SendMessageA(listbox
, WM_LBUTTONDOWN
, 0, MAKELPARAM(10, 10));
1861 capture
= GetCapture();
1862 ok(capture
== listbox
, "got %p expected %p\n", capture
, listbox
);
1864 /* Capture is released and LBN_SELCHANGE sent during WM_KILLFOCUS */
1867 capture
= GetCapture();
1868 ok(capture
== NULL
, "got %p\n", capture
);
1869 ok(got_selchange
, "got %d\n", got_selchange
);
1871 DestroyWindow(listbox
);
1872 DestroyWindow(parent
);
1875 static void test_extents(void)
1877 HWND listbox
, parent
;
1882 parent
= create_parent();
1884 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
, parent
);
1886 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1887 ok(res
== 0, "Got wrong initial horizontal extent: %u\n", res
);
1889 sinfo
.cbSize
= sizeof(sinfo
);
1890 sinfo
.fMask
= SIF_RANGE
;
1891 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1892 ok(br
== TRUE
, "GetScrollInfo failed\n");
1893 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1894 ok(sinfo
.nMax
== 100, "got wrong max: %u\n", sinfo
.nMax
);
1895 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1896 "List box should not have a horizontal scroll bar\n");
1898 /* horizontal extent < width */
1899 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 64, 0);
1901 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1902 ok(res
== 64, "Got wrong horizontal extent: %u\n", res
);
1904 sinfo
.cbSize
= sizeof(sinfo
);
1905 sinfo
.fMask
= SIF_RANGE
;
1906 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1907 ok(br
== TRUE
, "GetScrollInfo failed\n");
1908 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1909 ok(sinfo
.nMax
== 100, "got wrong max: %u\n", sinfo
.nMax
);
1910 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1911 "List box should not have a horizontal scroll bar\n");
1913 /* horizontal extent > width */
1914 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 184, 0);
1916 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1917 ok(res
== 184, "Got wrong horizontal extent: %u\n", res
);
1919 sinfo
.cbSize
= sizeof(sinfo
);
1920 sinfo
.fMask
= SIF_RANGE
;
1921 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1922 ok(br
== TRUE
, "GetScrollInfo failed\n");
1923 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1924 ok(sinfo
.nMax
== 100, "got wrong max: %u\n", sinfo
.nMax
);
1925 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1926 "List box should not have a horizontal scroll bar\n");
1928 DestroyWindow(listbox
);
1930 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
| WS_HSCROLL
, parent
);
1932 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1933 ok(res
== 0, "Got wrong initial horizontal extent: %u\n", res
);
1935 sinfo
.cbSize
= sizeof(sinfo
);
1936 sinfo
.fMask
= SIF_RANGE
;
1937 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1938 ok(br
== TRUE
, "GetScrollInfo failed\n");
1939 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1940 ok(sinfo
.nMax
== 100, "got wrong max: %u\n", sinfo
.nMax
);
1941 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1942 "List box should not have a horizontal scroll bar\n");
1944 /* horizontal extent < width */
1945 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 64, 0);
1947 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1948 ok(res
== 64, "Got wrong horizontal extent: %u\n", res
);
1950 sinfo
.cbSize
= sizeof(sinfo
);
1951 sinfo
.fMask
= SIF_RANGE
;
1952 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1953 ok(br
== TRUE
, "GetScrollInfo failed\n");
1954 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1955 ok(sinfo
.nMax
== 63, "got wrong max: %u\n", sinfo
.nMax
);
1956 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1957 "List box should not have a horizontal scroll bar\n");
1959 /* horizontal extent > width */
1960 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 184, 0);
1962 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1963 ok(res
== 184, "Got wrong horizontal extent: %u\n", res
);
1965 sinfo
.cbSize
= sizeof(sinfo
);
1966 sinfo
.fMask
= SIF_RANGE
;
1967 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1968 ok(br
== TRUE
, "GetScrollInfo failed\n");
1969 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1970 ok(sinfo
.nMax
== 183, "got wrong max: %u\n", sinfo
.nMax
);
1971 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
1972 "List box should have a horizontal scroll bar\n");
1974 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 0, 0);
1976 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1977 ok(res
== 0, "Got wrong horizontal extent: %u\n", res
);
1979 sinfo
.cbSize
= sizeof(sinfo
);
1980 sinfo
.fMask
= SIF_RANGE
;
1981 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1982 ok(br
== TRUE
, "GetScrollInfo failed\n");
1983 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
1984 ok(sinfo
.nMax
== 0, "got wrong max: %u\n", sinfo
.nMax
);
1985 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) == 0,
1986 "List box should not have a horizontal scroll bar\n");
1988 DestroyWindow(listbox
);
1991 listbox
= create_listbox(WS_CHILD
| WS_VISIBLE
| WS_HSCROLL
| LBS_DISABLENOSCROLL
, parent
);
1993 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
1994 ok(res
== 0, "Got wrong initial horizontal extent: %u\n", res
);
1996 sinfo
.cbSize
= sizeof(sinfo
);
1997 sinfo
.fMask
= SIF_RANGE
;
1998 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
1999 ok(br
== TRUE
, "GetScrollInfo failed\n");
2000 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
2001 ok(sinfo
.nMax
== 0, "got wrong max: %u\n", sinfo
.nMax
);
2002 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
2003 "List box should have a horizontal scroll bar\n");
2005 /* horizontal extent < width */
2006 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 64, 0);
2008 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
2009 ok(res
== 64, "Got wrong horizontal extent: %u\n", res
);
2011 sinfo
.cbSize
= sizeof(sinfo
);
2012 sinfo
.fMask
= SIF_RANGE
;
2013 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
2014 ok(br
== TRUE
, "GetScrollInfo failed\n");
2015 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
2016 ok(sinfo
.nMax
== 63, "got wrong max: %u\n", sinfo
.nMax
);
2017 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
2018 "List box should have a horizontal scroll bar\n");
2020 /* horizontal extent > width */
2021 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 184, 0);
2023 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
2024 ok(res
== 184, "Got wrong horizontal extent: %u\n", res
);
2026 sinfo
.cbSize
= sizeof(sinfo
);
2027 sinfo
.fMask
= SIF_RANGE
;
2028 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
2029 ok(br
== TRUE
, "GetScrollInfo failed\n");
2030 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
2031 ok(sinfo
.nMax
== 183, "got wrong max: %u\n", sinfo
.nMax
);
2032 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
2033 "List box should have a horizontal scroll bar\n");
2035 SendMessageA(listbox
, LB_SETHORIZONTALEXTENT
, 0, 0);
2037 res
= SendMessageA(listbox
, LB_GETHORIZONTALEXTENT
, 0, 0);
2038 ok(res
== 0, "Got wrong horizontal extent: %u\n", res
);
2040 sinfo
.cbSize
= sizeof(sinfo
);
2041 sinfo
.fMask
= SIF_RANGE
;
2042 br
= GetScrollInfo(listbox
, SB_HORZ
, &sinfo
);
2043 ok(br
== TRUE
, "GetScrollInfo failed\n");
2044 ok(sinfo
.nMin
== 0, "got wrong min: %u\n", sinfo
.nMin
);
2045 ok(sinfo
.nMax
== 0, "got wrong max: %u\n", sinfo
.nMax
);
2046 ok((GetWindowLongA(listbox
, GWL_STYLE
) & WS_HSCROLL
) != 0,
2047 "List box should have a horizontal scroll bar\n");
2049 DestroyWindow(listbox
);
2051 DestroyWindow(parent
);
2054 static void test_listbox(void)
2056 static const struct listbox_test SS
=
2058 {{LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
2059 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
2060 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
2061 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
2063 /* {selected, anchor, caret, selcount}{TODO fields} */
2064 static const struct listbox_test SS_NS
=
2065 {{LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
2066 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
2067 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
2068 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
2070 static const struct listbox_test MS
=
2071 {{ 0, LB_ERR
, 0, 0}, {0,0,0,0},
2072 { 1, 1, 1, 1}, {0,0,0,0},
2073 { 2, 1, 2, 1}, {0,0,0,0},
2074 { 0, LB_ERR
, 0, 2}, {0,0,0,0}};
2076 static const struct listbox_test MS_NS
=
2077 {{LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
2078 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
2079 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
2080 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
2082 static const struct listbox_test ES
=
2083 {{ 0, LB_ERR
, 0, 0}, {0,0,0,0},
2084 { 1, 1, 1, 1}, {0,0,0,0},
2085 { 2, 2, 2, 1}, {0,0,0,0},
2086 { 0, LB_ERR
, 0, 2}, {0,0,0,0}};
2088 static const struct listbox_test ES_NS
=
2089 {{LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
2090 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
2091 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
2092 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
2094 static const struct listbox_test EMS
=
2095 {{ 0, LB_ERR
, 0, 0}, {0,0,0,0},
2096 { 1, 1, 1, 1}, {0,0,0,0},
2097 { 2, 2, 2, 1}, {0,0,0,0},
2098 { 0, LB_ERR
, 0, 2}, {0,0,0,0}};
2100 static const struct listbox_test EMS_NS
=
2101 {{LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0},
2102 { 1, 1, 1, LB_ERR
}, {0,0,0,0},
2103 { 2, 2, 2, LB_ERR
}, {0,0,0,0},
2104 {LB_ERR
, LB_ERR
, 0, LB_ERR
}, {0,0,0,0}};
2107 run_test(LBS_NOSEL
, SS_NS
);
2108 run_test(LBS_MULTIPLESEL
, MS
);
2109 run_test(LBS_MULTIPLESEL
| LBS_NOSEL
, MS_NS
);
2110 run_test(LBS_EXTENDEDSEL
, ES
);
2111 run_test(LBS_EXTENDEDSEL
| LBS_NOSEL
, ES_NS
);
2112 run_test(LBS_EXTENDEDSEL
| LBS_MULTIPLESEL
, EMS
);
2113 run_test(LBS_EXTENDEDSEL
| LBS_MULTIPLESEL
| LBS_NOSEL
, EMS_NS
);
2115 run_test(LBS_NODATA
| LBS_OWNERDRAWFIXED
, SS
);
2116 run_test(LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_NOSEL
, SS_NS
);
2117 run_test(LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_MULTIPLESEL
, MS
);
2118 run_test(LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_MULTIPLESEL
| LBS_NOSEL
, MS_NS
);
2119 run_test(LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_EXTENDEDSEL
, ES
);
2120 run_test(LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_EXTENDEDSEL
| LBS_NOSEL
, ES_NS
);
2121 run_test(LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_EXTENDEDSEL
| LBS_MULTIPLESEL
, EMS
);
2122 run_test(LBS_NODATA
| LBS_OWNERDRAWFIXED
| LBS_EXTENDEDSEL
| LBS_MULTIPLESEL
| LBS_NOSEL
, EMS_NS
);
2125 static const struct message lb_addstring_ownerdraw_parent_seq
[] =
2127 { WM_MEASUREITEM
, sent
|wparam
|lparam
, 0x1012, 0xf30604ed },
2128 { WM_MEASUREITEM
, sent
|wparam
|lparam
, 0x1112, 0xf30604ee },
2129 { WM_MEASUREITEM
, sent
|wparam
|lparam
, 0x1212, 0xf30604ef },
2133 static const struct message lb_addstring_sort_parent_seq
[] =
2135 { WM_MEASUREITEM
, sent
|wparam
|lparam
, 0x1012, 0xf30604ed },
2136 { WM_COMPAREITEM
, sent
|wparam
|lparam
, 0xf30604ed, 0xf30604ee },
2137 { WM_MEASUREITEM
, sent
|wparam
|lparam
, 0x1112, 0xf30604ee },
2138 { WM_COMPAREITEM
, sent
|wparam
|lparam
, 0xf30604ed, 0xf30604ef },
2139 { WM_COMPAREITEM
, sent
|wparam
|lparam
, 0xf30604ee, 0xf30604ef },
2140 { WM_MEASUREITEM
, sent
|wparam
|lparam
, 0x1212, 0xf30604ef },
2144 static const struct message empty_seq
[] =
2149 static void test_WM_MEASUREITEM(void)
2151 HWND parent
, listbox
;
2154 parent
= create_parent();
2155 listbox
= create_listbox(WS_CHILD
| LBS_OWNERDRAWVARIABLE
, parent
);
2157 data
= SendMessageA(listbox
, LB_GETITEMDATA
, 0, 0);
2158 ok(data
== (LRESULT
)strings
[0], "data = %08lx, expected %p\n", data
, strings
[0]);
2159 DestroyWindow(parent
);
2161 parent
= create_parent();
2162 listbox
= create_listbox(WS_CHILD
| LBS_OWNERDRAWVARIABLE
| LBS_HASSTRINGS
, parent
);
2164 data
= SendMessageA(listbox
, LB_GETITEMDATA
, 0, 0);
2165 ok(!data
, "data = %08lx\n", data
);
2167 /* LBS_HASSTRINGS */
2168 parent
= create_parent();
2169 listbox
= CreateWindowExA(WS_EX_NOPARENTNOTIFY
, WC_LISTBOXA
, NULL
,
2170 WS_CHILD
| LBS_NOTIFY
| LBS_OWNERDRAWVARIABLE
| LBS_HASSTRINGS
| WS_VISIBLE
,
2171 10, 10, 80, 80, parent
, (HMENU
)ID_LISTBOX
, 0, NULL
);
2173 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
2175 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 0");
2176 ok(ret
== 0, "expected 0, got %ld\n", ret
);
2177 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 1");
2178 ok(ret
== 1, "expected 1, got %ld\n", ret
);
2179 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 2");
2180 ok(ret
== 2, "expected 2, got %ld\n", ret
);
2182 ok_sequence(sequences
, PARENT_SEQ_INDEX
, lb_addstring_ownerdraw_parent_seq
,
2183 "LB_ADDSTRING (LBS_HASSTRINGS, ownerdraw)", FALSE
);
2184 DestroyWindow(listbox
);
2186 /* LBS_SORT, no LBS_HASSTRINGS */
2187 listbox
= CreateWindowExA(WS_EX_NOPARENTNOTIFY
, WC_LISTBOXA
, NULL
,
2188 WS_CHILD
| LBS_NOTIFY
| LBS_OWNERDRAWVARIABLE
| LBS_SORT
| WS_VISIBLE
,
2189 10, 10, 80, 80, parent
, (HMENU
)ID_LISTBOX
, 0, NULL
);
2191 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
2193 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 0");
2194 ok(ret
== 0, "expected 0, got %ld\n", ret
);
2195 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 1");
2196 ok(ret
== 1, "expected 1, got %ld\n", ret
);
2197 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 2");
2198 ok(ret
== 2, "expected 2, got %ld\n", ret
);
2200 ok_sequence(sequences
, PARENT_SEQ_INDEX
, lb_addstring_sort_parent_seq
, "LB_ADDSTRING (LBS_SORT)", FALSE
);
2201 DestroyWindow(listbox
);
2203 /* LBS_HASSTRINGS */
2204 listbox
= CreateWindowExA(WS_EX_NOPARENTNOTIFY
, WC_LISTBOXA
, NULL
,
2205 WS_CHILD
| LBS_NOTIFY
| LBS_HASSTRINGS
| WS_VISIBLE
,
2206 10, 10, 80, 80, parent
, (HMENU
)ID_LISTBOX
, 0, NULL
);
2208 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
2210 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 2");
2211 ok(ret
== 0, "expected 0, got %ld\n", ret
);
2212 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 0");
2213 ok(ret
== 1, "expected 1, got %ld\n", ret
);
2214 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 1");
2215 ok(ret
== 2, "expected 2, got %ld\n", ret
);
2217 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_seq
, "LB_ADDSTRING (LBS_HASSTRINGS)", FALSE
);
2218 DestroyWindow(listbox
);
2220 /* LBS_HASSTRINGS, LBS_SORT */
2221 listbox
= CreateWindowExA(WS_EX_NOPARENTNOTIFY
, WC_LISTBOXA
, NULL
,
2222 WS_CHILD
| LBS_NOTIFY
| LBS_HASSTRINGS
| LBS_SORT
| WS_VISIBLE
,
2223 10, 10, 80, 80, parent
, (HMENU
)ID_LISTBOX
, 0, NULL
);
2225 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
2227 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 2");
2228 ok(ret
== 0, "expected 0, got %ld\n", ret
);
2229 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 0");
2230 ok(ret
== 0, "expected 0, got %ld\n", ret
);
2231 ret
= SendMessageA(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 1");
2232 ok(ret
== 1, "expected 1, got %ld\n", ret
);
2234 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_seq
, "LB_ADDSTRING (LBS_HASSTRINGS, LBS_SORT)", FALSE
);
2235 DestroyWindow(listbox
);
2237 DestroyWindow(parent
);
2240 static void test_LBS_NODATA(void)
2242 static const UINT invalid_idx
[] = { -2, 2 };
2243 static const UINT valid_idx
[] = { 0, 1 };
2244 static const ULONG_PTR zero_data
;
2251 listbox
= CreateWindowA(WC_LISTBOXA
, "TestList", LBS_NODATA
| LBS_OWNERDRAWFIXED
| WS_VISIBLE
,
2252 0, 0, 100, 100, NULL
, NULL
, NULL
, 0);
2253 ok(listbox
!= NULL
, "Failed to create ListBox window.\n");
2255 ret
= SendMessageA(listbox
, LB_INSERTSTRING
, -1, 0);
2256 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
2257 ret
= SendMessageA(listbox
, LB_INSERTSTRING
, -1, 0);
2258 ok(ret
== 1, "Unexpected return value %d.\n", ret
);
2259 ret
= SendMessageA(listbox
, LB_GETCOUNT
, 0, 0);
2260 ok(ret
== 2, "Unexpected return value %d.\n", ret
);
2262 /* Invalid indices. */
2263 for (i
= 0; i
< ARRAY_SIZE(invalid_idx
); ++i
)
2265 ret
= SendMessageA(listbox
, LB_SETITEMDATA
, invalid_idx
[i
], 42);
2266 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2267 ret
= SendMessageA(listbox
, LB_GETTEXTLEN
, invalid_idx
[i
], 0);
2268 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2271 ret
= SendMessageA(listbox
, LB_GETTEXT
, invalid_idx
[i
], (LPARAM
)&data
);
2272 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2274 ret
= SendMessageA(listbox
, LB_GETITEMDATA
, invalid_idx
[i
], 0);
2275 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2278 IsWow64Process(GetCurrentProcess(), &is_wow64
);
2282 text_len
= is_wow64
? 8 : 4;
2285 /* Valid indices. */
2286 for (i
= 0; i
< ARRAY_SIZE(valid_idx
); ++i
)
2288 ret
= SendMessageA(listbox
, LB_SETITEMDATA
, valid_idx
[i
], 42);
2289 ok(ret
== TRUE
, "Unexpected return value %d.\n", ret
);
2290 ret
= SendMessageA(listbox
, LB_GETTEXTLEN
, valid_idx
[i
], 0);
2291 todo_wine_if(text_len
== 8)
2292 ok(ret
== text_len
, "Unexpected return value %d.\n", ret
);
2294 memset(&data
, 0xee, sizeof(data
));
2295 ret
= SendMessageA(listbox
, LB_GETTEXT
, valid_idx
[i
], (LPARAM
)&data
);
2296 todo_wine_if(sizeof(void *) == 8)
2297 ok(ret
== sizeof(data
), "Unexpected return value %d.\n", ret
);
2299 ok(!memcmp(&data
, &zero_data
, sizeof(data
)), "Unexpected item data.\n");
2301 ret
= SendMessageA(listbox
, LB_GETITEMDATA
, valid_idx
[i
], 0);
2303 ok(ret
== 0, "Unexpected return value %d.\n", ret
);
2306 /* More messages that don't work with LBS_NODATA. */
2307 ret
= SendMessageA(listbox
, LB_FINDSTRING
, 1, 42);
2309 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2310 ret
= SendMessageA(listbox
, LB_FINDSTRINGEXACT
, 1, 42);
2312 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2313 ret
= SendMessageA(listbox
, LB_SELECTSTRING
, 1, 42);
2315 ok(ret
== LB_ERR
, "Unexpected return value %d.\n", ret
);
2317 DestroyWindow(listbox
);
2322 ULONG_PTR ctx_cookie
;
2325 if (!load_v6_module(&ctx_cookie
, &hCtx
))
2328 init_msg_sequences(sequences
, NUM_MSG_SEQUENCES
);
2333 test_LB_SELITEMRANGE();
2334 test_LB_SETCURSEL();
2335 test_listbox_height();
2336 test_itemfrompoint();
2337 test_listbox_item_data();
2338 test_listbox_LB_DIR();
2339 test_listbox_dlgdir();
2341 test_GetListBoxInfo();
2342 test_missing_lbuttonup();
2344 test_WM_MEASUREITEM();
2348 unload_v6_module(ctx_cookie
, hCtx
);