ReactOS  0.4.14-dev-606-g14ebc0b
listbox.c
Go to the documentation of this file.
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 <assert.h>
21 #include <stdarg.h>
22 #include <stdio.h>
23 
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wingdi.h"
27 #include "winuser.h"
28 #include "winnls.h"
29 
30 #include "wine/test.h"
31 
32 #ifdef VISIBLE
33 #define WAIT Sleep (1000)
34 #define REDRAW RedrawWindow (handle, NULL, 0, RDW_UPDATENOW)
35 #else
36 #define WAIT
37 #define REDRAW
38 #endif
39 
40 static const char * const strings[4] = {
41  "First added",
42  "Second added",
43  "Third added",
44  "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."
45 };
46 
47 static const char BAD_EXTENSION[] = "*.badtxt";
48 
49 static int strcmp_aw(LPCWSTR strw, const char *stra)
50 {
51  WCHAR buf[1024];
52 
53  if (!stra) return 1;
54  MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, ARRAY_SIZE(buf));
55  return lstrcmpW(strw, buf);
56 }
57 
58 static HWND
60 {
61  HWND handle;
62  INT_PTR ctl_id=0;
63  if (parent)
64  ctl_id=1;
65  handle=CreateWindowA("LISTBOX", "TestList",
66  (LBS_STANDARD & ~LBS_SORT) | add_style,
67  0, 0, 100, 100,
68  parent, (HMENU)ctl_id, NULL, 0);
69 
70  assert (handle);
75 
76 #ifdef VISIBLE
78 #endif
79  REDRAW;
80 
81  return handle;
82 }
83 
84 struct listbox_prop {
86 };
87 
88 struct listbox_stat {
90 };
91 
92 struct listbox_test {
93  struct listbox_stat init, init_todo;
94  struct listbox_stat click, click_todo;
95  struct listbox_stat step, step_todo;
96  struct listbox_stat sel, sel_todo;
97 };
98 
99 static void
101 {
102  results->selected = SendMessageA(handle, LB_GETCURSEL, 0, 0);
103  results->anchor = SendMessageA(handle, LB_GETANCHORINDEX, 0, 0);
104  results->caret = SendMessageA(handle, LB_GETCARETINDEX, 0, 0);
105  results->selcount = SendMessageA(handle, LB_GETSELCOUNT, 0, 0);
106 }
107 
108 static void
110 {
111  LPARAM lp=x+(y<<16);
112 
113  WAIT;
116  REDRAW;
117 }
118 
119 static void
120 keypress (HWND handle, WPARAM keycode, BYTE scancode, BOOL extended)
121 {
122  LPARAM lp=1+(scancode<<16)+(extended?KEYEVENTF_EXTENDEDKEY:0);
123 
124  WAIT;
125  SendMessageA(handle, WM_KEYDOWN, keycode, lp);
126  SendMessageA(handle, WM_KEYUP , keycode, lp | 0xc000000);
127  REDRAW;
128 }
129 
130 #define listbox_field_ok(t, s, f, got) \
131  ok (t.s.f==got.f, "style %#x, step " #s ", field " #f \
132  ": expected %d, got %d\n", style, t.s.f, got.f)
133 
134 #define listbox_todo_field_ok(t, s, f, got) \
135  todo_wine_if (t.s##_todo.f) { listbox_field_ok(t, s, f, got); }
136 
137 #define listbox_ok(t, s, got) \
138  listbox_todo_field_ok(t, s, selected, got); \
139  listbox_todo_field_ok(t, s, anchor, got); \
140  listbox_todo_field_ok(t, s, caret, got); \
141  listbox_todo_field_ok(t, s, selcount, got)
142 
143 static void
145 {
146  struct listbox_stat answer;
147  RECT second_item;
148  int i;
149  int res;
150  HWND hLB;
151 
152  hLB = create_listbox (style, 0);
153 
154  listbox_query (hLB, &answer);
155  listbox_ok (test, init, answer);
156 
157  SendMessageA(hLB, LB_GETITEMRECT, 1, (LPARAM) &second_item);
158  buttonpress(hLB, (WORD)second_item.left, (WORD)second_item.top);
159 
160  listbox_query (hLB, &answer);
161  listbox_ok (test, click, answer);
162 
163  keypress (hLB, VK_DOWN, 0x50, TRUE);
164 
165  listbox_query (hLB, &answer);
166  listbox_ok (test, step, answer);
167 
168  DestroyWindow (hLB);
169  hLB = create_listbox(style, 0);
170 
172  listbox_query (hLB, &answer);
173  listbox_ok (test, sel, answer);
174 
175  for (i = 0; i < 4 && !(style & LBS_NODATA); i++) {
176  DWORD size = SendMessageA(hLB, LB_GETTEXTLEN, i, 0);
177  CHAR *txt;
178  WCHAR *txtw;
179  int resA, resW;
180 
182  resA=SendMessageA(hLB, LB_GETTEXT, i, (LPARAM)txt);
183  ok(!strcmp (txt, strings[i]), "returned string for item %d does not match %s vs %s\n", i, txt, strings[i]);
184 
186  resW=SendMessageW(hLB, LB_GETTEXT, i, (LPARAM)txtw);
187  ok(resA == resW, "Unexpected text length.\n");
188  WideCharToMultiByte( CP_ACP, 0, txtw, -1, txt, size, NULL, NULL );
189  ok(!strcmp (txt, strings[i]), "returned string for item %d does not match %s vs %s\n", i, txt, strings[i]);
190 
191  HeapFree (GetProcessHeap(), 0, txtw);
192  HeapFree (GetProcessHeap(), 0, txt);
193  }
194 
195  /* Confirm the count of items, and that an invalid delete does not remove anything */
196  res = SendMessageA(hLB, LB_GETCOUNT, 0, 0);
197  ok((res==4), "Expected 4 items, got %d\n", res);
198  res = SendMessageA(hLB, LB_DELETESTRING, -1, 0);
199  ok((res==LB_ERR), "Expected LB_ERR items, got %d\n", res);
200  res = SendMessageA(hLB, LB_DELETESTRING, 4, 0);
201  ok((res==LB_ERR), "Expected LB_ERR items, got %d\n", res);
202  res = SendMessageA(hLB, LB_GETCOUNT, 0, 0);
203  ok((res==4), "Expected 4 items, got %d\n", res);
204 
205  WAIT;
206  DestroyWindow (hLB);
207 }
208 
209 static void check_item_height(void)
210 {
211  HWND hLB;
212  HDC hdc;
213  HFONT font;
214  TEXTMETRICA tm;
215  INT itemHeight;
216 
217  hLB = create_listbox (0, 0);
218  ok ((hdc = GetDCEx( hLB, 0, DCX_CACHE )) != 0, "Can't get hdc\n");
219  ok ((font = GetCurrentObject(hdc, OBJ_FONT)) != 0, "Can't get the current font\n");
220  ok (GetTextMetricsA( hdc, &tm ), "Can't read font metrics\n");
221  ReleaseDC( hLB, hdc);
222 
223  ok (SendMessageA(hLB, WM_SETFONT, (WPARAM)font, 0) == 0, "Can't set font\n");
224 
225  itemHeight = SendMessageA(hLB, LB_GETITEMHEIGHT, 0, 0);
226  ok (itemHeight == tm.tmHeight, "Item height wrong, got %d, expecting %d\n", itemHeight, tm.tmHeight);
227 
228  DestroyWindow (hLB);
229 
230  hLB = CreateWindowA("LISTBOX", "TestList", LBS_OWNERDRAWVARIABLE,
231  0, 0, 100, 100, NULL, NULL, NULL, 0);
232  itemHeight = SendMessageA(hLB, LB_GETITEMHEIGHT, 0, 0);
233  ok(itemHeight == tm.tmHeight, "itemHeight %d\n", itemHeight);
234  itemHeight = SendMessageA(hLB, LB_GETITEMHEIGHT, 5, 0);
235  ok(itemHeight == tm.tmHeight, "itemHeight %d\n", itemHeight);
236  itemHeight = SendMessageA(hLB, LB_GETITEMHEIGHT, -5, 0);
237  ok(itemHeight == tm.tmHeight, "itemHeight %d\n", itemHeight);
238  DestroyWindow (hLB);
239 }
240 
241 static int got_selchange;
242 
244 {
245  switch (msg)
246  {
247  case WM_MEASUREITEM:
248  {
250  MEASUREITEMSTRUCT *mi = (void*)lparam;
251 
252  ok(wparam == mi->CtlID, "got wParam=%08lx, expected %08x\n", wparam, mi->CtlID);
253  ok(mi->CtlType == ODT_LISTBOX, "mi->CtlType = %u\n", mi->CtlType);
254  ok(mi->CtlID == 1, "mi->CtlID = %u\n", mi->CtlID);
255  ok(mi->itemHeight, "mi->itemHeight = 0\n");
256 
257  if (mi->itemID > 4 || style & LBS_OWNERDRAWFIXED)
258  break;
259 
260  if (style & LBS_HASSTRINGS)
261  {
262  ok(!strcmp_aw((WCHAR*)mi->itemData, strings[mi->itemID]),
263  "mi->itemData = %s (%d)\n", wine_dbgstr_w((WCHAR*)mi->itemData), mi->itemID);
264  }
265  else
266  {
267  ok((void*)mi->itemData == strings[mi->itemID],
268  "mi->itemData = %08lx, expected %p\n", mi->itemData, strings[mi->itemID]);
269  }
270  break;
271  }
272  case WM_DRAWITEM:
273  {
274  RECT rc_item, rc_client, rc_clip;
276 
277  trace("%p WM_DRAWITEM %08lx %08lx\n", hwnd, wparam, lparam);
278 
279  ok(wparam == dis->CtlID, "got wParam=%08lx instead of %08x\n",
280  wparam, dis->CtlID);
281  ok(dis->CtlType == ODT_LISTBOX, "wrong CtlType %04x\n", dis->CtlType);
282 
283  GetClientRect(dis->hwndItem, &rc_client);
284  trace("hwndItem %p client rect %s\n", dis->hwndItem, wine_dbgstr_rect(&rc_client));
285  GetClipBox(dis->hDC, &rc_clip);
286  trace("clip rect %s\n", wine_dbgstr_rect(&rc_clip));
287  ok(EqualRect(&rc_client, &rc_clip) || IsRectEmpty(&rc_clip),
288  "client rect of the listbox should be equal to the clip box,"
289  "or the clip box should be empty\n");
290 
291  trace("rcItem %s\n", wine_dbgstr_rect(&dis->rcItem));
292  SendMessageA(dis->hwndItem, LB_GETITEMRECT, dis->itemID, (LPARAM)&rc_item);
293  trace("item rect %s\n", wine_dbgstr_rect(&rc_item));
294  ok(EqualRect(&dis->rcItem, &rc_item), "item rects are not equal\n");
295 
296  break;
297  }
298 
299  case WM_COMMAND:
301  break;
302 
303  default:
304  break;
305  }
306 
307  return DefWindowProcA(hwnd, msg, wparam, lparam);
308 }
309 
310 static HWND create_parent( void )
311 {
312  WNDCLASSA cls;
313  HWND parent;
314  static ATOM class;
315 
316  if (!class)
317  {
318  cls.style = 0;
320  cls.cbClsExtra = 0;
321  cls.cbWndExtra = 0;
323  cls.hIcon = 0;
324  cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
326  cls.lpszMenuName = NULL;
327  cls.lpszClassName = "main_window_class";
328  class = RegisterClassA( &cls );
329  }
330 
331  parent = CreateWindowExA(0, "main_window_class", NULL,
333  100, 100, 400, 400,
334  GetDesktopWindow(), 0,
336  return parent;
337 }
338 
339 static void test_ownerdraw(void)
340 {
341  static const DWORD styles[] =
342  {
343  0,
344  LBS_NODATA
345  };
346  HWND parent, hLB;
347  INT ret;
348  RECT rc;
349  UINT i;
350 
351  parent = create_parent();
352  assert(parent);
353 
354  for (i = 0; i < ARRAY_SIZE(styles); i++)
355  {
357  assert(hLB);
358 
359  SetForegroundWindow(hLB);
360  UpdateWindow(hLB);
361 
362  /* make height short enough */
363  SendMessageA(hLB, LB_GETITEMRECT, 0, (LPARAM)&rc);
364  SetWindowPos(hLB, 0, 0, 0, 100, rc.bottom - rc.top + 1,
366 
367  /* make 0 item invisible */
368  SendMessageA(hLB, LB_SETTOPINDEX, 1, 0);
369  ret = SendMessageA(hLB, LB_GETTOPINDEX, 0, 0);
370  ok(ret == 1, "wrong top index %d\n", ret);
371 
372  SendMessageA(hLB, LB_GETITEMRECT, 0, (LPARAM)&rc);
373  trace("item 0 rect %s\n", wine_dbgstr_rect(&rc));
374  ok(!IsRectEmpty(&rc), "empty item rect\n");
375  ok(rc.top < 0, "rc.top is not negative (%d)\n", rc.top);
376 
377  DestroyWindow(hLB);
378 
379  /* Both FIXED and VARIABLE, FIXED should override VARIABLE. */
380  hLB = CreateWindowA("listbox", "TestList", LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE | styles[i],
381  0, 0, 100, 100, NULL, NULL, NULL, 0);
382  ok(hLB != NULL, "last error 0x%08x\n", GetLastError());
383 
384  ok(GetWindowLongA(hLB, GWL_STYLE) & LBS_OWNERDRAWVARIABLE, "Unexpected window style.\n");
385 
386  ret = SendMessageA(hLB, LB_INSERTSTRING, -1, 0);
387  ok(ret == 0, "Unexpected return value %d.\n", ret);
388  ret = SendMessageA(hLB, LB_INSERTSTRING, -1, 0);
389  ok(ret == 1, "Unexpected return value %d.\n", ret);
390 
391  ret = SendMessageA(hLB, LB_SETITEMHEIGHT, 0, 13);
392  ok(ret == LB_OKAY, "Failed to set item height, %d.\n", ret);
393 
394  ret = SendMessageA(hLB, LB_GETITEMHEIGHT, 0, 0);
395  ok(ret == 13, "Unexpected item height %d.\n", ret);
396 
397  ret = SendMessageA(hLB, LB_SETITEMHEIGHT, 1, 42);
398  ok(ret == LB_OKAY, "Failed to set item height, %d.\n", ret);
399 
400  ret = SendMessageA(hLB, LB_GETITEMHEIGHT, 0, 0);
401  ok(ret == 42, "Unexpected item height %d.\n", ret);
402 
403  ret = SendMessageA(hLB, LB_GETITEMHEIGHT, 1, 0);
404  ok(ret == 42, "Unexpected item height %d.\n", ret);
405 
406  DestroyWindow (hLB);
407  }
409 }
410 
411 #define listbox_test_query(exp, got) \
412  ok(exp.selected == got.selected, "expected selected %d, got %d\n", exp.selected, got.selected); \
413  ok(exp.anchor == got.anchor, "expected anchor %d, got %d\n", exp.anchor, got.anchor); \
414  ok(exp.caret == got.caret, "expected caret %d, got %d\n", exp.caret, got.caret); \
415  ok(exp.selcount == got.selcount, "expected selcount %d, got %d\n", exp.selcount, got.selcount);
416 
417 static void test_LB_SELITEMRANGE(void)
418 {
419  static const struct listbox_stat test_nosel = { 0, LB_ERR, 0, 0 };
420  static const struct listbox_stat test_1 = { 0, LB_ERR, 0, 2 };
421  static const struct listbox_stat test_2 = { 0, LB_ERR, 0, 3 };
422  static const struct listbox_stat test_3 = { 0, LB_ERR, 0, 4 };
423  HWND hLB;
424  struct listbox_stat answer;
425  INT ret;
426 
427  trace("testing LB_SELITEMRANGE\n");
428 
430  assert(hLB);
431 
432  listbox_query(hLB, &answer);
433  listbox_test_query(test_nosel, answer);
434 
436  ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
437  listbox_query(hLB, &answer);
438  listbox_test_query(test_1, answer);
439 
440  SendMessageA(hLB, LB_SETSEL, FALSE, -1);
441  listbox_query(hLB, &answer);
442  listbox_test_query(test_nosel, answer);
443 
445  ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
446  listbox_query(hLB, &answer);
447  listbox_test_query(test_3, answer);
448 
449  SendMessageA(hLB, LB_SETSEL, FALSE, -1);
450  listbox_query(hLB, &answer);
451  listbox_test_query(test_nosel, answer);
452 
454  ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
455  listbox_query(hLB, &answer);
456  listbox_test_query(test_nosel, answer);
457 
458  SendMessageA(hLB, LB_SETSEL, FALSE, -1);
459  listbox_query(hLB, &answer);
460  listbox_test_query(test_nosel, answer);
461 
463  ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
464  listbox_query(hLB, &answer);
465  listbox_test_query(test_1, answer);
466 
467  SendMessageA(hLB, LB_SETSEL, FALSE, -1);
468  listbox_query(hLB, &answer);
469  listbox_test_query(test_nosel, answer);
470 
472  ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
473  listbox_query(hLB, &answer);
474  listbox_test_query(test_nosel, answer);
475 
476  SendMessageA(hLB, LB_SETSEL, FALSE, -1);
477  listbox_query(hLB, &answer);
478  listbox_test_query(test_nosel, answer);
479 
481  ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
482  listbox_query(hLB, &answer);
483  listbox_test_query(test_2, answer);
484 
485  SendMessageA(hLB, LB_SETSEL, FALSE, -1);
486  listbox_query(hLB, &answer);
487  listbox_test_query(test_nosel, answer);
488 
490  ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
491  listbox_query(hLB, &answer);
492  listbox_test_query(test_2, answer);
493 
494  DestroyWindow(hLB);
495 }
496 
497 static void test_LB_SETCURSEL(void)
498 {
499  HWND parent, hLB;
500  INT ret;
501 
502  trace("testing LB_SETCURSEL\n");
503 
504  parent = create_parent();
505  assert(parent);
506 
508  assert(hLB);
509 
510  SendMessageA(hLB, LB_SETITEMHEIGHT, 0, 32);
511 
512  ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
513  ok(ret == -1, "Unexpected anchor index %d.\n", ret);
514 
515  ret = SendMessageA(hLB, LB_SETCURSEL, 2, 0);
516  ok(ret == 2, "LB_SETCURSEL returned %d instead of 2\n", ret);
517  ret = GetScrollPos(hLB, SB_VERT);
518  ok(ret == 0, "expected vscroll 0, got %d\n", ret);
519 
520  ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
521  ok(ret == -1, "Unexpected anchor index %d.\n", ret);
522 
523  ret = SendMessageA(hLB, LB_SETCURSEL, 3, 0);
524  ok(ret == 3, "LB_SETCURSEL returned %d instead of 3\n", ret);
525  ret = GetScrollPos(hLB, SB_VERT);
526  ok(ret == 1, "expected vscroll 1, got %d\n", ret);
527 
528  ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
529  ok(ret == -1, "Unexpected anchor index %d.\n", ret);
530 
531  DestroyWindow(hLB);
532 
533  hLB = create_listbox(0, 0);
534  ok(hLB != NULL, "Failed to create ListBox window.\n");
535 
536  ret = SendMessageA(hLB, LB_SETCURSEL, 1, 0);
537  ok(ret == 1, "Unexpected return value %d.\n", ret);
538 
539  ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
540  ok(ret == -1, "Unexpected anchor index %d.\n", ret);
541 
542  DestroyWindow(hLB);
543 
544  /* LBS_EXTENDEDSEL */
546  ok(hLB != NULL, "Failed to create ListBox window.\n");
547 
548  ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
549  ok(ret == -1, "Unexpected anchor index %d.\n", ret);
550 
551  ret = SendMessageA(hLB, LB_SETCURSEL, 2, 0);
552  ok(ret == -1, "Unexpected return value %d.\n", ret);
553 
554  ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
555  ok(ret == -1, "Unexpected anchor index %d.\n", ret);
556 
557  DestroyWindow(hLB);
558 
559  /* LBS_MULTIPLESEL */
561  ok(hLB != NULL, "Failed to create ListBox window.\n");
562 
563  ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
564  ok(ret == -1, "Unexpected anchor index %d.\n", ret);
565 
566  ret = SendMessageA(hLB, LB_SETCURSEL, 2, 0);
567  ok(ret == -1, "Unexpected return value %d.\n", ret);
568 
569  ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
570  ok(ret == -1, "Unexpected anchor index %d.\n", ret);
571 
572  DestroyWindow(hLB);
573 }
574 
575 static void test_LB_SETSEL(void)
576 {
577  HWND list;
578  int ret;
579 
580  /* LBS_EXTENDEDSEL */
582  ok(list != NULL, "Failed to create ListBox window.\n");
583 
585  ok(ret == -1, "Unexpected anchor index %d.\n", ret);
586 
588  ok(ret == 0, "Unexpected return value %d.\n", ret);
590  ok(ret == 0, "Unexpected anchor index %d.\n", ret);
591 
593  ok(ret == 0, "Unexpected return value %d.\n", ret);
595  ok(ret == 1, "Unexpected anchor index %d.\n", ret);
596 
598  ok(ret == 0, "Unexpected return value %d.\n", ret);
600  ok(ret == 1, "Unexpected anchor index %d.\n", ret);
601 
603 
604  /* LBS_MULTIPLESEL */
606  ok(list != NULL, "Failed to create ListBox window.\n");
607 
609  ok(ret == -1, "Unexpected anchor index %d.\n", ret);
610 
612  ok(ret == 0, "Unexpected return value %d.\n", ret);
614  ok(ret == 0, "Unexpected anchor index %d.\n", ret);
615 
617  ok(ret == 0, "Unexpected return value %d.\n", ret);
619  ok(ret == 1, "Unexpected anchor index %d.\n", ret);
620 
622  ok(ret == 0, "Unexpected return value %d.\n", ret);
624  ok(ret == 1, "Unexpected anchor index %d.\n", ret);
625 
627 }
628 
629 static void test_listbox_height(void)
630 {
631  HWND hList;
632  int r, id;
633 
634  hList = CreateWindowA( "ListBox", "list test", 0,
635  1, 1, 600, 100, NULL, NULL, NULL, NULL );
636  ok( hList != NULL, "failed to create listbox\n");
637 
638  id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi");
639  ok( id == 0, "item id wrong\n");
640 
641  r = SendMessageA( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 20, 0 ));
642  ok( r == 0, "send message failed\n");
643 
645  ok( r == 20, "height wrong\n");
646 
647  r = SendMessageA( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 0, 30 ));
648  ok( r == -1, "send message failed\n");
649 
651  ok( r == 20, "height wrong\n");
652 
653  r = SendMessageA( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 0x100, 0 ));
654  ok( r == -1, "send message failed\n");
655 
657  ok( r == 20, "height wrong\n");
658 
659  r = SendMessageA( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 0xff, 0 ));
660  ok( r == 0, "send message failed\n");
661 
663  ok( r == 0xff, "height wrong\n");
664 
665  DestroyWindow( hList );
666 }
667 
669 {
670  static const DWORD styles[] =
671  {
672  0,
674  };
675  static const DWORD selstyles[] =
676  {
677  0,
681  };
682  static const LONG selexpect_single[] = { 0, 0, 1 };
683  static const LONG selexpect_single2[] = { 1, 0, 0 };
684  static const LONG selexpect_multi[] = { 1, 0, 1 };
685  static const LONG selexpect_multi2[] = { 1, 1, 0 };
686 
687  HWND parent, listbox;
688  DWORD style;
689  LONG ret;
690  UINT i, j, k;
691 
692  parent = create_parent();
693  ok(parent != NULL, "Failed to create parent window.\n");
694  for (i = 0; i < ARRAY_SIZE(styles); i++)
695  {
696  /* Test if changing selection styles affects selection storage */
697  for (j = 0; j < ARRAY_SIZE(selstyles); j++)
698  {
699  LONG setcursel_expect, selitemrange_expect, getselcount_expect;
700  const LONG *selexpect;
701 
702  listbox = CreateWindowA("listbox", "TestList", styles[i] | selstyles[j] | WS_CHILD | WS_VISIBLE,
703  0, 0, 100, 100, parent, (HMENU)1, NULL, 0);
704  ok(listbox != NULL, "%u: Failed to create ListBox window.\n", j);
705 
706  if (selstyles[j] & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL))
707  {
708  setcursel_expect = LB_ERR;
709  selitemrange_expect = LB_OKAY;
710  getselcount_expect = 2;
711  selexpect = selexpect_multi;
712  }
713  else
714  {
715  setcursel_expect = 2;
716  selitemrange_expect = LB_ERR;
717  getselcount_expect = LB_ERR;
718  selexpect = selexpect_single;
719  }
720 
721  for (k = 0; k < ARRAY_SIZE(selexpect_multi); k++)
722  {
723  ret = SendMessageA(listbox, LB_INSERTSTRING, -1, (LPARAM)"x");
724  ok(ret == k, "%u: Unexpected return value %d, expected %d.\n", j, ret, k);
725  }
726  ret = SendMessageA(listbox, LB_GETCOUNT, 0, 0);
727  ok(ret == ARRAY_SIZE(selexpect_multi), "%u: Unexpected count %d.\n", j, ret);
728 
729  /* Select items with different methods */
730  ret = SendMessageA(listbox, LB_SETCURSEL, 2, 0);
731  ok(ret == setcursel_expect, "%u: Unexpected return value %d.\n", j, ret);
732  ret = SendMessageA(listbox, LB_SELITEMRANGE, TRUE, MAKELPARAM(0, 0));
733  ok(ret == selitemrange_expect, "%u: Unexpected return value %d.\n", j, ret);
734  ret = SendMessageA(listbox, LB_SELITEMRANGE, TRUE, MAKELPARAM(2, 2));
735  ok(ret == selitemrange_expect, "%u: Unexpected return value %d.\n", j, ret);
736 
737  /* Verify that the proper items are selected */
738  for (k = 0; k < ARRAY_SIZE(selexpect_multi); k++)
739  {
740  ret = SendMessageA(listbox, LB_GETSEL, k, 0);
741  ok(ret == selexpect[k], "%u: Unexpected selection state %d, expected %d.\n",
742  j, ret, selexpect[k]);
743  }
744 
745  /* Now change the selection style */
746  style = GetWindowLongA(listbox, GWL_STYLE);
747  ok((style & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) == selstyles[j],
748  "%u: unexpected window styles %#x.\n", j, style);
749  if (selstyles[j] & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL))
750  style &= ~selstyles[j];
751  else
753  SetWindowLongA(listbox, GWL_STYLE, style);
754  style = GetWindowLongA(listbox, GWL_STYLE);
755  ok(!(style & selstyles[j]), "%u: unexpected window styles %#x.\n", j, style);
756 
757  /* Verify that the same items are selected */
758  ret = SendMessageA(listbox, LB_GETSELCOUNT, 0, 0);
759  ok(ret == getselcount_expect, "%u: expected %d from LB_GETSELCOUNT, got %d\n",
760  j, getselcount_expect, ret);
761 
762  for (k = 0; k < ARRAY_SIZE(selexpect_multi); k++)
763  {
764  ret = SendMessageA(listbox, LB_GETSEL, k, 0);
765  ok(ret == selexpect[k], "%u: Unexpected selection state %d, expected %d.\n",
766  j, ret, selexpect[k]);
767  }
768 
769  /* Lastly see if we can still change the selection as before with old style */
770  if (setcursel_expect != LB_ERR) setcursel_expect = 0;
771  ret = SendMessageA(listbox, LB_SETCURSEL, 0, 0);
772  ok(ret == setcursel_expect, "%u: Unexpected return value %d.\n", j, ret);
773  ret = SendMessageA(listbox, LB_SELITEMRANGE, TRUE, MAKELPARAM(1, 1));
774  ok(ret == selitemrange_expect, "%u: Unexpected return value %d.\n", j, ret);
775  ret = SendMessageA(listbox, LB_SELITEMRANGE, FALSE, MAKELPARAM(2, 2));
776  ok(ret == selitemrange_expect, "%u: Unexpected return value %d.\n", j, ret);
777 
778  /* And verify the selections */
779  selexpect = (selstyles[j] & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) ? selexpect_multi2 : selexpect_single2;
780  ret = SendMessageA(listbox, LB_GETSELCOUNT, 0, 0);
781  ok(ret == getselcount_expect, "%u: expected %d from LB_GETSELCOUNT, got %d\n",
782  j, getselcount_expect, ret);
783 
784  for (k = 0; k < ARRAY_SIZE(selexpect_multi); k++)
785  {
786  ret = SendMessageA(listbox, LB_GETSEL, k, 0);
787  ok(ret == selexpect[k], "%u: Unexpected selection state %d, expected %d.\n",
788  j, ret, selexpect[k]);
789  }
790 
791  DestroyWindow(listbox);
792  }
793  }
795 }
796 
797 static void test_itemfrompoint(void)
798 {
799  /* WS_POPUP is required in order to have a more accurate size calculation (
800  without caption). LBS_NOINTEGRALHEIGHT is required in order to test
801  behavior of partially-displayed item.
802  */
803  HWND hList = CreateWindowA( "ListBox", "list test",
805  1, 1, 600, 100, NULL, NULL, NULL, NULL );
806  ULONG r, id;
807  RECT rc;
808 
809  /* For an empty listbox win2k returns 0x1ffff, win98 returns 0x10000, nt4 returns 0xffffffff */
810  r = SendMessageA(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
811  ok( r == 0x1ffff || r == 0x10000 || r == 0xffffffff, "ret %x\n", r );
812 
813  r = SendMessageA(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( 700, 30 ));
814  ok( r == 0x1ffff || r == 0x10000 || r == 0xffffffff, "ret %x\n", r );
815 
816  r = SendMessageA(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( 30, 300 ));
817  ok( r == 0x1ffff || r == 0x10000 || r == 0xffffffff, "ret %x\n", r );
818 
819  id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi");
820  ok( id == 0, "item id wrong\n");
821  id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi1");
822  ok( id == 1, "item id wrong\n");
823 
824  r = SendMessageA(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
825  ok( r == 0x1, "ret %x\n", r );
826 
827  r = SendMessageA(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 601 ));
828  ok( r == 0x10001 || broken(r == 1), /* nt4 */
829  "ret %x\n", r );
830 
831  /* Resize control so that below assertions about sizes are valid */
832  r = SendMessageA( hList, LB_GETITEMRECT, 0, (LPARAM)&rc);
833  ok( r == 1, "ret %x\n", r);
834  r = MoveWindow(hList, 1, 1, 600, (rc.bottom - rc.top + 1) * 9 / 2, TRUE);
835  ok( r != 0, "ret %x\n", r);
836 
837  id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi2");
838  ok( id == 2, "item id wrong\n");
839  id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi3");
840  ok( id == 3, "item id wrong\n");
841  id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi4");
842  ok( id == 4, "item id wrong\n");
843  id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi5");
844  ok( id == 5, "item id wrong\n");
845  id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi6");
846  ok( id == 6, "item id wrong\n");
847  id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi7");
848  ok( id == 7, "item id wrong\n");
849 
850  /* Set the listbox up so that id 1 is at the top, this leaves 5
851  partially visible at the bottom and 6, 7 are invisible */
852 
854  r = SendMessageA( hList, LB_GETTOPINDEX, 0, 0);
855  ok( r == 1, "top %d\n", r);
856 
857  r = SendMessageA( hList, LB_GETITEMRECT, 5, (LPARAM)&rc);
858  ok( r == 1, "ret %x\n", r);
859  r = SendMessageA( hList, LB_GETITEMRECT, 6, (LPARAM)&rc);
860  ok( r == 0, "ret %x\n", r);
861 
862  r = SendMessageA( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(/* x */ 10, /* y */ 10) );
863  ok( r == 1, "ret %x\n", r);
864 
865  r = SendMessageA( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(1000, 10) );
866  ok( r == 0x10001 || broken(r == 1), /* nt4 */
867  "ret %x\n", r );
868 
869  r = SendMessageA( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, -10) );
870  ok( r == 0x10001 || broken(r == 1), /* nt4 */
871  "ret %x\n", r );
872 
873  r = SendMessageA( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, 100) );
874  ok( r == 0x10005 || broken(r == 5), /* nt4 */
875  "item %x\n", r );
876 
877  r = SendMessageA( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, 200) );
878  ok( r == 0x10005 || broken(r == 5), /* nt4 */
879  "item %x\n", r );
880 
881  DestroyWindow( hList );
882 }
883 
884 static void test_listbox_item_data(void)
885 {
886  HWND hList;
887  int r, id;
888 
889  hList = CreateWindowA( "ListBox", "list test", 0,
890  1, 1, 600, 100, NULL, NULL, NULL, NULL );
891  ok( hList != NULL, "failed to create listbox\n");
892 
893  id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi");
894  ok( id == 0, "item id wrong\n");
895 
896  r = SendMessageA( hList, LB_SETITEMDATA, 0, MAKELPARAM( 20, 0 ));
897  ok(r == TRUE, "LB_SETITEMDATA returned %d instead of TRUE\n", r);
898 
899  r = SendMessageA( hList, LB_GETITEMDATA, 0, 0);
900  ok( r == 20, "get item data failed\n");
901 
902  DestroyWindow( hList );
903 }
904 
905 static void test_listbox_LB_DIR(void)
906 {
907  char path[MAX_PATH], curdir[MAX_PATH];
908  HWND hList;
909  int res, itemCount;
910  int itemCount_justFiles;
911  int itemCount_justDrives;
912  int itemCount_allFiles;
913  int itemCount_allDirs;
914  int i;
915  char pathBuffer[MAX_PATH];
916  char * p;
917  char driveletter;
918  const char *wildcard = "*";
919  HANDLE file;
920  BOOL ret;
921 
922  GetCurrentDirectoryA(ARRAY_SIZE(curdir), curdir);
923 
926  ok(ret, "Failed to set current directory.\n");
927 
928  ret = CreateDirectoryA("lb_dir_test", NULL);
929  ok(ret, "Failed to create test directory.\n");
930 
932  ok(file != INVALID_HANDLE_VALUE, "Error creating the test file: %d\n", GetLastError());
933  CloseHandle( file );
934 
935  /* NOTE: for this test to succeed, there must be no subdirectories
936  under the current directory. In addition, there must be at least
937  one file that fits the wildcard w*.c . Normally, the test
938  directory itself satisfies both conditions.
939  */
940  hList = CreateWindowA( "ListBox", "list test", WS_VISIBLE|WS_POPUP,
941  1, 1, 600, 100, NULL, NULL, NULL, NULL );
942  assert(hList);
943 
944  /* Test for standard usage */
945 
946  /* This should list all the files in the test directory. */
947  strcpy(pathBuffer, wildcard);
950  if (res == -1) /* "*" wildcard doesn't work on win9x */
951  {
952  wildcard = "*.*";
953  strcpy(pathBuffer, wildcard);
955  }
956  ok (res >= 0, "SendMessage(LB_DIR, 0, *) failed - 0x%08x\n", GetLastError());
957 
958  /* There should be some content in the listbox */
959  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
960  ok (itemCount > 0, "SendMessage(LB_DIR) did NOT fill the listbox!\n");
961  itemCount_allFiles = itemCount;
962  ok(res + 1 == itemCount,
963  "SendMessage(LB_DIR, 0, *) returned incorrect index (expected %d got %d)!\n",
964  itemCount - 1, res);
965 
966  /* This tests behavior when no files match the wildcard */
970  ok (res == -1, "SendMessage(LB_DIR, 0, %s) returned %d, expected -1\n", BAD_EXTENSION, res);
971 
972  /* There should be NO content in the listbox */
973  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
974  ok (itemCount == 0, "SendMessage(LB_DIR) DID fill the listbox!\n");
975 
976 
977  /* This should list all the w*.c files in the test directory
978  * As of this writing, this includes win.c, winstation.c, wsprintf.c
979  */
980  strcpy(pathBuffer, "w*.c");
983  ok (res >= 0, "SendMessage(LB_DIR, 0, w*.c) failed - 0x%08x\n", GetLastError());
984 
985  /* Path specification does NOT converted to uppercase */
986  ok (!strcmp(pathBuffer, "w*.c"),
987  "expected no change to pathBuffer, got %s\n", pathBuffer);
988 
989  /* There should be some content in the listbox */
990  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
991  ok (itemCount > 0, "SendMessage(LB_DIR) did NOT fill the listbox!\n");
992  itemCount_justFiles = itemCount;
993  ok(res + 1 == itemCount,
994  "SendMessage(LB_DIR, 0, w*.c) returned incorrect index (expected %d got %d)!\n",
995  itemCount - 1, res);
996 
997  /* Every single item in the control should start with a w and end in .c */
998  for (i = 0; i < itemCount; i++) {
1002  ok(((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1003  (*(p-1) == 'c' || *(p-1) == 'C') &&
1004  (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1005  }
1006 
1007  /* Test DDL_DIRECTORY */
1008  strcpy(pathBuffer, wildcard);
1011  ok (res > 0, "SendMessage(LB_DIR, DDL_DIRECTORY, *) failed - 0x%08x\n", GetLastError());
1012 
1013  /* There should be some content in the listbox.
1014  * All files plus "[..]"
1015  */
1016  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1017  itemCount_allDirs = itemCount - itemCount_allFiles;
1018  ok (itemCount > itemCount_allFiles,
1019  "SendMessage(LB_DIR, DDL_DIRECTORY, *) filled with %d entries, expected > %d\n",
1020  itemCount, itemCount_allFiles);
1021  ok(res + 1 == itemCount,
1022  "SendMessage(LB_DIR, DDL_DIRECTORY, *) returned incorrect index (expected %d got %d)!\n",
1023  itemCount - 1, res);
1024 
1025  /* This tests behavior when no files match the wildcard */
1029  ok (res == -1, "SendMessage(LB_DIR, DDL_DIRECTORY, %s) returned %d, expected -1\n", BAD_EXTENSION, res);
1030 
1031  /* There should be NO content in the listbox */
1032  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1033  ok (itemCount == 0, "SendMessage(LB_DIR) DID fill the listbox!\n");
1034 
1035 
1036  /* Test DDL_DIRECTORY */
1037  strcpy(pathBuffer, "w*.c");
1040  ok (res >= 0, "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) failed - 0x%08x\n", GetLastError());
1041 
1042  /* There should be some content in the listbox. Since the parent directory does not
1043  * fit w*.c, there should be exactly the same number of items as without DDL_DIRECTORY
1044  */
1045  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1046  ok (itemCount == itemCount_justFiles,
1047  "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) filled with %d entries, expected %d\n",
1048  itemCount, itemCount_justFiles);
1049  ok(res + 1 == itemCount,
1050  "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) returned incorrect index (expected %d got %d)!\n",
1051  itemCount - 1, res);
1052 
1053  /* Every single item in the control should start with a w and end in .c. */
1054  for (i = 0; i < itemCount; i++) {
1055  memset(pathBuffer, 0, MAX_PATH);
1058  ok(
1059  ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1060  (*(p-1) == 'c' || *(p-1) == 'C') &&
1061  (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1062  }
1063 
1064 
1065  /* Test DDL_DRIVES|DDL_EXCLUSIVE */
1066  strcpy(pathBuffer, wildcard);
1069  ok (res >= 0, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) failed - 0x%08x\n", GetLastError());
1070 
1071  /* There should be some content in the listbox. In particular, there should
1072  * be at least one element before, since the string "[-c-]" should
1073  * have been added. Depending on the user setting, more drives might have
1074  * been added.
1075  */
1076  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1077  ok (itemCount >= 1,
1078  "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) filled with %d entries, expected at least %d\n",
1079  itemCount, 1);
1080  itemCount_justDrives = itemCount;
1081  ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) returned incorrect index!\n");
1082 
1083  /* Every single item in the control should fit the format [-c-] */
1084  for (i = 0; i < itemCount; i++) {
1085  memset(pathBuffer, 0, MAX_PATH);
1086  driveletter = '\0';
1088  ok( strlen(pathBuffer) == 5, "Length of drive string is not 5\n" );
1089  ok( sscanf(pathBuffer, "[-%c-]", &driveletter) == 1, "Element %d (%s) does not fit [-X-]\n", i, pathBuffer);
1090  ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1091  if (!(driveletter >= 'a' && driveletter <= 'z')) {
1092  /* Correct after invalid entry is found */
1093  trace("removing count of invalid entry %s\n", pathBuffer);
1094  itemCount_justDrives--;
1095  }
1096  }
1097 
1098  /* This tests behavior when no files match the wildcard */
1102  ok (res == itemCount_justDrives -1, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1103  BAD_EXTENSION, res, itemCount_justDrives -1);
1104 
1105  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1106  ok (itemCount == itemCount_justDrives, "SendMessage(LB_DIR) returned %d expected %d\n",
1107  itemCount, itemCount_justDrives);
1108 
1109  trace("Files with w*.c: %d Mapped drives: %d Directories: 1\n",
1110  itemCount_justFiles, itemCount_justDrives);
1111 
1112  /* Test DDL_DRIVES. */
1113  strcpy(pathBuffer, wildcard);
1116  ok (res > 0, "SendMessage(LB_DIR, DDL_DRIVES, *) failed - 0x%08x\n", GetLastError());
1117 
1118  /* There should be some content in the listbox. In particular, there should
1119  * be at least one element before, since the string "[-c-]" should
1120  * have been added. Depending on the user setting, more drives might have
1121  * been added.
1122  */
1123  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1124  ok (itemCount == itemCount_justDrives + itemCount_allFiles,
1125  "SendMessage(LB_DIR, DDL_DRIVES, *) filled with %d entries, expected %d\n",
1126  itemCount, itemCount_justDrives + itemCount_allFiles);
1127  ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DRIVES, *) returned incorrect index!\n");
1128 
1129  /* This tests behavior when no files match the wildcard */
1133  ok (res == itemCount_justDrives -1, "SendMessage(LB_DIR, DDL_DRIVES, %s) returned %d, expected %d\n",
1134  BAD_EXTENSION, res, itemCount_justDrives -1);
1135 
1136  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1137  ok (itemCount == res + 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount, res + 1);
1138 
1139 
1140  /* Test DDL_DRIVES. */
1141  strcpy(pathBuffer, "w*.c");
1144  ok (res > 0, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) failed - 0x%08x\n", GetLastError());
1145 
1146  /* There should be some content in the listbox. In particular, there should
1147  * be at least one element before, since the string "[-c-]" should
1148  * have been added. Depending on the user setting, more drives might have
1149  * been added.
1150  */
1151  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1152  ok (itemCount == itemCount_justDrives + itemCount_justFiles,
1153  "SendMessage(LB_DIR, DDL_DRIVES, w*.c) filled with %d entries, expected %d\n",
1154  itemCount, itemCount_justDrives + itemCount_justFiles);
1155  ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) returned incorrect index!\n");
1156 
1157  /* Every single item in the control should fit the format [-c-], or w*.c */
1158  for (i = 0; i < itemCount; i++) {
1159  memset(pathBuffer, 0, MAX_PATH);
1160  driveletter = '\0';
1163  if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1) {
1164  ok( strlen(pathBuffer) == 5, "Length of drive string is not 5\n" );
1165  ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1166  } else {
1167  ok(
1168  ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1169  (*(p-1) == 'c' || *(p-1) == 'C') &&
1170  (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1171  }
1172  }
1173 
1174 
1175  /* Test DDL_DIRECTORY|DDL_DRIVES. This does *not* imply DDL_EXCLUSIVE */
1176  strcpy(pathBuffer, wildcard);
1179  ok (res > 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, *) failed - 0x%08x\n", GetLastError());
1180 
1181  /* There should be some content in the listbox. In particular, there should
1182  * be exactly the number of plain files, plus the number of mapped drives.
1183  */
1184  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1185  ok (itemCount == itemCount_allFiles + itemCount_justDrives + itemCount_allDirs,
1186  "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1187  itemCount, itemCount_allFiles + itemCount_justDrives + itemCount_allDirs);
1188  ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
1189 
1190  /* Every single item in the control should start with a w and end in .c,
1191  * except for the "[..]" string, which should appear exactly as it is,
1192  * and the mapped drives in the format "[-X-]".
1193  */
1194  for (i = 0; i < itemCount; i++) {
1195  memset(pathBuffer, 0, MAX_PATH);
1196  driveletter = '\0';
1198  if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1) {
1199  ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1200  }
1201  }
1202 
1203  /* This tests behavior when no files match the wildcard */
1207  ok (res == itemCount_justDrives -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, %s) returned %d, expected %d\n",
1208  BAD_EXTENSION, res, itemCount_justDrives -1);
1209 
1210  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1211  ok (itemCount == res + 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount, res + 1);
1212 
1213 
1214 
1215  /* Test DDL_DIRECTORY|DDL_DRIVES. */
1216  strcpy(pathBuffer, "w*.c");
1219  ok (res > 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) failed - 0x%08x\n", GetLastError());
1220 
1221  /* There should be some content in the listbox. In particular, there should
1222  * be exactly the number of plain files, plus the number of mapped drives.
1223  */
1224  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1225  ok (itemCount == itemCount_justFiles + itemCount_justDrives,
1226  "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1227  itemCount, itemCount_justFiles + itemCount_justDrives);
1228  ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
1229 
1230  /* Every single item in the control should start with a w and end in .c,
1231  * except the mapped drives in the format "[-X-]". The "[..]" directory
1232  * should not appear.
1233  */
1234  for (i = 0; i < itemCount; i++) {
1235  memset(pathBuffer, 0, MAX_PATH);
1236  driveletter = '\0';
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(
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 
1249  /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1250  strcpy(pathBuffer, wildcard);
1253  ok (res != -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) failed err %u\n", GetLastError());
1254 
1255  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1256  ok (itemCount == itemCount_allDirs,
1257  "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1258  itemCount, itemCount_allDirs);
1259  ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) returned incorrect index!\n");
1260 
1261  if (itemCount)
1262  {
1263  memset(pathBuffer, 0, MAX_PATH);
1265  ok( !strcmp(pathBuffer, "[..]"), "First element is %s, not [..]\n", pathBuffer);
1266  }
1267 
1268  /* This tests behavior when no files match the wildcard */
1272  ok (res == -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1273  BAD_EXTENSION, res, -1);
1274 
1275  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1276  ok (itemCount == res + 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount, res + 1);
1277 
1278 
1279  /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1280  strcpy(pathBuffer, "w*.c");
1283  ok (res == LB_ERR, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, w*.c) returned %d expected %d\n", res, LB_ERR);
1284 
1285  /* There should be no elements, since "[..]" does not fit w*.c */
1286  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1287  ok (itemCount == 0,
1288  "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1289  itemCount, 0);
1290 
1291  /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1292  strcpy(pathBuffer, wildcard);
1295  ok (res > 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
1296 
1297  /* There should be no plain files on the listbox */
1298  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1299  ok (itemCount == itemCount_justDrives + itemCount_allDirs,
1300  "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1301  itemCount, itemCount_justDrives + itemCount_allDirs);
1302  ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
1303 
1304  for (i = 0; i < itemCount; i++) {
1305  memset(pathBuffer, 0, MAX_PATH);
1306  driveletter = '\0';
1308  if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1) {
1309  ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1310  } else {
1311  ok( pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']',
1312  "Element %d (%s) does not fit expected [...]\n", i, pathBuffer);
1313  }
1314  }
1315 
1316  /* This tests behavior when no files match the wildcard */
1320  ok (res == itemCount_justDrives -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1321  BAD_EXTENSION, res, itemCount_justDrives -1);
1322 
1323  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1324  ok (itemCount == res + 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount, res + 1);
1325 
1326  /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1327  strcpy(pathBuffer, "w*.c");
1330  ok (res >= 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
1331 
1332  /* There should be no plain files on the listbox, and no [..], since it does not fit w*.c */
1333  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1334  ok (itemCount == itemCount_justDrives,
1335  "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1336  itemCount, itemCount_justDrives);
1337  ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
1338 
1339  for (i = 0; i < itemCount; i++) {
1340  memset(pathBuffer, 0, MAX_PATH);
1341  driveletter = '\0';
1343  ok (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1, "Element %d (%s) does not fit [-X-]\n", i, pathBuffer);
1344  ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1345  }
1347 
1348  DeleteFileA( "wtest1.tmp.c" );
1349  RemoveDirectoryA("lb_dir_test");
1350 
1351  SetCurrentDirectoryA(curdir);
1352 }
1353 
1355 static HWND g_label;
1356 
1357 #define ID_TEST_LABEL 1001
1358 #define ID_TEST_LISTBOX 1002
1359 
1361 {
1363  "Static",
1364  "Contents of static control before DlgDirList.",
1365  WS_CHILD | WS_VISIBLE,
1366  10, 10, 512, 32,
1367  hwnd, (HMENU)ID_TEST_LABEL, NULL, 0);
1368  if (!g_label) return FALSE;
1370  "ListBox",
1371  "DlgDirList test",
1373  10, 60, 256, 256,
1374  hwnd, (HMENU)ID_TEST_LISTBOX, NULL, 0);
1375  if (!g_listBox) return FALSE;
1376 
1377  return TRUE;
1378 }
1379 
1381  HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
1382 {
1383  LRESULT result = 0;
1384 
1385  switch (uiMsg) {
1386  case WM_DESTROY:
1387  PostQuitMessage(0);
1388  break;
1389  case WM_CREATE:
1391  ? 0 : (LRESULT)-1;
1392  break;
1393  default:
1394  result = DefWindowProcA (hwnd, uiMsg, wParam, lParam);
1395  break;
1396  }
1397  return result;
1398 }
1399 
1401 {
1402  WNDCLASSA cls;
1403 
1404  cls.style = 0;
1405  cls.cbClsExtra = 0;
1406  cls.cbWndExtra = 0;
1407  cls.hInstance = hInst;
1408  cls.hIcon = NULL;
1410  cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
1411  cls.lpszMenuName = NULL;
1413  cls.lpszClassName = "ListboxContainerClass";
1414  if (!RegisterClassA (&cls)) return FALSE;
1415 
1416  return TRUE;
1417 }
1418 
1419 static void test_listbox_dlgdir(void)
1420 {
1421  HINSTANCE hInst;
1422  HWND hWnd;
1423  int res, itemCount;
1424  int itemCount_allDirs;
1425  int itemCount_justFiles;
1426  int itemCount_justDrives;
1427  int i;
1428  char pathBuffer[MAX_PATH];
1429  char itemBuffer[MAX_PATH];
1430  char tempBuffer[MAX_PATH];
1431  char * p;
1432  char driveletter;
1433  HANDLE file;
1434 
1436  ok(file != INVALID_HANDLE_VALUE, "Error creating the test file: %d\n", GetLastError());
1437  CloseHandle( file );
1438 
1439  /* NOTE: for this test to succeed, there must be no subdirectories
1440  under the current directory. In addition, there must be at least
1441  one file that fits the wildcard w*.c . Normally, the test
1442  directory itself satisfies both conditions.
1443  */
1444 
1445  hInst = GetModuleHandleA(0);
1447  hWnd = CreateWindowA("ListboxContainerClass", "ListboxContainerClass",
1450  NULL, NULL, hInst, 0);
1451  assert(hWnd);
1452 
1453  /* Test for standard usage */
1454 
1455  /* The following should be overwritten by the directory path */
1456  SendMessageA(g_label, WM_SETTEXT, 0, (LPARAM)"default contents");
1457 
1458  /* This should list all the w*.c files in the test directory
1459  * As of this writing, this includes win.c, winstation.c, wsprintf.c
1460  */
1461  strcpy(pathBuffer, "w*.c");
1463  ok (res == 1, "DlgDirList(*.c, 0) returned %d - expected 1 - 0x%08x\n", res, GetLastError());
1464 
1465  /* Path specification gets converted to uppercase */
1466  ok (!strcmp(pathBuffer, "W*.C"),
1467  "expected conversion to uppercase, got %s\n", pathBuffer);
1468 
1469  /* Loaded path should have overwritten the label text */
1471  trace("Static control after DlgDirList: %s\n", pathBuffer);
1472  ok (strcmp("default contents", pathBuffer), "DlgDirList() did not modify static control!\n");
1473 
1474  /* There should be some content in the listbox */
1475  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1476  ok (itemCount > 0, "DlgDirList() did NOT fill the listbox!\n");
1477  itemCount_justFiles = itemCount;
1478 
1479  /* Every single item in the control should start with a w and end in .c */
1480  for (i = 0; i < itemCount; i++) {
1481  memset(pathBuffer, 0, MAX_PATH);
1484  ok(((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1485  (*(p-1) == 'c' || *(p-1) == 'C') &&
1486  (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1487  }
1488 
1489  /* Test behavior when no files match the wildcard */
1492  ok (res == 1, "DlgDirList(%s, 0) returned %d expected 1\n", BAD_EXTENSION, res);
1493 
1494  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1495  ok (itemCount == 0, "DlgDirList() DID fill the listbox!\n");
1496 
1497  /* Test DDL_DIRECTORY */
1498  strcpy(pathBuffer, "w*.c");
1500  DDL_DIRECTORY);
1501  ok (res == 1, "DlgDirList(*.c, DDL_DIRECTORY) failed - 0x%08x\n", GetLastError());
1502 
1503  /* There should be some content in the listbox. In particular, there should
1504  * be exactly more elements than before, since the directories should
1505  * have been added.
1506  */
1507  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1508  itemCount_allDirs = itemCount - itemCount_justFiles;
1509  ok (itemCount >= itemCount_justFiles,
1510  "DlgDirList(DDL_DIRECTORY) filled with %d entries, expected > %d\n",
1511  itemCount, itemCount_justFiles);
1512 
1513  /* Every single item in the control should start with a w and end in .c,
1514  * except for the "[..]" string, which should appear exactly as it is.
1515  */
1516  for (i = 0; i < itemCount; i++) {
1517  memset(pathBuffer, 0, MAX_PATH);
1520  ok( (pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']') ||
1521  ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1522  (*(p-1) == 'c' || *(p-1) == 'C') &&
1523  (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1524  }
1525 
1526  /* Test behavior when no files match the wildcard */
1529  DDL_DIRECTORY);
1530  ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY) returned %d expected 1\n", BAD_EXTENSION, res);
1531 
1532  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1533  ok (itemCount == itemCount_allDirs,
1534  "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
1535  itemCount_allDirs, itemCount);
1536  for (i = 0; i < itemCount; i++) {
1537  memset(pathBuffer, 0, MAX_PATH);
1539  ok( pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']',
1540  "Element %d (%s) does not fit requested [...]\n", i, pathBuffer);
1541  }
1542 
1543 
1544  /* Test DDL_DRIVES. At least on WinXP-SP2, this implies DDL_EXCLUSIVE */
1545  strcpy(pathBuffer, "w*.c");
1547  DDL_DRIVES);
1548  ok (res == 1, "DlgDirList(*.c, DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1549 
1550  /* There should be some content in the listbox. In particular, there should
1551  * be at least one element before, since the string "[-c-]" should
1552  * have been added. Depending on the user setting, more drives might have
1553  * been added.
1554  */
1555  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1556  ok (itemCount >= 1,
1557  "DlgDirList(DDL_DRIVES) filled with %d entries, expected at least %d\n",
1558  itemCount, 1);
1559  itemCount_justDrives = itemCount;
1560 
1561  /* Every single item in the control should fit the format [-c-] */
1562  for (i = 0; i < itemCount; i++) {
1563  memset(pathBuffer, 0, MAX_PATH);
1564  driveletter = '\0';
1566  ok( strlen(pathBuffer) == 5, "Length of drive string is not 5\n" );
1567  ok( sscanf(pathBuffer, "[-%c-]", &driveletter) == 1, "Element %d (%s) does not fit [-X-]\n", i, pathBuffer);
1568  ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1569  if (!(driveletter >= 'a' && driveletter <= 'z')) {
1570  /* Correct after invalid entry is found */
1571  trace("removing count of invalid entry %s\n", pathBuffer);
1572  itemCount_justDrives--;
1573  }
1574  }
1575 
1576  /* Test behavior when no files match the wildcard */
1579  DDL_DRIVES);
1580  ok (res == 1, "DlgDirList(%s, DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION, res);
1581 
1582  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1583  ok (itemCount == itemCount_justDrives, "DlgDirList() incorrectly filled the listbox!\n");
1584 
1585 
1586  /* Test DDL_DIRECTORY|DDL_DRIVES. This does *not* imply DDL_EXCLUSIVE */
1587  strcpy(pathBuffer, "w*.c");
1590  ok (res == 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1591 
1592  /* There should be some content in the listbox. In particular, there should
1593  * be exactly the number of plain files, plus the number of mapped drives,
1594  * plus one "[..]"
1595  */
1596  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1597  ok (itemCount == itemCount_justFiles + itemCount_justDrives + itemCount_allDirs,
1598  "DlgDirList(DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1599  itemCount, itemCount_justFiles + itemCount_justDrives + itemCount_allDirs);
1600 
1601  /* Every single item in the control should start with a w and end in .c,
1602  * except for the "[..]" string, which should appear exactly as it is,
1603  * and the mapped drives in the format "[-X-]".
1604  */
1605  for (i = 0; i < itemCount; i++) {
1606  memset(pathBuffer, 0, MAX_PATH);
1607  driveletter = '\0';
1610  if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1) {
1611  ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1612  } else {
1613  ok( (pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']') ||
1614  ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1615  (*(p-1) == 'c' || *(p-1) == 'C') &&
1616  (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1617  }
1618  }
1619 
1620  /* Test behavior when no files match the wildcard */
1624  ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION, res);
1625 
1626  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1627  ok (itemCount == itemCount_justDrives + itemCount_allDirs,
1628  "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
1629  itemCount_justDrives + itemCount_allDirs, itemCount);
1630 
1631 
1632 
1633  /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1634  strcpy(pathBuffer, "w*.c");
1637  ok (res == 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_EXCLUSIVE) failed - 0x%08x\n", GetLastError());
1638 
1639  /* There should be exactly one element: "[..]" */
1640  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1641  ok (itemCount == itemCount_allDirs,
1642  "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1643  itemCount, itemCount_allDirs);
1644 
1645  if (itemCount && GetCurrentDirectoryA( MAX_PATH, pathBuffer ) > 3) /* there's no [..] in drive root */
1646  {
1647  memset(pathBuffer, 0, MAX_PATH);
1649  ok( !strcmp(pathBuffer, "[..]"), "First (and only) element is not [..]\n");
1650  }
1651 
1652  /* Test behavior when no files match the wildcard */
1656  ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION, res);
1657 
1658  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1659  ok (itemCount == itemCount_allDirs, "DlgDirList() incorrectly filled the listbox!\n");
1660 
1661 
1662  /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1663  strcpy(pathBuffer, "w*.c");
1666  ok (res == 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) failed - 0x%08x\n", GetLastError());
1667 
1668  /* There should be no plain files on the listbox */
1669  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1670  ok (itemCount == itemCount_justDrives + itemCount_allDirs,
1671  "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1672  itemCount, itemCount_justDrives + itemCount_allDirs);
1673 
1674  for (i = 0; i < itemCount; i++) {
1675  memset(pathBuffer, 0, MAX_PATH);
1676  driveletter = '\0';
1678  if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1) {
1679  ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1680  } else {
1681  ok( pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']',
1682  "Element %d (%s) does not fit expected [...]\n", i, pathBuffer);
1683  }
1684  }
1685 
1686  /* Test behavior when no files match the wildcard */
1690  ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION, res);
1691 
1692  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1693  ok (itemCount == itemCount_justDrives + itemCount_allDirs,
1694  "DlgDirList() incorrectly filled the listbox!\n");
1695 
1696  /* Now test DlgDirSelectEx() in normal operation */
1697  /* Fill with everything - drives, directory and all plain files. */
1698  strcpy(pathBuffer, "*");
1701  ok (res != 0, "DlgDirList(*, DDL_DIRECTORY|DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1702 
1703  SendMessageA(g_listBox, LB_SETCURSEL, -1, 0); /* Unselect any current selection */
1704  memset(pathBuffer, 0, MAX_PATH);
1705  SetLastError(0xdeadbeef);
1707  ok (GetLastError() == 0xdeadbeef,
1708  "DlgDirSelectEx() with no selection modified last error code from 0xdeadbeef to 0x%08x\n",
1709  GetLastError());
1710  ok (res == 0, "DlgDirSelectEx() with no selection returned %d, expected 0\n", res);
1711  /* WinXP-SP2 leaves pathBuffer untouched, but Win98 fills it with garbage. */
1712  /*
1713  ok (strlen(pathBuffer) == 0, "DlgDirSelectEx() with no selection filled buffer with %s\n", pathBuffer);
1714  */
1715  /* Test proper drive/dir/file recognition */
1716  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1717  for (i = 0; i < itemCount; i++) {
1718  memset(itemBuffer, 0, MAX_PATH);
1719  memset(pathBuffer, 0, MAX_PATH);
1720  memset(tempBuffer, 0, MAX_PATH);
1721  driveletter = '\0';
1722  SendMessageA(g_listBox, LB_GETTEXT, i, (LPARAM)itemBuffer);
1723  if (!strstr(itemBuffer, ".exe")) continue; // skip downloaded/generated files from other tests
1725  ok (res == i, "SendMessageA(LB_SETCURSEL, %d) failed\n", i);
1726  if (sscanf(itemBuffer, "[-%c-]", &driveletter) == 1) {
1727  /* Current item is a drive letter */
1728  SetLastError(0xdeadbeef);
1730  ok (GetLastError() == 0xdeadbeef,
1731  "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1732  i, GetLastError());
1733  ok(res == 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer, pathBuffer);
1734 
1735  /* For drive letters, DlgDirSelectEx tacks on a colon */
1736  ok (pathBuffer[0] == driveletter && pathBuffer[1] == ':' && pathBuffer[2] == '\0',
1737  "%d: got \"%s\" expected \"%c:\"\n", i, pathBuffer, driveletter);
1738  } else if (itemBuffer[0] == '[') {
1739  /* Current item is the parent directory */
1740  SetLastError(0xdeadbeef);
1742  ok (GetLastError() == 0xdeadbeef,
1743  "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1744  i, GetLastError());
1745  ok(res == 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer, pathBuffer);
1746 
1747  /* For directories, DlgDirSelectEx tacks on a backslash */
1749  ok (*(p-1) == '\\', "DlgDirSelectEx did NOT tack on a backslash to dir, got %s\n", pathBuffer);
1750 
1751  tempBuffer[0] = '[';
1752  lstrcpynA(tempBuffer + 1, pathBuffer, strlen(pathBuffer));
1753  strcat(tempBuffer, "]");
1754  ok (!strcmp(tempBuffer, itemBuffer), "Formatted directory should be %s, got %s\n", tempBuffer, itemBuffer);
1755  } else {
1756  /* Current item is a plain file */
1757  SetLastError(0xdeadbeef);
1759  ok (GetLastError() == 0xdeadbeef,
1760  "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1761  i, GetLastError());
1762  ok(res == 0, "DlgDirSelectEx() thinks %s (%s) is a drive/directory!\n", itemBuffer, pathBuffer);
1763 
1764  /* NOTE: WinXP tacks a period on all files that lack an extension. This affects
1765  * for example, "Makefile", which gets reported as "Makefile."
1766  */
1767  strcpy(tempBuffer, itemBuffer);
1768  if (strchr(tempBuffer, '.') == NULL) strcat(tempBuffer, ".");
1769  ok (!strcmp(pathBuffer, tempBuffer), "Formatted file should be %s, got %s\n", tempBuffer, pathBuffer);
1770  }
1771  }
1772 
1773  DeleteFileA( "wtest1.tmp.c" );
1774 
1775  /* Now test DlgDirSelectEx() in abnormal operation */
1776  /* Fill list with bogus entries, that look somewhat valid */
1778  SendMessageA(g_listBox, LB_ADDSTRING, 0, (LPARAM)"[notexist.dir]");
1779  SendMessageA(g_listBox, LB_ADDSTRING, 0, (LPARAM)"notexist.fil");
1780  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1781  for (i = 0; i < itemCount; i++) {
1782  memset(itemBuffer, 0, MAX_PATH);
1783  memset(pathBuffer, 0, MAX_PATH);
1784  memset(tempBuffer, 0, MAX_PATH);
1785  driveletter = '\0';
1786  SendMessageA(g_listBox, LB_GETTEXT, i, (LPARAM)itemBuffer);
1788  ok (res == i, "SendMessage(LB_SETCURSEL, %d) failed\n", i);
1789  if (sscanf(itemBuffer, "[-%c-]", &driveletter) == 1) {
1790  /* Current item is a drive letter */
1791  SetLastError(0xdeadbeef);
1793  ok (GetLastError() == 0xdeadbeef,
1794  "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1795  i, GetLastError());
1796  ok(res == 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer, pathBuffer);
1797 
1798  /* For drive letters, DlgDirSelectEx tacks on a colon */
1799  ok (pathBuffer[0] == driveletter && pathBuffer[1] == ':' && pathBuffer[2] == '\0',
1800  "%d: got \"%s\" expected \"%c:\"\n", i, pathBuffer, driveletter);
1801  } else if (itemBuffer[0] == '[') {
1802  /* Current item is the parent directory */
1803  SetLastError(0xdeadbeef);
1805  ok (GetLastError() == 0xdeadbeef,
1806  "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1807  i, GetLastError());
1808  ok(res == 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer, pathBuffer);
1809 
1810  /* For directories, DlgDirSelectEx tacks on a backslash */
1812  ok (*(p-1) == '\\', "DlgDirSelectEx did NOT tack on a backslash to dir, got %s\n", pathBuffer);
1813 
1814  tempBuffer[0] = '[';
1815  lstrcpynA(tempBuffer + 1, pathBuffer, strlen(pathBuffer));
1816  strcat(tempBuffer, "]");
1817  ok (!strcmp(tempBuffer, itemBuffer), "Formatted directory should be %s, got %s\n", tempBuffer, itemBuffer);
1818  } else {
1819  /* Current item is a plain file */
1820  SetLastError(0xdeadbeef);
1822  ok (GetLastError() == 0xdeadbeef,
1823  "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1824  i, GetLastError());
1825  ok(res == 0, "DlgDirSelectEx() thinks %s (%s) is a drive/directory!\n", itemBuffer, pathBuffer);
1826 
1827  /* NOTE: WinXP and Win98 tack a period on all files that lack an extension.
1828  * This affects for example, "Makefile", which gets reported as "Makefile."
1829  */
1830  strcpy(tempBuffer, itemBuffer);
1831  if (strchr(tempBuffer, '.') == NULL) strcat(tempBuffer, ".");
1832  ok (!strcmp(pathBuffer, tempBuffer), "Formatted file should be %s, got %s\n", tempBuffer, pathBuffer);
1833  }
1834  }
1835 
1836  /* Test behavior when loading folders from root with and without wildcard */
1837  strcpy(pathBuffer, "C:\\");
1839  ok(res || broken(!res) /* NT4/W2K */, "DlgDirList failed to list C:\\ folders\n");
1840  ok(!strcmp(pathBuffer, "*") || broken(!res) /* NT4/W2K */,
1841  "DlgDirList set the invalid path spec '%s', expected '*'\n", pathBuffer);
1842 
1843  strcpy(pathBuffer, "C:\\*");
1845  ok(res || broken(!res) /* NT4/W2K */, "DlgDirList failed to list C:\\* folders\n");
1846  ok(!strcmp(pathBuffer, "*") || broken(!res) /* NT4/W2K */,
1847  "DlgDirList set the invalid path spec '%s', expected '*'\n", pathBuffer);
1848 
1849  /* Try loading files from an invalid folder */
1850  SetLastError(0xdeadbeef);
1851  strcpy(pathBuffer, "C:\\INVALID$$DIR");
1853  ok(!res, "DlgDirList should have failed with 0 but %d was returned\n", res);
1855  "GetLastError should return 0x589, got 0x%X\n",GetLastError());
1856 
1858 }
1859 
1860 static void test_set_count( void )
1861 {
1862  static const DWORD styles[] =
1863  {
1866  };
1867  HWND parent, listbox;
1868  unsigned int i;
1869  LONG ret;
1870  RECT r;
1871 
1872  parent = create_parent();
1874 
1875  UpdateWindow( listbox );
1876  GetUpdateRect( listbox, &r, TRUE );
1877  ok( IsRectEmpty( &r ), "got non-empty rect\n");
1878 
1879  ret = SendMessageA( listbox, LB_SETCOUNT, 100, 0 );
1880  ok( ret == 0, "got %d\n", ret );
1881  ret = SendMessageA( listbox, LB_GETCOUNT, 0, 0 );
1882  ok( ret == 100, "got %d\n", ret );
1883 
1884  GetUpdateRect( listbox, &r, TRUE );
1885  ok( !IsRectEmpty( &r ), "got empty rect\n");
1886 
1887  ValidateRect( listbox, NULL );
1888  GetUpdateRect( listbox, &r, TRUE );
1889  ok( IsRectEmpty( &r ), "got non-empty rect\n");
1890 
1891  ret = SendMessageA( listbox, LB_SETCOUNT, 99, 0 );
1892  ok( ret == 0, "got %d\n", ret );
1893 
1894  GetUpdateRect( listbox, &r, TRUE );
1895  ok( !IsRectEmpty( &r ), "got empty rect\n");
1896 
1897  ret = SendMessageA( listbox, LB_SETCOUNT, -5, 0 );
1898  ok( ret == 0, "got %d\n", ret );
1899  ret = SendMessageA( listbox, LB_GETCOUNT, 0, 0 );
1900  ok( ret == -5, "got %d\n", ret );
1901 
1902  DestroyWindow( listbox );
1903 
1904  for (i = 0; i < ARRAY_SIZE(styles); ++i)
1905  {
1906  listbox = create_listbox( styles[i] | WS_CHILD | WS_VISIBLE, parent );
1907 
1908  SetLastError( 0xdeadbeef );
1909  ret = SendMessageA( listbox, LB_SETCOUNT, 100, 0 );
1910  ok( ret == LB_ERR, "expected %d, got %d\n", LB_ERR, ret );
1911  ok( GetLastError() == ERROR_SETCOUNT_ON_BAD_LB, "Unexpected error %d.\n", GetLastError() );
1912 
1913  DestroyWindow( listbox );
1914  }
1915 
1916  DestroyWindow( parent );
1917 }
1918 
1919 static DWORD (WINAPI *pGetListBoxInfo)(HWND);
1921 
1923 {
1925 
1926  if (message == LB_GETLISTBOXINFO)
1928 
1929  return CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
1930 }
1931 
1932 static void test_GetListBoxInfo(void)
1933 {
1934  HWND listbox, parent;
1935  WNDPROC oldproc;
1936  DWORD ret;
1937 
1938  pGetListBoxInfo = (void*)GetProcAddress(GetModuleHandleA("user32.dll"), "GetListBoxInfo");
1939 
1940  if (!pGetListBoxInfo)
1941  {
1942  win_skip("GetListBoxInfo() not available\n");
1943  return;
1944  }
1945 
1946  parent = create_parent();
1947  listbox = create_listbox(WS_CHILD | WS_VISIBLE, parent);
1948 
1950  SetWindowLongPtrA(listbox, GWLP_USERDATA, (LONG_PTR)oldproc);
1951 
1952  lb_getlistboxinfo = 0;
1953  ret = pGetListBoxInfo(listbox);
1954  ok(ret > 0, "got %d\n", ret);
1955 todo_wine
1956  ok(lb_getlistboxinfo == 0, "got %d\n", lb_getlistboxinfo);
1957 
1958  DestroyWindow(listbox);
1960 }
1961 
1962 static void test_init_storage( void )
1963 {
1964  static const DWORD styles[] =
1965  {
1968  };
1969  HWND parent, listbox;
1970  LONG ret, items_size;
1971  int i, j;
1972 
1973  parent = create_parent();
1974  for (i = 0; i < ARRAY_SIZE(styles); i++)
1975  {
1976  listbox = CreateWindowA("listbox", "TestList", styles[i] | WS_CHILD,
1977  0, 0, 100, 100, parent, (HMENU)1, NULL, 0);
1978 
1979  items_size = SendMessageA(listbox, LB_INITSTORAGE, 100, 0);
1980  ok(items_size >= 100, "expected at least 100, got %d\n", items_size);
1981 
1982  ret = SendMessageA(listbox, LB_INITSTORAGE, 0, 0);
1983  ok(ret == items_size, "expected %d, got %d\n", items_size, ret);
1984 
1985  /* it doesn't grow since the space was already reserved */
1986  ret = SendMessageA(listbox, LB_INITSTORAGE, items_size, 0);
1987  ok(ret == items_size, "expected %d, got %d\n", items_size, ret);
1988 
1989  /* it doesn't shrink the reserved space */
1990  ret = SendMessageA(listbox, LB_INITSTORAGE, 42, 0);
1991  ok(ret == items_size, "expected %d, got %d\n", items_size, ret);
1992 
1993  /* now populate almost all of it so it's not reserved anymore */
1994  if (styles[i] & LBS_NODATA)
1995  {
1996  ret = SendMessageA(listbox, LB_SETCOUNT, items_size - 1, 0);
1997  ok(ret == 0, "unexpected return value %d\n", ret);
1998  }
1999  else
2000  {
2001  for (j = 0; j < items_size - 1; j++)
2002  {
2003  ret = SendMessageA(listbox, LB_INSERTSTRING, -1, (LPARAM)"");
2004  ok(ret == j, "expected %d, got %d\n", j, ret);
2005  }
2006  }
2007 
2008  /* we still have one more reserved slot, so it doesn't grow yet */
2009  ret = SendMessageA(listbox, LB_INITSTORAGE, 1, 0);
2010  ok(ret == items_size, "expected %d, got %d\n", items_size, ret);
2011 
2012  /* fill the slot and check again, it should grow this time */
2013  ret = SendMessageA(listbox, LB_INSERTSTRING, -1, (LPARAM)"");
2014  ok(ret == items_size - 1, "expected %d, got %d\n", items_size - 1, ret);
2015  ret = SendMessageA(listbox, LB_INITSTORAGE, 0, 0);
2016  ok(ret == items_size, "expected %d, got %d\n", items_size, ret);
2017  ret = SendMessageA(listbox, LB_INITSTORAGE, 1, 0);
2018  ok(ret > items_size, "expected it to grow past %d, got %d\n", items_size, ret);
2019 
2020  DestroyWindow(listbox);
2021  }
2023 }
2024 
2025 static void test_missing_lbuttonup( void )
2026 {
2027  HWND listbox, parent, capture;
2028 
2029  parent = create_parent();
2030  listbox = create_listbox(WS_CHILD | WS_VISIBLE, parent);
2031 
2032  /* Send button down without a corresponding button up */
2033  SendMessageA(listbox, WM_LBUTTONDOWN, 0, MAKELPARAM(10,10));
2034  capture = GetCapture();
2035  ok(capture == listbox, "got %p expected %p\n", capture, listbox);
2036 
2037  /* Capture is released and LBN_SELCHANGE sent during WM_KILLFOCUS */
2038  got_selchange = 0;
2039  SetFocus(NULL);
2040  capture = GetCapture();
2041  ok(capture == NULL, "got %p\n", capture);
2042  ok(got_selchange, "got %d\n", got_selchange);
2043 
2044  DestroyWindow(listbox);
2046 }
2047 
2048 static void test_extents(void)
2049 {
2050  HWND listbox, parent;
2051  DWORD res;
2052  SCROLLINFO sinfo;
2053  BOOL br;
2054 
2055  parent = create_parent();
2056 
2057  listbox = create_listbox(WS_CHILD | WS_VISIBLE, parent);
2058 
2059  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2060  ok(res == 0, "Got wrong initial horizontal extent: %u\n", res);
2061 
2062  sinfo.cbSize = sizeof(sinfo);
2063  sinfo.fMask = SIF_RANGE;
2064  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2065  ok(br == TRUE, "GetScrollInfo failed\n");
2066  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2067  ok(sinfo.nMax == 100, "got wrong max: %u\n", sinfo.nMax);
2068  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
2069  "List box should not have a horizontal scroll bar\n");
2070 
2071  /* horizontal extent < width */
2072  SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 64, 0);
2073 
2074  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2075  ok(res == 64, "Got wrong horizontal extent: %u\n", res);
2076 
2077  sinfo.cbSize = sizeof(sinfo);
2078  sinfo.fMask = SIF_RANGE;
2079  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2080  ok(br == TRUE, "GetScrollInfo failed\n");
2081  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2082  ok(sinfo.nMax == 100, "got wrong max: %u\n", sinfo.nMax);
2083  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
2084  "List box should not have a horizontal scroll bar\n");
2085 
2086  /* horizontal extent > width */
2087  SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 184, 0);
2088 
2089  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2090  ok(res == 184, "Got wrong horizontal extent: %u\n", res);
2091 
2092  sinfo.cbSize = sizeof(sinfo);
2093  sinfo.fMask = SIF_RANGE;
2094  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2095  ok(br == TRUE, "GetScrollInfo failed\n");
2096  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2097  ok(sinfo.nMax == 100, "got wrong max: %u\n", sinfo.nMax);
2098  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
2099  "List box should not have a horizontal scroll bar\n");
2100 
2101  DestroyWindow(listbox);
2102 
2103 
2105 
2106  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2107  ok(res == 0, "Got wrong initial horizontal extent: %u\n", res);
2108 
2109  sinfo.cbSize = sizeof(sinfo);
2110  sinfo.fMask = SIF_RANGE;
2111  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2112  ok(br == TRUE, "GetScrollInfo failed\n");
2113  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2114  ok(sinfo.nMax == 100, "got wrong max: %u\n", sinfo.nMax);
2115  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
2116  "List box should not have a horizontal scroll bar\n");
2117 
2118  /* horizontal extent < width */
2119  SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 64, 0);
2120 
2121  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2122  ok(res == 64, "Got wrong horizontal extent: %u\n", res);
2123 
2124  sinfo.cbSize = sizeof(sinfo);
2125  sinfo.fMask = SIF_RANGE;
2126  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2127  ok(br == TRUE, "GetScrollInfo failed\n");
2128  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2129  ok(sinfo.nMax == 63, "got wrong max: %u\n", sinfo.nMax);
2130  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
2131  "List box should not have a horizontal scroll bar\n");
2132 
2133  /* horizontal extent > width */
2134  SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 184, 0);
2135 
2136  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2137  ok(res == 184, "Got wrong horizontal extent: %u\n", res);
2138 
2139  sinfo.cbSize = sizeof(sinfo);
2140  sinfo.fMask = SIF_RANGE;
2141  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2142  ok(br == TRUE, "GetScrollInfo failed\n");
2143  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2144  ok(sinfo.nMax == 183, "got wrong max: %u\n", sinfo.nMax);
2145  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) != 0,
2146  "List box should have a horizontal scroll bar\n");
2147 
2148  SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 0, 0);
2149 
2150  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2151  ok(res == 0, "Got wrong horizontal extent: %u\n", res);
2152 
2153  sinfo.cbSize = sizeof(sinfo);
2154  sinfo.fMask = SIF_RANGE;
2155  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2156  ok(br == TRUE, "GetScrollInfo failed\n");
2157  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2158  ok(sinfo.nMax == 0, "got wrong max: %u\n", sinfo.nMax);
2159  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
2160  "List box should not have a horizontal scroll bar\n");
2161 
2162  DestroyWindow(listbox);
2163 
2164 
2166 
2167  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2168  ok(res == 0, "Got wrong initial horizontal extent: %u\n", res);
2169 
2170  sinfo.cbSize = sizeof(sinfo);
2171  sinfo.fMask = SIF_RANGE;
2172  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2173  ok(br == TRUE, "GetScrollInfo failed\n");
2174  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2175  ok(sinfo.nMax == 0, "got wrong max: %u\n", sinfo.nMax);
2176  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) != 0,
2177  "List box should have a horizontal scroll bar\n");
2178 
2179  /* horizontal extent < width */
2180  SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 64, 0);
2181 
2182  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2183  ok(res == 64, "Got wrong horizontal extent: %u\n", res);
2184 
2185  sinfo.cbSize = sizeof(sinfo);
2186  sinfo.fMask = SIF_RANGE;
2187  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2188  ok(br == TRUE, "GetScrollInfo failed\n");
2189  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2190  ok(sinfo.nMax == 63, "got wrong max: %u\n", sinfo.nMax);
2191  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) != 0,
2192  "List box should have a horizontal scroll bar\n");
2193 
2194  /* horizontal extent > width */
2195  SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 184, 0);
2196 
2197  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2198  ok(res == 184, "Got wrong horizontal extent: %u\n", res);
2199 
2200  sinfo.cbSize = sizeof(sinfo);
2201  sinfo.fMask = SIF_RANGE;
2202  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2203  ok(br == TRUE, "GetScrollInfo failed\n");
2204  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2205  ok(sinfo.nMax == 183, "got wrong max: %u\n", sinfo.nMax);
2206  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) != 0,
2207  "List box should have a horizontal scroll bar\n");
2208 
2209  SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 0, 0);
2210 
2211  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2212  ok(res == 0, "Got wrong horizontal extent: %u\n", res);
2213 
2214  sinfo.cbSize = sizeof(sinfo);
2215  sinfo.fMask = SIF_RANGE;
2216  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2217  ok(br == TRUE, "GetScrollInfo failed\n");
2218  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2219  ok(sinfo.nMax == 0, "got wrong max: %u\n", sinfo.nMax);
2220  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) != 0,
2221  "List box should have a horizontal scroll bar\n");
2222 
2223  DestroyWindow(listbox);
2224 
2226 }
2227 
2228 static void test_WM_MEASUREITEM(void)
2229 {
2230  HWND parent, listbox;
2231  LRESULT data;
2232 
2233  parent = create_parent();
2235 
2236  data = SendMessageA(listbox, LB_GETITEMDATA, 0, 0);
2237  ok(data == (LRESULT)strings[0], "data = %08lx, expected %p\n", data, strings[0]);
2239 
2240  parent = create_parent();
2242 
2243  data = SendMessageA(listbox, LB_GETITEMDATA, 0, 0);
2244  ok(!data, "data = %08lx\n", data);
2246 }
2247 
2248 static void test_LBS_NODATA(void)
2249 {
2250  static const DWORD invalid_styles[] =
2251  {
2252  0,
2254  LBS_SORT,
2258  };
2259  static const UINT invalid_idx[] = { -2, 2 };
2260  static const UINT valid_idx[] = { 0, 1 };
2261  static const ULONG_PTR zero_data;
2262  HWND listbox, parent;
2263  unsigned int i;
2264  ULONG_PTR data;
2265  INT ret;
2266 
2267  listbox = CreateWindowA("listbox", "TestList", LBS_NODATA | LBS_OWNERDRAWFIXED | WS_VISIBLE,
2268  0, 0, 100, 100, NULL, NULL, NULL, 0);
2269  ok(listbox != NULL, "Failed to create ListBox window.\n");
2270 
2271  ret = SendMessageA(listbox, LB_INSERTSTRING, -1, 0);
2272  ok(ret == 0, "Unexpected return value %d.\n", ret);
2273  ret = SendMessageA(listbox, LB_INSERTSTRING, -1, 0);
2274  ok(ret == 1, "Unexpected return value %d.\n", ret);
2275  ret = SendMessageA(listbox, LB_GETCOUNT, 0, 0);
2276  ok(ret == 2, "Unexpected return value %d.\n", ret);
2277 
2278  /* Invalid indices. */
2279  for (i = 0; i < ARRAY_SIZE(invalid_idx); ++i)
2280  {
2281  ret = SendMessageA(listbox, LB_SETITEMDATA, invalid_idx[i], 42);
2282  ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2283  ret = SendMessageA(listbox, LB_GETTEXTLEN, invalid_idx[i], 0);
2284  ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2285  if (ret == LB_ERR)
2286  {
2287  ret = SendMessageA(listbox, LB_GETTEXT, invalid_idx[i], (LPARAM)&data);
2288  ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2289  }
2290  ret = SendMessageA(listbox, LB_GETITEMDATA, invalid_idx[i], 0);
2291  ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2292  }
2293 
2294  /* Valid indices. */
2295  for (i = 0; i < ARRAY_SIZE(valid_idx); ++i)
2296  {
2297  ret = SendMessageA(listbox, LB_SETITEMDATA, valid_idx[i], 42);
2298  ok(ret == TRUE, "Unexpected return value %d.\n", ret);
2299  ret = SendMessageA(listbox, LB_GETTEXTLEN, valid_idx[i], 0);
2300  ok(ret == sizeof(data), "Unexpected return value %d.\n", ret);
2301 
2302  memset(&data, 0xee, sizeof(data));
2303  ret = SendMessageA(listbox, LB_GETTEXT, valid_idx[i], (LPARAM)&data);
2304  ok(ret == sizeof(data), "Unexpected return value %d.\n", ret);
2305  ok(!memcmp(&data, &zero_data, sizeof(data)), "Unexpected item data.\n");
2306 
2307  ret = SendMessageA(listbox, LB_GETITEMDATA, valid_idx[i], 0);
2308  ok(ret == 0, "Unexpected return value %d.\n", ret);
2309  }
2310 
2311  /* More messages that don't work with LBS_NODATA. */
2312  SetLastError(0xdeadbeef);
2313  ret = SendMessageA(listbox, LB_FINDSTRING, 1, 0);
2314  ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2315  ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError should return 0x57, got 0x%X\n", GetLastError());
2316  SetLastError(0xdeadbeef);
2317  ret = SendMessageA(listbox, LB_FINDSTRING, 1, 42);
2318  ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2319  ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError should return 0x57, got 0x%X\n", GetLastError());
2320  SetLastError(0xdeadbeef);
2321  ret = SendMessageA(listbox, LB_FINDSTRINGEXACT, 1, 0);
2322  ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2323  ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError should return 0x57, got 0x%X\n", GetLastError());
2324  SetLastError(0xdeadbeef);
2325  ret = SendMessageA(listbox, LB_FINDSTRINGEXACT, 1, 42);
2326  ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2327  ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError should return 0x57, got 0x%X\n", GetLastError());
2328  SetLastError(0xdeadbeef);
2329  ret = SendMessageA(listbox, LB_SELECTSTRING, 1, 0);
2330  ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2331  ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError should return 0x57, got 0x%X\n", GetLastError());
2332  SetLastError(0xdeadbeef);
2333  ret = SendMessageA(listbox, LB_SELECTSTRING, 1, 42);
2334  ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2335  ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError should return 0x57, got 0x%X\n", GetLastError());
2336 
2337  DestroyWindow(listbox);
2338 
2339  /* Invalid window style combinations. */
2340  parent = create_parent();
2341  ok(parent != NULL, "Failed to create parent window.\n");
2342 
2343  for (i = 0; i < ARRAY_SIZE(invalid_styles); ++i)
2344  {
2345  DWORD style;
2346 
2347  listbox = CreateWindowA("listbox", "TestList", LBS_NODATA | WS_CHILD | invalid_styles[i],
2348  0, 0, 100, 100, parent, (HMENU)1, NULL, 0);
2349  ok(listbox != NULL, "Failed to create a listbox.\n");
2350 
2351  style = GetWindowLongA(listbox, GWL_STYLE);
2352  ok((style & invalid_styles[i]) == invalid_styles[i], "%u: unexpected window styles %#x.\n", i, style);
2353  ret = SendMessageA(listbox, LB_SETCOUNT, 100, 0);
2354  ok(ret == LB_ERR, "%u: unexpected return value %d.\n", i, ret);
2355  DestroyWindow(listbox);
2356  }
2357 
2359 }
2360 
2361 START_TEST(listbox)
2362 {
2363  const struct listbox_test SS =
2364 /* {add_style} */
2365  {{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
2366  { 1, 1, 1, LB_ERR}, {0,0,0,0},
2367  { 2, 2, 2, LB_ERR}, {0,0,0,0},
2368  {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
2369 /* {selected, anchor, caret, selcount}{TODO fields} */
2370  const struct listbox_test SS_NS =
2371  {{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
2372  { 1, 1, 1, LB_ERR}, {0,0,0,0},
2373  { 2, 2, 2, LB_ERR}, {0,0,0,0},
2374  {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
2375  const struct listbox_test MS =
2376  {{ 0, LB_ERR, 0, 0}, {0,0,0,0},
2377  { 1, 1, 1, 1}, {0,0,0,0},
2378  { 2, 1, 2, 1}, {0,0,0,0},
2379  { 0, LB_ERR, 0, 2}, {0,0,0,0}};
2380  const struct listbox_test MS_NS =
2381  {{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
2382  { 1, 1, 1, LB_ERR}, {0,0,0,0},
2383  { 2, 2, 2, LB_ERR}, {0,0,0,0},
2384  {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
2385  const struct listbox_test ES =
2386  {{ 0, LB_ERR, 0, 0}, {0,0,0,0},
2387  { 1, 1, 1, 1}, {0,0,0,0},
2388  { 2, 2, 2, 1}, {0,0,0,0},
2389  { 0, LB_ERR, 0, 2}, {0,0,0,0}};
2390  const struct listbox_test ES_NS =
2391  {{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
2392  { 1, 1, 1, LB_ERR}, {0,0,0,0},
2393  { 2, 2, 2, LB_ERR}, {0,0,0,0},
2394  {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
2395  const struct listbox_test EMS =
2396  {{ 0, LB_ERR, 0, 0}, {0,0,0,0},
2397  { 1, 1, 1, 1}, {0,0,0,0},
2398  { 2, 2, 2, 1}, {0,0,0,0},
2399  { 0, LB_ERR, 0, 2}, {0,0,0,0}};
2400  const struct listbox_test EMS_NS =
2401  {{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
2402  { 1, 1, 1, LB_ERR}, {0,0,0,0},
2403  { 2, 2, 2, LB_ERR}, {0,0,0,0},
2404  {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
2405 
2406  trace (" Testing single selection...\n");
2407  check (0, SS);
2408  trace (" ... with NOSEL\n");
2409  check (LBS_NOSEL, SS_NS);
2410  trace (" ... LBS_NODATA variant ...\n");
2412  trace (" ... with NOSEL\n");
2414 
2415  trace (" Testing multiple selection...\n");
2417  trace (" ... with NOSEL\n");
2418  check (LBS_MULTIPLESEL | LBS_NOSEL, MS_NS);
2419  trace (" ... LBS_NODATA variant ...\n");
2421  trace (" ... with NOSEL\n");
2423 
2424  trace (" Testing extended selection...\n");
2426  trace (" ... with NOSEL\n");
2427  check (LBS_EXTENDEDSEL | LBS_NOSEL, ES_NS);
2428  trace (" ... LBS_NODATA variant ...\n");
2430  trace (" ... with NOSEL\n");
2432 
2433  trace (" Testing extended and multiple selection...\n");
2435  trace (" ... with NOSEL\n");
2437  trace (" ... LBS_NODATA variant ...\n");
2439  trace (" ... with NOSEL\n");
2441 
2443  test_ownerdraw();
2452  test_set_count();
2456  test_extents();
2458  test_LB_SETSEL();
2459  test_LBS_NODATA();
2460 }
static void test_listbox_item_data(void)
Definition: listbox.c:884
HGDIOBJ WINAPI GetStockObject(_In_ int)
#define LB_SETCURSEL
Definition: winuser.h:2045
static DWORD(WINAPI *pGetListBoxInfo)(HWND)
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
static LPWSTR pathBuffer
Definition: treeview.c:31
static void test_itemfrompoint(void)
Definition: listbox.c:797
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
HDC WINAPI GetDCEx(_In_opt_ HWND, _In_opt_ HRGN, _In_ DWORD)
#define LBS_NODATA
Definition: winuser.h:313
Definition: tftpd.h:59
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:406
#define LB_DIR
Definition: winuser.h:2015
static LRESULT WINAPI main_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: listbox.c:243
#define SIF_RANGE
Definition: winuser.h:1221
#define LB_FINDSTRINGEXACT
Definition: winuser.h:2017
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define GW_CHILD
Definition: winuser.h:758
#define WM_LBUTTONDOWN
Definition: winuser.h:1758
#define LB_SETHORIZONTALEXTENT
Definition: winuser.h:2046
#define WideCharToMultiByte
Definition: compat.h:101
static void listbox_query(HWND handle, struct listbox_stat *results)
Definition: listbox.c:100
static HWND create_listbox(DWORD add_style, HWND parent)
Definition: listbox.c:59
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define LB_ADDSTRING
Definition: winuser.h:2013
#define LB_GETHORIZONTALEXTENT
Definition: winuser.h:2022
#define MK_LBUTTON
Definition: winuser.h:2342
#define LBS_EXTENDEDSEL
Definition: pedump.c:689
#define LB_SETSEL
Definition: winuser.h:2050
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ERROR_SETCOUNT_ON_BAD_LB
Definition: winerror.h:914
#define SB_VERT
Definition: winuser.h:553
WORD ATOM
Definition: dimm.idl:113
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
Definition: mk_font.cpp:20
static void test_LB_SELITEMRANGE(void)
Definition: listbox.c:417
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: atltest.h:87
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
#define CP_ACP
Definition: compat.h:99
#define LB_GETITEMDATA
Definition: winuser.h:2023
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
#define LBS_HASSTRINGS
Definition: pedump.c:684
char CHAR
Definition: xmlstorage.h:175
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
#define WM_GETTEXT
Definition: winuser.h:1600
#define SB_HORZ
Definition: winuser.h:552
#define MAKELPARAM(l, h)
Definition: winuser.h:3983
static NTSTATUS zero_data(device_extension *Vcb, fcb *fcb, uint64_t start, uint64_t length, PIRP Irp, LIST_ENTRY *rollback)
Definition: fsctl.c:1805
static HDC
Definition: imagelist.c:92
#define CALLBACK
Definition: compat.h:27
static void buttonpress(HWND handle, WORD x, WORD y)
Definition: listbox.c:109
BOOL WINAPI UpdateWindow(_In_ HWND)
HWND hWnd
Definition: settings.c:17
static void check(DWORD style, const struct listbox_test test)
Definition: listbox.c:144
HANDLE HWND
Definition: compat.h:13
static LRESULT CALLBACK listbox_container_window_procA(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
Definition: listbox.c:1380
#define DDL_DIRECTORY
Definition: winuser.h:422
static void test_listbox_dlgdir(void)
Definition: listbox.c:1419
int cbClsExtra
Definition: winuser.h:3140
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
#define LBS_SORT
Definition: pedump.c:679
#define assert(x)
Definition: debug.h:53
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
LPCSTR lpszMenuName
Definition: winuser.h:3146
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define WHITE_BRUSH
Definition: wingdi.h:901
HWND WINAPI SetFocus(_In_opt_ HWND)
static MONITORINFO mi
Definition: win.c:7339
#define test
Definition: rosglue.h:37
#define ID_TEST_LISTBOX
Definition: listbox.c:1358
UINT_PTR WPARAM
Definition: windef.h:207
#define VK_DOWN
Definition: winuser.h:2202
HBRUSH hbrBackground
Definition: winuser.h:3145
#define WS_CHILD
Definition: pedump.c:617
Definition: bidi.c:78
#define SWP_NOZORDER
Definition: winuser.h:1232
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
int32_t INT_PTR
Definition: typedefs.h:62
START_TEST(listbox)
Definition: listbox.c:2604
struct listbox_stat sel sel_todo
Definition: listbox.c:170
#define LB_GETSELCOUNT
Definition: winuser.h:2029
#define LB_GETSEL
Definition: winuser.h:2028
BOOL WINAPI DestroyWindow(_In_ HWND)
#define LBN_SELCHANGE
Definition: winuser.h:2057
#define COLOR_WINDOW
Definition: winuser.h:908
int32_t INT
Definition: typedefs.h:56
static int init
Definition: wintirpc.c:33
WPARAM wParam
Definition: combotst.c:138
#define LB_SELECTSTRING
Definition: winuser.h:2038
#define LBS_STANDARD
Definition: winuser.h:321
static LRESULT WINAPI listbox_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: listbox.c:1922
static const char BAD_EXTENSION[]
Definition: listbox.c:47
#define LB_GETANCHORINDEX
Definition: winuser.h:2018
#define LBS_OWNERDRAWFIXED
Definition: pedump.c:682
LRESULT WINAPI CallWindowProcA(_In_ WNDPROC, _In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define LB_SETITEMHEIGHT
Definition: winuser.h:2048
static BOOL on_listbox_container_create(HWND hwnd, LPCREATESTRUCTA lpcs)
Definition: listbox.c:1360
uint32_t ULONG_PTR
Definition: typedefs.h:63
int cbWndExtra
Definition: winuser.h:3141
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define LB_RESETCONTENT
Definition: winuser.h:2037
LONG WINAPI GetWindowLongA(_In_ HWND, _In_ int)
static BOOL RegisterListboxWindowClass(HINSTANCE hInst)
Definition: listbox.c:1400
#define LB_ERR
Definition: winuser.h:2407
#define LBS_NOINTEGRALHEIGHT
Definition: pedump.c:686
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
static UINT WPARAM LPARAM lparam
Definition: combo.c:716
#define listbox_ok(t, s, got)
Definition: listbox.c:137
#define GENERIC_WRITE
Definition: nt_native.h:90
HWND WINAPI GetCapture(void)
Definition: message.c:2879
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
static void test_WM_MEASUREITEM(void)
Definition: listbox.c:2228
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4290
HCURSOR hCursor
Definition: winuser.h:3144
#define CW_USEDEFAULT
Definition: winuser.h:225
#define GWLP_USERDATA
Definition: treelist.c:63
BOOL WINAPI IsRectEmpty(_In_ LPCRECT)
static HWND g_label
Definition: listbox.c:1355
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
smooth NULL
Definition: ftsmooth.c:416
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:652
static int strcmp_aw(LPCWSTR strw, const char *stra)
Definition: listbox.c:49
static void test_LB_SETSEL(void)
Definition: listbox.c:575
#define WM_KEYDOWN
Definition: winuser.h:1697
LONG_PTR LPARAM
Definition: windef.h:208
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
static void test_set_count(void)
Definition: listbox.c:1860
#define MS
Definition: i386-dis.c:442
Definition: general.c:220
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
BOOL WINAPI GetTextMetricsA(_In_ HDC, _Out_ LPTEXTMETRICA)
Definition: text.c:200
const char * LPCSTR
Definition: xmlstorage.h:183
static void test_extents(void)
Definition: listbox.c:2048
static void test_GetListBoxInfo(void)
Definition: listbox.c:1932
#define LB_GETTEXTLEN
Definition: winuser.h:2032
#define SW_SHOW
Definition: winuser.h:769
BOOL WINAPI DlgDirSelectExA(_In_ HWND hwndDlg, _Out_writes_(chCount) LPSTR lpString, _In_ int chCount, _In_ int idListBox)
static HWND create_parent(void)
Definition: listbox.c:310
#define LB_GETCOUNT
Definition: winuser.h:2020
#define WM_SETTEXT
Definition: winuser.h:1599
#define LB_INITSTORAGE
Definition: winuser.h:2034
#define WM_DESTROY
Definition: winuser.h:1591
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define GetWindowLongPtrA
Definition: winuser.h:4803
static void test_listbox_height(void)
Definition: listbox.c:629
#define WAIT
Definition: listbox.c:36
int selected
Definition: listbox.c:162
static void test_init_storage(void)
Definition: listbox.c:1962
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:403
#define trace
Definition: atltest.h:70
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define LB_SETTOPINDEX
Definition: winuser.h:2052
static void test_listbox_LB_DIR(void)
Definition: listbox.c:905
r parent
Definition: btrfs.c:2869
int selcount
Definition: listbox.c:162
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define LB_OKAY
Definition: winuser.h:2406
int WINAPI GetScrollPos(_In_ HWND, _In_ int)
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:6
const char file[]
Definition: icontest.c:11
#define LB_SELITEMRANGE
Definition: winuser.h:2039
BOOL WINAPI ValidateRect(_In_opt_ HWND, _In_opt_ LPCRECT)
#define WM_KEYUP
Definition: winuser.h:1698
const char * wine_dbgstr_rect(const RECT *rect)
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
static void test_changing_selection_styles(void)
Definition: listbox.c:668
#define WM_MEASUREITEM
Definition: winuser.h:1628
static HWND g_listBox
Definition: listbox.c:1354
int WINAPI GetClipBox(_In_ HDC, _Out_ LPRECT)
#define SetLastError(x)
Definition: compat.h:417
#define LB_SETITEMDATA
Definition: winuser.h:2047
#define OBJ_FONT
Definition: objidl.idl:1414
static int got_selchange
Definition: listbox.c:241
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
struct _test_info results[8]
Definition: SetCursorPos.c:29
#define WS_HSCROLL
Definition: pedump.c:628
static void test_ownerdraw(void)
Definition: listbox.c:339
BOOL WINAPI GetScrollInfo(_In_ HWND, _In_ int, _Inout_ LPSCROLLINFO)
static void test_missing_lbuttonup(void)
Definition: listbox.c:2025
int ret
GLsizei const GLchar *const * strings
Definition: glext.h:7622
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
HWND WINAPI GetWindow(_In_ HWND, _In_ UINT)
#define LB_GETTEXT
Definition: winuser.h:2031
#define todo_wine
Definition: test.h:163
HDC hdc
Definition: main.c:9
#define DDL_DRIVES
Definition: winuser.h:425
BOOL WINAPI GetUpdateRect(_In_ HWND, _Out_opt_ LPRECT, _In_ BOOL)
BOOL WINAPI SetCurrentDirectoryA(IN LPCSTR lpPathName)
Definition: path.c:2205
#define SetWindowLongPtrA
Definition: winuser.h:5320
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:821
unsigned char BYTE
Definition: mem.h:68
#define LRESULT
Definition: ole.h:14
#define ID_TEST_LABEL
Definition: listbox.c:1357
Definition: _list.h:228
#define GENERIC_READ
Definition: compat.h:124
#define WS_TABSTOP
Definition: pedump.c:634
Definition: time.h:76
#define WM_COMMAND
Definition: winuser.h:1722
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
LPCSTR lpszClassName
Definition: winuser.h:3147
DWORD add_style
Definition: listbox.c:157
static void keypress(HWND handle, WPARAM keycode, BYTE scancode, BOOL extended)
Definition: listbox.c:120
BOOL WINAPI MoveWindow(_In_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ BOOL)
#define LB_GETITEMHEIGHT
Definition: winuser.h:2024
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2059
static void test_LB_SETCURSEL(void)
Definition: listbox.c:497
#define GWLP_WNDPROC
Definition: treelist.c:66
#define broken(x)
Definition: _sntprintf.h:21
int anchor
Definition: listbox.c:162
UINT style
Definition: winuser.h:3138
struct listbox_stat step step_todo
Definition: listbox.c:169
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2881
#define GWL_STYLE
Definition: winuser.h:846
HWND hList
Definition: livecd.c:10
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define DCX_CACHE
Definition: winuser.h:2096
#define LB_FINDSTRING
Definition: winuser.h:2016
HINSTANCE hInst
Definition: dxdiag.c:13
#define WS_BORDER
Definition: pedump.c:625
#define LB_ITEMFROMPOINT
Definition: winuser.h:2036
BOOL WINAPI EqualRect(_In_ LPCRECT, _In_ LPCRECT)
#define LB_SETCOUNT
Definition: winuser.h:2044
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2053
HINSTANCE hInstance
Definition: winuser.h:3142
#define LBS_DISABLENOSCROLL
Definition: pedump.c:690
#define ARRAY_SIZE(a)
Definition: main.h:24
#define LB_GETTOPINDEX
Definition: winuser.h:2033
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define ok(value,...)
Definition: atltest.h:57
#define WM_LBUTTONUP
Definition: winuser.h:1759
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2145
#define LB_GETCARETINDEX
Definition: winuser.h:2019
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714
#define list
Definition: rosglue.h:35
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define WS_POPUP
Definition: pedump.c:616
#define LB_GETCURSEL
Definition: winuser.h:2021
unsigned int UINT
Definition: ndis.h:50
#define WS_VSCROLL
Definition: pedump.c:627
LONG WINAPI SetWindowLongA(_In_ HWND, _In_ int, _In_ LONG)
int WINAPI DlgDirListA(_In_ HWND, _Inout_ LPSTR, _In_ int, _In_ int, _In_ UINT)
#define lstrcpynA
Definition: compat.h:416
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
#define KEYEVENTF_EXTENDEDKEY
Definition: winuser.h:1091
#define MultiByteToWideChar
Definition: compat.h:100
#define WM_SETFONT
Definition: winuser.h:1632
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define LBS_OWNERDRAWVARIABLE
Definition: pedump.c:683
WNDPROC lpfnWndProc
Definition: winuser.h:3139
#define ODT_LISTBOX
Definition: winuser.h:2513
#define WM_DRAWITEM
Definition: winuser.h:1627
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
#define LB_GETLISTBOXINFO
Definition: winuser.h:2026
#define msg(x)
Definition: auth_time.c:54
#define IDC_ARROW
Definition: winuser.h:682
static int lb_getlistboxinfo
Definition: listbox.c:1920
#define SS(fs)
Definition: ff.c:54
#define WM_CREATE
Definition: winuser.h:1590
GLuint res
Definition: glext.h:9613
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
#define HIWORD(l)
Definition: typedefs.h:246
unsigned int ULONG
Definition: retypes.h:1
GLenum GLuint id
Definition: glext.h:5579
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
BOOL WINAPI SetForegroundWindow(_In_ HWND)
#define GetProcAddress(x, y)
Definition: compat.h:418
#define SWP_NOMOVE
Definition: winuser.h:1229
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define LB_GETITEMRECT
Definition: winuser.h:2025
#define REDRAW
Definition: listbox.c:37
#define CREATE_NEW
Definition: disk.h:69
#define LBS_NOSEL
Definition: winuser.h:316
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:407
GLfloat GLfloat p
Definition: glext.h:8902
LONG_PTR LRESULT
Definition: windef.h:209
#define listbox_test_query(exp, got)
Definition: listbox.c:411
#define ERROR_NO_WILDCARD_CHARACTERS
Definition: winerror.h:898
Arabic default style
Definition: afstyles.h:93
#define LB_DELETESTRING
Definition: winuser.h:2014
#define WS_VISIBLE
Definition: pedump.c:620
GLuint64EXT * result
Definition: glext.h:11304
#define memset(x, y, z)
Definition: compat.h:39
static const char * strw(LPCWSTR x)
Definition: actctx.c:49
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
#define win_skip
Definition: test.h:150
#define LB_INSERTSTRING
Definition: winuser.h:2035
LPARAM lParam
Definition: combotst.c:139
int k
Definition: mpi.c:3369
struct listbox_stat click click_todo
Definition: listbox.c:168
#define HeapFree(x, y, z)
Definition: compat.h:402
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
HGDIOBJ WINAPI GetCurrentObject(_In_ HDC, _In_ UINT)
Definition: dc.c:439
struct listbox_stat init init_todo
Definition: listbox.c:167
#define DDL_EXCLUSIVE
Definition: winuser.h:426
static UINT WPARAM wparam
Definition: combo.c:716
#define LBS_MULTIPLESEL
Definition: pedump.c:681
static void check_item_height(void)
Definition: listbox.c:209
static void test_LBS_NODATA(void)
Definition: listbox.c:2248
HICON hIcon
Definition: winuser.h:3143
Definition: fci.c:126