ReactOS  0.4.13-dev-99-g7e18b6d
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 <stdarg.h>
21 #include <stdio.h>
22 
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wingdi.h"
26 #include "winuser.h"
27 #include "winnls.h"
28 #include "commctrl.h"
29 
30 #include "wine/heap.h"
31 #include "wine/test.h"
32 #include "v6util.h"
33 #include "msg.h"
34 
36 {
40 };
41 
43 
44 /* encoded MEASUREITEMSTRUCT into a WPARAM */
45 typedef struct
46 {
47  union
48  {
49  struct
50  {
52  UINT CtlID : 4;
53  UINT itemID : 4;
54  UINT wParam : 20;
55  } item;
57  } u;
59 
60 static unsigned hash_Ly_W(const WCHAR *str)
61 {
62  unsigned hash = 0;
63 
64  for (; *str; str++)
65  hash = hash * 1664525u + (unsigned char)(*str) + 1013904223u;
66 
67  return hash;
68 }
69 
70 static unsigned hash_Ly(const char *str)
71 {
72  unsigned hash = 0;
73 
74  for (; *str; str++)
75  hash = hash * 1664525u + (unsigned char)(*str) + 1013904223u;
76 
77  return hash;
78 }
79 
80 static const char * const strings[4] = {
81  "First added",
82  "Second added",
83  "Third added",
84  "Fourth added which is very long because at some time we only had a 256 byte character buffer and "
85  "that was overflowing in one of those applications that had a common dialog file open box and tried "
86  "to add a 300 characters long custom filter string which of course the code did not like and crashed. "
87  "Just make sure this string is longer than 256 characters."
88 };
89 
90 static const char BAD_EXTENSION[] = "*.badtxt";
91 
92 #define ID_LISTBOX 1
93 
95 {
97  static LONG defwndproc_counter = 0;
98  struct message msg = { 0 };
99  LRESULT ret;
100 
101  switch (message)
102  {
103  case WM_SIZE:
104  case WM_GETTEXT:
105  case WM_PAINT:
106  case WM_ERASEBKGND:
108  case WM_WINDOWPOSCHANGED:
109  case WM_NCCALCSIZE:
110  case WM_NCPAINT:
111  case WM_NCHITTEST:
112  case WM_DEVICECHANGE:
113  break;
114 
115  default:
116  msg.message = message;
117  msg.flags = sent|wparam|lparam;
118  if (defwndproc_counter) msg.flags |= defwinproc;
119  msg.wParam = wParam;
120  msg.lParam = lParam;
122  }
123 
124  defwndproc_counter++;
125  ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
126  defwndproc_counter--;
127 
128  return ret;
129 }
130 
131 static HWND create_listbox(DWORD add_style, HWND parent)
132 {
133  INT_PTR ctl_id = 0;
134  WNDPROC oldproc;
135  HWND handle;
136 
137  if (parent)
138  ctl_id = ID_LISTBOX;
139 
140  handle = CreateWindowA(WC_LISTBOXA, "TestList", (LBS_STANDARD & ~LBS_SORT) | add_style, 0, 0, 100, 100,
141  parent, (HMENU)ctl_id, NULL, 0);
142  ok(handle != NULL, "Failed to create listbox window.\n");
143 
148 
151 
152  return handle;
153 }
154 
156 {
158 };
159 
161 {
163 };
164 
166 {
168  struct listbox_stat click, click_todo;
169  struct listbox_stat step, step_todo;
170  struct listbox_stat sel, sel_todo;
171 };
172 
174 {
175  results->selected = SendMessageA(handle, LB_GETCURSEL, 0, 0);
176  results->anchor = SendMessageA(handle, LB_GETANCHORINDEX, 0, 0);
177  results->caret = SendMessageA(handle, LB_GETCARETINDEX, 0, 0);
178  results->selcount = SendMessageA(handle, LB_GETSELCOUNT, 0, 0);
179 }
180 
182 {
183  LPARAM lp = x + (y << 16);
184 
187 }
188 
189 static void keypress(HWND handle, WPARAM keycode, BYTE scancode, BOOL extended)
190 {
191  LPARAM lp = 1 + (scancode << 16) + (extended ? KEYEVENTF_EXTENDEDKEY : 0);
192 
193  SendMessageA(handle, WM_KEYDOWN, keycode, lp);
194  SendMessageA(handle, WM_KEYUP , keycode, lp | 0xc000000);
195 }
196 
197 #define listbox_field_ok(t, s, f, got) \
198  ok (t.s.f==got.f, "style %#x, step " #s ", field " #f \
199  ": expected %d, got %d\n", style, t.s.f, got.f)
200 
201 #define listbox_todo_field_ok(t, s, f, got) \
202  todo_wine_if (t.s##_todo.f) { listbox_field_ok(t, s, f, got); }
203 
204 #define listbox_ok(t, s, got) \
205  listbox_todo_field_ok(t, s, selected, got); \
206  listbox_todo_field_ok(t, s, anchor, got); \
207  listbox_todo_field_ok(t, s, caret, got); \
208  listbox_todo_field_ok(t, s, selcount, got)
209 
210 static void run_test(DWORD style, const struct listbox_test test)
211 {
212  static const struct message delete_seq[] =
213  {
214  { LB_DELETESTRING, sent|wparam|lparam, 0, 0 },
215  { LB_DELETESTRING, sent|wparam|lparam, 0, 0 },
216  { LB_DELETESTRING, sent|wparam|lparam, 0, 0 },
217  { LB_DELETESTRING, sent|wparam|lparam, 0, 0 },
219  { 0 }
220  };
221  struct listbox_stat answer;
222  int i, res, count;
223  RECT second_item;
224  HWND hLB;
225 
226  hLB = create_listbox (style, 0);
227 
228  listbox_query (hLB, &answer);
229  listbox_ok (test, init, answer);
230 
231  SendMessageA(hLB, LB_GETITEMRECT, 1, (LPARAM) &second_item);
232  buttonpress(hLB, (WORD)second_item.left, (WORD)second_item.top);
233 
234  listbox_query(hLB, &answer);
235  listbox_ok(test, click, answer);
236 
237  keypress(hLB, VK_DOWN, 0x50, TRUE);
238 
239  listbox_query(hLB, &answer);
240  listbox_ok(test, step, answer);
241 
242  DestroyWindow(hLB);
243 
244  hLB = create_listbox(style, 0);
245 
247  listbox_query(hLB, &answer);
248  listbox_ok(test, sel, answer);
249 
250  for (i = 0; i < 4 && !(style & LBS_NODATA); i++)
251  {
252  DWORD size = SendMessageA(hLB, LB_GETTEXTLEN, i, 0);
253  int resA, resW;
254  WCHAR *txtw;
255  CHAR *txt;
256 
257  txt = heap_alloc_zero(size + 1);
258  resA = SendMessageA(hLB, LB_GETTEXT, i, (LPARAM)txt);
259  ok(!strcmp(txt, strings[i]), "returned string for item %d does not match %s vs %s\n", i, txt, strings[i]);
260 
261  txtw = heap_alloc_zero((size + 1) * sizeof(*txtw));
262  resW = SendMessageW(hLB, LB_GETTEXT, i, (LPARAM)txtw);
263  ok(resA == resW, "Unexpected text length.\n");
264  WideCharToMultiByte(CP_ACP, 0, txtw, -1, txt, size, NULL, NULL);
265  ok(!strcmp (txt, strings[i]), "Unexpected string for item %d, %s vs %s.\n", i, txt, strings[i]);
266 
267  heap_free(txtw);
268  heap_free(txt);
269  }
270 
271  /* Confirm the count of items, and that an invalid delete does not remove anything */
272  res = SendMessageA(hLB, LB_GETCOUNT, 0, 0);
273  ok(res == 4, "Expected 4 items, got %d\n", res);
274  res = SendMessageA(hLB, LB_DELETESTRING, -1, 0);
275  ok(res == LB_ERR, "Expected LB_ERR items, got %d\n", res);
276  res = SendMessageA(hLB, LB_DELETESTRING, 4, 0);
277  ok(res == LB_ERR, "Expected LB_ERR items, got %d\n", res);
278  count = SendMessageA(hLB, LB_GETCOUNT, 0, 0);
279  ok(count == 4, "Unexpected item count %d.\n", count);
280 
281  /* Emptying listbox sends a LB_RESETCONTENT to itself. */
283  for (i = count; i--;)
284  {
285  res = SendMessageA(hLB, LB_DELETESTRING, 0, 0);
286  ok(res == i, "Unexpected return value %d.\n", res);
287  }
288  ok_sequence(sequences, LB_SEQ_INDEX, delete_seq, "Emptying listbox", FALSE);
289 
290  DestroyWindow(hLB);
291 }
292 
293 static void test_item_height(void)
294 {
295  INT itemHeight;
296  TEXTMETRICA tm;
297  HFONT font;
298  HWND hLB;
299  HDC hdc;
300 
301  hLB = create_listbox (0, 0);
302  ok ((hdc = GetDCEx( hLB, 0, DCX_CACHE )) != 0, "Can't get hdc\n");
303  ok ((font = GetCurrentObject(hdc, OBJ_FONT)) != 0, "Can't get the current font\n");
304  ok (GetTextMetricsA( hdc, &tm ), "Can't read font metrics\n");
305  ReleaseDC( hLB, hdc);
306 
307  ok (SendMessageA(hLB, WM_SETFONT, (WPARAM)font, 0) == 0, "Can't set font\n");
308 
309  itemHeight = SendMessageA(hLB, LB_GETITEMHEIGHT, 0, 0);
310  ok (itemHeight == tm.tmHeight, "Item height wrong, got %d, expecting %d\n", itemHeight, tm.tmHeight);
311 
312  DestroyWindow (hLB);
313 
314  hLB = CreateWindowA(WC_LISTBOXA, "TestList", LBS_OWNERDRAWVARIABLE, 0, 0, 100, 100, NULL, NULL, NULL, 0);
315 
316  itemHeight = SendMessageA(hLB, LB_GETITEMHEIGHT, 0, 0);
317  ok(itemHeight > 0 && itemHeight <= tm.tmHeight, "Unexpected item height %d, expected %d.\n",
318  itemHeight, tm.tmHeight);
319  itemHeight = SendMessageA(hLB, LB_GETITEMHEIGHT, 5, 0);
320  ok(itemHeight > 0 && itemHeight <= tm.tmHeight, "Unexpected item height %d, expected %d.\n",
321  itemHeight, tm.tmHeight);
322  itemHeight = SendMessageA(hLB, LB_GETITEMHEIGHT, -5, 0);
323  ok(itemHeight > 0 && itemHeight <= tm.tmHeight, "Unexpected item height %d, expected %d.\n",
324  itemHeight, tm.tmHeight);
325 
326  DestroyWindow (hLB);
327 }
328 
329 static int got_selchange;
330 
332 {
333  static LONG defwndproc_counter = 0;
334  struct message m = { 0 };
335  LRESULT ret;
336 
337  m.message = msg;
338  m.flags = sent|wparam|lparam;
339  if (defwndproc_counter) m.flags |= defwinproc;
340  m.wParam = wParam;
341  m.lParam = lParam;
342 
343  switch (msg)
344  {
345  case WM_MEASUREITEM:
346  {
347  MEASUREITEMSTRUCT *mis = (void *)lParam;
348  BOOL is_unicode_data = FALSE;
350 
351  if (mis->CtlType == ODT_LISTBOX)
352  {
353  HWND ctrl = GetDlgItem(hwnd, mis->CtlID);
354  is_unicode_data = GetWindowLongA(ctrl, GWL_STYLE) & LBS_HASSTRINGS;
355  }
356 
357  mi.u.wp = 0;
358  mi.u.item.CtlType = mis->CtlType;
359  mi.u.item.CtlID = mis->CtlID;
360  mi.u.item.itemID = mis->itemID;
361  mi.u.item.wParam = wParam;
362 
363  m.wParam = mi.u.wp;
364  if (is_unicode_data)
365  m.lParam = mis->itemData ? hash_Ly_W((const WCHAR *)mis->itemData) : 0;
366  else
367  m.lParam = mis->itemData ? hash_Ly((const char *)mis->itemData) : 0;
369 
370  ok(wParam == mis->CtlID, "got wParam=%08lx, expected %08x\n", wParam, mis->CtlID);
371  ok(mis->CtlType == ODT_LISTBOX, "mi->CtlType = %u\n", mis->CtlType);
372  ok(mis->CtlID == 1, "mi->CtlID = %u\n", mis->CtlID);
373  ok(mis->itemHeight, "mi->itemHeight = 0\n");
374 
375  break;
376  }
377  case WM_COMPAREITEM:
378  {
380  HWND ctrl = GetDlgItem(hwnd, cis->CtlID);
381  BOOL is_unicode_data = TRUE;
382 
383  ok(wParam == cis->CtlID, "expected %#x, got %#lx\n", cis->CtlID, wParam);
384  ok(cis->hwndItem == ctrl, "expected %p, got %p\n", ctrl, cis->hwndItem);
385  ok((int)cis->itemID1 >= 0, "expected >= 0, got %d\n", cis->itemID1);
386  ok((int)cis->itemID2 == -1, "expected -1, got %d\n", cis->itemID2);
387 
388  if (cis->CtlType == ODT_LISTBOX)
389  is_unicode_data = GetWindowLongA(ctrl, GWL_STYLE) & LBS_HASSTRINGS;
390 
391  if (is_unicode_data)
392  {
393  m.wParam = cis->itemData1 ? hash_Ly_W((const WCHAR *)cis->itemData1) : 0;
394  m.lParam = cis->itemData2 ? hash_Ly_W((const WCHAR *)cis->itemData2) : 0;
395  }
396  else
397  {
398  m.wParam = cis->itemData1 ? hash_Ly((const char *)cis->itemData1) : 0;
399  m.lParam = cis->itemData2 ? hash_Ly((const char *)cis->itemData2) : 0;
400  }
402  break;
403  }
404  case WM_DRAWITEM:
405  {
406  RECT rc_item, rc_client, rc_clip;
408 
409  ok(wParam == dis->CtlID, "got wParam=%08lx instead of %08x\n", wParam, dis->CtlID);
410  ok(dis->CtlType == ODT_LISTBOX, "wrong CtlType %04x\n", dis->CtlType);
411 
412  GetClientRect(dis->hwndItem, &rc_client);
413  GetClipBox(dis->hDC, &rc_clip);
414  ok(EqualRect(&rc_client, &rc_clip) || IsRectEmpty(&rc_clip),
415  "client rect of the listbox should be equal to the clip box,"
416  "or the clip box should be empty\n");
417 
418  SendMessageA(dis->hwndItem, LB_GETITEMRECT, dis->itemID, (LPARAM)&rc_item);
419  ok(EqualRect(&dis->rcItem, &rc_item), "item rects are not equal\n");
420 
421  break;
422  }
423 
424  case WM_COMMAND:
426  break;
427 
428  default:
429  break;
430  }
431 
432  defwndproc_counter++;
434  defwndproc_counter--;
435 
436  return msg == WM_COMPAREITEM ? -1 : ret;
437 }
438 
439 static HWND create_parent( void )
440 {
441  static ATOM class;
442  WNDCLASSA cls;
443 
444  if (!class)
445  {
446  cls.style = 0;
448  cls.cbClsExtra = 0;
449  cls.cbWndExtra = 0;
451  cls.hIcon = 0;
452  cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
454  cls.lpszMenuName = NULL;
455  cls.lpszClassName = "main_window_class";
456  class = RegisterClassA( &cls );
457  }
458 
459  return CreateWindowExA(0, "main_window_class", NULL, WS_POPUP | WS_VISIBLE, 100, 100, 400, 400, GetDesktopWindow(),
460  0, GetModuleHandleA(NULL), NULL);
461 }
462 
463 static void test_ownerdraw(void)
464 {
465  static const DWORD styles[] =
466  {
467  0,
468  LBS_NODATA
469  };
470  HWND parent, hLB;
471  INT ret;
472  RECT rc;
473  UINT i;
474 
475  parent = create_parent();
476  ok(parent != NULL, "Failed to create parent window.\n");
477 
478  for (i = 0; i < ARRAY_SIZE(styles); i++)
479  {
481  ok(hLB != NULL, "Failed to create listbox window.\n");
482 
483  SetForegroundWindow(hLB);
484  UpdateWindow(hLB);
485 
486  /* make height short enough */
487  SendMessageA(hLB, LB_GETITEMRECT, 0, (LPARAM)&rc);
488  SetWindowPos(hLB, 0, 0, 0, 100, rc.bottom - rc.top + 1, SWP_NOZORDER | SWP_NOMOVE);
489 
490  /* make 0 item invisible */
491  SendMessageA(hLB, LB_SETTOPINDEX, 1, 0);
492  ret = SendMessageA(hLB, LB_GETTOPINDEX, 0, 0);
493  ok(ret == 1, "wrong top index %d\n", ret);
494 
495  SendMessageA(hLB, LB_GETITEMRECT, 0, (LPARAM)&rc);
496  ok(!IsRectEmpty(&rc), "empty item rect\n");
497  ok(rc.top < 0, "rc.top is not negative (%d)\n", rc.top);
498 
499  DestroyWindow(hLB);
500 
501  /* Both FIXED and VARIABLE, FIXED should override VARIABLE. */
502  hLB = CreateWindowA(WC_LISTBOXA, "TestList", LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE | styles[i],
503  0, 0, 100, 100, NULL, NULL, NULL, 0);
504  ok(hLB != NULL, "last error 0x%08x\n", GetLastError());
505 
506  ok(GetWindowLongA(hLB, GWL_STYLE) & LBS_OWNERDRAWVARIABLE, "Unexpected window style.\n");
507 
508  ret = SendMessageA(hLB, LB_INSERTSTRING, -1, 0);
509  ok(ret == 0, "Unexpected return value %d.\n", ret);
510  ret = SendMessageA(hLB, LB_INSERTSTRING, -1, 0);
511  ok(ret == 1, "Unexpected return value %d.\n", ret);
512 
513  ret = SendMessageA(hLB, LB_SETITEMHEIGHT, 0, 13);
514  ok(ret == LB_OKAY, "Failed to set item height, %d.\n", ret);
515 
516  ret = SendMessageA(hLB, LB_GETITEMHEIGHT, 0, 0);
517  ok(ret == 13, "Unexpected item height %d.\n", ret);
518 
519  ret = SendMessageA(hLB, LB_SETITEMHEIGHT, 1, 42);
520  ok(ret == LB_OKAY, "Failed to set item height, %d.\n", ret);
521 
522  ret = SendMessageA(hLB, LB_GETITEMHEIGHT, 0, 0);
523  ok(ret == 42, "Unexpected item height %d.\n", ret);
524 
525  ret = SendMessageA(hLB, LB_GETITEMHEIGHT, 1, 0);
526  ok(ret == 42, "Unexpected item height %d.\n", ret);
527 
528  DestroyWindow (hLB);
529  }
530 
532 }
533 
534 #define listbox_test_query(exp, got) \
535  ok(exp.selected == got.selected, "expected selected %d, got %d\n", exp.selected, got.selected); \
536  ok(exp.anchor == got.anchor, "expected anchor %d, got %d\n", exp.anchor, got.anchor); \
537  ok(exp.caret == got.caret, "expected caret %d, got %d\n", exp.caret, got.caret); \
538  ok(exp.selcount == got.selcount, "expected selcount %d, got %d\n", exp.selcount, got.selcount);
539 
540 static void test_LB_SELITEMRANGE(void)
541 {
542  static const struct listbox_stat test_nosel = { 0, LB_ERR, 0, 0 };
543  static const struct listbox_stat test_1 = { 0, LB_ERR, 0, 2 };
544  static const struct listbox_stat test_2 = { 0, LB_ERR, 0, 3 };
545  static const struct listbox_stat test_3 = { 0, LB_ERR, 0, 4 };
546  struct listbox_stat answer;
547  HWND hLB;
548  INT ret;
549 
551  ok(hLB != NULL, "Failed to create listbox window.\n");
552 
553  listbox_query(hLB, &answer);
554  listbox_test_query(test_nosel, answer);
555 
557  ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
558  listbox_query(hLB, &answer);
559  listbox_test_query(test_1, answer);
560 
561  SendMessageA(hLB, LB_SETSEL, FALSE, -1);
562  listbox_query(hLB, &answer);
563  listbox_test_query(test_nosel, answer);
564 
566  ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
567  listbox_query(hLB, &answer);
568  listbox_test_query(test_3, answer);
569 
570  SendMessageA(hLB, LB_SETSEL, FALSE, -1);
571  listbox_query(hLB, &answer);
572  listbox_test_query(test_nosel, answer);
573 
575  ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
576  listbox_query(hLB, &answer);
577  listbox_test_query(test_nosel, answer);
578 
579  SendMessageA(hLB, LB_SETSEL, FALSE, -1);
580  listbox_query(hLB, &answer);
581  listbox_test_query(test_nosel, answer);
582 
584  ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
585  listbox_query(hLB, &answer);
586  listbox_test_query(test_1, answer);
587 
588  SendMessageA(hLB, LB_SETSEL, FALSE, -1);
589  listbox_query(hLB, &answer);
590  listbox_test_query(test_nosel, answer);
591 
593  ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
594  listbox_query(hLB, &answer);
595  listbox_test_query(test_nosel, answer);
596 
597  SendMessageA(hLB, LB_SETSEL, FALSE, -1);
598  listbox_query(hLB, &answer);
599  listbox_test_query(test_nosel, answer);
600 
602  ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
603  listbox_query(hLB, &answer);
604  listbox_test_query(test_2, answer);
605 
606  SendMessageA(hLB, LB_SETSEL, FALSE, -1);
607  listbox_query(hLB, &answer);
608  listbox_test_query(test_nosel, answer);
609 
611  ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
612  listbox_query(hLB, &answer);
613  listbox_test_query(test_2, answer);
614 
615  DestroyWindow(hLB);
616 }
617 
618 static void test_LB_SETCURSEL(void)
619 {
620  HWND parent, hLB;
621  INT ret;
622 
623  parent = create_parent();
624  ok(parent != NULL, "Failed to create parent window.\n");
625 
627  ok(hLB != NULL, "Failed to create listbox.\n");
628 
629  SendMessageA(hLB, LB_SETITEMHEIGHT, 0, 32);
630 
631  ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
632  ok(ret == -1, "Unexpected anchor index %d.\n", ret);
633 
634  ret = SendMessageA(hLB, LB_SETCURSEL, 2, 0);
635  ok(ret == 2, "LB_SETCURSEL returned %d instead of 2\n", ret);
636  ret = GetScrollPos(hLB, SB_VERT);
637  ok(ret == 0, "expected vscroll 0, got %d\n", ret);
638 
639  ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
640  ok(ret == -1, "Unexpected anchor index %d.\n", ret);
641 
642  ret = SendMessageA(hLB, LB_SETCURSEL, 3, 0);
643  ok(ret == 3, "LB_SETCURSEL returned %d instead of 3\n", ret);
644  ret = GetScrollPos(hLB, SB_VERT);
645  ok(ret == 1, "expected vscroll 1, got %d\n", ret);
646 
647  ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
648  ok(ret == -1, "Unexpected anchor index %d.\n", ret);
649 
650  DestroyWindow(hLB);
651 
652  hLB = create_listbox(0, 0);
653  ok(hLB != NULL, "Failed to create ListBox window.\n");
654 
655  ret = SendMessageA(hLB, LB_SETCURSEL, 1, 0);
656  ok(ret == 1, "Unexpected return value %d.\n", ret);
657 
658  ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
659  ok(ret == -1, "Unexpected anchor index %d.\n", ret);
660 
661  DestroyWindow(hLB);
662 
663  /* LBS_EXTENDEDSEL */
665  ok(hLB != NULL, "Failed to create listbox.\n");
666 
667  ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
668  ok(ret == -1, "Unexpected anchor index %d.\n", ret);
669 
670  ret = SendMessageA(hLB, LB_SETCURSEL, 2, 0);
671  ok(ret == -1, "LB_SETCURSEL returned %d instead of 2\n", ret);
672 
673  ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
674  ok(ret == -1, "Unexpected anchor index %d.\n", ret);
675 
676  DestroyWindow(hLB);
677 
678  /* LBS_MULTIPLESEL */
680  ok(hLB != NULL, "Failed to create listbox.\n");
681 
682  ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
683  ok(ret == -1, "Unexpected anchor index %d.\n", ret);
684 
685  ret = SendMessageA(hLB, LB_SETCURSEL, 2, 0);
686  ok(ret == -1, "LB_SETCURSEL returned %d instead of 2\n", ret);
687 
688  ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
689  ok(ret == -1, "Unexpected anchor index %d.\n", ret);
690 
691  DestroyWindow(hLB);
692 }
693 
694 static void test_LB_SETSEL(void)
695 {
696  HWND list;
697  int ret;
698 
699  /* LBS_EXTENDEDSEL */
701  ok(list != NULL, "Failed to create ListBox window.\n");
702 
704  ok(ret == -1, "Unexpected anchor index %d.\n", ret);
705 
707  ok(ret == 0, "Unexpected return value %d.\n", ret);
709  ok(ret == 0, "Unexpected anchor index %d.\n", ret);
710 
712  ok(ret == 0, "Unexpected return value %d.\n", ret);
714  ok(ret == 1, "Unexpected anchor index %d.\n", ret);
715 
717  ok(ret == 0, "Unexpected return value %d.\n", ret);
719  ok(ret == 1, "Unexpected anchor index %d.\n", ret);
720 
722 
723  /* LBS_MULTIPLESEL */
725  ok(list != NULL, "Failed to create ListBox window.\n");
726 
728  ok(ret == -1, "Unexpected anchor index %d.\n", ret);
729 
731  ok(ret == 0, "Unexpected return value %d.\n", ret);
733  ok(ret == 0, "Unexpected anchor index %d.\n", ret);
734 
736  ok(ret == 0, "Unexpected return value %d.\n", ret);
738  ok(ret == 1, "Unexpected anchor index %d.\n", ret);
739 
741  ok(ret == 0, "Unexpected return value %d.\n", ret);
743  ok(ret == 1, "Unexpected anchor index %d.\n", ret);
744 
746 }
747 
748 static void test_listbox_height(void)
749 {
750  HWND hList;
751  int r, id;
752 
753  hList = CreateWindowA( WC_LISTBOXA, "list test", 0,
754  1, 1, 600, 100, NULL, NULL, NULL, NULL );
755  ok( hList != NULL, "failed to create listbox\n");
756 
757  id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi");
758  ok( id == 0, "item id wrong\n");
759 
760  r = SendMessageA( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 20, 0 ));
761  ok( r == 0, "send message failed\n");
762 
764  ok( r == 20, "height wrong\n");
765 
766  r = SendMessageA( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 0, 30 ));
767  ok( r == -1, "send message failed\n");
768 
770  ok( r == 20, "height wrong\n");
771 
772  r = SendMessageA( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 256, 0 ));
773  ok( r == -1, "Failed to set item height, %d.\n", r);
774 
776  ok( r == 20, "Unexpected item height %d.\n", r);
777 
778  r = SendMessageA( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 0xff, 0 ));
779  ok( r == 0, "send message failed\n");
780 
782  ok( r == 0xff, "height wrong\n");
783 
784  DestroyWindow( hList );
785 }
786 
787 static void test_itemfrompoint(void)
788 {
789  /* WS_POPUP is required in order to have a more accurate size calculation (
790  without caption). LBS_NOINTEGRALHEIGHT is required in order to test
791  behavior of partially-displayed item.
792  */
793  HWND hList = CreateWindowA( WC_LISTBOXA, "list test",
795  1, 1, 600, 100, NULL, NULL, NULL, NULL );
796  ULONG r, id;
797  RECT rc;
798 
799  r = SendMessageA(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
800  ok( r == MAKELPARAM(0xffff, 1), "Unexpected ret value %#x.\n", r );
801 
802  r = SendMessageA(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( 700, 30 ));
803  ok( r == MAKELPARAM(0xffff, 1), "Unexpected ret value %#x.\n", r );
804 
805  r = SendMessageA(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( 30, 300 ));
806  ok( r == MAKELPARAM(0xffff, 1), "Unexpected ret value %#x.\n", r );
807 
808  id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi");
809  ok( id == 0, "item id wrong\n");
810  id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi1");
811  ok( id == 1, "item id wrong\n");
812 
813  r = SendMessageA(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
814  ok( r == 0x1, "ret %x\n", r );
815 
816  r = SendMessageA(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 601 ));
817  ok( r == MAKELPARAM(1, 1), "Unexpected ret value %#x.\n", r );
818 
819  /* Resize control so that below assertions about sizes are valid */
820  r = SendMessageA( hList, LB_GETITEMRECT, 0, (LPARAM)&rc);
821  ok( r == 1, "ret %x\n", r);
822  r = MoveWindow(hList, 1, 1, 600, (rc.bottom - rc.top + 1) * 9 / 2, TRUE);
823  ok( r != 0, "ret %x\n", r);
824 
825  id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi2");
826  ok( id == 2, "item id wrong\n");
827  id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi3");
828  ok( id == 3, "item id wrong\n");
829  id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi4");
830  ok( id == 4, "item id wrong\n");
831  id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi5");
832  ok( id == 5, "item id wrong\n");
833  id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi6");
834  ok( id == 6, "item id wrong\n");
835  id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi7");
836  ok( id == 7, "item id wrong\n");
837 
838  /* Set the listbox up so that id 1 is at the top, this leaves 5
839  partially visible at the bottom and 6, 7 are invisible */
840 
842  r = SendMessageA( hList, LB_GETTOPINDEX, 0, 0);
843  ok( r == 1, "top %d\n", r);
844 
845  r = SendMessageA( hList, LB_GETITEMRECT, 5, (LPARAM)&rc);
846  ok( r == 1, "ret %x\n", r);
847  r = SendMessageA( hList, LB_GETITEMRECT, 6, (LPARAM)&rc);
848  ok( r == 0, "ret %x\n", r);
849 
850  r = SendMessageA( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(/* x */ 10, /* y */ 10) );
851  ok( r == 1, "ret %x\n", r);
852 
853  r = SendMessageA( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(1000, 10) );
854  ok( r == 0x10001, "ret %x\n", r );
855 
856  r = SendMessageA( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, -10) );
857  ok( r == 0x10001, "ret %x\n", r );
858 
859  r = SendMessageA( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, 100) );
860  ok( r == 0x10005, "item %x\n", r );
861 
862  r = SendMessageA( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, 200) );
863  ok( r == 0x10005, "item %x\n", r );
864 
865  DestroyWindow( hList );
866 }
867 
868 static void test_listbox_item_data(void)
869 {
870  HWND hList;
871  int r, id;
872 
873  hList = CreateWindowA( WC_LISTBOXA, "list test", 0,
874  1, 1, 600, 100, NULL, NULL, NULL, NULL );
875  ok( hList != NULL, "failed to create listbox\n");
876 
877  id = SendMessageA( hList, LB_ADDSTRING, 0, (LPARAM) "hi");
878  ok( id == 0, "item id wrong\n");
879 
880  r = SendMessageA( hList, LB_SETITEMDATA, 0, MAKELPARAM( 20, 0 ));
881  ok(r == TRUE, "LB_SETITEMDATA returned %d instead of TRUE\n", r);
882 
883  r = SendMessageA( hList, LB_GETITEMDATA, 0, 0);
884  ok( r == 20, "get item data failed\n");
885 
886  DestroyWindow( hList );
887 }
888 
889 static void test_listbox_LB_DIR(void)
890 {
891  char path[MAX_PATH], curdir[MAX_PATH];
892  HWND hList;
893  int res, itemCount;
894  int itemCount_justFiles;
895  int itemCount_justDrives;
896  int itemCount_allFiles;
897  int itemCount_allDirs;
898  int i;
899  char pathBuffer[MAX_PATH];
900  char * p;
901  char driveletter;
902  const char *wildcard = "*";
903  HANDLE file;
904  BOOL ret;
905 
906  GetCurrentDirectoryA(ARRAY_SIZE(curdir), curdir);
907 
910  ok(ret, "Failed to set current directory.\n");
911 
912  ret = CreateDirectoryA("lb_dir_test", NULL);
913  ok(ret, "Failed to create test directory.\n");
914 
916  ok(file != INVALID_HANDLE_VALUE, "Error creating the test file: %d\n", GetLastError());
917  CloseHandle( file );
918 
919  /* NOTE: for this test to succeed, there must be no subdirectories
920  under the current directory. In addition, there must be at least
921  one file that fits the wildcard w*.c . Normally, the test
922  directory itself satisfies both conditions.
923  */
925  1, 1, 600, 100, NULL, NULL, NULL, NULL );
926  ok(hList != NULL, "Failed to create listbox window.\n");
927 
928  /* Test for standard usage */
929 
930  /* This should list all the files in the test directory. */
931  strcpy(pathBuffer, wildcard);
934  if (res == -1) /* "*" wildcard doesn't work on win9x */
935  {
936  wildcard = "*.*";
937  strcpy(pathBuffer, wildcard);
939  }
940  ok (res >= 0, "SendMessage(LB_DIR, 0, *) failed - 0x%08x\n", GetLastError());
941 
942  /* There should be some content in the listbox */
943  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
944  ok (itemCount > 0, "SendMessage(LB_DIR) did NOT fill the listbox!\n");
945  itemCount_allFiles = itemCount;
946  ok(res + 1 == itemCount,
947  "SendMessage(LB_DIR, 0, *) returned incorrect index (expected %d got %d)!\n",
948  itemCount - 1, res);
949 
950  /* This tests behavior when no files match the wildcard */
954  ok (res == -1, "SendMessage(LB_DIR, 0, %s) returned %d, expected -1\n", BAD_EXTENSION, res);
955 
956  /* There should be NO content in the listbox */
957  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
958  ok (itemCount == 0, "SendMessage(LB_DIR) DID fill the listbox!\n");
959 
960 
961  /* This should list all the w*.c files in the test directory
962  * As of this writing, this includes win.c, winstation.c, wsprintf.c
963  */
964  strcpy(pathBuffer, "w*.c");
967  ok (res >= 0, "SendMessage(LB_DIR, 0, w*.c) failed - 0x%08x\n", GetLastError());
968 
969  /* Path specification does NOT converted to uppercase */
970  ok (!strcmp(pathBuffer, "w*.c"),
971  "expected no change to pathBuffer, got %s\n", pathBuffer);
972 
973  /* There should be some content in the listbox */
974  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
975  ok (itemCount > 0, "SendMessage(LB_DIR) did NOT fill the listbox!\n");
976  itemCount_justFiles = itemCount;
977  ok(res + 1 == itemCount,
978  "SendMessage(LB_DIR, 0, w*.c) returned incorrect index (expected %d got %d)!\n",
979  itemCount - 1, res);
980 
981  /* Every single item in the control should start with a w and end in .c */
982  for (i = 0; i < itemCount; i++)
983  {
987  ok(((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
988  (*(p-1) == 'c' || *(p-1) == 'C') &&
989  (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
990  }
991 
992  /* Test DDL_DIRECTORY */
993  strcpy(pathBuffer, wildcard);
996  ok (res > 0, "SendMessage(LB_DIR, DDL_DIRECTORY, *) failed - 0x%08x\n", GetLastError());
997 
998  /* There should be some content in the listbox.
999  * All files plus "[..]"
1000  */
1001  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1002  itemCount_allDirs = itemCount - itemCount_allFiles;
1003  ok (itemCount >= itemCount_allFiles,
1004  "SendMessage(LB_DIR, DDL_DIRECTORY, *) filled with %d entries, expected > %d\n",
1005  itemCount, itemCount_allFiles);
1006  ok(res + 1 == itemCount,
1007  "SendMessage(LB_DIR, DDL_DIRECTORY, *) returned incorrect index (expected %d got %d)!\n",
1008  itemCount - 1, res);
1009 
1010  /* This tests behavior when no files match the wildcard */
1014  ok (res == -1, "SendMessage(LB_DIR, DDL_DIRECTORY, %s) returned %d, expected -1\n", BAD_EXTENSION, res);
1015 
1016  /* There should be NO content in the listbox */
1017  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1018  ok (itemCount == 0, "SendMessage(LB_DIR) DID fill the listbox!\n");
1019 
1020  /* Test DDL_DIRECTORY */
1021  strcpy(pathBuffer, "w*.c");
1024  ok (res >= 0, "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) failed - 0x%08x\n", GetLastError());
1025 
1026  /* There should be some content in the listbox. Since the parent directory does not
1027  * fit w*.c, there should be exactly the same number of items as without DDL_DIRECTORY
1028  */
1029  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1030  ok (itemCount == itemCount_justFiles,
1031  "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) filled with %d entries, expected %d\n",
1032  itemCount, itemCount_justFiles);
1033  ok(res + 1 == itemCount,
1034  "SendMessage(LB_DIR, DDL_DIRECTORY, w*.c) returned incorrect index (expected %d got %d)!\n",
1035  itemCount - 1, res);
1036 
1037  /* Every single item in the control should start with a w and end in .c. */
1038  for (i = 0; i < itemCount; i++)
1039  {
1040  memset(pathBuffer, 0, MAX_PATH);
1043  ok(
1044  ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1045  (*(p-1) == 'c' || *(p-1) == 'C') &&
1046  (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1047  }
1048 
1049  /* Test DDL_DRIVES|DDL_EXCLUSIVE */
1050  strcpy(pathBuffer, wildcard);
1053  ok (res >= 0, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) failed - 0x%08x\n", GetLastError());
1054 
1055  /* There should be some content in the listbox. In particular, there should
1056  * be at least one element before, since the string "[-c-]" should
1057  * have been added. Depending on the user setting, more drives might have
1058  * been added.
1059  */
1060  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1061  ok (itemCount >= 1,
1062  "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) filled with %d entries, expected at least %d\n",
1063  itemCount, 1);
1064  itemCount_justDrives = itemCount;
1065  ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) returned incorrect index!\n");
1066 
1067  /* Every single item in the control should fit the format [-c-] */
1068  for (i = 0; i < itemCount; i++)
1069  {
1070  memset(pathBuffer, 0, MAX_PATH);
1071  driveletter = '\0';
1073  ok( strlen(pathBuffer) == 5, "Length of drive string is not 5\n" );
1074  ok( sscanf(pathBuffer, "[-%c-]", &driveletter) == 1, "Element %d (%s) does not fit [-X-]\n", i, pathBuffer);
1075  ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1076  if (!(driveletter >= 'a' && driveletter <= 'z'))
1077  {
1078  /* Correct after invalid entry is found */
1079  itemCount_justDrives--;
1080  }
1081  }
1082 
1083  /* This tests behavior when no files match the wildcard */
1087  ok (res == itemCount_justDrives -1, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1088  BAD_EXTENSION, res, itemCount_justDrives -1);
1089 
1090  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1091  ok (itemCount == itemCount_justDrives, "SendMessage(LB_DIR) returned %d expected %d\n",
1092  itemCount, itemCount_justDrives);
1093 
1094  /* Test DDL_DRIVES. */
1095  strcpy(pathBuffer, wildcard);
1098  ok (res > 0, "SendMessage(LB_DIR, DDL_DRIVES, *) failed - 0x%08x\n", GetLastError());
1099 
1100  /* There should be some content in the listbox. In particular, there should
1101  * be at least one element before, since the string "[-c-]" should
1102  * have been added. Depending on the user setting, more drives might have
1103  * been added.
1104  */
1105  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1106  ok (itemCount == itemCount_justDrives + itemCount_allFiles,
1107  "SendMessage(LB_DIR, DDL_DRIVES, *) filled with %d entries, expected %d\n",
1108  itemCount, itemCount_justDrives + itemCount_allFiles);
1109  ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DRIVES, *) returned incorrect index!\n");
1110 
1111  /* This tests behavior when no files match the wildcard */
1115  ok (res == itemCount_justDrives -1, "SendMessage(LB_DIR, DDL_DRIVES, %s) returned %d, expected %d\n",
1116  BAD_EXTENSION, res, itemCount_justDrives -1);
1117 
1118  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1119  ok (itemCount == res + 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount, res + 1);
1120 
1121  /* Test DDL_DRIVES. */
1122  strcpy(pathBuffer, "w*.c");
1125  ok (res > 0, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) failed - 0x%08x\n", GetLastError());
1126 
1127  /* There should be some content in the listbox. In particular, there should
1128  * be at least one element before, since the string "[-c-]" should
1129  * have been added. Depending on the user setting, more drives might have
1130  * been added.
1131  */
1132  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1133  ok (itemCount == itemCount_justDrives + itemCount_justFiles,
1134  "SendMessage(LB_DIR, DDL_DRIVES, w*.c) filled with %d entries, expected %d\n",
1135  itemCount, itemCount_justDrives + itemCount_justFiles);
1136  ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) returned incorrect index!\n");
1137 
1138  /* Every single item in the control should fit the format [-c-], or w*.c */
1139  for (i = 0; i < itemCount; i++)
1140  {
1141  memset(pathBuffer, 0, MAX_PATH);
1142  driveletter = '\0';
1145  if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1)
1146  {
1147  ok( strlen(pathBuffer) == 5, "Length of drive string is not 5\n" );
1148  ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1149  }
1150  else
1151  {
1152  ok(
1153  ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1154  (*(p-1) == 'c' || *(p-1) == 'C') &&
1155  (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1156  }
1157  }
1158 
1159  /* Test DDL_DIRECTORY|DDL_DRIVES. This does *not* imply DDL_EXCLUSIVE */
1160  strcpy(pathBuffer, wildcard);
1163  ok (res > 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, *) failed - 0x%08x\n", GetLastError());
1164 
1165  /* There should be some content in the listbox. In particular, there should
1166  * be exactly the number of plain files, plus the number of mapped drives.
1167  */
1168  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1169  ok (itemCount == itemCount_allFiles + itemCount_justDrives + itemCount_allDirs,
1170  "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1171  itemCount, itemCount_allFiles + itemCount_justDrives + itemCount_allDirs);
1172  ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
1173 
1174  /* Every single item in the control should start with a w and end in .c,
1175  * except for the "[..]" string, which should appear exactly as it is,
1176  * and the mapped drives in the format "[-X-]".
1177  */
1178  for (i = 0; i < itemCount; i++)
1179  {
1180  memset(pathBuffer, 0, MAX_PATH);
1181  driveletter = '\0';
1183  if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1)
1184  ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1185  }
1186 
1187  /* This tests behavior when no files match the wildcard */
1191  ok (res == itemCount_justDrives -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, %s) returned %d, expected %d\n",
1192  BAD_EXTENSION, res, itemCount_justDrives -1);
1193 
1194  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1195  ok (itemCount == res + 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount, res + 1);
1196 
1197  /* Test DDL_DIRECTORY|DDL_DRIVES. */
1198  strcpy(pathBuffer, "w*.c");
1201  ok (res > 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) failed - 0x%08x\n", GetLastError());
1202 
1203  /* There should be some content in the listbox. In particular, there should
1204  * be exactly the number of plain files, plus the number of mapped drives.
1205  */
1206  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1207  ok (itemCount == itemCount_justFiles + itemCount_justDrives,
1208  "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1209  itemCount, itemCount_justFiles + itemCount_justDrives);
1210  ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
1211 
1212  /* Every single item in the control should start with a w and end in .c,
1213  * except the mapped drives in the format "[-X-]". The "[..]" directory
1214  * should not appear.
1215  */
1216  for (i = 0; i < itemCount; i++)
1217  {
1218  memset(pathBuffer, 0, MAX_PATH);
1219  driveletter = '\0';
1222  if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1)
1223  ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1224  else
1225  ok(
1226  ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1227  (*(p-1) == 'c' || *(p-1) == 'C') &&
1228  (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1229  }
1230 
1231  /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1232  strcpy(pathBuffer, wildcard);
1235  ok (res != -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) failed err %u\n",
1236  GetLastError());
1237 
1238  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1239  ok (itemCount == itemCount_allDirs,
1240  "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1241  itemCount, itemCount_allDirs);
1242  ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) returned incorrect index!\n");
1243 
1244  if (itemCount)
1245  {
1246  memset(pathBuffer, 0, MAX_PATH);
1248  ok( !strcmp(pathBuffer, "[..]"), "First element is %s, not [..]\n", pathBuffer);
1249  }
1250 
1251  /* This tests behavior when no files match the wildcard */
1255  ok (res == -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1256  BAD_EXTENSION, res, -1);
1257 
1258  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1259  ok (itemCount == res + 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount, res + 1);
1260 
1261 
1262  /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1263  strcpy(pathBuffer, "w*.c");
1266  ok (res == LB_ERR, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, w*.c) returned %d expected %d\n", res, LB_ERR);
1267 
1268  /* There should be no elements, since "[..]" does not fit w*.c */
1269  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1270  ok (itemCount == 0,
1271  "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1272  itemCount, 0);
1273 
1274  /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1275  strcpy(pathBuffer, wildcard);
1278  ok (res > 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
1279 
1280  /* There should be no plain files on the listbox */
1281  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1282  ok (itemCount == itemCount_justDrives + itemCount_allDirs,
1283  "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1284  itemCount, itemCount_justDrives + itemCount_allDirs);
1285  ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
1286 
1287  for (i = 0; i < itemCount; i++)
1288  {
1289  memset(pathBuffer, 0, MAX_PATH);
1290  driveletter = '\0';
1292  if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1)
1293  ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1294  else
1295  ok( pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']',
1296  "Element %d (%s) does not fit expected [...]\n", i, pathBuffer);
1297  }
1298 
1299  /* This tests behavior when no files match the wildcard */
1303  ok (res == itemCount_justDrives -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, %s) returned %d, expected %d\n",
1304  BAD_EXTENSION, res, itemCount_justDrives -1);
1305 
1306  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1307  ok (itemCount == res + 1, "SendMessage(LB_DIR) returned %d expected %d\n", itemCount, res + 1);
1308 
1309  /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1310  strcpy(pathBuffer, "w*.c");
1313  ok (res >= 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
1314 
1315  /* There should be no plain files on the listbox, and no [..], since it does not fit w*.c */
1316  itemCount = SendMessageA(hList, LB_GETCOUNT, 0, 0);
1317  ok (itemCount == itemCount_justDrives,
1318  "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1319  itemCount, itemCount_justDrives);
1320  ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
1321 
1322  for (i = 0; i < itemCount; i++)
1323  {
1324  memset(pathBuffer, 0, MAX_PATH);
1325  driveletter = '\0';
1327  ok (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1, "Element %d (%s) does not fit [-X-]\n", i, pathBuffer);
1328  ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1329  }
1331 
1332  DeleteFileA( "wtest1.tmp.c" );
1333  RemoveDirectoryA("lb_dir_test");
1334 
1335  SetCurrentDirectoryA(curdir);
1336 }
1337 
1339 static HWND g_label;
1340 
1341 #define ID_TEST_LABEL 1001
1342 #define ID_TEST_LISTBOX 1002
1343 
1345 {
1346  g_label = CreateWindowA(WC_STATICA, "Contents of static control before DlgDirList.",
1347  WS_CHILD | WS_VISIBLE, 10, 10, 512, 32, hwnd, (HMENU)ID_TEST_LABEL, NULL, 0);
1348  if (!g_label) return FALSE;
1349 
1350  g_listBox = CreateWindowA(WC_LISTBOXA, "DlgDirList test",
1351  WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | WS_VSCROLL, 10, 60, 256, 256,
1352  hwnd, (HMENU)ID_TEST_LISTBOX, NULL, 0);
1353  if (!g_listBox) return FALSE;
1354 
1355  return TRUE;
1356 }
1357 
1359 {
1360  LRESULT result = 0;
1361 
1362  switch (uiMsg)
1363  {
1364  case WM_DESTROY:
1365  PostQuitMessage(0);
1366  break;
1367  case WM_CREATE:
1369  break;
1370  default:
1371  result = DefWindowProcA(hwnd, uiMsg, wParam, lParam);
1372  break;
1373  }
1374  return result;
1375 }
1376 
1378 {
1379  WNDCLASSA cls;
1380 
1381  cls.style = 0;
1382  cls.cbClsExtra = 0;
1383  cls.cbWndExtra = 0;
1384  cls.hInstance = hInst;
1385  cls.hIcon = NULL;
1387  cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
1388  cls.lpszMenuName = NULL;
1390  cls.lpszClassName = "ListboxContainerClass";
1391  if (!RegisterClassA (&cls)) return FALSE;
1392 
1393  return TRUE;
1394 }
1395 
1396 static void test_listbox_dlgdir(void)
1397 {
1398  HINSTANCE hInst;
1399  HWND hWnd;
1400  int res, itemCount;
1401  int itemCount_allDirs;
1402  int itemCount_justFiles;
1403  int itemCount_justDrives;
1404  int i;
1405  char pathBuffer[MAX_PATH];
1406  char itemBuffer[MAX_PATH];
1407  char tempBuffer[MAX_PATH];
1408  char * p;
1409  char driveletter;
1410  HANDLE file;
1411  BOOL ret;
1412 
1414  ok(file != INVALID_HANDLE_VALUE, "Error creating the test file: %d\n", GetLastError());
1415  CloseHandle( file );
1416 
1417  /* NOTE: for this test to succeed, there must be no subdirectories
1418  under the current directory. In addition, there must be at least
1419  one file that fits the wildcard w*.c . Normally, the test
1420  directory itself satisfies both conditions.
1421  */
1422 
1423  hInst = GetModuleHandleA(0);
1425  ok(ret, "Failed to register test class.\n");
1426 
1427  hWnd = CreateWindowA("ListboxContainerClass", "ListboxContainerClass",
1430  NULL, NULL, hInst, 0);
1431  ok(hWnd != NULL, "Failed to create container window.\n");
1432 
1433  /* Test for standard usage */
1434 
1435  /* The following should be overwritten by the directory path */
1436  SendMessageA(g_label, WM_SETTEXT, 0, (LPARAM)"default contents");
1437 
1438  /* This should list all the w*.c files in the test directory
1439  * As of this writing, this includes win.c, winstation.c, wsprintf.c
1440  */
1441  strcpy(pathBuffer, "w*.c");
1443  ok (res == 1, "DlgDirList(*.c, 0) returned %d - expected 1 - 0x%08x\n", res, GetLastError());
1444 
1445  /* Path specification gets converted to uppercase */
1446  ok (!strcmp(pathBuffer, "W*.C"),
1447  "expected conversion to uppercase, got %s\n", pathBuffer);
1448 
1449  /* Loaded path should have overwritten the label text */
1451  ok (strcmp("default contents", pathBuffer), "DlgDirList() did not modify static control!\n");
1452 
1453  /* There should be some content in the listbox */
1454  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1455  ok (itemCount > 0, "DlgDirList() did NOT fill the listbox!\n");
1456  itemCount_justFiles = itemCount;
1457 
1458  /* Every single item in the control should start with a w and end in .c */
1459  for (i = 0; i < itemCount; i++)
1460  {
1461  memset(pathBuffer, 0, MAX_PATH);
1464  ok(((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1465  (*(p-1) == 'c' || *(p-1) == 'C') &&
1466  (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1467  }
1468 
1469  /* Test behavior when no files match the wildcard */
1472  ok (res == 1, "DlgDirList(%s, 0) returned %d expected 1\n", BAD_EXTENSION, res);
1473 
1474  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1475  ok (itemCount == 0, "DlgDirList() DID fill the listbox!\n");
1476 
1477  /* Test DDL_DIRECTORY */
1478  strcpy(pathBuffer, "w*.c");
1480  ok (res == 1, "DlgDirList(*.c, DDL_DIRECTORY) failed - 0x%08x\n", GetLastError());
1481 
1482  /* There should be some content in the listbox. In particular, there should
1483  * be exactly more elements than before, since the directories should
1484  * have been added.
1485  */
1486  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1487  itemCount_allDirs = itemCount - itemCount_justFiles;
1488  ok (itemCount >= itemCount_justFiles, "DlgDirList(DDL_DIRECTORY) filled with %d entries, expected > %d\n",
1489  itemCount, itemCount_justFiles);
1490 
1491  /* Every single item in the control should start with a w and end in .c,
1492  * except for the "[..]" string, which should appear exactly as it is.
1493  */
1494  for (i = 0; i < itemCount; i++)
1495  {
1496  memset(pathBuffer, 0, MAX_PATH);
1499  ok( (pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']') ||
1500  ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1501  (*(p-1) == 'c' || *(p-1) == 'C') &&
1502  (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1503  }
1504 
1505  /* Test behavior when no files match the wildcard */
1508  ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY) returned %d expected 1\n", BAD_EXTENSION, res);
1509 
1510  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1511  ok (itemCount == itemCount_allDirs, "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
1512  itemCount_allDirs, itemCount);
1513  for (i = 0; i < itemCount; i++)
1514  {
1515  memset(pathBuffer, 0, MAX_PATH);
1517  ok( pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']',
1518  "Element %d (%s) does not fit requested [...]\n", i, pathBuffer);
1519  }
1520 
1521  /* Test DDL_DRIVES. At least on WinXP-SP2, this implies DDL_EXCLUSIVE */
1522  strcpy(pathBuffer, "w*.c");
1524  ok (res == 1, "DlgDirList(*.c, DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1525 
1526  /* There should be some content in the listbox. In particular, there should
1527  * be at least one element before, since the string "[-c-]" should
1528  * have been added. Depending on the user setting, more drives might have
1529  * been added.
1530  */
1531  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1532  ok (itemCount >= 1,
1533  "DlgDirList(DDL_DRIVES) filled with %d entries, expected at least %d\n",
1534  itemCount, 1);
1535  itemCount_justDrives = itemCount;
1536 
1537  /* Every single item in the control should fit the format [-c-] */
1538  for (i = 0; i < itemCount; i++)
1539  {
1540  memset(pathBuffer, 0, MAX_PATH);
1541  driveletter = '\0';
1543  ok( strlen(pathBuffer) == 5, "Length of drive string is not 5\n" );
1544  ok( sscanf(pathBuffer, "[-%c-]", &driveletter) == 1, "Element %d (%s) does not fit [-X-]\n", i, pathBuffer);
1545  ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1546  if (!(driveletter >= 'a' && driveletter <= 'z')) {
1547  /* Correct after invalid entry is found */
1548  trace("removing count of invalid entry %s\n", pathBuffer);
1549  itemCount_justDrives--;
1550  }
1551  }
1552 
1553  /* Test behavior when no files match the wildcard */
1556  ok (res == 1, "DlgDirList(%s, DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION, res);
1557 
1558  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1559  ok (itemCount == itemCount_justDrives, "DlgDirList() incorrectly filled the listbox!\n");
1560 
1561  /* Test DDL_DIRECTORY|DDL_DRIVES. This does *not* imply DDL_EXCLUSIVE */
1562  strcpy(pathBuffer, "w*.c");
1564  ok (res == 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1565 
1566  /* There should be some content in the listbox. In particular, there should
1567  * be exactly the number of plain files, plus the number of mapped drives,
1568  * plus one "[..]"
1569  */
1570  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1571  ok (itemCount == itemCount_justFiles + itemCount_justDrives + itemCount_allDirs,
1572  "DlgDirList(DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
1573  itemCount, itemCount_justFiles + itemCount_justDrives + itemCount_allDirs);
1574 
1575  /* Every single item in the control should start with a w and end in .c,
1576  * except for the "[..]" string, which should appear exactly as it is,
1577  * and the mapped drives in the format "[-X-]".
1578  */
1579  for (i = 0; i < itemCount; i++)
1580  {
1581  memset(pathBuffer, 0, MAX_PATH);
1582  driveletter = '\0';
1585  if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1)
1586  ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1587  else
1588  ok( (pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']') ||
1589  ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
1590  (*(p-1) == 'c' || *(p-1) == 'C') &&
1591  (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
1592  }
1593 
1594  /* Test behavior when no files match the wildcard */
1597  ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION, res);
1598 
1599  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1600  ok (itemCount == itemCount_justDrives + itemCount_allDirs,
1601  "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
1602  itemCount_justDrives + itemCount_allDirs, itemCount);
1603 
1604  /* Test DDL_DIRECTORY|DDL_EXCLUSIVE. */
1605  strcpy(pathBuffer, "w*.c");
1607  ok (res == 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_EXCLUSIVE) failed - 0x%08x\n", GetLastError());
1608 
1609  /* There should be exactly one element: "[..]" */
1610  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1611  ok (itemCount == itemCount_allDirs,
1612  "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1613  itemCount, itemCount_allDirs);
1614 
1615  if (itemCount && GetCurrentDirectoryA( MAX_PATH, pathBuffer ) > 3) /* there's no [..] in drive root */
1616  {
1617  memset(pathBuffer, 0, MAX_PATH);
1619  ok( !strcmp(pathBuffer, "[..]"), "First (and only) element is not [..]\n");
1620  }
1621 
1622  /* Test behavior when no files match the wildcard */
1625  ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION, res);
1626 
1627  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1628  ok (itemCount == itemCount_allDirs, "DlgDirList() incorrectly filled the listbox!\n");
1629 
1630  /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
1631  strcpy(pathBuffer, "w*.c");
1633  ok (res == 1, "DlgDirList(*.c, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) failed - 0x%08x\n", GetLastError());
1634 
1635  /* There should be no plain files on the listbox */
1636  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1637  ok (itemCount == itemCount_justDrives + itemCount_allDirs,
1638  "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
1639  itemCount, itemCount_justDrives + itemCount_allDirs);
1640 
1641  for (i = 0; i < itemCount; i++)
1642  {
1643  memset(pathBuffer, 0, MAX_PATH);
1644  driveletter = '\0';
1646  if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1)
1647  ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
1648  else
1649  ok( pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']',
1650  "Element %d (%s) does not fit expected [...]\n", i, pathBuffer);
1651  }
1652 
1653  /* Test behavior when no files match the wildcard */
1656  ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION, res);
1657 
1658  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1659  ok (itemCount == itemCount_justDrives + itemCount_allDirs, "DlgDirList() incorrectly filled the listbox!\n");
1660 
1661  /* Now test DlgDirSelectEx() in normal operation */
1662  /* Fill with everything - drives, directory and all plain files. */
1663  strcpy(pathBuffer, "*");
1665  ok (res != 0, "DlgDirList(*, DDL_DIRECTORY|DDL_DRIVES) failed - 0x%08x\n", GetLastError());
1666 
1667  SendMessageA(g_listBox, LB_SETCURSEL, -1, 0); /* Unselect any current selection */
1668  memset(pathBuffer, 0, MAX_PATH);
1669  SetLastError(0xdeadbeef);
1671  ok (GetLastError() == 0xdeadbeef,
1672  "DlgDirSelectEx() with no selection modified last error code from 0xdeadbeef to 0x%08x\n",
1673  GetLastError());
1674  ok (res == 0, "DlgDirSelectEx() with no selection returned %d, expected 0\n", res);
1675  /* WinXP-SP2 leaves pathBuffer untouched, but Win98 fills it with garbage. */
1676  /*
1677  ok (strlen(pathBuffer) == 0, "DlgDirSelectEx() with no selection filled buffer with %s\n", pathBuffer);
1678  */
1679  /* Test proper drive/dir/file recognition */
1680  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1681  for (i = 0; i < itemCount; i++)
1682  {
1683  memset(itemBuffer, 0, MAX_PATH);
1684  memset(pathBuffer, 0, MAX_PATH);
1685  memset(tempBuffer, 0, MAX_PATH);
1686  driveletter = '\0';
1687  SendMessageA(g_listBox, LB_GETTEXT, i, (LPARAM)itemBuffer);
1689  ok (res == i, "SendMessageA(LB_SETCURSEL, %d) failed\n", i);
1690  if (sscanf(itemBuffer, "[-%c-]", &driveletter) == 1)
1691  {
1692  /* Current item is a drive letter */
1693  SetLastError(0xdeadbeef);
1695  ok (GetLastError() == 0xdeadbeef,
1696  "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1697  i, GetLastError());
1698  ok(res == 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer, pathBuffer);
1699 
1700  /* For drive letters, DlgDirSelectEx tacks on a colon */
1701  ok (pathBuffer[0] == driveletter && pathBuffer[1] == ':' && pathBuffer[2] == '\0',
1702  "%d: got \"%s\" expected \"%c:\"\n", i, pathBuffer, driveletter);
1703  }
1704  else if (itemBuffer[0] == '[')
1705  {
1706  /* Current item is the parent directory */
1707  SetLastError(0xdeadbeef);
1709  ok (GetLastError() == 0xdeadbeef,
1710  "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1711  i, GetLastError());
1712  ok(res == 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer, pathBuffer);
1713 
1714  /* For directories, DlgDirSelectEx tacks on a backslash */
1716  ok (*(p-1) == '\\', "DlgDirSelectEx did NOT tack on a backslash to dir, got %s\n", pathBuffer);
1717 
1718  tempBuffer[0] = '[';
1719  lstrcpynA(tempBuffer + 1, pathBuffer, strlen(pathBuffer));
1720  strcat(tempBuffer, "]");
1721  ok (!strcmp(tempBuffer, itemBuffer), "Formatted directory should be %s, got %s\n", tempBuffer, itemBuffer);
1722  }
1723  else
1724  {
1725  /* Current item is a plain file */
1726  SetLastError(0xdeadbeef);
1728  ok (GetLastError() == 0xdeadbeef,
1729  "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1730  i, GetLastError());
1731  ok(res == 0, "DlgDirSelectEx() thinks %s (%s) is a drive/directory!\n", itemBuffer, pathBuffer);
1732 
1733  /* NOTE: WinXP tacks a period on all files that lack an extension. This affects
1734  * for example, "Makefile", which gets reported as "Makefile."
1735  */
1736  strcpy(tempBuffer, itemBuffer);
1737  if (strchr(tempBuffer, '.') == NULL) strcat(tempBuffer, ".");
1738  ok (!strcmp(pathBuffer, tempBuffer), "Formatted file should be %s, got %s\n", tempBuffer, pathBuffer);
1739  }
1740  }
1741 
1742  DeleteFileA( "wtest1.tmp.c" );
1743 
1744  /* Now test DlgDirSelectEx() in abnormal operation */
1745  /* Fill list with bogus entries, that look somewhat valid */
1747  SendMessageA(g_listBox, LB_ADDSTRING, 0, (LPARAM)"[notexist.dir]");
1748  SendMessageA(g_listBox, LB_ADDSTRING, 0, (LPARAM)"notexist.fil");
1749  itemCount = SendMessageA(g_listBox, LB_GETCOUNT, 0, 0);
1750  for (i = 0; i < itemCount; i++)
1751  {
1752  memset(itemBuffer, 0, MAX_PATH);
1753  memset(pathBuffer, 0, MAX_PATH);
1754  memset(tempBuffer, 0, MAX_PATH);
1755  driveletter = '\0';
1756  SendMessageA(g_listBox, LB_GETTEXT, i, (LPARAM)itemBuffer);
1758  ok (res == i, "SendMessage(LB_SETCURSEL, %d) failed\n", i);
1759  if (sscanf(itemBuffer, "[-%c-]", &driveletter) == 1)
1760  {
1761  /* Current item is a drive letter */
1762  SetLastError(0xdeadbeef);
1764  ok (GetLastError() == 0xdeadbeef,
1765  "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1766  i, GetLastError());
1767  ok(res == 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer, pathBuffer);
1768 
1769  /* For drive letters, DlgDirSelectEx tacks on a colon */
1770  ok (pathBuffer[0] == driveletter && pathBuffer[1] == ':' && pathBuffer[2] == '\0',
1771  "%d: got \"%s\" expected \"%c:\"\n", i, pathBuffer, driveletter);
1772  }
1773  else if (itemBuffer[0] == '[')
1774  {
1775  /* Current item is the parent directory */
1776  SetLastError(0xdeadbeef);
1778  ok (GetLastError() == 0xdeadbeef,
1779  "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1780  i, GetLastError());
1781  ok(res == 1, "DlgDirSelectEx() thinks %s (%s) is not a drive/directory!\n", itemBuffer, pathBuffer);
1782 
1783  /* For directories, DlgDirSelectEx tacks on a backslash */
1785  ok (*(p-1) == '\\', "DlgDirSelectEx did NOT tack on a backslash to dir, got %s\n", pathBuffer);
1786 
1787  tempBuffer[0] = '[';
1788  lstrcpynA(tempBuffer + 1, pathBuffer, strlen(pathBuffer));
1789  strcat(tempBuffer, "]");
1790  ok (!strcmp(tempBuffer, itemBuffer), "Formatted directory should be %s, got %s\n", tempBuffer, itemBuffer);
1791  }
1792  else
1793  {
1794  /* Current item is a plain file */
1795  SetLastError(0xdeadbeef);
1797  ok (GetLastError() == 0xdeadbeef,
1798  "DlgDirSelectEx() with selection at %d modified last error code from 0xdeadbeef to 0x%08x\n",
1799  i, GetLastError());
1800  ok(res == 0, "DlgDirSelectEx() thinks %s (%s) is a drive/directory!\n", itemBuffer, pathBuffer);
1801 
1802  /* NOTE: WinXP and Win98 tack a period on all files that lack an extension.
1803  * This affects for example, "Makefile", which gets reported as "Makefile."
1804  */
1805  strcpy(tempBuffer, itemBuffer);
1806  if (strchr(tempBuffer, '.') == NULL) strcat(tempBuffer, ".");
1807  ok (!strcmp(pathBuffer, tempBuffer), "Formatted file should be %s, got %s\n", tempBuffer, pathBuffer);
1808  }
1809  }
1810 
1811  /* Test behavior when loading folders from root with and without wildcard */
1812  strcpy(pathBuffer, "C:\\");
1814  ok(res, "DlgDirList failed to list C:\\ folders\n");
1815  todo_wine ok(!strcmp(pathBuffer, "*"), "DlgDirList set the invalid path spec '%s', expected '*'\n", pathBuffer);
1816 
1817  strcpy(pathBuffer, "C:\\*");
1819  ok(res, "DlgDirList failed to list C:\\* folders\n");
1820  ok(!strcmp(pathBuffer, "*"), "DlgDirList set the invalid path spec '%s', expected '*'\n", pathBuffer);
1821 
1822  /* Try loading files from an invalid folder */
1823  SetLastError(0xdeadbeef);
1824  strcpy(pathBuffer, "C:\\INVALID$$DIR");
1826  todo_wine ok(!res, "DlgDirList should have failed with 0 but %d was returned\n", res);
1828  "GetLastError should return 0x589, got 0x%X\n",GetLastError());
1829 
1831 }
1832 
1833 static void test_set_count( void )
1834 {
1835  static const DWORD styles[] =
1836  {
1839  };
1840  HWND parent, listbox;
1841  unsigned int i;
1842  LONG ret;
1843  RECT r;
1844 
1845  parent = create_parent();
1847 
1848  UpdateWindow( listbox );
1849  GetUpdateRect( listbox, &r, TRUE );
1850  ok( IsRectEmpty( &r ), "got non-empty rect\n");
1851 
1852  ret = SendMessageA( listbox, LB_SETCOUNT, 100, 0 );
1853  ok( ret == 0, "got %d\n", ret );
1854  ret = SendMessageA( listbox, LB_GETCOUNT, 0, 0 );
1855  ok( ret == 100, "got %d\n", ret );
1856 
1857  GetUpdateRect( listbox, &r, TRUE );
1858  ok( !IsRectEmpty( &r ), "got empty rect\n");
1859 
1860  ValidateRect( listbox, NULL );
1861  GetUpdateRect( listbox, &r, TRUE );
1862  ok( IsRectEmpty( &r ), "got non-empty rect\n");
1863 
1864  ret = SendMessageA( listbox, LB_SETCOUNT, 99, 0 );
1865  ok( ret == 0, "got %d\n", ret );
1866 
1867  GetUpdateRect( listbox, &r, TRUE );
1868  ok( !IsRectEmpty( &r ), "got empty rect\n");
1869 
1870  DestroyWindow( listbox );
1871 
1872  for (i = 0; i < ARRAY_SIZE(styles); ++i)
1873  {
1874  listbox = create_listbox( styles[i] | WS_CHILD | WS_VISIBLE, parent );
1875 
1876  SetLastError( 0xdeadbeef );
1877  ret = SendMessageA( listbox, LB_SETCOUNT, 100, 0 );
1878  ok( ret == LB_ERR, "expected %d, got %d\n", LB_ERR, ret );
1879  ok( GetLastError() == 0xdeadbeef, "Unexpected error %d.\n", GetLastError() );
1880 
1881  DestroyWindow( listbox );
1882  }
1883 
1884  DestroyWindow( parent );
1885 }
1886 
1887 static void test_GetListBoxInfo(void)
1888 {
1889  static const struct message getlistboxinfo_seq[] =
1890  {
1891  { LB_GETLISTBOXINFO, sent },
1892  { 0 }
1893  };
1894  HWND listbox, parent;
1895  DWORD ret;
1896 
1897  parent = create_parent();
1898  listbox = create_listbox(WS_CHILD | WS_VISIBLE, parent);
1899 
1901  ret = GetListBoxInfo(listbox);
1902  ok(ret > 0, "got %d\n", ret);
1903  ok_sequence(sequences, LB_SEQ_INDEX, getlistboxinfo_seq, "GetListBoxInfo()", FALSE);
1904 
1905  DestroyWindow(listbox);
1907 }
1908 
1909 static void test_missing_lbuttonup(void)
1910 {
1911  HWND listbox, parent, capture;
1912 
1913  parent = create_parent();
1914  listbox = create_listbox(WS_CHILD | WS_VISIBLE, parent);
1915 
1916  /* Send button down without a corresponding button up */
1917  SendMessageA(listbox, WM_LBUTTONDOWN, 0, MAKELPARAM(10, 10));
1918  capture = GetCapture();
1919  ok(capture == listbox, "got %p expected %p\n", capture, listbox);
1920 
1921  /* Capture is released and LBN_SELCHANGE sent during WM_KILLFOCUS */
1922  got_selchange = 0;
1923  SetFocus(NULL);
1924  capture = GetCapture();
1925  ok(capture == NULL, "got %p\n", capture);
1926  ok(got_selchange, "got %d\n", got_selchange);
1927 
1928  DestroyWindow(listbox);
1930 }
1931 
1932 static void test_extents(void)
1933 {
1934  HWND listbox, parent;
1935  SCROLLINFO sinfo;
1936  DWORD res;
1937  BOOL br;
1938 
1939  parent = create_parent();
1940 
1941  listbox = create_listbox(WS_CHILD | WS_VISIBLE, parent);
1942 
1943  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
1944  ok(res == 0, "Got wrong initial horizontal extent: %u\n", res);
1945 
1946  sinfo.cbSize = sizeof(sinfo);
1947  sinfo.fMask = SIF_RANGE;
1948  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
1949  ok(br == TRUE, "GetScrollInfo failed\n");
1950  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
1951  ok(sinfo.nMax == 100, "got wrong max: %u\n", sinfo.nMax);
1952  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
1953  "List box should not have a horizontal scroll bar\n");
1954 
1955  /* horizontal extent < width */
1956  SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 64, 0);
1957 
1958  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
1959  ok(res == 64, "Got wrong horizontal extent: %u\n", res);
1960 
1961  sinfo.cbSize = sizeof(sinfo);
1962  sinfo.fMask = SIF_RANGE;
1963  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
1964  ok(br == TRUE, "GetScrollInfo failed\n");
1965  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
1966  ok(sinfo.nMax == 100, "got wrong max: %u\n", sinfo.nMax);
1967  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
1968  "List box should not have a horizontal scroll bar\n");
1969 
1970  /* horizontal extent > width */
1971  SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 184, 0);
1972 
1973  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
1974  ok(res == 184, "Got wrong horizontal extent: %u\n", res);
1975 
1976  sinfo.cbSize = sizeof(sinfo);
1977  sinfo.fMask = SIF_RANGE;
1978  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
1979  ok(br == TRUE, "GetScrollInfo failed\n");
1980  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
1981  ok(sinfo.nMax == 100, "got wrong max: %u\n", sinfo.nMax);
1982  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
1983  "List box should not have a horizontal scroll bar\n");
1984 
1985  DestroyWindow(listbox);
1986 
1988 
1989  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
1990  ok(res == 0, "Got wrong initial horizontal extent: %u\n", res);
1991 
1992  sinfo.cbSize = sizeof(sinfo);
1993  sinfo.fMask = SIF_RANGE;
1994  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
1995  ok(br == TRUE, "GetScrollInfo failed\n");
1996  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
1997  ok(sinfo.nMax == 100, "got wrong max: %u\n", sinfo.nMax);
1998  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
1999  "List box should not have a horizontal scroll bar\n");
2000 
2001  /* horizontal extent < width */
2002  SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 64, 0);
2003 
2004  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2005  ok(res == 64, "Got wrong horizontal extent: %u\n", res);
2006 
2007  sinfo.cbSize = sizeof(sinfo);
2008  sinfo.fMask = SIF_RANGE;
2009  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2010  ok(br == TRUE, "GetScrollInfo failed\n");
2011  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2012  ok(sinfo.nMax == 63, "got wrong max: %u\n", sinfo.nMax);
2013  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
2014  "List box should not have a horizontal scroll bar\n");
2015 
2016  /* horizontal extent > width */
2017  SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 184, 0);
2018 
2019  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2020  ok(res == 184, "Got wrong horizontal extent: %u\n", res);
2021 
2022  sinfo.cbSize = sizeof(sinfo);
2023  sinfo.fMask = SIF_RANGE;
2024  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2025  ok(br == TRUE, "GetScrollInfo failed\n");
2026  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2027  ok(sinfo.nMax == 183, "got wrong max: %u\n", sinfo.nMax);
2028  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) != 0,
2029  "List box should have a horizontal scroll bar\n");
2030 
2031  SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 0, 0);
2032 
2033  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2034  ok(res == 0, "Got wrong horizontal extent: %u\n", res);
2035 
2036  sinfo.cbSize = sizeof(sinfo);
2037  sinfo.fMask = SIF_RANGE;
2038  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2039  ok(br == TRUE, "GetScrollInfo failed\n");
2040  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2041  ok(sinfo.nMax == 0, "got wrong max: %u\n", sinfo.nMax);
2042  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) == 0,
2043  "List box should not have a horizontal scroll bar\n");
2044 
2045  DestroyWindow(listbox);
2046 
2047 
2049 
2050  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2051  ok(res == 0, "Got wrong initial horizontal extent: %u\n", res);
2052 
2053  sinfo.cbSize = sizeof(sinfo);
2054  sinfo.fMask = SIF_RANGE;
2055  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2056  ok(br == TRUE, "GetScrollInfo failed\n");
2057  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2058  ok(sinfo.nMax == 0, "got wrong max: %u\n", sinfo.nMax);
2059  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) != 0,
2060  "List box should have a horizontal scroll bar\n");
2061 
2062  /* horizontal extent < width */
2063  SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 64, 0);
2064 
2065  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2066  ok(res == 64, "Got wrong horizontal extent: %u\n", res);
2067 
2068  sinfo.cbSize = sizeof(sinfo);
2069  sinfo.fMask = SIF_RANGE;
2070  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2071  ok(br == TRUE, "GetScrollInfo failed\n");
2072  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2073  ok(sinfo.nMax == 63, "got wrong max: %u\n", sinfo.nMax);
2074  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) != 0,
2075  "List box should have a horizontal scroll bar\n");
2076 
2077  /* horizontal extent > width */
2078  SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 184, 0);
2079 
2080  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2081  ok(res == 184, "Got wrong horizontal extent: %u\n", res);
2082 
2083  sinfo.cbSize = sizeof(sinfo);
2084  sinfo.fMask = SIF_RANGE;
2085  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2086  ok(br == TRUE, "GetScrollInfo failed\n");
2087  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2088  ok(sinfo.nMax == 183, "got wrong max: %u\n", sinfo.nMax);
2089  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) != 0,
2090  "List box should have a horizontal scroll bar\n");
2091 
2092  SendMessageA(listbox, LB_SETHORIZONTALEXTENT, 0, 0);
2093 
2094  res = SendMessageA(listbox, LB_GETHORIZONTALEXTENT, 0, 0);
2095  ok(res == 0, "Got wrong horizontal extent: %u\n", res);
2096 
2097  sinfo.cbSize = sizeof(sinfo);
2098  sinfo.fMask = SIF_RANGE;
2099  br = GetScrollInfo(listbox, SB_HORZ, &sinfo);
2100  ok(br == TRUE, "GetScrollInfo failed\n");
2101  ok(sinfo.nMin == 0, "got wrong min: %u\n", sinfo.nMin);
2102  ok(sinfo.nMax == 0, "got wrong max: %u\n", sinfo.nMax);
2103  ok((GetWindowLongA(listbox, GWL_STYLE) & WS_HSCROLL) != 0,
2104  "List box should have a horizontal scroll bar\n");
2105 
2106  DestroyWindow(listbox);
2107 
2109 }
2110 
2111 static void test_listbox(void)
2112 {
2113  static const struct listbox_test SS =
2114  /* {add_style} */
2115  {{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
2116  { 1, 1, 1, LB_ERR}, {0,0,0,0},
2117  { 2, 2, 2, LB_ERR}, {0,0,0,0},
2118  {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
2119 
2120  /* {selected, anchor, caret, selcount}{TODO fields} */
2121  static const struct listbox_test SS_NS =
2122  {{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
2123  { 1, 1, 1, LB_ERR}, {0,0,0,0},
2124  { 2, 2, 2, LB_ERR}, {0,0,0,0},
2125  {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
2126 
2127  static const struct listbox_test MS =
2128  {{ 0, LB_ERR, 0, 0}, {0,0,0,0},
2129  { 1, 1, 1, 1}, {0,0,0,0},
2130  { 2, 1, 2, 1}, {0,0,0,0},
2131  { 0, LB_ERR, 0, 2}, {0,0,0,0}};
2132 
2133  static const struct listbox_test MS_NS =
2134  {{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
2135  { 1, 1, 1, LB_ERR}, {0,0,0,0},
2136  { 2, 2, 2, LB_ERR}, {0,0,0,0},
2137  {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
2138 
2139  static const struct listbox_test ES =
2140  {{ 0, LB_ERR, 0, 0}, {0,0,0,0},
2141  { 1, 1, 1, 1}, {0,0,0,0},
2142  { 2, 2, 2, 1}, {0,0,0,0},
2143  { 0, LB_ERR, 0, 2}, {0,0,0,0}};
2144 
2145  static const struct listbox_test ES_NS =
2146  {{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
2147  { 1, 1, 1, LB_ERR}, {0,0,0,0},
2148  { 2, 2, 2, LB_ERR}, {0,0,0,0},
2149  {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
2150 
2151  static const struct listbox_test EMS =
2152  {{ 0, LB_ERR, 0, 0}, {0,0,0,0},
2153  { 1, 1, 1, 1}, {0,0,0,0},
2154  { 2, 2, 2, 1}, {0,0,0,0},
2155  { 0, LB_ERR, 0, 2}, {0,0,0,0}};
2156 
2157  static const struct listbox_test EMS_NS =
2158  {{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
2159  { 1, 1, 1, LB_ERR}, {0,0,0,0},
2160  { 2, 2, 2, LB_ERR}, {0,0,0,0},
2161  {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
2162 
2163  run_test(0, SS);
2164  run_test(LBS_NOSEL, SS_NS);
2171 
2180 }
2181 
2183 {
2184  { WM_MEASUREITEM, sent|wparam|lparam, 0x1012, 0xf30604ed },
2185  { WM_MEASUREITEM, sent|wparam|lparam, 0x1112, 0xf30604ee },
2186  { WM_MEASUREITEM, sent|wparam|lparam, 0x1212, 0xf30604ef },
2187  { 0 }
2188 };
2189 
2190 static const struct message lb_addstring_sort_parent_seq[] =
2191 {
2192  { WM_MEASUREITEM, sent|wparam|lparam, 0x1012, 0xf30604ed },
2193  { WM_COMPAREITEM, sent|wparam|lparam, 0xf30604ed, 0xf30604ee },
2194  { WM_MEASUREITEM, sent|wparam|lparam, 0x1112, 0xf30604ee },
2195  { WM_COMPAREITEM, sent|wparam|lparam, 0xf30604ed, 0xf30604ef },
2196  { WM_COMPAREITEM, sent|wparam|lparam, 0xf30604ee, 0xf30604ef },
2197  { WM_MEASUREITEM, sent|wparam|lparam, 0x1212, 0xf30604ef },
2198  { 0 }
2199 };
2200 
2201 static const struct message empty_seq[] =
2202 {
2203  { 0 }
2204 };
2205 
2206 static void test_WM_MEASUREITEM(void)
2207 {
2208  HWND parent, listbox;
2209  LRESULT data, ret;
2210 
2211  parent = create_parent();
2213 
2214  data = SendMessageA(listbox, LB_GETITEMDATA, 0, 0);
2215  ok(data == (LRESULT)strings[0], "data = %08lx, expected %p\n", data, strings[0]);
2217 
2218  parent = create_parent();
2220 
2221  data = SendMessageA(listbox, LB_GETITEMDATA, 0, 0);
2222  ok(!data, "data = %08lx\n", data);
2223 
2224  /* LBS_HASSTRINGS */
2225  parent = create_parent();
2228  10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
2229 
2231 
2232  ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
2233  ok(ret == 0, "expected 0, got %ld\n", ret);
2234  ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
2235  ok(ret == 1, "expected 1, got %ld\n", ret);
2236  ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
2237  ok(ret == 2, "expected 2, got %ld\n", ret);
2238 
2240  "LB_ADDSTRING (LBS_HASSTRINGS, ownerdraw)", FALSE);
2241  DestroyWindow(listbox);
2242 
2243  /* LBS_SORT, no LBS_HASSTRINGS */
2246  10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
2247 
2249 
2250  ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
2251  ok(ret == 0, "expected 0, got %ld\n", ret);
2252  ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
2253  ok(ret == 1, "expected 1, got %ld\n", ret);
2254  ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
2255  ok(ret == 2, "expected 2, got %ld\n", ret);
2256 
2258  DestroyWindow(listbox);
2259 
2260  /* LBS_HASSTRINGS */
2263  10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
2264 
2266 
2267  ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
2268  ok(ret == 0, "expected 0, got %ld\n", ret);
2269  ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
2270  ok(ret == 1, "expected 1, got %ld\n", ret);
2271  ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
2272  ok(ret == 2, "expected 2, got %ld\n", ret);
2273 
2274  ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "LB_ADDSTRING (LBS_HASSTRINGS)", FALSE);
2275  DestroyWindow(listbox);
2276 
2277  /* LBS_HASSTRINGS, LBS_SORT */
2280  10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
2281 
2283 
2284  ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
2285  ok(ret == 0, "expected 0, got %ld\n", ret);
2286  ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
2287  ok(ret == 0, "expected 0, got %ld\n", ret);
2288  ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
2289  ok(ret == 1, "expected 1, got %ld\n", ret);
2290 
2291  ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "LB_ADDSTRING (LBS_HASSTRINGS, LBS_SORT)", FALSE);
2292  DestroyWindow(listbox);
2293 
2295 }
2296 
2297 static void test_LBS_NODATA(void)
2298 {
2299  static const DWORD invalid_styles[] =
2300  {
2301  0,
2303  LBS_SORT,
2307  };
2308  static const UINT invalid_idx[] = { -2, 2 };
2309  static const UINT valid_idx[] = { 0, 1 };
2310  static const ULONG_PTR zero_data;
2311  HWND listbox, parent;
2312  INT ret, text_len;
2313  unsigned int i;
2314  ULONG_PTR data;
2315  BOOL is_wow64;
2316 
2318  0, 0, 100, 100, NULL, NULL, NULL, 0);
2319  ok(listbox != NULL, "Failed to create ListBox window.\n");
2320 
2321  ret = SendMessageA(listbox, LB_INSERTSTRING, -1, 0);
2322  ok(ret == 0, "Unexpected return value %d.\n", ret);
2323  ret = SendMessageA(listbox, LB_INSERTSTRING, -1, 0);
2324  ok(ret == 1, "Unexpected return value %d.\n", ret);
2325  ret = SendMessageA(listbox, LB_GETCOUNT, 0, 0);
2326  ok(ret == 2, "Unexpected return value %d.\n", ret);
2327 
2328  /* Invalid indices. */
2329  for (i = 0; i < ARRAY_SIZE(invalid_idx); ++i)
2330  {
2331  ret = SendMessageA(listbox, LB_SETITEMDATA, invalid_idx[i], 42);
2332  ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2333  ret = SendMessageA(listbox, LB_GETTEXTLEN, invalid_idx[i], 0);
2334  ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2335  if (ret == LB_ERR)
2336  {
2337  ret = SendMessageA(listbox, LB_GETTEXT, invalid_idx[i], (LPARAM)&data);
2338  ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2339  }
2340  ret = SendMessageA(listbox, LB_GETITEMDATA, invalid_idx[i], 0);
2341  ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2342  }
2343 
2345 #ifdef _WIN64
2346  text_len = 8;
2347 #else
2348  text_len = is_wow64 ? 8 : 4;
2349 #endif
2350 
2351  /* Valid indices. */
2352  for (i = 0; i < ARRAY_SIZE(valid_idx); ++i)
2353  {
2354  ret = SendMessageA(listbox, LB_SETITEMDATA, valid_idx[i], 42);
2355  ok(ret == TRUE, "Unexpected return value %d.\n", ret);
2356  ret = SendMessageA(listbox, LB_GETTEXTLEN, valid_idx[i], 0);
2358  ok(ret == text_len, "Unexpected return value %d.\n", ret);
2359 
2360  memset(&data, 0xee, sizeof(data));
2361  ret = SendMessageA(listbox, LB_GETTEXT, valid_idx[i], (LPARAM)&data);
2362  ok(ret == sizeof(data), "Unexpected return value %d.\n", ret);
2363  ok(!memcmp(&data, &zero_data, sizeof(data)), "Unexpected item data.\n");
2364 
2365  ret = SendMessageA(listbox, LB_GETITEMDATA, valid_idx[i], 0);
2366  ok(ret == 0, "Unexpected return value %d.\n", ret);
2367  }
2368 
2369  /* More messages that don't work with LBS_NODATA. */
2370  ret = SendMessageA(listbox, LB_FINDSTRING, 1, 0);
2371  ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2372  ret = SendMessageA(listbox, LB_FINDSTRING, 1, 42);
2373  ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2374  ret = SendMessageA(listbox, LB_FINDSTRINGEXACT, 1, 0);
2375  ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2376  ret = SendMessageA(listbox, LB_FINDSTRINGEXACT, 1, 42);
2377  ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2378  ret = SendMessageA(listbox, LB_SELECTSTRING, 1, 0);
2379  ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2380  ret = SendMessageA(listbox, LB_SELECTSTRING, 1, 42);
2381  ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
2382 
2383  DestroyWindow(listbox);
2384 
2385  /* Invalid window style combinations. */
2386  parent = create_parent();
2387  ok(parent != NULL, "Failed to create parent window.\n");
2388 
2389  for (i = 0; i < ARRAY_SIZE(invalid_styles); ++i)
2390  {
2391  DWORD style;
2392 
2393  listbox = CreateWindowA(WC_LISTBOXA, "TestList", LBS_NODATA | WS_CHILD | invalid_styles[i],
2394  0, 0, 100, 100, parent, (HMENU)ID_LISTBOX, NULL, 0);
2395  ok(listbox != NULL, "Failed to create a listbox.\n");
2396 
2397  style = GetWindowLongA(listbox, GWL_STYLE);
2398  ok((style & invalid_styles[i]) == invalid_styles[i], "%u: unexpected window styles %#x.\n", i, style);
2399  ret = SendMessageA(listbox, LB_SETCOUNT, 100, 0);
2400  ok(ret == LB_ERR, "%u: unexpected return value %d.\n", i, ret);
2401  DestroyWindow(listbox);
2402  }
2403 
2405 }
2406 
2407 START_TEST(listbox)
2408 {
2409  ULONG_PTR ctx_cookie;
2410  HANDLE hCtx;
2411 
2412  if (!load_v6_module(&ctx_cookie, &hCtx))
2413  return;
2414 
2416 
2417  test_listbox();
2418  test_item_height();
2419  test_ownerdraw();
2427  test_set_count();
2430  test_extents();
2432  test_LB_SETSEL();
2433  test_LBS_NODATA();
2434 
2435  unload_v6_module(ctx_cookie, hCtx);
2436 }
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 * u
Definition: glfuncs.h:240
HGDIOBJ WINAPI GetStockObject(_In_ int)
#define WC_STATICA
Definition: commctrl.h:4650
#define LB_SETCURSEL
Definition: winuser.h:2024
static void test_ownerdraw(void)
Definition: listbox.c:463
static LPWSTR pathBuffer
Definition: treeview.c:31
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define trace(...)
Definition: kmt_test.h:217
HDC WINAPI GetDCEx(_In_opt_ HWND, _In_opt_ HRGN, _In_ DWORD)
#define LBS_NODATA
Definition: winuser.h:313
Definition: tftpd.h:59
static void listbox_query(HWND handle, struct listbox_stat *results)
Definition: listbox.c:173
static void test_missing_lbuttonup(void)
Definition: listbox.c:1909
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
DWORD WINAPI GetListBoxInfo(_In_ HWND)
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
#define LB_DIR
Definition: winuser.h:1994
static void test_LB_SELITEMRANGE(void)
Definition: listbox.c:540
static const struct message lb_addstring_ownerdraw_parent_seq[]
Definition: listbox.c:2182
static void test_listbox(void)
Definition: listbox.c:2111
#define SIF_RANGE
Definition: winuser.h:1221
#define LB_FINDSTRINGEXACT
Definition: winuser.h:1996
static BOOL on_listbox_container_create(HWND hwnd, CREATESTRUCTA *lpcs)
Definition: listbox.c:1344
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define WM_LBUTTONDOWN
Definition: winuser.h:1752
#define LB_SETHORIZONTALEXTENT
Definition: winuser.h:2025
#define WideCharToMultiByte
Definition: compat.h:101
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
#define LB_ADDSTRING
Definition: winuser.h:1992
#define LB_GETHORIZONTALEXTENT
Definition: winuser.h:2001
#define MK_LBUTTON
Definition: winuser.h:2321
#define LBS_EXTENDEDSEL
Definition: pedump.c:689
#define LB_SETSEL
Definition: winuser.h:2029
static const char BAD_EXTENSION[]
Definition: listbox.c:90
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define SB_VERT
Definition: winuser.h:553
WORD ATOM
Definition: dimm.idl:113
Definition: mk_font.cpp:20
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define WM_NCCALCSIZE
Definition: winuser.h:1667
#define CP_ACP
Definition: compat.h:99
#define LB_GETITEMDATA
Definition: winuser.h:2002
GLuint GLuint GLsizei count
Definition: gl.h:1545
#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
Definition: msg.h:39
#define MAKELPARAM(l, h)
Definition: winuser.h:3915
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glext.h:5579
static HDC
Definition: imagelist.c:92
#define CALLBACK
Definition: compat.h:27
BOOL WINAPI UpdateWindow(_In_ HWND)
HWND hWnd
Definition: settings.c:17
static void test_listbox_height(void)
Definition: listbox.c:748
#define DDL_DIRECTORY
Definition: winuser.h:422
int cbClsExtra
Definition: winuser.h:3118
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
#define LBS_SORT
Definition: pedump.c:679
static NTSTATUS zero_data(device_extension *Vcb, fcb *fcb, UINT64 start, UINT64 length, PIRP Irp, LIST_ENTRY *rollback)
Definition: fsctl.c:1785
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
LPCSTR lpszMenuName
Definition: winuser.h:3124
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
static void unload_v6_module(ULONG_PTR cookie, HANDLE hCtx)
Definition: v6util.h:63
static void test_extents(void)
Definition: listbox.c:1932
#define WHITE_BRUSH
Definition: wingdi.h:901
HWND WINAPI SetFocus(_In_opt_ HWND)
ULONG_PTR itemData2
Definition: winuser.h:2949
static MONITORINFO mi
Definition: win.c:7331
#define WM_NCHITTEST
Definition: winuser.h:1668
static void test_set_count(void)
Definition: listbox.c:1833
#define test
Definition: rosglue.h:37
UINT_PTR WPARAM
Definition: windef.h:207
#define VK_DOWN
Definition: winuser.h:2181
HBRUSH hbrBackground
Definition: winuser.h:3123
#define WS_CHILD
Definition: pedump.c:617
#define listbox_ok(t, s, got)
Definition: listbox.c:204
Definition: bidi.c:78
#define SWP_NOZORDER
Definition: winuser.h:1232
static int got_selchange
Definition: listbox.c:329
int32_t INT_PTR
Definition: typedefs.h:62
static void test_GetListBoxInfo(void)
Definition: listbox.c:1887
START_TEST(listbox)
Definition: listbox.c:2407
struct listbox_stat sel sel_todo
Definition: listbox.c:170
#define LB_GETSELCOUNT
Definition: winuser.h:2008
BOOL WINAPI DestroyWindow(_In_ HWND)
#define LBN_SELCHANGE
Definition: winuser.h:2036
#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:2017
#define LBS_STANDARD
Definition: winuser.h:321
const GLfloat * m
Definition: glext.h:10848
static HWND g_label
Definition: listbox.c:1339
#define LB_GETANCHORINDEX
Definition: winuser.h:1997
static LRESULT WINAPI listbox_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: listbox.c:94
#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:2027
uint32_t ULONG_PTR
Definition: typedefs.h:63
static const struct message lb_addstring_sort_parent_seq[]
Definition: listbox.c:2190
#define WM_NCPAINT
Definition: winuser.h:1669
int cbWndExtra
Definition: winuser.h:3119
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:2016
LONG WINAPI GetWindowLongA(_In_ HWND, _In_ int)
int hash
Definition: main.c:58
#define LB_ERR
Definition: winuser.h:2386
static struct msg_sequence * sequences[NUM_MSG_SEQUENCES]
Definition: listbox.c:42
static BOOL load_v6_module(ULONG_PTR *pcookie, HANDLE *hCtx)
Definition: v6util.h:71
#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 GENERIC_WRITE
Definition: nt_native.h:90
HWND WINAPI GetCapture(void)
Definition: message.c:2879
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define ok(value,...)
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4184
HCURSOR hCursor
Definition: winuser.h:3122
static HWND create_parent(void)
Definition: listbox.c:439
static void init_msg_sequences(struct msg_sequence **seq, int n)
Definition: msg.h:391
#define CW_USEDEFAULT
Definition: winuser.h:225
#define GWLP_USERDATA
Definition: treelist.c:63
BOOL WINAPI IsRectEmpty(_In_ LPCRECT)
const WCHAR * str
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:622
#define WM_KEYDOWN
Definition: winuser.h:1691
LONG_PTR LPARAM
Definition: windef.h:208
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
#define MS
Definition: i386-dis.c:442
Definition: general.c:220
static void test_LBS_NODATA(void)
Definition: listbox.c:2297
_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_itemfrompoint(void)
Definition: listbox.c:787
#define LB_GETTEXTLEN
Definition: winuser.h:2011
BOOL WINAPI DlgDirSelectExA(_In_ HWND hwndDlg, _Out_writes_(chCount) LPSTR lpString, _In_ int chCount, _In_ int idListBox)
static unsigned hash_Ly(const char *str)
Definition: listbox.c:70
#define LB_GETCOUNT
Definition: winuser.h:1999
#define WM_SETTEXT
Definition: winuser.h:1599
#define WM_DESTROY
Definition: winuser.h:1591
#define ctrl
Definition: input.c:1669
#define GetWindowLongPtrA
Definition: winuser.h:4697
BOOL WINAPI IsWow64Process(IN HANDLE hProcess, OUT PBOOL Wow64Process)
Definition: proc.c:2004
#define todo_wine_if(is_todo)
Definition: test.h:155
ULONG_PTR itemData1
Definition: winuser.h:2947
static void test_listbox_item_data(void)
Definition: listbox.c:868
int selected
Definition: listbox.c:162
GLsizeiptr size
Definition: glext.h:5919
#define LB_SETTOPINDEX
Definition: winuser.h:2031
r parent
Definition: btrfs.c:2659
int selcount
Definition: listbox.c:162
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
static void test_listbox_LB_DIR(void)
Definition: listbox.c:889
__wchar_t WCHAR
Definition: xmlstorage.h:180
static LRESULT WINAPI main_window_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: listbox.c:331
#define WM_SIZE
Definition: winuser.h:1593
#define LB_OKAY
Definition: winuser.h:2385
HANDLE WINAPI GetCurrentProcess(VOID)
Definition: proc.c:1168
static BOOL is_wow64
Definition: loader.c:55
#define WM_WINDOWPOSCHANGING
Definition: winuser.h:1643
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 ok_sequence(seq, index, exp, contx, todo)
Definition: msg.h:387
#define LB_SELITEMRANGE
Definition: winuser.h:2018
BOOL WINAPI ValidateRect(_In_opt_ HWND, _In_opt_ LPCRECT)
#define WM_KEYUP
Definition: winuser.h:1692
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
#define WM_MEASUREITEM
Definition: winuser.h:1628
static BOOL RegisterListboxWindowClass(HINSTANCE hInst)
Definition: listbox.c:1377
int WINAPI GetClipBox(_In_ HDC, _Out_ LPRECT)
#define SetLastError(x)
Definition: compat.h:409
#define LB_SETITEMDATA
Definition: winuser.h:2026
#define OBJ_FONT
Definition: objidl.idl:1414
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
#define WM_PAINT
Definition: winuser.h:1602
static HWND create_listbox(DWORD add_style, HWND parent)
Definition: listbox.c:131
BOOL WINAPI GetScrollInfo(_In_ HWND, _In_ int, _Inout_ LPSCROLLINFO)
#define ID_TEST_LABEL
Definition: listbox.c:1341
static void test_LB_SETSEL(void)
Definition: listbox.c:694
int ret
GLsizei const GLchar *const * strings
Definition: glext.h:7622
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
Definition: msg.h:34
#define LB_GETTEXT
Definition: winuser.h:2010
#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)
BOOL WINAPI SetCurrentDirectoryA(IN LPCSTR lpPathName)
Definition: path.c:2205
static void flush_sequence(struct msg_sequence **seg, int sequence_index)
Definition: msg.h:89
ULONG_PTR itemData
Definition: winuser.h:3588
#define SetWindowLongPtrA
Definition: winuser.h:5214
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:819
unsigned char BYTE
Definition: mem.h:68
#define LRESULT
Definition: ole.h:14
Definition: _list.h:228
static const struct message empty_seq[]
Definition: listbox.c:2201
static void test_item_height(void)
Definition: listbox.c:293
#define GENERIC_READ
Definition: compat.h:124
#define WS_TABSTOP
Definition: pedump.c:634
Definition: time.h:76
#define ID_TEST_LISTBOX
Definition: listbox.c:1342
#define WM_COMMAND
Definition: winuser.h:1716
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
LPCSTR lpszClassName
Definition: winuser.h:3125
DWORD add_style
Definition: listbox.c:157
static void test_WM_MEASUREITEM(void)
Definition: listbox.c:2206
BOOL WINAPI MoveWindow(_In_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ BOOL)
#define LB_GETITEMHEIGHT
Definition: winuser.h:2003
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2059
#define GWLP_WNDPROC
Definition: treelist.c:66
int anchor
Definition: listbox.c:162
UINT style
Definition: winuser.h:3116
struct listbox_stat step step_todo
Definition: listbox.c:169
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2859
static void test_listbox_dlgdir(void)
Definition: listbox.c:1396
#define GWL_STYLE
Definition: winuser.h:846
#define listbox_test_query(exp, got)
Definition: listbox.c:534
HWND hList
Definition: livecd.c:10
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define DCX_CACHE
Definition: winuser.h:2075
static void run_test(DWORD style, const struct listbox_test test)
Definition: listbox.c:210
static void buttonpress(HWND handle, WORD x, WORD y)
Definition: listbox.c:181
#define WM_COMPAREITEM
Definition: winuser.h:1637
#define LB_FINDSTRING
Definition: winuser.h:1995
HINSTANCE hInst
Definition: dxdiag.c:13
#define WS_BORDER
Definition: pedump.c:625
#define LBS_NOTIFY
Definition: pedump.c:678
#define WS_EX_NOPARENTNOTIFY
Definition: pedump.c:646
#define LB_ITEMFROMPOINT
Definition: winuser.h:2015
static ATOM item
Definition: dde.c:856
BOOL WINAPI EqualRect(_In_ LPCRECT, _In_ LPCRECT)
static LRESULT CALLBACK listbox_container_window_procA(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
Definition: listbox.c:1358
#define LB_SETCOUNT
Definition: winuser.h:2023
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2053
HINSTANCE hInstance
Definition: winuser.h:3120
#define LBS_DISABLENOSCROLL
Definition: pedump.c:690
#define add_message(msg)
Definition: msg.c:2142
#define ARRAY_SIZE(a)
Definition: main.h:24
#define LB_GETTOPINDEX
Definition: winuser.h:2012
seq_index
Definition: edit.c:36
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_LBUTTONUP
Definition: winuser.h:1753
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2145
#define LB_GETCARETINDEX
Definition: winuser.h:1998
Definition: services.c:325
static void flush_sequences(struct msg_sequence **seq, int n)
Definition: msg.h:97
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:2000
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
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
#define KEYEVENTF_EXTENDEDKEY
Definition: winuser.h:1091
#define WM_SETFONT
Definition: winuser.h:1632
#define WM_DEVICECHANGE
Definition: winuser.h:1787
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define LBS_OWNERDRAWVARIABLE
Definition: pedump.c:683
WNDPROC lpfnWndProc
Definition: winuser.h:3117
#define ODT_LISTBOX
Definition: winuser.h:2492
#define WM_DRAWITEM
Definition: winuser.h:1627
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
#define LB_GETLISTBOXINFO
Definition: winuser.h:2005
#define WM_WINDOWPOSCHANGED
Definition: winuser.h:1644
static void keypress(HWND handle, WPARAM keycode, BYTE scancode, BOOL extended)
Definition: listbox.c:189
#define msg(x)
Definition: auth_time.c:54
#define IDC_ARROW
Definition: winuser.h:682
#define WC_LISTBOXA
Definition: commctrl.h:4681
#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)
static HWND g_listBox
Definition: listbox.c:1338
#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 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:2004
#define CREATE_NEW
Definition: disk.h:69
#define LBS_NOSEL
Definition: winuser.h:316
#define WM_ERASEBKGND
Definition: winuser.h:1607
static unsigned hash_Ly_W(const WCHAR *str)
Definition: listbox.c:60
#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 ERROR_NO_WILDCARD_CHARACTERS
Definition: winerror.h:898
Arabic default style
Definition: afstyles.h:93
#define LB_DELETESTRING
Definition: winuser.h:1993
#define WS_VISIBLE
Definition: pedump.c:620
Definition: _hash_fun.h:40
GLuint64EXT * result
Definition: glext.h:11304
#define memset(x, y, z)
Definition: compat.h:39
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
#define LB_INSERTSTRING
Definition: winuser.h:2014
LPARAM lParam
Definition: combotst.c:139
static void test_LB_SETCURSEL(void)
Definition: listbox.c:618
struct listbox_stat click click_todo
Definition: listbox.c:168
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
#define ID_LISTBOX
Definition: listbox.c:92
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
HICON hIcon
Definition: winuser.h:3121
Definition: fci.c:126