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