- Fix test. ATM AW and WA testing is going well.
[reactos.git] / rostests / winetests / user32 / combo.c
1 /* Unit test suite for combo boxes.
2 *
3 * Copyright 2007 Mikolaj Zalewski
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 #define STRICT
24 #define WIN32_LEAN_AND_MEAN
25 #include <windows.h>
26
27 #include "wine/test.h"
28
29 #define COMBO_ID 1995
30
31 static HWND hMainWnd;
32
33 #define expect_eq(expr, value, type, fmt); { type val = expr; ok(val == (value), #expr " expected " #fmt " got " #fmt "\n", (value), val); }
34 #define expect_rect(r, _left, _top, _right, _bottom) ok(r.left == _left && r.top == _top && \
35 r.bottom == _bottom && r.right == _right, "Invalid rect (%d,%d) (%d,%d) vs (%d,%d) (%d,%d)\n", \
36 r.left, r.top, r.right, r.bottom, _left, _top, _right, _bottom);
37
38 static HWND build_combo(DWORD style)
39 {
40 return CreateWindowA("ComboBox", "Combo", WS_VISIBLE|WS_CHILD|style, 5, 5, 100, 100, hMainWnd, (HMENU)COMBO_ID, NULL, 0);
41 }
42
43 static int font_height(HFONT hFont)
44 {
45 TEXTMETRICA tm;
46 HFONT hFontOld;
47 HDC hDC;
48
49 hDC = CreateCompatibleDC(NULL);
50 hFontOld = SelectObject(hDC, hFont);
51 GetTextMetricsA(hDC, &tm);
52 SelectObject(hDC, hFontOld);
53 DeleteDC(hDC);
54
55 return tm.tmHeight;
56 }
57
58 static INT CALLBACK is_font_installed_proc(const LOGFONTA *elf, const TEXTMETRICA *tm, DWORD type, LPARAM lParam)
59 {
60 return 0;
61 }
62
63 static int is_font_installed(const char *name)
64 {
65 HDC hdc = GetDC(NULL);
66 BOOL ret = !EnumFontFamiliesA(hdc, name, is_font_installed_proc, 0);
67 ReleaseDC(NULL, hdc);
68 return ret;
69 }
70
71 static void test_setitemheight(DWORD style)
72 {
73 HWND hCombo = build_combo(style);
74 RECT r;
75 int i;
76
77 trace("Style %x\n", style);
78 GetClientRect(hCombo, &r);
79 expect_rect(r, 0, 0, 100, font_height(GetStockObject(SYSTEM_FONT)) + 8);
80 SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r);
81 MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2);
82 todo_wine expect_rect(r, 5, 5, 105, 105);
83
84 for (i = 1; i < 30; i++)
85 {
86 SendMessageA(hCombo, CB_SETITEMHEIGHT, -1, i);
87 GetClientRect(hCombo, &r);
88 expect_eq(r.bottom - r.top, i + 6, int, "%d");
89 }
90
91 DestroyWindow(hCombo);
92 }
93
94 static void test_setfont(DWORD style)
95 {
96 HWND hCombo;
97 HFONT hFont1, hFont2;
98 RECT r;
99 int i;
100
101 if (!is_font_installed("Marlett"))
102 {
103 skip("Marlett font not available\n");
104 return;
105 }
106
107 trace("Style %x\n", style);
108
109 hCombo = build_combo(style);
110 hFont1 = CreateFontA(10, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, SYMBOL_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Marlett");
111 hFont2 = CreateFontA(8, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, SYMBOL_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Marlett");
112
113 GetClientRect(hCombo, &r);
114 expect_rect(r, 0, 0, 100, font_height(GetStockObject(SYSTEM_FONT)) + 8);
115 SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r);
116 MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2);
117 todo_wine expect_rect(r, 5, 5, 105, 105);
118
119 /* The size of the dropped control is initially equal to the size
120 of the window when it was created. The size of the calculated
121 dropped area changes only by how much the selection area
122 changes, not by how much the list area changes. */
123 if (font_height(hFont1) == 10 && font_height(hFont2) == 8)
124 {
125 SendMessageA(hCombo, WM_SETFONT, (WPARAM)hFont1, FALSE);
126 GetClientRect(hCombo, &r);
127 expect_rect(r, 0, 0, 100, 18);
128 SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r);
129 MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2);
130 todo_wine expect_rect(r, 5, 5, 105, 105 - (font_height(GetStockObject(SYSTEM_FONT)) - font_height(hFont1)));
131
132 SendMessageA(hCombo, WM_SETFONT, (WPARAM)hFont2, FALSE);
133 GetClientRect(hCombo, &r);
134 expect_rect(r, 0, 0, 100, 16);
135 SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r);
136 MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2);
137 todo_wine expect_rect(r, 5, 5, 105, 105 - (font_height(GetStockObject(SYSTEM_FONT)) - font_height(hFont2)));
138
139 SendMessageA(hCombo, WM_SETFONT, (WPARAM)hFont1, FALSE);
140 GetClientRect(hCombo, &r);
141 expect_rect(r, 0, 0, 100, 18);
142 SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r);
143 MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2);
144 todo_wine expect_rect(r, 5, 5, 105, 105 - (font_height(GetStockObject(SYSTEM_FONT)) - font_height(hFont1)));
145 }
146 else
147 {
148 ok(0, "Expected Marlett font heights 10/8, got %d/%d\n",
149 font_height(hFont1), font_height(hFont2));
150 }
151
152 for (i = 1; i < 30; i++)
153 {
154 HFONT hFont = CreateFontA(i, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, SYMBOL_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Marlett");
155 int height = font_height(hFont);
156
157 SendMessageA(hCombo, WM_SETFONT, (WPARAM)hFont, FALSE);
158 GetClientRect(hCombo, &r);
159 expect_eq(r.bottom - r.top, height + 8, int, "%d");
160 SendMessageA(hCombo, WM_SETFONT, 0, FALSE);
161 DeleteObject(hFont);
162 }
163
164 DestroyWindow(hCombo);
165 DeleteObject(hFont1);
166 DeleteObject(hFont2);
167 }
168
169 static LRESULT (CALLBACK *old_parent_proc)(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
170 static LPCSTR expected_edit_text;
171 static LPCSTR expected_list_text;
172 static BOOL selchange_fired;
173
174 static LRESULT CALLBACK parent_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
175 {
176 switch (msg)
177 {
178 case WM_COMMAND:
179 switch (wparam)
180 {
181 case MAKEWPARAM(COMBO_ID, CBN_SELCHANGE):
182 {
183 HWND hCombo = (HWND)lparam;
184 int idx;
185 char list[20], edit[20];
186
187 memset(list, 0, sizeof(list));
188 memset(edit, 0, sizeof(edit));
189
190 idx = SendMessageA(hCombo, CB_GETCURSEL, 0, 0);
191 SendMessageA(hCombo, CB_GETLBTEXT, idx, (LPARAM)list);
192 SendMessageA(hCombo, WM_GETTEXT, sizeof(edit), (LPARAM)edit);
193
194 ok(!strcmp(edit, expected_edit_text), "edit: got %s, expected %s\n",
195 edit, expected_edit_text);
196 ok(!strcmp(list, expected_list_text), "list: got %s, expected %s\n",
197 list, expected_list_text);
198
199 selchange_fired = TRUE;
200 }
201 break;
202 }
203 break;
204 }
205
206 return CallWindowProcA(old_parent_proc, hwnd, msg, wparam, lparam);
207 }
208
209 static void test_selection(DWORD style, const char * const text[],
210 const int *edit, const int *list)
211 {
212 INT idx;
213 HWND hCombo;
214
215 hCombo = build_combo(style);
216
217 SendMessageA(hCombo, CB_ADDSTRING, 0, (LPARAM)text[0]);
218 SendMessageA(hCombo, CB_ADDSTRING, 0, (LPARAM)text[1]);
219 SendMessageA(hCombo, CB_SETCURSEL, -1, 0);
220
221 old_parent_proc = (void *)SetWindowLongPtrA(hMainWnd, GWLP_WNDPROC, (ULONG_PTR)parent_wnd_proc);
222
223 idx = SendMessageA(hCombo, CB_GETCURSEL, 0, 0);
224 ok(idx == -1, "expected selection -1, got %d\n", idx);
225
226 /* keyboard navigation */
227
228 expected_list_text = text[list[0]];
229 expected_edit_text = text[edit[0]];
230 selchange_fired = FALSE;
231 SendMessageA(hCombo, WM_KEYDOWN, VK_DOWN, 0);
232 ok(selchange_fired, "CBN_SELCHANGE not sent!\n");
233
234 expected_list_text = text[list[1]];
235 expected_edit_text = text[edit[1]];
236 selchange_fired = FALSE;
237 SendMessageA(hCombo, WM_KEYDOWN, VK_DOWN, 0);
238 ok(selchange_fired, "CBN_SELCHANGE not sent!\n");
239
240 expected_list_text = text[list[2]];
241 expected_edit_text = text[edit[2]];
242 selchange_fired = FALSE;
243 SendMessageA(hCombo, WM_KEYDOWN, VK_UP, 0);
244 ok(selchange_fired, "CBN_SELCHANGE not sent!\n");
245
246 /* programmatic navigation */
247
248 expected_list_text = text[list[3]];
249 expected_edit_text = text[edit[3]];
250 selchange_fired = FALSE;
251 SendMessageA(hCombo, CB_SETCURSEL, list[3], 0);
252 ok(!selchange_fired, "CBN_SELCHANGE sent!\n");
253
254 expected_list_text = text[list[4]];
255 expected_edit_text = text[edit[4]];
256 selchange_fired = FALSE;
257 SendMessageA(hCombo, CB_SETCURSEL, list[4], 0);
258 ok(!selchange_fired, "CBN_SELCHANGE sent!\n");
259
260 SetWindowLongPtrA(hMainWnd, GWLP_WNDPROC, (ULONG_PTR)old_parent_proc);
261 DestroyWindow(hCombo);
262 }
263
264 static void test_CBN_SELCHANGE(void)
265 {
266 static const char * const text[] = { "alpha", "beta", "" };
267 static const int sel_1[] = { 2, 0, 1, 0, 1 };
268 static const int sel_2[] = { 0, 1, 0, 0, 1 };
269
270 test_selection(CBS_SIMPLE, text, sel_1, sel_2);
271 test_selection(CBS_DROPDOWN, text, sel_1, sel_2);
272 test_selection(CBS_DROPDOWNLIST, text, sel_2, sel_2);
273 }
274
275 static void test_WM_LBUTTONDOWN(void)
276 {
277 HWND hCombo, hEdit, hList;
278 COMBOBOXINFO cbInfo;
279 UINT x, y, item_height;
280 LRESULT result;
281 int i, idx;
282 RECT rect;
283 CHAR buffer[3];
284 static const UINT choices[] = {8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
285 static const CHAR stringFormat[] = "%2d";
286 BOOL ret;
287 BOOL (WINAPI *pGetComboBoxInfo)(HWND, PCOMBOBOXINFO);
288
289 pGetComboBoxInfo = (void*)GetProcAddress(GetModuleHandleA("user32.dll"), "GetComboBoxInfo");
290 if (!pGetComboBoxInfo){
291 win_skip("GetComboBoxInfo is not available\n");
292 return;
293 }
294
295 hCombo = CreateWindowA("ComboBox", "Combo", WS_VISIBLE|WS_CHILD|CBS_DROPDOWN,
296 0, 0, 200, 150, hMainWnd, (HMENU)COMBO_ID, NULL, 0);
297
298 for (i = 0; i < sizeof(choices)/sizeof(UINT); i++){
299 sprintf(buffer, stringFormat, choices[i]);
300 result = SendMessageA(hCombo, CB_ADDSTRING, 0, (LPARAM)buffer);
301 ok(result == i,
302 "Failed to add item %d\n", i);
303 }
304
305 cbInfo.cbSize = sizeof(COMBOBOXINFO);
306 SetLastError(0xdeadbeef);
307 ret = pGetComboBoxInfo(hCombo, &cbInfo);
308 ok(ret, "Failed to get combobox info structure. LastError=%d\n",
309 GetLastError());
310 hEdit = cbInfo.hwndItem;
311 hList = cbInfo.hwndList;
312
313 trace("hMainWnd=%p, hCombo=%p, hList=%p, hEdit=%p\n", hMainWnd, hCombo, hList, hEdit);
314 ok(GetFocus() == hMainWnd, "Focus not on Main Window, instead on %p\n", GetFocus());
315
316 /* Click on the button to drop down the list */
317 x = cbInfo.rcButton.left + (cbInfo.rcButton.right-cbInfo.rcButton.left)/2;
318 y = cbInfo.rcButton.top + (cbInfo.rcButton.bottom-cbInfo.rcButton.top)/2;
319 result = SendMessageA(hCombo, WM_LBUTTONDOWN, 0, MAKELPARAM(x, y));
320 ok(result, "WM_LBUTTONDOWN was not processed. LastError=%d\n",
321 GetLastError());
322 ok(SendMessageA(hCombo, CB_GETDROPPEDSTATE, 0, 0),
323 "The dropdown list should have appeared after clicking the button.\n");
324
325 ok(GetFocus() == hEdit,
326 "Focus not on ComboBox's Edit Control, instead on %p\n", GetFocus());
327 result = SendMessageA(hCombo, WM_LBUTTONUP, 0, MAKELPARAM(x, y));
328 ok(result, "WM_LBUTTONUP was not processed. LastError=%d\n",
329 GetLastError());
330 ok(GetFocus() == hEdit,
331 "Focus not on ComboBox's Edit Control, instead on %p\n", GetFocus());
332
333 /* Click on the 5th item in the list */
334 item_height = SendMessageA(hCombo, CB_GETITEMHEIGHT, 0, 0);
335 ok(GetClientRect(hList, &rect), "Failed to get list's client rect.\n");
336 x = rect.left + (rect.right-rect.left)/2;
337 y = item_height/2 + item_height*4;
338 result = SendMessageA(hList, WM_LBUTTONDOWN, 0, MAKELPARAM(x, y));
339 ok(!result, "WM_LBUTTONDOWN was not processed. LastError=%d\n",
340 GetLastError());
341 ok(GetFocus() == hEdit,
342 "Focus not on ComboBox's Edit Control, instead on %p\n", GetFocus());
343
344 result = SendMessageA(hList, WM_MOUSEMOVE, 0, MAKELPARAM(x, y));
345 ok(!result, "WM_MOUSEMOVE was not processed. LastError=%d\n",
346 GetLastError());
347 ok(GetFocus() == hEdit,
348 "Focus not on ComboBox's Edit Control, instead on %p\n", GetFocus());
349 ok(SendMessageA(hCombo, CB_GETDROPPEDSTATE, 0, 0),
350 "The dropdown list should still be visible.\n");
351
352 result = SendMessageA(hList, WM_LBUTTONUP, 0, MAKELPARAM(x, y));
353 ok(!result, "WM_LBUTTONUP was not processed. LastError=%d\n",
354 GetLastError());
355 ok(GetFocus() == hEdit,
356 "Focus not on ComboBox's Edit Control, instead on %p\n", GetFocus());
357 ok(!SendMessageA(hCombo, CB_GETDROPPEDSTATE, 0, 0),
358 "The dropdown list should have been rolled up.\n");
359 idx = SendMessageA(hCombo, CB_GETCURSEL, 0, 0);
360 ok(idx, "Current Selection: expected %d, got %d\n", 4, idx);
361
362 DestroyWindow(hCombo);
363 }
364
365 static void test_changesize( DWORD style)
366 {
367 HWND hCombo = build_combo(style);
368 RECT rc;
369 INT ddheight, clheight, ddwidth, clwidth;
370 /* get initial measurements */
371 GetClientRect( hCombo, &rc);
372 clheight = rc.bottom - rc.top;
373 clwidth = rc.right - rc.left;
374 SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&rc);
375 ddheight = rc.bottom - rc.top;
376 ddwidth = rc.right - rc.left;
377 /* use MoveWindow to move & resize the combo */
378 /* first make it slightly smaller */
379 MoveWindow( hCombo, 10, 10, clwidth - 2, clheight - 2, TRUE);
380 GetClientRect( hCombo, &rc);
381 ok( rc.right - rc.left == clwidth - 2, "clientrect witdh is %d vs %d\n",
382 rc.right - rc.left, clwidth - 2);
383 ok( rc.bottom - rc.top == clheight, "clientrect height is %d vs %d\n",
384 rc.bottom - rc.top, clheight);
385 SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&rc);
386 ok( rc.right - rc.left == clwidth - 2, "drop-down rect witdh is %d vs %d\n",
387 rc.right - rc.left, clwidth - 2);
388 ok( rc.bottom - rc.top == ddheight, "drop-down rect height is %d vs %d\n",
389 rc.bottom - rc.top, ddheight);
390 ok( rc.right - rc.left == ddwidth -2, "drop-down rect width is %d vs %d\n",
391 rc.right - rc.left, ddwidth - 2);
392 /* new cx, cy is slightly bigger than the initial values */
393 MoveWindow( hCombo, 10, 10, clwidth + 2, clheight + 2, TRUE);
394 GetClientRect( hCombo, &rc);
395 ok( rc.right - rc.left == clwidth + 2, "clientrect witdh is %d vs %d\n",
396 rc.right - rc.left, clwidth + 2);
397 ok( rc.bottom - rc.top == clheight, "clientrect height is %d vs %d\n",
398 rc.bottom - rc.top, clheight);
399 SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&rc);
400 ok( rc.right - rc.left == clwidth + 2, "drop-down rect witdh is %d vs %d\n",
401 rc.right - rc.left, clwidth + 2);
402 todo_wine {
403 ok( rc.bottom - rc.top == clheight + 2, "drop-down rect height is %d vs %d\n",
404 rc.bottom - rc.top, clheight + 2);
405 }
406
407 ddwidth = SendMessageA(hCombo, CB_SETDROPPEDWIDTH, -1, 0);
408 ok( ddwidth == clwidth + 2, "drop-width is %d vs %d\n", ddwidth, clwidth + 2);
409 ddwidth = SendMessageA(hCombo, CB_GETDROPPEDWIDTH, 0, 0);
410 ok( ddwidth == clwidth + 2, "drop-width is %d vs %d\n", ddwidth, clwidth + 2);
411
412 ddwidth = SendMessageA(hCombo, CB_SETDROPPEDWIDTH, 0, 0);
413 ok( ddwidth == clwidth + 2, "drop-width is %d vs %d\n", ddwidth, clwidth + 2);
414 ddwidth = SendMessageA(hCombo, CB_GETDROPPEDWIDTH, 0, 0);
415 ok( ddwidth == clwidth + 2, "drop-width is %d vs %d\n", ddwidth, clwidth + 2);
416
417 ddwidth = SendMessageA(hCombo, CB_SETDROPPEDWIDTH, clwidth - 1, 0);
418 ok( ddwidth == clwidth + 2, "drop-width is %d vs %d\n", ddwidth, clwidth + 2);
419 ddwidth = SendMessageA(hCombo, CB_GETDROPPEDWIDTH, 0, 0);
420 ok( ddwidth == clwidth + 2, "drop-width is %d vs %d\n", ddwidth, clwidth + 2);
421
422 ddwidth = SendMessageA(hCombo, CB_SETDROPPEDWIDTH, clwidth << 1, 0);
423 ok( ddwidth == (clwidth << 1), "drop-width is %d vs %d\n", ddwidth, clwidth << 1);
424 ddwidth = SendMessageA(hCombo, CB_GETDROPPEDWIDTH, 0, 0);
425 ok( ddwidth == (clwidth << 1), "drop-width is %d vs %d\n", ddwidth, clwidth << 1);
426
427 ddwidth = SendMessageA(hCombo, CB_SETDROPPEDWIDTH, 0, 0);
428 ok( ddwidth == (clwidth << 1), "drop-width is %d vs %d\n", ddwidth, clwidth << 1);
429 ddwidth = SendMessageA(hCombo, CB_GETDROPPEDWIDTH, 0, 0);
430 ok( ddwidth == (clwidth << 1), "drop-width is %d vs %d\n", ddwidth, clwidth << 1);
431
432 ddwidth = SendMessageA(hCombo, CB_SETDROPPEDWIDTH, 1, 0);
433 ok( ddwidth == clwidth + 2, "drop-width is %d vs %d\n", ddwidth, clwidth + 2);
434 ddwidth = SendMessageA(hCombo, CB_GETDROPPEDWIDTH, 0, 0);
435 ok( ddwidth == clwidth + 2, "drop-width is %d vs %d\n", ddwidth, clwidth + 2);
436
437 DestroyWindow(hCombo);
438 }
439
440 static void test_editselection(void)
441 {
442 HWND hCombo;
443 INT start,end;
444 HWND hEdit;
445 COMBOBOXINFO cbInfo;
446 BOOL ret;
447 DWORD len;
448 BOOL (WINAPI *pGetComboBoxInfo)(HWND, PCOMBOBOXINFO);
449 char edit[20];
450
451 pGetComboBoxInfo = (void*)GetProcAddress(GetModuleHandleA("user32.dll"), "GetComboBoxInfo");
452 if (!pGetComboBoxInfo){
453 win_skip("GetComboBoxInfo is not available\n");
454 return;
455 }
456
457 /* Build a combo */
458 hCombo = build_combo(CBS_SIMPLE);
459 cbInfo.cbSize = sizeof(COMBOBOXINFO);
460 SetLastError(0xdeadbeef);
461 ret = pGetComboBoxInfo(hCombo, &cbInfo);
462 ok(ret, "Failed to get combobox info structure. LastError=%d\n",
463 GetLastError());
464 hEdit = cbInfo.hwndItem;
465
466 /* Initially combo selection is empty*/
467 len = SendMessageA(hCombo, CB_GETEDITSEL, 0,0);
468 ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len));
469 ok(HIWORD(len)==0, "Unexpected end position for selection %d\n", HIWORD(len));
470
471 /* Set some text, and press a key to replace it */
472 edit[0] = 0x00;
473 SendMessageA(hCombo, WM_SETTEXT, 0, (LPARAM)"Jason1");
474 SendMessageA(hCombo, WM_GETTEXT, sizeof(edit), (LPARAM)edit);
475 ok(strcmp(edit, "Jason1")==0, "Unexpected text retrieved %s\n", edit);
476
477 /* Now what is the selection - still empty */
478 SendMessageA(hCombo, CB_GETEDITSEL, (WPARAM)&start, (WPARAM)&end);
479 len = SendMessageA(hCombo, CB_GETEDITSEL, 0,0);
480 ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len));
481 ok(HIWORD(len)==0, "Unexpected end position for selection %d\n", HIWORD(len));
482
483 /* Give it focus, and it gets selected */
484 SendMessageA(hCombo, WM_SETFOCUS, 0, (LPARAM)hEdit);
485 SendMessageA(hCombo, CB_GETEDITSEL, (WPARAM)&start, (WPARAM)&end);
486 len = SendMessageA(hCombo, CB_GETEDITSEL, 0,0);
487 ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len));
488 ok(HIWORD(len)==6, "Unexpected end position for selection %d\n", HIWORD(len));
489
490 /* Now emulate a key press */
491 edit[0] = 0x00;
492 SendMessageA(hCombo, WM_CHAR, 'A', 0x1c0001);
493 SendMessageA(hCombo, WM_GETTEXT, sizeof(edit), (LPARAM)edit);
494 ok(strcmp(edit, "A")==0, "Unexpected text retrieved %s\n", edit);
495
496 len = SendMessageA(hCombo, CB_GETEDITSEL, 0,0);
497 ok(LOWORD(len)==1, "Unexpected start position for selection %d\n", LOWORD(len));
498 ok(HIWORD(len)==1, "Unexpected end position for selection %d\n", HIWORD(len));
499
500 /* Now what happens when it gets more focus a second time - it doesn't reselect */
501 SendMessageA(hCombo, WM_SETFOCUS, 0, (LPARAM)hEdit);
502 len = SendMessageA(hCombo, CB_GETEDITSEL, 0,0);
503 ok(LOWORD(len)==1, "Unexpected start position for selection %d\n", LOWORD(len));
504 ok(HIWORD(len)==1, "Unexpected end position for selection %d\n", HIWORD(len));
505 DestroyWindow(hCombo);
506
507 /* Start again - Build a combo */
508 hCombo = build_combo(CBS_SIMPLE);
509 cbInfo.cbSize = sizeof(COMBOBOXINFO);
510 SetLastError(0xdeadbeef);
511 ret = pGetComboBoxInfo(hCombo, &cbInfo);
512 ok(ret, "Failed to get combobox info structure. LastError=%d\n",
513 GetLastError());
514 hEdit = cbInfo.hwndItem;
515
516 /* Set some text and give focus so it gets selected */
517 edit[0] = 0x00;
518 SendMessageA(hCombo, WM_SETTEXT, 0, (LPARAM)"Jason2");
519 SendMessageA(hCombo, WM_GETTEXT, sizeof(edit), (LPARAM)edit);
520 ok(strcmp(edit, "Jason2")==0, "Unexpected text retrieved %s\n", edit);
521
522 SendMessageA(hCombo, WM_SETFOCUS, 0, (LPARAM)hEdit);
523
524 /* Now what is the selection */
525 SendMessageA(hCombo, CB_GETEDITSEL, (WPARAM)&start, (WPARAM)&end);
526 len = SendMessageA(hCombo, CB_GETEDITSEL, 0,0);
527 ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len));
528 ok(HIWORD(len)==6, "Unexpected end position for selection %d\n", HIWORD(len));
529
530 /* Now change the selection to the apparently invalid start -1, end -1 and
531 show it means no selection (ie start -1) but cursor at end */
532 SendMessageA(hCombo, CB_SETEDITSEL, 0, -1);
533 edit[0] = 0x00;
534 SendMessageA(hCombo, WM_CHAR, 'A', 0x1c0001);
535 SendMessageA(hCombo, WM_GETTEXT, sizeof(edit), (LPARAM)edit);
536 ok(strcmp(edit, "Jason2A")==0, "Unexpected text retrieved %s\n", edit);
537 DestroyWindow(hCombo);
538 }
539
540 START_TEST(combo)
541 {
542 hMainWnd = CreateWindowA("static", "Test", WS_OVERLAPPEDWINDOW, 10, 10, 300, 300, NULL, NULL, NULL, 0);
543 ShowWindow(hMainWnd, SW_SHOW);
544
545 test_setfont(CBS_DROPDOWN);
546 test_setfont(CBS_DROPDOWNLIST);
547 test_setitemheight(CBS_DROPDOWN);
548 test_setitemheight(CBS_DROPDOWNLIST);
549 test_CBN_SELCHANGE();
550 test_WM_LBUTTONDOWN();
551 test_changesize(CBS_DROPDOWN);
552 test_changesize(CBS_DROPDOWNLIST);
553 test_editselection();
554
555 DestroyWindow(hMainWnd);
556 }