1 /* Unit test suite for combo boxes.
3 * Copyright 2007 Mikolaj Zalewski
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
25 #define WIN32_LEAN_AND_MEAN
28 #include "wine/test.h"
34 #define expect_eq(expr, value, type, fmt); { type val = expr; ok(val == (value), #expr " expected " #fmt " got " #fmt "\n", (value), val); }
35 #define expect_rect(r, _left, _top, _right, _bottom) ok(r.left == _left && r.top == _top && \
36 r.bottom == _bottom && r.right == _right, "Invalid rect (%d,%d) (%d,%d) vs (%d,%d) (%d,%d)\n", \
37 r.left, r.top, r.right, r.bottom, _left, _top, _right, _bottom);
39 static HWND
build_combo(DWORD style
)
41 return CreateWindow("ComboBox", "Combo", WS_VISIBLE
|WS_CHILD
|style
, 5, 5, 100, 100, hMainWnd
, (HMENU
)COMBO_ID
, NULL
, 0);
44 static int font_height(HFONT hFont
)
50 hDC
= CreateCompatibleDC(NULL
);
51 hFontOld
= SelectObject(hDC
, hFont
);
52 GetTextMetrics(hDC
, &tm
);
53 SelectObject(hDC
, hFontOld
);
59 static INT CALLBACK
is_font_installed_proc(const LOGFONT
*elf
, const TEXTMETRIC
*tm
, DWORD type
, LPARAM lParam
)
64 static int is_font_installed(const char *name
)
66 HDC hdc
= GetDC(NULL
);
67 BOOL ret
= !EnumFontFamilies(hdc
, name
, is_font_installed_proc
, 0);
72 static void test_setitemheight(DWORD style
)
74 HWND hCombo
= build_combo(style
);
78 trace("Style %x\n", style
);
79 GetClientRect(hCombo
, &r
);
80 expect_rect(r
, 0, 0, 100, 24);
81 SendMessageA(hCombo
, CB_GETDROPPEDCONTROLRECT
, 0, (LPARAM
)&r
);
82 MapWindowPoints(HWND_DESKTOP
, hMainWnd
, (LPPOINT
)&r
, 2);
83 todo_wine
expect_rect(r
, 5, 5, 105, 105);
85 for (i
= 1; i
< 30; i
++)
87 SendMessage(hCombo
, CB_SETITEMHEIGHT
, -1, i
);
88 GetClientRect(hCombo
, &r
);
89 expect_eq(r
.bottom
- r
.top
, i
+ 6, int, "%d");
92 DestroyWindow(hCombo
);
95 static void test_setfont(DWORD style
)
97 HWND hCombo
= build_combo(style
);
98 HFONT hFont1
= CreateFont(10, 0, 0, 0, FW_DONTCARE
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
, OUT_DEFAULT_PRECIS
, CLIP_DEFAULT_PRECIS
, DEFAULT_QUALITY
, DEFAULT_PITCH
|FF_DONTCARE
, "Marlett");
99 HFONT hFont2
= CreateFont(8, 0, 0, 0, FW_DONTCARE
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
, OUT_DEFAULT_PRECIS
, CLIP_DEFAULT_PRECIS
, DEFAULT_QUALITY
, DEFAULT_PITCH
|FF_DONTCARE
, "Marlett");
103 trace("Style %x\n", style
);
104 GetClientRect(hCombo
, &r
);
105 expect_rect(r
, 0, 0, 100, 24);
106 SendMessageA(hCombo
, CB_GETDROPPEDCONTROLRECT
, 0, (LPARAM
)&r
);
107 MapWindowPoints(HWND_DESKTOP
, hMainWnd
, (LPPOINT
)&r
, 2);
108 todo_wine
expect_rect(r
, 5, 5, 105, 105);
110 if (!is_font_installed("Marlett"))
112 skip("Marlett font not available\n");
113 DestroyWindow(hCombo
);
114 DeleteObject(hFont1
);
115 DeleteObject(hFont2
);
119 if (font_height(hFont1
) == 10 && font_height(hFont2
) == 8)
121 SendMessage(hCombo
, WM_SETFONT
, (WPARAM
)hFont1
, FALSE
);
122 GetClientRect(hCombo
, &r
);
123 expect_rect(r
, 0, 0, 100, 18);
124 SendMessageA(hCombo
, CB_GETDROPPEDCONTROLRECT
, 0, (LPARAM
)&r
);
125 MapWindowPoints(HWND_DESKTOP
, hMainWnd
, (LPPOINT
)&r
, 2);
126 todo_wine
expect_rect(r
, 5, 5, 105, 99);
128 SendMessage(hCombo
, WM_SETFONT
, (WPARAM
)hFont2
, FALSE
);
129 GetClientRect(hCombo
, &r
);
130 expect_rect(r
, 0, 0, 100, 16);
131 SendMessageA(hCombo
, CB_GETDROPPEDCONTROLRECT
, 0, (LPARAM
)&r
);
132 MapWindowPoints(HWND_DESKTOP
, hMainWnd
, (LPPOINT
)&r
, 2);
133 todo_wine
expect_rect(r
, 5, 5, 105, 97);
135 SendMessage(hCombo
, WM_SETFONT
, (WPARAM
)hFont1
, FALSE
);
136 GetClientRect(hCombo
, &r
);
137 expect_rect(r
, 0, 0, 100, 18);
138 SendMessageA(hCombo
, CB_GETDROPPEDCONTROLRECT
, 0, (LPARAM
)&r
);
139 MapWindowPoints(HWND_DESKTOP
, hMainWnd
, (LPPOINT
)&r
, 2);
140 todo_wine
expect_rect(r
, 5, 5, 105, 99);
143 skip("Invalid Marlett font heights\n");
145 for (i
= 1; i
< 30; i
++)
147 HFONT hFont
= CreateFont(i
, 0, 0, 0, FW_DONTCARE
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
, OUT_DEFAULT_PRECIS
, CLIP_DEFAULT_PRECIS
, DEFAULT_QUALITY
, DEFAULT_PITCH
|FF_DONTCARE
, "Marlett");
148 int height
= font_height(hFont
);
150 SendMessage(hCombo
, WM_SETFONT
, (WPARAM
)hFont
, FALSE
);
151 GetClientRect(hCombo
, &r
);
152 expect_eq(r
.bottom
- r
.top
, height
+ 8, int, "%d");
153 SendMessage(hCombo
, WM_SETFONT
, 0, FALSE
);
157 DestroyWindow(hCombo
);
158 DeleteObject(hFont1
);
159 DeleteObject(hFont2
);
162 static LRESULT (CALLBACK
*old_parent_proc
)(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
);
163 static LPCSTR expected_edit_text
;
164 static LPCSTR expected_list_text
;
165 static BOOL selchange_fired
;
167 static LRESULT CALLBACK
parent_wnd_proc(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
174 case MAKEWPARAM(COMBO_ID
, CBN_SELCHANGE
):
176 HWND hCombo
= (HWND
)lparam
;
178 char list
[20], edit
[20];
180 memset(list
, 0, sizeof(list
));
181 memset(edit
, 0, sizeof(edit
));
183 idx
= SendMessage(hCombo
, CB_GETCURSEL
, 0, 0);
184 SendMessage(hCombo
, CB_GETLBTEXT
, idx
, (LPARAM
)list
);
185 SendMessage(hCombo
, WM_GETTEXT
, sizeof(edit
), (LPARAM
)edit
);
187 ok(!strcmp(edit
, expected_edit_text
), "edit: got %s, expected %s\n",
188 edit
, expected_edit_text
);
189 ok(!strcmp(list
, expected_list_text
), "list: got %s, expected %s\n",
190 list
, expected_list_text
);
192 selchange_fired
= TRUE
;
199 return CallWindowProc(old_parent_proc
, hwnd
, msg
, wparam
, lparam
);
202 static void test_selection(DWORD style
, const char * const text
[],
203 const int *edit
, const int *list
)
208 hCombo
= build_combo(style
);
210 SendMessage(hCombo
, CB_ADDSTRING
, 0, (LPARAM
)text
[0]);
211 SendMessage(hCombo
, CB_ADDSTRING
, 0, (LPARAM
)text
[1]);
212 SendMessage(hCombo
, CB_SETCURSEL
, -1, 0);
214 old_parent_proc
= (void *)SetWindowLongPtr(hMainWnd
, GWLP_WNDPROC
, (ULONG_PTR
)parent_wnd_proc
);
216 idx
= SendMessage(hCombo
, CB_GETCURSEL
, 0, 0);
217 ok(idx
== -1, "expected selection -1, got %d\n", idx
);
219 /* keyboard navigation */
221 expected_list_text
= text
[list
[0]];
222 expected_edit_text
= text
[edit
[0]];
223 selchange_fired
= FALSE
;
224 SendMessage(hCombo
, WM_KEYDOWN
, VK_DOWN
, 0);
225 ok(selchange_fired
, "CBN_SELCHANGE not sent!\n");
227 expected_list_text
= text
[list
[1]];
228 expected_edit_text
= text
[edit
[1]];
229 selchange_fired
= FALSE
;
230 SendMessage(hCombo
, WM_KEYDOWN
, VK_DOWN
, 0);
231 ok(selchange_fired
, "CBN_SELCHANGE not sent!\n");
233 expected_list_text
= text
[list
[2]];
234 expected_edit_text
= text
[edit
[2]];
235 selchange_fired
= FALSE
;
236 SendMessage(hCombo
, WM_KEYDOWN
, VK_UP
, 0);
237 ok(selchange_fired
, "CBN_SELCHANGE not sent!\n");
239 /* programmatic navigation */
241 expected_list_text
= text
[list
[3]];
242 expected_edit_text
= text
[edit
[3]];
243 selchange_fired
= FALSE
;
244 SendMessage(hCombo
, CB_SETCURSEL
, list
[3], 0);
245 ok(!selchange_fired
, "CBN_SELCHANGE sent!\n");
247 expected_list_text
= text
[list
[4]];
248 expected_edit_text
= text
[edit
[4]];
249 selchange_fired
= FALSE
;
250 SendMessage(hCombo
, CB_SETCURSEL
, list
[4], 0);
251 ok(!selchange_fired
, "CBN_SELCHANGE sent!\n");
253 SetWindowLongPtr(hMainWnd
, GWLP_WNDPROC
, (ULONG_PTR
)old_parent_proc
);
254 DestroyWindow(hCombo
);
257 static void test_CBN_SELCHANGE(void)
259 static const char * const text
[] = { "alpha", "beta", "" };
260 static const int sel_1
[] = { 2, 0, 1, 0, 1 };
261 static const int sel_2
[] = { 0, 1, 0, 0, 1 };
263 test_selection(CBS_SIMPLE
, text
, sel_1
, sel_2
);
264 test_selection(CBS_DROPDOWN
, text
, sel_1
, sel_2
);
265 test_selection(CBS_DROPDOWNLIST
, text
, sel_2
, sel_2
);
270 hMainWnd
= CreateWindow("static", "Test", WS_OVERLAPPEDWINDOW
, 10, 10, 300, 300, NULL
, NULL
, NULL
, 0);
271 ShowWindow(hMainWnd
, SW_SHOW
);
273 test_setfont(CBS_DROPDOWN
);
274 test_setfont(CBS_DROPDOWNLIST
);
275 test_setitemheight(CBS_DROPDOWN
);
276 test_setitemheight(CBS_DROPDOWNLIST
);
277 test_CBN_SELCHANGE();
279 DestroyWindow(hMainWnd
);