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