push 4d5485f9b89f417d46b39b93e8d940437007f325
[wine/hacks.git] / dlls / user32 / tests / listbox.c
blob663e37f16d8456985fc763e795703daf0399de60
1 /* Unit test suite for list boxes.
3 * Copyright 2003 Ferenc Wagner
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.
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.
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
20 #include <assert.h>
21 #include <stdarg.h>
22 #include <stdio.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wingdi.h"
27 #include "winuser.h"
28 #include "winnls.h"
30 #include "wine/test.h"
32 #ifdef VISIBLE
33 #define WAIT Sleep (1000)
34 #define REDRAW RedrawWindow (handle, NULL, 0, RDW_UPDATENOW)
35 #else
36 #define WAIT
37 #define REDRAW
38 #endif
40 static const char * const strings[4] = {
41 "First added",
42 "Second added",
43 "Third added",
44 "Fourth added which is very long because at some time we only had a 256 byte character buffer and that was overflowing in one of those applications that had a common dialog file open box and tried to add a 300 characters long custom filter string which of course the code did not like and crashed. Just make sure this string is longer than 256 characters."
47 static HWND
48 create_listbox (DWORD add_style, HWND parent)
50 HWND handle;
51 int ctl_id=0;
52 if (parent)
53 ctl_id=1;
54 handle=CreateWindow ("LISTBOX", "TestList",
55 (LBS_STANDARD & ~LBS_SORT) | add_style,
56 0, 0, 100, 100,
57 parent, (HMENU)ctl_id, NULL, 0);
59 assert (handle);
60 SendMessage (handle, LB_ADDSTRING, 0, (LPARAM) (LPCTSTR) strings[0]);
61 SendMessage (handle, LB_ADDSTRING, 0, (LPARAM) (LPCTSTR) strings[1]);
62 SendMessage (handle, LB_ADDSTRING, 0, (LPARAM) (LPCTSTR) strings[2]);
63 SendMessage (handle, LB_ADDSTRING, 0, (LPARAM) (LPCTSTR) strings[3]);
65 #ifdef VISIBLE
66 ShowWindow (handle, SW_SHOW);
67 #endif
68 REDRAW;
70 return handle;
73 struct listbox_prop {
74 DWORD add_style;
77 struct listbox_stat {
78 int selected, anchor, caret, selcount;
81 struct listbox_test {
82 struct listbox_prop prop;
83 struct listbox_stat init, init_todo;
84 struct listbox_stat click, click_todo;
85 struct listbox_stat step, step_todo;
86 struct listbox_stat sel, sel_todo;
89 static void
90 listbox_query (HWND handle, struct listbox_stat *results)
92 results->selected = SendMessage (handle, LB_GETCURSEL, 0, 0);
93 results->anchor = SendMessage (handle, LB_GETANCHORINDEX, 0, 0);
94 results->caret = SendMessage (handle, LB_GETCARETINDEX, 0, 0);
95 results->selcount = SendMessage (handle, LB_GETSELCOUNT, 0, 0);
98 static void
99 buttonpress (HWND handle, WORD x, WORD y)
101 LPARAM lp=x+(y<<16);
103 WAIT;
104 SendMessage (handle, WM_LBUTTONDOWN, (WPARAM) MK_LBUTTON, lp);
105 SendMessage (handle, WM_LBUTTONUP , (WPARAM) 0 , lp);
106 REDRAW;
109 static void
110 keypress (HWND handle, WPARAM keycode, BYTE scancode, BOOL extended)
112 LPARAM lp=1+(scancode<<16)+(extended?KEYEVENTF_EXTENDEDKEY:0);
114 WAIT;
115 SendMessage (handle, WM_KEYDOWN, keycode, lp);
116 SendMessage (handle, WM_KEYUP , keycode, lp | 0xc000000);
117 REDRAW;
120 #define listbox_field_ok(t, s, f, got) \
121 ok (t.s.f==got.f, "style %#x, step " #s ", field " #f \
122 ": expected %d, got %d\n", (unsigned int)t.prop.add_style, \
123 t.s.f, got.f)
125 #define listbox_todo_field_ok(t, s, f, got) \
126 if (t.s##_todo.f) todo_wine { listbox_field_ok(t, s, f, got); } \
127 else listbox_field_ok(t, s, f, got)
129 #define listbox_ok(t, s, got) \
130 listbox_todo_field_ok(t, s, selected, got); \
131 listbox_todo_field_ok(t, s, anchor, got); \
132 listbox_todo_field_ok(t, s, caret, got); \
133 listbox_todo_field_ok(t, s, selcount, got)
135 static void
136 check (const struct listbox_test test)
138 struct listbox_stat answer;
139 HWND hLB=create_listbox (test.prop.add_style, 0);
140 RECT second_item;
141 int i;
142 int res;
144 listbox_query (hLB, &answer);
145 listbox_ok (test, init, answer);
147 SendMessage (hLB, LB_GETITEMRECT, (WPARAM) 1, (LPARAM) &second_item);
148 buttonpress(hLB, (WORD)second_item.left, (WORD)second_item.top);
150 listbox_query (hLB, &answer);
151 listbox_ok (test, click, answer);
153 keypress (hLB, VK_DOWN, 0x50, TRUE);
155 listbox_query (hLB, &answer);
156 listbox_ok (test, step, answer);
158 DestroyWindow (hLB);
159 hLB=create_listbox (test.prop.add_style, 0);
161 SendMessage (hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(1, 2));
162 listbox_query (hLB, &answer);
163 listbox_ok (test, sel, answer);
165 for (i=0;i<4;i++) {
166 DWORD size = SendMessage (hLB, LB_GETTEXTLEN, i, 0);
167 CHAR *txt;
168 WCHAR *txtw;
170 txt = HeapAlloc (GetProcessHeap(), 0, size+1);
171 SendMessageA(hLB, LB_GETTEXT, i, (LPARAM)txt);
172 ok(!strcmp (txt, strings[i]), "returned string for item %d does not match %s vs %s\n", i, txt, strings[i]);
174 txtw = HeapAlloc (GetProcessHeap(), 0, 2*size+2);
175 SendMessageW(hLB, LB_GETTEXT, i, (LPARAM)txtw);
176 WideCharToMultiByte( CP_ACP, 0, txtw, -1, txt, size, NULL, NULL );
177 ok(!strcmp (txt, strings[i]), "returned string for item %d does not match %s vs %s\n", i, txt, strings[i]);
179 HeapFree (GetProcessHeap(), 0, txtw);
180 HeapFree (GetProcessHeap(), 0, txt);
183 /* Confirm the count of items, and that an invalid delete does not remove anything */
184 res = SendMessage (hLB, LB_GETCOUNT, 0, 0);
185 ok((res==4), "Expected 4 items, got %d\n", res);
186 res = SendMessage (hLB, LB_DELETESTRING, -1, 0);
187 ok((res==LB_ERR), "Expected LB_ERR items, got %d\n", res);
188 res = SendMessage (hLB, LB_DELETESTRING, 4, 0);
189 ok((res==LB_ERR), "Expected LB_ERR items, got %d\n", res);
190 res = SendMessage (hLB, LB_GETCOUNT, 0, 0);
191 ok((res==4), "Expected 4 items, got %d\n", res);
193 WAIT;
194 DestroyWindow (hLB);
197 static void check_item_height(void)
199 HWND hLB;
200 HDC hdc;
201 HFONT font;
202 TEXTMETRIC tm;
203 INT itemHeight;
205 hLB = create_listbox (0, 0);
206 ok ((hdc = GetDCEx( hLB, 0, DCX_CACHE )) != 0, "Can't get hdc\n");
207 ok ((font = GetCurrentObject(hdc, OBJ_FONT)) != 0, "Can't get the current font\n");
208 ok (GetTextMetrics( hdc, &tm ), "Can't read font metrics\n");
209 ReleaseDC( hLB, hdc);
211 ok (SendMessage(hLB, WM_SETFONT, (WPARAM)font, 0) == 0, "Can't set font\n");
213 itemHeight = SendMessage(hLB, LB_GETITEMHEIGHT, 0, 0);
214 ok (itemHeight == tm.tmHeight, "Item height wrong, got %d, expecting %d\n", itemHeight, tm.tmHeight);
216 DestroyWindow (hLB);
218 hLB = CreateWindow ("LISTBOX", "TestList", LBS_OWNERDRAWVARIABLE,
219 0, 0, 100, 100, NULL, NULL, NULL, 0);
220 itemHeight = SendMessage(hLB, LB_GETITEMHEIGHT, 0, 0);
221 ok(itemHeight == tm.tmHeight, "itemHeight %d\n", itemHeight);
222 itemHeight = SendMessage(hLB, LB_GETITEMHEIGHT, 5, 0);
223 ok(itemHeight == tm.tmHeight, "itemHeight %d\n", itemHeight);
224 itemHeight = SendMessage(hLB, LB_GETITEMHEIGHT, -5, 0);
225 ok(itemHeight == tm.tmHeight, "itemHeight %d\n", itemHeight);
226 DestroyWindow (hLB);
229 static LRESULT WINAPI main_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
231 switch (msg)
233 case WM_DRAWITEM:
235 RECT rc_item, rc_client, rc_clip;
236 DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lparam;
238 trace("%p WM_DRAWITEM %08lx %08lx\n", hwnd, wparam, lparam);
240 ok(wparam == dis->CtlID, "got wParam=%08lx instead of %08x\n",
241 wparam, dis->CtlID);
242 ok(dis->CtlType == ODT_LISTBOX, "wrong CtlType %04x\n", dis->CtlType);
244 GetClientRect(dis->hwndItem, &rc_client);
245 trace("hwndItem %p client rect (%d,%d-%d,%d)\n", dis->hwndItem,
246 rc_client.left, rc_client.top, rc_client.right, rc_client.bottom);
247 GetClipBox(dis->hDC, &rc_clip);
248 trace("clip rect (%d,%d-%d,%d)\n", rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
249 ok(EqualRect(&rc_client, &rc_clip), "client rect of the listbox should be equal to the clip box\n");
251 trace("rcItem (%d,%d-%d,%d)\n", dis->rcItem.left, dis->rcItem.top,
252 dis->rcItem.right, dis->rcItem.bottom);
253 SendMessage(dis->hwndItem, LB_GETITEMRECT, dis->itemID, (LPARAM)&rc_item);
254 trace("item rect (%d,%d-%d,%d)\n", rc_item.left, rc_item.top, rc_item.right, rc_item.bottom);
255 ok(EqualRect(&dis->rcItem, &rc_item), "item rects are not equal\n");
257 break;
260 default:
261 break;
264 return DefWindowProc(hwnd, msg, wparam, lparam);
267 static void test_ownerdraw(void)
269 WNDCLASS cls;
270 HWND parent, hLB;
271 INT ret;
272 RECT rc;
274 cls.style = 0;
275 cls.lpfnWndProc = main_window_proc;
276 cls.cbClsExtra = 0;
277 cls.cbWndExtra = 0;
278 cls.hInstance = GetModuleHandle(0);
279 cls.hIcon = 0;
280 cls.hCursor = LoadCursor(0, (LPSTR)IDC_ARROW);
281 cls.hbrBackground = GetStockObject(WHITE_BRUSH);
282 cls.lpszMenuName = NULL;
283 cls.lpszClassName = "main_window_class";
284 assert(RegisterClass(&cls));
286 parent = CreateWindowEx(0, "main_window_class", NULL,
287 WS_POPUP | WS_VISIBLE,
288 100, 100, 400, 400,
289 GetDesktopWindow(), 0,
290 GetModuleHandle(0), NULL);
291 assert(parent);
293 hLB = create_listbox(LBS_OWNERDRAWFIXED | WS_CHILD | WS_VISIBLE, parent);
294 assert(hLB);
296 UpdateWindow(hLB);
298 /* make height short enough */
299 SendMessage(hLB, LB_GETITEMRECT, 0, (LPARAM)&rc);
300 SetWindowPos(hLB, 0, 0, 0, 100, rc.bottom - rc.top + 1,
301 SWP_NOZORDER | SWP_NOMOVE);
303 /* make 0 item invisible */
304 SendMessage(hLB, LB_SETTOPINDEX, 1, 0);
305 ret = SendMessage(hLB, LB_GETTOPINDEX, 0, 0);
306 ok(ret == 1, "wrong top index %d\n", ret);
308 SendMessage(hLB, LB_GETITEMRECT, 0, (LPARAM)&rc);
309 trace("item 0 rect (%d,%d-%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom);
310 ok(!IsRectEmpty(&rc), "empty item rect\n");
311 ok(rc.top < 0, "rc.top is not negative (%d)\n", rc.top);
313 DestroyWindow(hLB);
314 DestroyWindow(parent);
317 #define listbox_test_query(exp, got) \
318 ok(exp.selected == got.selected, "expected selected %d, got %d\n", exp.selected, got.selected); \
319 ok(exp.anchor == got.anchor, "expected anchor %d, got %d\n", exp.anchor, got.anchor); \
320 ok(exp.caret == got.caret, "expected caret %d, got %d\n", exp.caret, got.caret); \
321 ok(exp.selcount == got.selcount, "expected selcount %d, got %d\n", exp.selcount, got.selcount);
323 static void test_selection(void)
325 static const struct listbox_stat test_nosel = { 0, LB_ERR, 0, 0 };
326 static const struct listbox_stat test_1 = { 0, LB_ERR, 0, 2 };
327 static const struct listbox_stat test_2 = { 0, LB_ERR, 0, 3 };
328 static const struct listbox_stat test_3 = { 0, LB_ERR, 0, 4 };
329 HWND hLB;
330 struct listbox_stat answer;
331 INT ret;
333 trace("testing LB_SELITEMRANGE\n");
335 hLB = create_listbox(LBS_EXTENDEDSEL, 0);
336 assert(hLB);
338 listbox_query(hLB, &answer);
339 listbox_test_query(test_nosel, answer);
341 ret = SendMessage(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(1, 2));
342 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
343 listbox_query(hLB, &answer);
344 listbox_test_query(test_1, answer);
346 SendMessage(hLB, LB_SETSEL, FALSE, (LPARAM)-1);
347 listbox_query(hLB, &answer);
348 listbox_test_query(test_nosel, answer);
350 ret = SendMessage(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(0, 4));
351 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
352 listbox_query(hLB, &answer);
353 listbox_test_query(test_3, answer);
355 SendMessage(hLB, LB_SETSEL, FALSE, (LPARAM)-1);
356 listbox_query(hLB, &answer);
357 listbox_test_query(test_nosel, answer);
359 ret = SendMessage(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(-5, 5));
360 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
361 listbox_query(hLB, &answer);
362 listbox_test_query(test_nosel, answer);
364 SendMessage(hLB, LB_SETSEL, FALSE, (LPARAM)-1);
365 listbox_query(hLB, &answer);
366 listbox_test_query(test_nosel, answer);
368 ret = SendMessage(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(2, 10));
369 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
370 listbox_query(hLB, &answer);
371 listbox_test_query(test_1, answer);
373 SendMessage(hLB, LB_SETSEL, FALSE, (LPARAM)-1);
374 listbox_query(hLB, &answer);
375 listbox_test_query(test_nosel, answer);
377 ret = SendMessage(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(4, 10));
378 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
379 listbox_query(hLB, &answer);
380 listbox_test_query(test_nosel, answer);
382 SendMessage(hLB, LB_SETSEL, FALSE, (LPARAM)-1);
383 listbox_query(hLB, &answer);
384 listbox_test_query(test_nosel, answer);
386 ret = SendMessage(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(10, 1));
387 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
388 listbox_query(hLB, &answer);
389 listbox_test_query(test_2, answer);
391 SendMessage(hLB, LB_SETSEL, FALSE, (LPARAM)-1);
392 listbox_query(hLB, &answer);
393 listbox_test_query(test_nosel, answer);
395 ret = SendMessage(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(1, -1));
396 ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret);
397 listbox_query(hLB, &answer);
398 listbox_test_query(test_2, answer);
400 DestroyWindow(hLB);
403 static void test_listbox_height(void)
405 HWND hList;
406 int r, id;
408 hList = CreateWindow( "ListBox", "list test", 0,
409 1, 1, 600, 100, NULL, NULL, NULL, NULL );
410 ok( hList != NULL, "failed to create listbox\n");
412 id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi");
413 ok( id == 0, "item id wrong\n");
415 r = SendMessage( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 20, 0 ));
416 ok( r == 0, "send message failed\n");
418 r = SendMessage(hList, LB_GETITEMHEIGHT, 0, 0 );
419 ok( r == 20, "height wrong\n");
421 r = SendMessage( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 0, 30 ));
422 ok( r == -1, "send message failed\n");
424 r = SendMessage(hList, LB_GETITEMHEIGHT, 0, 0 );
425 ok( r == 20, "height wrong\n");
427 r = SendMessage( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 0x100, 0 ));
428 ok( r == -1, "send message failed\n");
430 r = SendMessage(hList, LB_GETITEMHEIGHT, 0, 0 );
431 ok( r == 20, "height wrong\n");
433 r = SendMessage( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 0xff, 0 ));
434 ok( r == 0, "send message failed\n");
436 r = SendMessage(hList, LB_GETITEMHEIGHT, 0, 0 );
437 ok( r == 0xff, "height wrong\n");
439 DestroyWindow( hList );
442 static void test_itemfrompoint(void)
444 HWND hList = CreateWindow( "ListBox", "list test", 0,
445 1, 1, 600, 100, NULL, NULL, NULL, NULL );
446 LONG r, id;
447 RECT rc;
449 /* For an empty listbox win2k returns 0x1ffff, win98 returns 0x10000 */
450 r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
451 ok( r == 0x1ffff || r == 0x10000, "ret %x\n", r );
453 r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( 700, 30 ));
454 ok( r == 0x1ffff || r == 0x10000, "ret %x\n", r );
456 r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( 30, 300 ));
457 ok( r == 0x1ffff || r == 0x10000, "ret %x\n", r );
459 id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi");
460 ok( id == 0, "item id wrong\n");
461 id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi1");
462 ok( id == 1, "item id wrong\n");
464 r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
465 ok( r == 0x1, "ret %x\n", r );
467 r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 37 ));
468 ok( r == 0x10001, "ret %x\n", r );
472 id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi2");
473 ok( id == 2, "item id wrong\n");
474 id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi3");
475 ok( id == 3, "item id wrong\n");
476 id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi4");
477 ok( id == 4, "item id wrong\n");
478 id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi5");
479 ok( id == 5, "item id wrong\n");
480 id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi6");
481 ok( id == 6, "item id wrong\n");
482 id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi7");
483 ok( id == 7, "item id wrong\n");
485 /* Set the listbox up so that id 1 is at the top, this leaves 5
486 partially visible at the bottom and 6, 7 are invisible */
488 SendMessage( hList, LB_SETTOPINDEX, 1, 0);
489 r = SendMessage( hList, LB_GETTOPINDEX, 0, 0);
490 ok( r == 1, "top %d\n", r);
492 r = SendMessage( hList, LB_GETITEMRECT, 5, (LPARAM)&rc);
493 ok( r == 1, "ret %x\n", r);
494 r = SendMessage( hList, LB_GETITEMRECT, 6, (LPARAM)&rc);
495 ok( r == 0, "ret %x\n", r);
497 r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(/* x */ 10, /* y */ 10) );
498 ok( r == 1, "ret %x\n", r);
500 r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(1000, 10) );
501 ok( r == 0x10001, "ret %x\n", r );
503 r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, -10) );
504 ok( r == 0x10001, "ret %x\n", r );
506 r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, 100) );
507 ok( r == 0x10005, "item %x\n", r );
509 r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, 200) );
510 ok( r == 0x10005, "item %x\n", r );
512 DestroyWindow( hList );
515 static void test_listbox_item_data(void)
517 HWND hList;
518 int r, id;
520 hList = CreateWindow( "ListBox", "list test", 0,
521 1, 1, 600, 100, NULL, NULL, NULL, NULL );
522 ok( hList != NULL, "failed to create listbox\n");
524 id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi");
525 ok( id == 0, "item id wrong\n");
527 r = SendMessage( hList, LB_SETITEMDATA, 0, MAKELPARAM( 20, 0 ));
528 ok(r == TRUE, "LB_SETITEMDATA returned %d instead of TRUE\n", r);
530 r = SendMessage( hList, LB_GETITEMDATA, 0, 0);
531 ok( r == 20, "get item data failed\n");
533 DestroyWindow( hList );
536 START_TEST(listbox)
538 const struct listbox_test SS =
539 /* {add_style} */
540 {{0},
541 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
542 { 1, 1, 1, LB_ERR}, {0,0,0,0},
543 { 2, 2, 2, LB_ERR}, {0,0,0,0},
544 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
545 /* {selected, anchor, caret, selcount}{TODO fields} */
546 const struct listbox_test SS_NS =
547 {{LBS_NOSEL},
548 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
549 { 1, 1, 1, LB_ERR}, {0,0,0,0},
550 { 2, 2, 2, LB_ERR}, {0,0,0,0},
551 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
552 const struct listbox_test MS =
553 {{LBS_MULTIPLESEL},
554 { 0, LB_ERR, 0, 0}, {0,0,0,0},
555 { 1, 1, 1, 1}, {0,0,0,0},
556 { 2, 1, 2, 1}, {0,0,0,0},
557 { 0, LB_ERR, 0, 2}, {0,0,0,0}};
558 const struct listbox_test MS_NS =
559 {{LBS_MULTIPLESEL | LBS_NOSEL},
560 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
561 { 1, 1, 1, LB_ERR}, {0,0,0,0},
562 { 2, 2, 2, LB_ERR}, {0,0,0,0},
563 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
564 const struct listbox_test ES =
565 {{LBS_EXTENDEDSEL},
566 { 0, LB_ERR, 0, 0}, {0,0,0,0},
567 { 1, 1, 1, 1}, {0,0,0,0},
568 { 2, 2, 2, 1}, {0,0,0,0},
569 { 0, LB_ERR, 0, 2}, {0,0,0,0}};
570 const struct listbox_test ES_NS =
571 {{LBS_EXTENDEDSEL | LBS_NOSEL},
572 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
573 { 1, 1, 1, LB_ERR}, {0,0,0,0},
574 { 2, 2, 2, LB_ERR}, {0,0,0,0},
575 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
576 const struct listbox_test EMS =
577 {{LBS_EXTENDEDSEL | LBS_MULTIPLESEL},
578 { 0, LB_ERR, 0, 0}, {0,0,0,0},
579 { 1, 1, 1, 1}, {0,0,0,0},
580 { 2, 2, 2, 1}, {0,0,0,0},
581 { 0, LB_ERR, 0, 2}, {0,0,0,0}};
582 const struct listbox_test EMS_NS =
583 {{LBS_EXTENDEDSEL | LBS_MULTIPLESEL | LBS_NOSEL},
584 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
585 { 1, 1, 1, LB_ERR}, {0,0,0,0},
586 { 2, 2, 2, LB_ERR}, {0,0,0,0},
587 {LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
589 trace (" Testing single selection...\n");
590 check (SS);
591 trace (" ... with NOSEL\n");
592 check (SS_NS);
593 trace (" Testing multiple selection...\n");
594 check (MS);
595 trace (" ... with NOSEL\n");
596 check (MS_NS);
597 trace (" Testing extended selection...\n");
598 check (ES);
599 trace (" ... with NOSEL\n");
600 check (ES_NS);
601 trace (" Testing extended and multiple selection...\n");
602 check (EMS);
603 trace (" ... with NOSEL\n");
604 check (EMS_NS);
606 check_item_height();
607 test_ownerdraw();
608 test_selection();
609 test_listbox_height();
610 test_itemfrompoint();
611 test_listbox_item_data();