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