Expand conformance registry entry test to handle registry entries that
[wine] / dlls / user / tests / listbox.c
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #include <assert.h>
21 #include <windows.h>
22
23 #include "wine/test.h"
24
25 #ifdef VISIBLE
26 #define WAIT Sleep (1000)
27 #define REDRAW RedrawWindow (handle, NULL, 0, RDW_UPDATENOW)
28 #else
29 #define WAIT
30 #define REDRAW
31 #endif
32
33 HWND
34 create_listbox (DWORD add_style)
35 {
36   HWND handle=CreateWindow ("LISTBOX", "TestList",
37                             (LBS_STANDARD & ~LBS_SORT) | add_style,
38                             0, 0, 100, 100,
39                             NULL, NULL, NULL, 0);
40
41   assert (handle);
42   SendMessage (handle, LB_ADDSTRING, 0, (LPARAM) (LPCTSTR) "First added");
43   SendMessage (handle, LB_ADDSTRING, 0, (LPARAM) (LPCTSTR) "Second added");
44   SendMessage (handle, LB_ADDSTRING, 0, (LPARAM) (LPCTSTR) "Third added");
45
46 #ifdef VISIBLE
47   ShowWindow (handle, SW_SHOW);
48 #endif
49   REDRAW;
50
51   return handle;
52 }
53
54 struct listbox_prop {
55   DWORD add_style;
56 };
57
58 struct listbox_stat {
59   int selected, anchor, caret, selcount;
60 };
61
62 struct listbox_test {
63   struct listbox_prop prop;
64   struct listbox_stat  init,  init_todo;
65   struct listbox_stat click, click_todo;
66   struct listbox_stat  step,  step_todo;
67   struct listbox_stat   sel,   sel_todo;
68 };
69
70 void
71 listbox_query (HWND handle, struct listbox_stat *results)
72 {
73   results->selected = SendMessage (handle, LB_GETCURSEL, 0, 0);
74   results->anchor   = SendMessage (handle, LB_GETANCHORINDEX, 0, 0);
75   results->caret    = SendMessage (handle, LB_GETCARETINDEX, 0, 0);
76   results->selcount = SendMessage (handle, LB_GETSELCOUNT, 0, 0);
77 }
78
79 void
80 buttonpress (HWND handle, WORD x, WORD y)
81 {
82   LPARAM lp=x+(y<<16);
83
84   WAIT;
85   SendMessage (handle, WM_LBUTTONDOWN, (WPARAM) MK_LBUTTON, lp);
86   SendMessage (handle, WM_LBUTTONUP  , (WPARAM) 0         , lp);
87   REDRAW;
88 }
89
90 void
91 keypress (HWND handle, WPARAM keycode, BYTE scancode, BOOL extended)
92 {
93   LPARAM lp=1+(scancode<<16)+(extended?KEYEVENTF_EXTENDEDKEY:0);
94
95   WAIT;
96   SendMessage (handle, WM_KEYDOWN, keycode, lp);
97   SendMessage (handle, WM_KEYUP  , keycode, lp | 0xc000000);
98   REDRAW;
99 }
100
101 #define listbox_field_ok(t, s, f, got) \
102   ok (t.s.f==got.f, "style %#x, step " #s ", field " #f \
103       ": expected %d, got %d\n", (unsigned int)t.prop.add_style, \
104       t.s.f, got.f)
105
106 #define listbox_todo_field_ok(t, s, f, got) \
107   if (t.s##_todo.f) todo_wine { listbox_field_ok(t, s, f, got); } \
108   else listbox_field_ok(t, s, f, got)
109
110 #define listbox_ok(t, s, got) \
111   listbox_todo_field_ok(t, s, selected, got); \
112   listbox_todo_field_ok(t, s, anchor, got); \
113   listbox_todo_field_ok(t, s, caret, got); \
114   listbox_todo_field_ok(t, s, selcount, got)
115
116 void
117 check (const struct listbox_test test)
118 {
119   struct listbox_stat answer;
120   HWND hLB=create_listbox (test.prop.add_style);
121   RECT second_item;
122
123   listbox_query (hLB, &answer);
124   listbox_ok (test, init, answer);
125
126   SendMessage (hLB, LB_GETITEMRECT, (WPARAM) 1, (LPARAM) &second_item);
127   buttonpress(hLB, (WORD)second_item.left, (WORD)second_item.top);
128
129   listbox_query (hLB, &answer);
130   listbox_ok (test, click, answer);
131
132   keypress (hLB, VK_DOWN, 0x50, TRUE);
133
134   listbox_query (hLB, &answer);
135   listbox_ok (test, step, answer);
136
137   DestroyWindow (hLB);
138   hLB=create_listbox (test.prop.add_style);
139
140   SendMessage (hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(1, 2));
141   listbox_query (hLB, &answer);
142   listbox_ok (test, sel, answer);
143   
144   WAIT;
145   DestroyWindow (hLB);
146 }
147
148 void check_item_height()
149 {
150     HWND hLB;
151     HDC hdc;
152     HFONT font;
153     TEXTMETRICW tm;
154     INT itemHeight;
155
156     hLB = create_listbox (0);
157     ok ((hdc = GetDCEx( hLB, 0, DCX_CACHE )) != 0, "Can't get hdc\n");
158     ok ((font = GetCurrentObject(hdc, OBJ_FONT)) != 0, "Can't get the current font\n");
159     ok (GetTextMetricsW( hdc, &tm ), "Can't read font metrics\n");
160     ReleaseDC( hLB, hdc);
161
162     ok (SendMessageW(hLB, WM_SETFONT, (WPARAM)font, 0) == 0, "Can't set font\n");
163
164     itemHeight = SendMessageW(hLB, LB_GETITEMHEIGHT, 0, 0);
165     ok (itemHeight == tm.tmHeight, "Item height wrong, got %d, expecting %ld\n", itemHeight, tm.tmHeight);
166
167     DestroyWindow (hLB);
168 }
169
170 START_TEST(listbox)
171 {
172   const struct listbox_test SS =
173 /*   {add_style} */
174     {{0},
175      {LB_ERR, LB_ERR,      0, LB_ERR}, {0,0,0,0},
176      {     1,      1,      1, LB_ERR}, {0,0,0,0},
177      {     2,      2,      2, LB_ERR}, {0,0,0,0},
178      {LB_ERR, LB_ERR,      0, LB_ERR}, {0,0,0,0}};
179 /* {selected, anchor,  caret, selcount}{TODO fields} */
180   const struct listbox_test SS_NS =
181     {{LBS_NOSEL},
182      {LB_ERR, LB_ERR,      0, LB_ERR}, {0,0,0,0},
183      {     1,      1,      1, LB_ERR}, {0,0,0,0},
184      {     2,      2,      2, LB_ERR}, {0,0,0,0},
185      {LB_ERR, LB_ERR,      0, LB_ERR}, {0,0,0,0}};
186   const struct listbox_test MS =
187     {{LBS_MULTIPLESEL},
188      {     0, LB_ERR,      0,      0}, {0,0,0,0},
189      {     1,      1,      1,      1}, {0,0,0,0},
190      {     2,      1,      2,      1}, {0,0,0,0},
191      {     0, LB_ERR,      0,      2}, {0,0,0,0}};
192   const struct listbox_test MS_NS =
193     {{LBS_MULTIPLESEL | LBS_NOSEL},
194      {LB_ERR, LB_ERR,      0, LB_ERR}, {0,0,0,0},
195      {     1,      1,      1, LB_ERR}, {0,0,0,0},
196      {     2,      2,      2, LB_ERR}, {0,0,0,0},
197      {LB_ERR, LB_ERR,      0, LB_ERR}, {0,0,0,0}};
198   const struct listbox_test ES =
199     {{LBS_EXTENDEDSEL},
200      {     0, LB_ERR,      0,      0}, {0,0,0,0},
201      {     1,      1,      1,      1}, {0,0,0,0},
202      {     2,      2,      2,      1}, {0,0,0,0},
203      {     0, LB_ERR,      0,      2}, {0,0,0,0}};
204   const struct listbox_test ES_NS =
205     {{LBS_EXTENDEDSEL | LBS_NOSEL},
206      {LB_ERR, LB_ERR,      0, LB_ERR}, {0,0,0,0},
207      {     1,      1,      1, LB_ERR}, {0,0,0,0},
208      {     2,      2,      2, LB_ERR}, {0,0,0,0},
209      {LB_ERR, LB_ERR,      0, LB_ERR}, {0,0,0,0}};
210   const struct listbox_test EMS =
211     {{LBS_EXTENDEDSEL | LBS_MULTIPLESEL},
212      {     0, LB_ERR,      0,      0}, {0,0,0,0},
213      {     1,      1,      1,      1}, {0,0,0,0},
214      {     2,      2,      2,      1}, {0,0,0,0},
215      {     0, LB_ERR,      0,      2}, {0,0,0,0}};
216   const struct listbox_test EMS_NS =
217     {{LBS_EXTENDEDSEL | LBS_MULTIPLESEL | LBS_NOSEL},
218      {LB_ERR, LB_ERR,      0, LB_ERR}, {0,0,0,0},
219      {     1,      1,      1, LB_ERR}, {0,0,0,0},
220      {     2,      2,      2, LB_ERR}, {0,0,0,0},
221      {LB_ERR, LB_ERR,      0, LB_ERR}, {0,0,0,0}};
222
223   trace (" Testing single selection...\n");
224   check (SS);
225   trace (" ... with NOSEL\n");
226   check (SS_NS);
227   trace (" Testing multiple selection...\n");
228   check (MS);
229   trace (" ... with NOSEL\n");
230   check (MS_NS);
231   trace (" Testing extended selection...\n");
232   check (ES);
233   trace (" ... with NOSEL\n");
234   check (ES_NS);
235   trace (" Testing extended and multiple selection...\n");
236   check (EMS);
237   trace (" ... with NOSEL\n");
238   check (EMS_NS);
239
240   check_item_height();
241 }