1 /* Unit test suite for tab control.
2 *
3 * Copyright 2003 Vitaliy Margolen
4 * Copyright 2007 Hagop Hagopian
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include <windows.h>
22 #include <commctrl.h>
23 #include <stdio.h>
24
25 #include "wine/test.h"
26 #include "msg.h"
27
28 #define DEFAULT_MIN_TAB_WIDTH 54
29 #define TAB_PADDING_X 6
30 #define EXTRA_ICON_PADDING 3
31 #define MAX_TABLEN 32
32
33 #define NUM_MSG_SEQUENCES 2
34 #define PARENT_SEQ_INDEX 0
35 #define TAB_SEQ_INDEX 1
36
37 #define expect(expected, got) ok ( expected == got, "Expected %d, got %d\n", expected, got)
38 #define expect_str(expected, got)\
39 ok ( strcmp(expected, got) == 0, "Expected '%s', got '%s'\n", expected, got)
40
41 #define TabWidthPadded(padd_x, num) (DEFAULT_MIN_TAB_WIDTH - (TAB_PADDING_X - (padd_x)) * num)
42
43 static HIMAGELIST (WINAPI *pImageList_Create)(INT,INT,UINT,INT,INT);
44 static BOOL (WINAPI *pImageList_Destroy)(HIMAGELIST);
45 static INT (WINAPI *pImageList_GetImageCount)(HIMAGELIST);
46 static INT (WINAPI *pImageList_ReplaceIcon)(HIMAGELIST,INT,HICON);
47
CheckSize(HWND hwnd,INT width,INT height,const char * msg,int line)48 static void CheckSize(HWND hwnd, INT width, INT height, const char *msg, int line)
49 {
50 RECT r;
51
52 SendMessageA(hwnd, TCM_GETITEMRECT, 0, (LPARAM)&r);
53 if (width >= 0 && height < 0)
54 ok_(__FILE__,line) (width == r.right - r.left, "%s: Expected width [%d] got [%d]\n",
55 msg, width, r.right - r.left);
56 else if (height >= 0 && width < 0)
57 ok_(__FILE__,line) (height == r.bottom - r.top, "%s: Expected height [%d] got [%d]\n",
58 msg, height, r.bottom - r.top);
59 else
60 ok_(__FILE__,line) ((width == r.right - r.left) && (height == r.bottom - r.top ),
61 "%s: Expected [%d,%d] got [%d,%d]\n", msg, width, height,
62 r.right - r.left, r.bottom - r.top);
63 }
64
65 #define CHECKSIZE(hwnd,width,height,msg) CheckSize(hwnd,width,height,msg,__LINE__)
66
TabCheckSetSize(HWND hwnd,INT set_width,INT set_height,INT exp_width,INT exp_height,const char * msg,int line)67 static void TabCheckSetSize(HWND hwnd, INT set_width, INT set_height, INT exp_width,
68 INT exp_height, const char *msg, int line)
69 {
70 SendMessageA(hwnd, TCM_SETITEMSIZE, 0,
71 MAKELPARAM((set_width >= 0) ? set_width : 0, (set_height >= 0) ? set_height : 0));
72 if (winetest_interactive) RedrawWindow (hwnd, NULL, 0, RDW_UPDATENOW);
73 CheckSize(hwnd, exp_width, exp_height, msg, line);
74 }
75
76 #define TABCHECKSETSIZE(hwnd,set_width,set_height,exp_width,exp_height,msg) \
77 TabCheckSetSize(hwnd,set_width,set_height,exp_width,exp_height,msg,__LINE__)
78
79 static HFONT hFont;
80 static DRAWITEMSTRUCT g_drawitem;
81 static HWND parent_wnd;
82 static LRESULT tcn_selchanging_result;
83
84 static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
85
86 static const struct message empty_sequence[] = {
87 { 0 }
88 };
89
90 static const struct message get_row_count_seq[] = {
91 { TCM_GETROWCOUNT, sent|wparam|lparam, 0, 0 },
92 { 0 }
93 };
94
95 static const struct message getset_cur_focus_seq[] = {
96 { TCM_SETCURFOCUS, sent|lparam, 0 },
97 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
98 { TCM_SETCURFOCUS, sent|lparam, 0 },
99 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
100 { TCM_SETCURSEL, sent|lparam, 0 },
101 { TCM_SETCURFOCUS, sent|lparam, 0 },
102 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
103 { 0 }
104 };
105
106 static const struct message getset_cur_sel_seq[] = {
107 { TCM_SETCURSEL, sent|lparam, 0 },
108 { TCM_GETCURSEL, sent|wparam|lparam, 0, 0 },
109 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
110 { TCM_SETCURSEL, sent|lparam, 0 },
111 { TCM_GETCURSEL, sent|wparam|lparam, 0, 0 },
112 { TCM_SETCURSEL, sent|lparam, 0 },
113 { TCM_SETCURSEL, sent|lparam, 0 },
114 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
115 { 0 }
116 };
117
118 static const struct message getset_extended_style_seq[] = {
119 { TCM_GETEXTENDEDSTYLE, sent|wparam|lparam, 0, 0 },
120 { TCM_SETEXTENDEDSTYLE, sent },
121 { TCM_GETEXTENDEDSTYLE, sent|wparam|lparam, 0, 0 },
122 { TCM_SETEXTENDEDSTYLE, sent },
123 { TCM_GETEXTENDEDSTYLE, sent|wparam|lparam, 0, 0 },
124 { 0 }
125 };
126
127 static const struct message getset_unicode_format_seq[] = {
128 { CCM_SETUNICODEFORMAT, sent|lparam, 0 },
129 { CCM_GETUNICODEFORMAT, sent|wparam|lparam, 0, 0 },
130 { CCM_SETUNICODEFORMAT, sent|lparam, 0 },
131 { CCM_GETUNICODEFORMAT, sent|wparam|lparam, 0, 0 },
132 { CCM_SETUNICODEFORMAT, sent|lparam, 0 },
133 { 0 }
134 };
135
136 static const struct message getset_item_seq[] = {
137 { TCM_SETITEMA, sent },
138 { TCM_GETITEMA, sent },
139 { TCM_GETITEMA, sent },
140 { 0 }
141 };
142
143 static const struct message getset_tooltip_seq[] = {
144 { WM_NOTIFYFORMAT, sent|optional },
145 { WM_QUERYUISTATE, sent|wparam|lparam|optional, 0, 0 },
146 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
147 { WM_NOTIFYFORMAT, sent|optional },
148 { TCM_SETTOOLTIPS, sent|lparam, 0 },
149 { TCM_GETTOOLTIPS, sent|wparam|lparam, 0, 0 },
150 { TCM_SETTOOLTIPS, sent|lparam, 0 },
151 { TCM_GETTOOLTIPS, sent|wparam|lparam, 0, 0 },
152 { 0 }
153 };
154
155 static const struct message getset_tooltip_parent_seq[] = {
156 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
157 { 0 }
158 };
159
160 static const struct message insert_focus_seq[] = {
161 { TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
162 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
163 { TCM_INSERTITEMA, sent|wparam, 1 },
164 { WM_NOTIFYFORMAT, sent|defwinproc|optional },
165 { WM_QUERYUISTATE, sent|defwinproc|optional },
166 { WM_PARENTNOTIFY, sent|defwinproc|optional },
167 { TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
168 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
169 { TCM_INSERTITEMA, sent|wparam, 2 },
170 { WM_NOTIFYFORMAT, sent|defwinproc|optional },
171 { WM_QUERYUISTATE, sent|defwinproc|optional, },
172 { WM_PARENTNOTIFY, sent|defwinproc|optional },
173 { TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
174 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
175 { TCM_SETCURFOCUS, sent|wparam|lparam, -1, 0 },
176 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
177 { TCM_INSERTITEMA, sent|wparam, 3 },
178 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
179 { 0 }
180 };
181
182 static const struct message delete_focus_seq[] = {
183 { TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
184 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
185 { TCM_DELETEITEM, sent|wparam|lparam, 1, 0 },
186 { TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
187 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
188 { TCM_SETCURFOCUS, sent|wparam|lparam, -1, 0 },
189 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
190 { TCM_DELETEITEM, sent|wparam|lparam, 0, 0 },
191 { TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
192 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
193 { 0 }
194 };
195
196 static const struct message rbuttonup_seq[] = {
197 { WM_RBUTTONUP, sent|wparam|lparam, 0, 0 },
198 { WM_CONTEXTMENU, sent|defwinproc },
199 { 0 }
200 };
201
202 static const struct message full_selchange_parent_seq[] = {
203 { WM_NOTIFY, sent|id, 0, 0, TCN_SELCHANGING },
204 { WM_NOTIFY, sent|id, 0, 0, TCN_SELCHANGE },
205 { 0 }
206 };
207
208 static const struct message selchanging_parent_seq[] = {
209 { WM_NOTIFY, sent|id, 0, 0, TCN_SELCHANGING },
210 { 0 }
211 };
212
213 static const struct message selchange_parent_seq[] = {
214 { WM_NOTIFY, sent|id, 0, 0, TCN_SELCHANGE },
215 { 0 }
216 };
217
218 static const struct message setfocus_parent_seq[] = {
219 { WM_NOTIFY, sent|id, 0, 0, TCN_FOCUSCHANGE },
220 { 0 }
221 };
222
223 static HWND
create_tabcontrol(DWORD style,DWORD mask)224 create_tabcontrol (DWORD style, DWORD mask)
225 {
226 HWND handle;
227 TCITEMA tcNewTab;
228 static char text1[] = "Tab 1",
229 text2[] = "Wide Tab 2",
230 text3[] = "T 3";
231
232 handle = CreateWindowA(WC_TABCONTROLA, "TestTab",
233 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | style, 10, 10, 300, 100, NULL,
234 NULL, NULL, 0);
235 ok(handle != NULL, "failed to create tab wnd\n");
236
237 SetWindowLongA(handle, GWL_STYLE, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | style);
238 SendMessageA(handle, WM_SETFONT, 0, (LPARAM)hFont);
239
240 tcNewTab.mask = mask;
241 tcNewTab.pszText = text1;
242 tcNewTab.iImage = 0;
243 SendMessageA(handle, TCM_INSERTITEMA, 0, (LPARAM)&tcNewTab);
244 tcNewTab.pszText = text2;
245 tcNewTab.iImage = 1;
246 SendMessageA(handle, TCM_INSERTITEMA, 1, (LPARAM)&tcNewTab);
247 tcNewTab.pszText = text3;
248 tcNewTab.iImage = 2;
249 SendMessageA(handle, TCM_INSERTITEMA, 2, (LPARAM)&tcNewTab);
250
251 if (winetest_interactive)
252 {
253 ShowWindow (handle, SW_SHOW);
254 RedrawWindow (handle, NULL, 0, RDW_UPDATENOW);
255 Sleep (1000);
256 }
257
258 return handle;
259 }
260
parent_wnd_proc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)261 static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
262 {
263 static LONG defwndproc_counter = 0;
264 struct message msg = { 0 };
265 LRESULT ret;
266
267 /* do not log painting messages */
268 if (message != WM_PAINT &&
269 message != WM_ERASEBKGND &&
270 message != WM_NCPAINT &&
271 message != WM_NCHITTEST &&
272 message != WM_GETTEXT &&
273 message != WM_GETICON &&
274 message != WM_DEVICECHANGE)
275 {
276 msg.message = message;
277 msg.flags = sent|wparam|lparam;
278 if (defwndproc_counter) msg.flags |= defwinproc;
279 msg.wParam = wParam;
280 msg.lParam = lParam;
281 if (message == WM_NOTIFY && lParam)
282 msg.id = ((NMHDR*)lParam)->code;
283 add_message(sequences, PARENT_SEQ_INDEX, &msg);
284 }
285
286 /* dump sent structure data */
287 if (message == WM_DRAWITEM)
288 g_drawitem = *(DRAWITEMSTRUCT*)lParam;
289
290 if (message == WM_NOTIFY)
291 {
292 NMHDR *nmhdr = (NMHDR *)lParam;
293 if (nmhdr && nmhdr->code == TCN_SELCHANGING)
294 return tcn_selchanging_result;
295 }
296
297 defwndproc_counter++;
298 ret = DefWindowProcA(hwnd, message, wParam, lParam);
299 defwndproc_counter--;
300
301 return ret;
302 }
303
registerParentWindowClass(void)304 static BOOL registerParentWindowClass(void)
305 {
306 WNDCLASSA cls;
307
308 cls.style = 0;
309 cls.lpfnWndProc = parent_wnd_proc;
310 cls.cbClsExtra = 0;
311 cls.cbWndExtra = 0;
312 cls.hInstance = GetModuleHandleA(NULL);
313 cls.hIcon = 0;
314 cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
315 cls.hbrBackground = GetStockObject(WHITE_BRUSH);
316 cls.lpszMenuName = NULL;
317 cls.lpszClassName = "Tab test parent class";
318 return RegisterClassA(&cls);
319 }
320
createParentWindow(void)321 static HWND createParentWindow(void)
322 {
323 if (!registerParentWindowClass())
324 return NULL;
325
326 return CreateWindowExA(0, "Tab test parent class", "Tab test parent window",
327 WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE, 0, 0, 100, 100,
328 GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL);
329 }
330
tab_subclass_proc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)331 static LRESULT WINAPI tab_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
332 {
333 WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
334 static LONG defwndproc_counter = 0;
335 struct message msg = { 0 };
336 LRESULT ret;
337
338 /* do not log painting messages */
339 if (message != WM_PAINT &&
340 message != WM_ERASEBKGND &&
341 message != WM_NCPAINT &&
342 message != WM_NCHITTEST &&
343 message != WM_GETTEXT &&
344 message != WM_GETICON &&
345 message != WM_DEVICECHANGE)
346 {
347 msg.message = message;
348 msg.flags = sent|wparam|lparam;
349 if (defwndproc_counter) msg.flags |= defwinproc;
350 msg.wParam = wParam;
351 msg.lParam = lParam;
352 add_message(sequences, TAB_SEQ_INDEX, &msg);
353 }
354
355 defwndproc_counter++;
356 ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
357 defwndproc_counter--;
358
359 return ret;
360 }
361
createFilledTabControl(HWND parent_wnd,DWORD style,DWORD mask,INT nTabs)362 static HWND createFilledTabControl(HWND parent_wnd, DWORD style, DWORD mask, INT nTabs)
363 {
364 HWND tabHandle;
365 TCITEMA tcNewTab;
366 WNDPROC oldproc;
367 RECT rect;
368 INT i;
369
370 GetClientRect(parent_wnd, &rect);
371
372 tabHandle = CreateWindowA(WC_TABCONTROLA, "TestTab",
373 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | style, 0, 0, rect.right,
374 rect.bottom, parent_wnd, NULL, NULL, 0);
375 ok(tabHandle != NULL, "failed to create tab wnd\n");
376
377 oldproc = (WNDPROC)SetWindowLongPtrA(tabHandle, GWLP_WNDPROC, (LONG_PTR)tab_subclass_proc);
378 SetWindowLongPtrA(tabHandle, GWLP_USERDATA, (LONG_PTR)oldproc);
379
380 tcNewTab.mask = mask;
381
382 for (i = 0; i < nTabs; i++)
383 {
384 char tabName[MAX_TABLEN];
385
386 sprintf(tabName, "Tab %d", i+1);
387 tcNewTab.pszText = tabName;
388 tcNewTab.iImage = i;
389 SendMessageA(tabHandle, TCM_INSERTITEMA, i, (LPARAM)&tcNewTab);
390 }
391
392 if (winetest_interactive)
393 {
394 ShowWindow (tabHandle, SW_SHOW);
395 RedrawWindow (tabHandle, NULL, 0, RDW_UPDATENOW);
396 Sleep (1000);
397 }
398
399 return tabHandle;
400 }
401
create_tooltip(HWND hTab,char toolTipText[])402 static HWND create_tooltip (HWND hTab, char toolTipText[])
403 {
404 HWND hwndTT;
405
406 TTTOOLINFOA ti;
407 LPSTR lptstr = toolTipText;
408 RECT rect;
409
410 /* Creating a tooltip window*/
411 hwndTT = CreateWindowExA(WS_EX_TOPMOST, TOOLTIPS_CLASSA, NULL,
412 WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
413 CW_USEDEFAULT, hTab, NULL, 0, NULL);
414
415 SetWindowPos(
416 hwndTT,
417 HWND_TOPMOST,
418 0, 0, 0, 0,
419 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
420
421 GetClientRect (hTab, &rect);
422
423 /* Initialize members of toolinfo*/
424 ti.cbSize = sizeof(TTTOOLINFOA);
425 ti.uFlags = TTF_SUBCLASS;
426 ti.hwnd = hTab;
427 ti.hinst = 0;
428 ti.uId = 0;
429 ti.lpszText = lptstr;
430
431 ti.rect = rect;
432
433 /* Add toolinfo structure to the tooltip control */
434 SendMessageA(hwndTT, TTM_ADDTOOLA, 0, (LPARAM)&ti);
435
436 return hwndTT;
437 }
438
test_tab(INT nMinTabWidth)439 static void test_tab(INT nMinTabWidth)
440 {
441 HWND hwTab;
442 RECT rTab;
443 HIMAGELIST himl = pImageList_Create(21, 21, ILC_COLOR, 3, 4);
444 SIZE size;
445 HDC hdc;
446 HFONT hOldFont;
447 INT i, dpi, exp;
448
449 hwTab = create_tabcontrol(TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE);
450 SendMessageA(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth);
451 /* Get System default MinTabWidth */
452 if (nMinTabWidth < 0)
453 nMinTabWidth = SendMessageA(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth);
454
455 hdc = GetDC(hwTab);
456 dpi = GetDeviceCaps(hdc, LOGPIXELSX);
457 hOldFont = SelectObject(hdc, (HFONT)SendMessageA(hwTab, WM_GETFONT, 0, 0));
458 GetTextExtentPoint32A(hdc, "Tab 1", strlen("Tab 1"), &size);
459 trace("Tab1 text size: size.cx=%d size.cy=%d\n", size.cx, size.cy);
460 SelectObject(hdc, hOldFont);
461 ReleaseDC(hwTab, hdc);
462
463 trace (" TCS_FIXEDWIDTH tabs no icon...\n");
464 CHECKSIZE(hwTab, dpi, -1, "default width");
465 TABCHECKSETSIZE(hwTab, 50, 20, 50, 20, "set size");
466 TABCHECKSETSIZE(hwTab, 0, 1, 0, 1, "min size");
467
468 SendMessageA(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
469
470 trace (" TCS_FIXEDWIDTH tabs with icon...\n");
471 TABCHECKSETSIZE(hwTab, 50, 30, 50, 30, "set size > icon");
472 TABCHECKSETSIZE(hwTab, 20, 20, 25, 20, "set size < icon");
473 TABCHECKSETSIZE(hwTab, 0, 1, 25, 1, "min size");
474
475 DestroyWindow (hwTab);
476
477 hwTab = create_tabcontrol(TCS_FIXEDWIDTH | TCS_BUTTONS, TCIF_TEXT|TCIF_IMAGE);
478 SendMessageA(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth);
479
480 hdc = GetDC(hwTab);
481 dpi = GetDeviceCaps(hdc, LOGPIXELSX);
482 ReleaseDC(hwTab, hdc);
483 trace (" TCS_FIXEDWIDTH buttons no icon...\n");
484 CHECKSIZE(hwTab, dpi, -1, "default width");
485 TABCHECKSETSIZE(hwTab, 20, 20, 20, 20, "set size 1");
486 TABCHECKSETSIZE(hwTab, 10, 50, 10, 50, "set size 2");
487 TABCHECKSETSIZE(hwTab, 0, 1, 0, 1, "min size");
488
489 SendMessageA(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
490
491 trace (" TCS_FIXEDWIDTH buttons with icon...\n");
492 TABCHECKSETSIZE(hwTab, 50, 30, 50, 30, "set size > icon");
493 TABCHECKSETSIZE(hwTab, 20, 20, 25, 20, "set size < icon");
494 TABCHECKSETSIZE(hwTab, 0, 1, 25, 1, "min size");
495 SendMessageA(hwTab, TCM_SETPADDING, 0, MAKELPARAM(4, 4));
496 TABCHECKSETSIZE(hwTab, 0, 1, 25, 1, "set padding, min size");
497
498 DestroyWindow (hwTab);
499
500 hwTab = create_tabcontrol(TCS_FIXEDWIDTH | TCS_BOTTOM, TCIF_TEXT|TCIF_IMAGE);
501 SendMessageA(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth);
502
503 hdc = GetDC(hwTab);
504 dpi = GetDeviceCaps(hdc, LOGPIXELSX);
505 ReleaseDC(hwTab, hdc);
506 trace (" TCS_FIXEDWIDTH | TCS_BOTTOM tabs...\n");
507 CHECKSIZE(hwTab, dpi, -1, "no icon, default width");
508
509 TABCHECKSETSIZE(hwTab, 20, 20, 20, 20, "no icon, set size 1");
510 TABCHECKSETSIZE(hwTab, 10, 50, 10, 50, "no icon, set size 2");
511 TABCHECKSETSIZE(hwTab, 0, 1, 0, 1, "no icon, min size");
512
513 SendMessageA(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
514
515 TABCHECKSETSIZE(hwTab, 50, 30, 50, 30, "with icon, set size > icon");
516 TABCHECKSETSIZE(hwTab, 20, 20, 25, 20, "with icon, set size < icon");
517 TABCHECKSETSIZE(hwTab, 0, 1, 25, 1, "with icon, min size");
518 SendMessageA(hwTab, TCM_SETPADDING, 0, MAKELPARAM(4, 4));
519 TABCHECKSETSIZE(hwTab, 0, 1, 25, 1, "set padding, min size");
520
521 DestroyWindow (hwTab);
522
523 hwTab = create_tabcontrol(0, TCIF_TEXT|TCIF_IMAGE);
524 SendMessageA(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth);
525
526 trace (" non fixed width, with text...\n");
527 exp = max(size.cx +TAB_PADDING_X*2, (nMinTabWidth < 0) ? DEFAULT_MIN_TAB_WIDTH : nMinTabWidth);
528 SendMessageA( hwTab, TCM_GETITEMRECT, 0, (LPARAM)&rTab );
529 ok( rTab.right - rTab.left == exp || broken(rTab.right - rTab.left == DEFAULT_MIN_TAB_WIDTH),
530 "no icon, default width: Expected width [%d] got [%d]\n", exp, rTab.right - rTab.left );
531
532 for (i=0; i<8; i++)
533 {
534 INT nTabWidth = (nMinTabWidth < 0) ? TabWidthPadded(i, 2) : nMinTabWidth;
535
536 SendMessageA(hwTab, TCM_SETIMAGELIST, 0, 0);
537 SendMessageA(hwTab, TCM_SETPADDING, 0, MAKELPARAM(i, i));
538
539 TABCHECKSETSIZE(hwTab, 50, 20, max(size.cx + i*2, nTabWidth), 20, "no icon, set size");
540 TABCHECKSETSIZE(hwTab, 0, 1, max(size.cx + i*2, nTabWidth), 1, "no icon, min size");
541
542 SendMessageA(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
543 nTabWidth = (nMinTabWidth < 0) ? TabWidthPadded(i, 3) : nMinTabWidth;
544
545 TABCHECKSETSIZE(hwTab, 50, 30, max(size.cx + 21 + i*3, nTabWidth), 30, "with icon, set size > icon");
546 TABCHECKSETSIZE(hwTab, 20, 20, max(size.cx + 21 + i*3, nTabWidth), 20, "with icon, set size < icon");
547 TABCHECKSETSIZE(hwTab, 0, 1, max(size.cx + 21 + i*3, nTabWidth), 1, "with icon, min size");
548 }
549 DestroyWindow (hwTab);
550
551 hwTab = create_tabcontrol(0, TCIF_IMAGE);
552 SendMessageA(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth);
553
554 trace (" non fixed width, no text...\n");
555 exp = (nMinTabWidth < 0) ? DEFAULT_MIN_TAB_WIDTH : nMinTabWidth;
556 SendMessageA( hwTab, TCM_GETITEMRECT, 0, (LPARAM)&rTab );
557 ok( rTab.right - rTab.left == exp || broken(rTab.right - rTab.left == DEFAULT_MIN_TAB_WIDTH),
558 "no icon, default width: Expected width [%d] got [%d]\n", exp, rTab.right - rTab.left );
559
560 for (i=0; i<8; i++)
561 {
562 INT nTabWidth = (nMinTabWidth < 0) ? TabWidthPadded(i, 2) : nMinTabWidth;
563
564 SendMessageA(hwTab, TCM_SETIMAGELIST, 0, 0);
565 SendMessageA(hwTab, TCM_SETPADDING, 0, MAKELPARAM(i, i));
566
567 TABCHECKSETSIZE(hwTab, 50, 20, nTabWidth, 20, "no icon, set size");
568 TABCHECKSETSIZE(hwTab, 0, 1, nTabWidth, 1, "no icon, min size");
569
570 SendMessageA(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
571 if (i > 1 && nMinTabWidth > 0 && nMinTabWidth < DEFAULT_MIN_TAB_WIDTH)
572 nTabWidth += EXTRA_ICON_PADDING *(i-1);
573
574 TABCHECKSETSIZE(hwTab, 50, 30, nTabWidth, 30, "with icon, set size > icon");
575 TABCHECKSETSIZE(hwTab, 20, 20, nTabWidth, 20, "with icon, set size < icon");
576 TABCHECKSETSIZE(hwTab, 0, 1, nTabWidth, 1, "with icon, min size");
577 }
578
579 DestroyWindow (hwTab);
580
581 pImageList_Destroy(himl);
582 }
583
test_width(void)584 static void test_width(void)
585 {
586 trace ("Testing with default MinWidth\n");
587 test_tab(-1);
588 trace ("Testing with MinWidth set to -3\n");
589 test_tab(-3);
590 trace ("Testing with MinWidth set to 24\n");
591 test_tab(24);
592 trace ("Testing with MinWidth set to 54\n");
593 test_tab(54);
594 trace ("Testing with MinWidth set to 94\n");
595 test_tab(94);
596 }
597
test_curfocus(void)598 static void test_curfocus(void)
599 {
600 const INT nTabs = 5;
601 INT ret;
602 HWND hTab;
603
604 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
605 ok(hTab != NULL, "Failed to create tab control\n");
606
607 flush_sequences(sequences, NUM_MSG_SEQUENCES);
608
609 /* Testing CurFocus with largest appropriate value */
610 ret = SendMessageA(hTab, TCM_SETCURFOCUS, nTabs - 1, 0);
611 ok(ret == 0, "Unexpected ret value %d.\n", ret);
612 ret = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
613 ok(ret == nTabs - 1, "Unexpected focus index %d.\n", ret);
614
615 /* Testing CurFocus with negative value */
616 ret = SendMessageA(hTab, TCM_SETCURFOCUS, -10, 0);
617 ok(ret == 0, "Unexpected ret value %d.\n", ret);
618 ret = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
619 ok(ret == -1, "Unexpected focus index %d.\n", ret);
620
621 /* Testing CurFocus with value larger than number of tabs */
622 ret = SendMessageA(hTab, TCM_SETCURSEL, 1, 0);
623 ok(ret == -1, "Unexpected focus index %d.\n", ret);
624
625 ret = SendMessageA(hTab, TCM_SETCURFOCUS, nTabs + 1, 0);
626 ok(ret == 0, "Unexpected ret value %d.\n", ret);
627 ret = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
628 ok(ret == 1, "Unexpected focus index %d.\n", ret);
629
630 ok_sequence(sequences, TAB_SEQ_INDEX, getset_cur_focus_seq, "Set focused tab sequence", FALSE);
631 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Set focused tab parent sequence", TRUE);
632
633 DestroyWindow(hTab);
634
635 /* TCS_BUTTONS */
636 hTab = createFilledTabControl(parent_wnd, TCS_BUTTONS, TCIF_TEXT|TCIF_IMAGE, nTabs);
637 ok(hTab != NULL, "Failed to create tab control\n");
638
639 flush_sequences(sequences, NUM_MSG_SEQUENCES);
640
641 /* Testing CurFocus with largest appropriate value */
642 ret = SendMessageA(hTab, TCM_SETCURFOCUS, nTabs - 1, 0);
643 ok(ret == 0, "Unexpected ret value %d.\n", ret);
644 ret = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
645 ok(ret == nTabs - 1, "Unexpected focus index %d.\n", ret);
646
647 /* Testing CurFocus with negative value */
648 ret = SendMessageA(hTab, TCM_SETCURFOCUS, -10, 0);
649 ok(ret == 0, "Unexpected ret value %d.\n", ret);
650 ret = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
651 todo_wine
652 ok(ret == nTabs - 1, "Unexpected focus index %d.\n", ret);
653
654 /* Testing CurFocus with value larger than number of tabs */
655 ret = SendMessageA(hTab, TCM_SETCURSEL, 1, 0);
656 todo_wine
657 ok(ret == 0, "Unexpected focus index %d.\n", ret);
658
659 ret = SendMessageA(hTab, TCM_SETCURFOCUS, nTabs + 1, 0);
660 ok(ret == 0, "Unexpected ret value %d.\n", ret);
661 ret = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
662 todo_wine
663 ok(ret == nTabs - 1, "Unexpected focus index %d.\n", ret);
664
665 ok_sequence(sequences, TAB_SEQ_INDEX, getset_cur_focus_seq, "TCS_BUTTONS: set focused tab sequence", FALSE);
666 ok_sequence(sequences, PARENT_SEQ_INDEX, setfocus_parent_seq, "TCS_BUTTONS: set focused tab parent sequence", TRUE);
667
668 DestroyWindow(hTab);
669 }
670
test_cursel(void)671 static void test_cursel(void)
672 {
673 const INT nTabs = 5;
674 INT selectionIndex;
675 INT focusIndex;
676 TCITEMA tcItem;
677 HWND hTab;
678
679 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
680 ok(hTab != NULL, "Failed to create tab control\n");
681
682 flush_sequences(sequences, NUM_MSG_SEQUENCES);
683
684 /* Testing CurSel with largest appropriate value */
685 selectionIndex = SendMessageA(hTab, TCM_SETCURSEL, nTabs - 1, 0);
686 expect(0, selectionIndex);
687 selectionIndex = SendMessageA(hTab, TCM_GETCURSEL, 0, 0);
688 expect(nTabs-1, selectionIndex);
689
690 /* Focus should switch with selection */
691 focusIndex = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
692 expect(nTabs-1, focusIndex);
693
694 /* Testing CurSel with negative value */
695 SendMessageA(hTab, TCM_SETCURSEL, -10, 0);
696 selectionIndex = SendMessageA(hTab, TCM_GETCURSEL, 0, 0);
697 expect(-1, selectionIndex);
698
699 /* Testing CurSel with value larger than number of tabs */
700 selectionIndex = SendMessageA(hTab, TCM_SETCURSEL, 1, 0);
701 expect(-1, selectionIndex);
702
703 selectionIndex = SendMessageA(hTab, TCM_SETCURSEL, nTabs + 1, 0);
704 expect(-1, selectionIndex);
705 selectionIndex = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
706 expect(1, selectionIndex);
707
708 ok_sequence(sequences, TAB_SEQ_INDEX, getset_cur_sel_seq, "Getset curSel test sequence", FALSE);
709 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset curSel test parent sequence", FALSE);
710
711 /* selected item should have TCIS_BUTTONPRESSED state
712 It doesn't depend on button state */
713 memset(&tcItem, 0, sizeof(TCITEMA));
714 tcItem.mask = TCIF_STATE;
715 tcItem.dwStateMask = TCIS_BUTTONPRESSED;
716 selectionIndex = SendMessageA(hTab, TCM_GETCURSEL, 0, 0);
717 SendMessageA(hTab, TCM_GETITEMA, selectionIndex, (LPARAM)&tcItem);
718 ok (tcItem.dwState & TCIS_BUTTONPRESSED || broken(tcItem.dwState == 0), /* older comctl32 */
719 "Selected item should have TCIS_BUTTONPRESSED\n");
720
721 /* now deselect all and check previously selected item state */
722 focusIndex = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
723 ok(focusIndex == 1, "got %d\n", focusIndex);
724
725 selectionIndex = SendMessageA(hTab, TCM_SETCURSEL, -1, 0);
726 ok(selectionIndex == 1, "got %d\n", selectionIndex);
727
728 memset(&tcItem, 0, sizeof(TCITEMA));
729
730 /* focus is reset too */
731 focusIndex = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
732 ok(focusIndex == -1, "got %d\n", focusIndex);
733
734 tcItem.mask = TCIF_STATE;
735 tcItem.dwStateMask = TCIS_BUTTONPRESSED;
736 SendMessageA(hTab, TCM_GETITEMA, selectionIndex, (LPARAM)&tcItem);
737 ok(tcItem.dwState == 0, "got state %d\n", tcItem.dwState);
738
739 DestroyWindow(hTab);
740 }
741
test_extendedstyle(void)742 static void test_extendedstyle(void)
743 {
744 const INT nTabs = 5;
745 DWORD prevExtendedStyle;
746 DWORD extendedStyle;
747 HWND hTab;
748
749 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
750 ok(hTab != NULL, "Failed to create tab control\n");
751
752 flush_sequences(sequences, NUM_MSG_SEQUENCES);
753
754 /* Testing Flat Separators */
755 extendedStyle = SendMessageA(hTab, TCM_GETEXTENDEDSTYLE, 0, 0);
756 prevExtendedStyle = SendMessageA(hTab, TCM_SETEXTENDEDSTYLE, 0, TCS_EX_FLATSEPARATORS);
757 expect(extendedStyle, prevExtendedStyle);
758
759 extendedStyle = SendMessageA(hTab, TCM_GETEXTENDEDSTYLE, 0, 0);
760 expect(TCS_EX_FLATSEPARATORS, extendedStyle);
761
762 /* Testing Register Drop */
763 prevExtendedStyle = SendMessageA(hTab, TCM_SETEXTENDEDSTYLE, 0, TCS_EX_REGISTERDROP);
764 expect(extendedStyle, prevExtendedStyle);
765
766 extendedStyle = SendMessageA(hTab, TCM_GETEXTENDEDSTYLE, 0, 0);
767 todo_wine{
768 expect(TCS_EX_REGISTERDROP, extendedStyle);
769 }
770
771 ok_sequence(sequences, TAB_SEQ_INDEX, getset_extended_style_seq, "Getset extendedStyle test sequence", FALSE);
772 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset extendedStyle test parent sequence", FALSE);
773
774 DestroyWindow(hTab);
775 }
776
test_unicodeformat(void)777 static void test_unicodeformat(void)
778 {
779 const INT nTabs = 5;
780 INT unicodeFormat;
781 HWND hTab;
782
783 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
784 ok(hTab != NULL, "Failed to create tab control\n");
785
786 flush_sequences(sequences, NUM_MSG_SEQUENCES);
787
788 unicodeFormat = SendMessageA(hTab, TCM_SETUNICODEFORMAT, TRUE, 0);
789 todo_wine{
790 expect(0, unicodeFormat);
791 }
792 unicodeFormat = SendMessageA(hTab, TCM_GETUNICODEFORMAT, 0, 0);
793 expect(1, unicodeFormat);
794
795 unicodeFormat = SendMessageA(hTab, TCM_SETUNICODEFORMAT, FALSE, 0);
796 expect(1, unicodeFormat);
797 unicodeFormat = SendMessageA(hTab, TCM_GETUNICODEFORMAT, 0, 0);
798 expect(0, unicodeFormat);
799
800 unicodeFormat = SendMessageA(hTab, TCM_SETUNICODEFORMAT, TRUE, 0);
801 expect(0, unicodeFormat);
802
803 ok_sequence(sequences, TAB_SEQ_INDEX, getset_unicode_format_seq, "Getset unicodeFormat test sequence", FALSE);
804 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset unicodeFormat test parent sequence", FALSE);
805
806 DestroyWindow(hTab);
807 }
808
test_getset_item(void)809 static void test_getset_item(void)
810 {
811 char szText[32] = "New Label";
812 const INT nTabs = 5;
813 TCITEMA tcItem;
814 LPARAM lparam;
815 DWORD ret;
816 HWND hTab;
817
818 hTab = CreateWindowA(
819 WC_TABCONTROLA,
820 "TestTab",
821 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | TCS_FIXEDWIDTH | TCS_OWNERDRAWFIXED,
822 10, 10, 300, 100,
823 parent_wnd, NULL, NULL, 0);
824
825 ok(GetParent(hTab) == NULL, "got %p, expected null parent\n", GetParent(hTab));
826
827 ret = SendMessageA(hTab, TCM_SETITEMEXTRA, sizeof(LPARAM)-1, 0);
828 ok(ret == TRUE, "got %d\n", ret);
829
830 /* set some item data */
831 tcItem.lParam = ~0;
832 tcItem.mask = TCIF_PARAM;
833
834 ret = SendMessageA(hTab, TCM_INSERTITEMA, 0, (LPARAM)&tcItem);
835 ok(ret == 0, "got %d\n", ret);
836
837 /* all sizeof(LPARAM) returned anyway when using sizeof(LPARAM)-1 size */
838 memset(&lparam, 0xaa, sizeof(lparam));
839 tcItem.lParam = lparam;
840 tcItem.mask = TCIF_PARAM;
841 ret = SendMessageA(hTab, TCM_GETITEMA, 0, (LPARAM)&tcItem);
842 expect(TRUE, ret);
843 /* everything higher specified size is preserved */
844 memset(&lparam, 0xff, sizeof(lparam)-1);
845 ok(tcItem.lParam == lparam, "Expected 0x%lx, got 0x%lx\n", lparam, tcItem.lParam);
846
847 DestroyWindow(hTab);
848
849 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
850 ok(hTab != NULL, "Failed to create tab control\n");
851
852 /* passing invalid index should result in initialization to zero
853 for members mentioned in mask requested */
854
855 /* valid range here is [0,4] */
856 memset(&tcItem, 0xcc, sizeof(tcItem));
857 tcItem.mask = TCIF_PARAM;
858 ret = SendMessageA(hTab, TCM_GETITEMA, 5, (LPARAM)&tcItem);
859 expect(FALSE, ret);
860 ok(tcItem.lParam == 0, "Expected zero lParam, got %lu\n", tcItem.lParam);
861
862 memset(&tcItem, 0xcc, sizeof(tcItem));
863 tcItem.mask = TCIF_IMAGE;
864 ret = SendMessageA(hTab, TCM_GETITEMA, 5, (LPARAM)&tcItem);
865 expect(FALSE, ret);
866 expect(0, tcItem.iImage);
867
868 memset(&tcItem, 0xcc, sizeof(tcItem));
869 tcItem.mask = TCIF_TEXT;
870 tcItem.pszText = szText;
871 szText[0] = 'a';
872 ret = SendMessageA(hTab, TCM_GETITEMA, 5, (LPARAM)&tcItem);
873 expect(FALSE, ret);
874 expect('a', szText[0]);
875
876 memset(&tcItem, 0xcc, sizeof(tcItem));
877 tcItem.mask = TCIF_STATE;
878 tcItem.dwStateMask = 0;
879 tcItem.dwState = TCIS_BUTTONPRESSED;
880 ret = SendMessageA(hTab, TCM_GETITEMA, 5, (LPARAM)&tcItem);
881 expect(FALSE, ret);
882 ok(tcItem.dwState == 0, "Expected zero dwState, got %u\n", tcItem.dwState);
883
884 memset(&tcItem, 0xcc, sizeof(tcItem));
885 tcItem.mask = TCIF_STATE;
886 tcItem.dwStateMask = TCIS_BUTTONPRESSED;
887 tcItem.dwState = TCIS_BUTTONPRESSED;
888 ret = SendMessageA(hTab, TCM_GETITEMA, 5, (LPARAM)&tcItem);
889 expect(FALSE, ret);
890 ok(tcItem.dwState == 0, "Expected zero dwState\n");
891
892 /* check with negative index to be sure */
893 memset(&tcItem, 0xcc, sizeof(tcItem));
894 tcItem.mask = TCIF_PARAM;
895 ret = SendMessageA(hTab, TCM_GETITEMA, -1, (LPARAM)&tcItem);
896 expect(FALSE, ret);
897 ok(tcItem.lParam == 0, "Expected zero lParam, got %lu\n", tcItem.lParam);
898
899 memset(&tcItem, 0xcc, sizeof(tcItem));
900 tcItem.mask = TCIF_PARAM;
901 ret = SendMessageA(hTab, TCM_GETITEMA, -2, (LPARAM)&tcItem);
902 expect(FALSE, ret);
903 ok(tcItem.lParam == 0, "Expected zero lParam, got %lu\n", tcItem.lParam);
904
905 flush_sequences(sequences, NUM_MSG_SEQUENCES);
906
907 tcItem.mask = TCIF_TEXT;
908 tcItem.pszText = &szText[0];
909 tcItem.cchTextMax = sizeof(szText);
910
911 strcpy(szText, "New Label");
912 ok(SendMessageA(hTab, TCM_SETITEMA, 0, (LPARAM)&tcItem), "Setting new item failed.\n");
913 ok(SendMessageA(hTab, TCM_GETITEMA, 0, (LPARAM)&tcItem), "Getting item failed.\n");
914 expect_str("New Label", tcItem.pszText);
915
916 ok(SendMessageA(hTab, TCM_GETITEMA, 1, (LPARAM)&tcItem), "Getting item failed.\n");
917 expect_str("Tab 2", tcItem.pszText);
918
919 ok_sequence(sequences, TAB_SEQ_INDEX, getset_item_seq, "Getset item test sequence", FALSE);
920 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset item test parent sequence", FALSE);
921
922 /* TCIS_BUTTONPRESSED doesn't depend on tab style */
923 memset(&tcItem, 0, sizeof(tcItem));
924 tcItem.mask = TCIF_STATE;
925 tcItem.dwStateMask = TCIS_BUTTONPRESSED;
926 tcItem.dwState = TCIS_BUTTONPRESSED;
927 ok(SendMessageA(hTab, TCM_SETITEMA, 0, (LPARAM)&tcItem), "Setting new item failed.\n");
928 tcItem.dwState = 0;
929 ok(SendMessageA(hTab, TCM_GETITEMA, 0, (LPARAM)&tcItem), "Getting item failed.\n");
930 if (tcItem.dwState)
931 {
932 ok (tcItem.dwState == TCIS_BUTTONPRESSED, "TCIS_BUTTONPRESSED should be set.\n");
933 /* next highlight item, test that dwStateMask actually masks */
934 tcItem.mask = TCIF_STATE;
935 tcItem.dwStateMask = TCIS_HIGHLIGHTED;
936 tcItem.dwState = TCIS_HIGHLIGHTED;
937 ok(SendMessageA(hTab, TCM_SETITEMA, 0, (LPARAM)&tcItem), "Setting new item failed.\n");
938 tcItem.dwState = 0;
939 ok(SendMessageA(hTab, TCM_GETITEMA, 0, (LPARAM)&tcItem), "Getting item failed.\n");
940 ok (tcItem.dwState == TCIS_HIGHLIGHTED, "TCIS_HIGHLIGHTED should be set.\n");
941 tcItem.mask = TCIF_STATE;
942 tcItem.dwStateMask = TCIS_BUTTONPRESSED;
943 tcItem.dwState = 0;
944 ok(SendMessageA(hTab, TCM_GETITEMA, 0, (LPARAM)&tcItem), "Getting item failed.\n");
945 ok (tcItem.dwState == TCIS_BUTTONPRESSED, "TCIS_BUTTONPRESSED should be set.\n");
946 }
947 else win_skip( "Item state mask not supported\n" );
948
949 DestroyWindow(hTab);
950 }
951
test_getset_tooltips(void)952 static void test_getset_tooltips(void)
953 {
954 char toolTipText[32] = "ToolTip Text Test";
955 HWND hTab, toolTip, hwnd;
956 const INT nTabs = 5;
957 int ret;
958
959 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
960 ok(hTab != NULL, "Failed to create tab control\n");
961
962 flush_sequences(sequences, NUM_MSG_SEQUENCES);
963
964 toolTip = create_tooltip(hTab, toolTipText);
965 ret = SendMessageA(hTab, TCM_SETTOOLTIPS, (WPARAM)toolTip, 0);
966 ok(ret == 0, "Unexpected ret value %d.\n", ret);
967 hwnd = (HWND)SendMessageA(hTab, TCM_GETTOOLTIPS, 0, 0);
968 ok(toolTip == hwnd, "Unexpected tooltip window.\n");
969
970 ret = SendMessageA(hTab, TCM_SETTOOLTIPS, 0, 0);
971 ok(ret == 0, "Unexpected ret value %d.\n", ret);
972 hwnd = (HWND)SendMessageA(hTab, TCM_GETTOOLTIPS, 0, 0);
973 ok(hwnd == NULL, "Unexpected tooltip window.\n");
974 ok(IsWindow(toolTip), "Expected tooltip window to be alive.\n");
975
976 ok_sequence(sequences, TAB_SEQ_INDEX, getset_tooltip_seq, "Getset tooltip test sequence", TRUE);
977 ok_sequence(sequences, PARENT_SEQ_INDEX, getset_tooltip_parent_seq, "Getset tooltip test parent sequence", TRUE);
978
979 DestroyWindow(hTab);
980 DestroyWindow(toolTip);
981 }
982
test_adjustrect(void)983 static void test_adjustrect(void)
984 {
985 HWND hTab;
986 INT r;
987
988 ok(parent_wnd != NULL, "no parent window!\n");
989
990 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, 0, 0);
991 ok(hTab != NULL, "Failed to create tab control\n");
992
993 r = SendMessageA(hTab, TCM_ADJUSTRECT, FALSE, 0);
994 expect(-1, r);
995
996 r = SendMessageA(hTab, TCM_ADJUSTRECT, TRUE, 0);
997 expect(-1, r);
998 }
999
test_insert_focus(void)1000 static void test_insert_focus(void)
1001 {
1002 HWND hTab;
1003 INT nTabsRetrieved;
1004 INT r;
1005 TCITEMA tcNewTab;
1006 DWORD mask = TCIF_TEXT|TCIF_IMAGE;
1007 static char tabName[] = "TAB";
1008 tcNewTab.mask = mask;
1009 tcNewTab.pszText = tabName;
1010
1011 ok(parent_wnd != NULL, "no parent window!\n");
1012
1013 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, mask, 0);
1014 ok(hTab != NULL, "Failed to create tab control\n");
1015
1016 r = SendMessageA(hTab, TCM_GETCURSEL, 0, 0);
1017 expect(-1, r);
1018
1019 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1020
1021 nTabsRetrieved = SendMessageA(hTab, TCM_GETITEMCOUNT, 0, 0);
1022 expect(0, nTabsRetrieved);
1023
1024 r = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
1025 expect(-1, r);
1026
1027 tcNewTab.iImage = 1;
1028 r = SendMessageA(hTab, TCM_INSERTITEMA, 1, (LPARAM)&tcNewTab);
1029 expect(0, r);
1030
1031 nTabsRetrieved = SendMessageA(hTab, TCM_GETITEMCOUNT, 0, 0);
1032 expect(1, nTabsRetrieved);
1033
1034 r = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
1035 expect(0, r);
1036
1037 tcNewTab.iImage = 2;
1038 r = SendMessageA(hTab, TCM_INSERTITEMA, 2, (LPARAM)&tcNewTab);
1039 expect(1, r);
1040
1041 nTabsRetrieved = SendMessageA(hTab, TCM_GETITEMCOUNT, 0, 0);
1042 expect(2, nTabsRetrieved);
1043
1044 r = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
1045 expect(0, r);
1046
1047 r = SendMessageA(hTab, TCM_SETCURFOCUS, -1, 0);
1048 expect(0, r);
1049
1050 r = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
1051 expect(-1, r);
1052
1053 tcNewTab.iImage = 3;
1054 r = SendMessageA(hTab, TCM_INSERTITEMA, 3, (LPARAM)&tcNewTab);
1055 expect(2, r);
1056
1057 r = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
1058 expect(2, r);
1059
1060 ok_sequence(sequences, TAB_SEQ_INDEX, insert_focus_seq, "insert_focus test sequence", FALSE);
1061 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "insert_focus parent test sequence", TRUE);
1062
1063 DestroyWindow(hTab);
1064 }
1065
test_delete_focus(void)1066 static void test_delete_focus(void)
1067 {
1068 HWND hTab;
1069 INT nTabsRetrieved;
1070 INT r;
1071
1072 ok(parent_wnd != NULL, "no parent window!\n");
1073
1074 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, 2);
1075 ok(hTab != NULL, "Failed to create tab control\n");
1076
1077 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1078
1079 nTabsRetrieved = SendMessageA(hTab, TCM_GETITEMCOUNT, 0, 0);
1080 expect(2, nTabsRetrieved);
1081
1082 r = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
1083 expect(0, r);
1084
1085 r = SendMessageA(hTab, TCM_DELETEITEM, 1, 0);
1086 expect(1, r);
1087
1088 nTabsRetrieved = SendMessageA(hTab, TCM_GETITEMCOUNT, 0, 0);
1089 expect(1, nTabsRetrieved);
1090
1091 r = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
1092 expect(0, r);
1093
1094 r = SendMessageA(hTab, TCM_SETCURFOCUS, -1, 0);
1095 expect(0, r);
1096
1097 r = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
1098 expect(-1, r);
1099
1100 r = SendMessageA(hTab, TCM_DELETEITEM, 0, 0);
1101 expect(1, r);
1102
1103 nTabsRetrieved = SendMessageA(hTab, TCM_GETITEMCOUNT, 0, 0);
1104 expect(0, nTabsRetrieved);
1105
1106 r = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
1107 expect(-1, r);
1108
1109 ok_sequence(sequences, TAB_SEQ_INDEX, delete_focus_seq, "delete_focus test sequence", FALSE);
1110 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "delete_focus parent test sequence", TRUE);
1111
1112 DestroyWindow(hTab);
1113 }
1114
test_removeimage(void)1115 static void test_removeimage(void)
1116 {
1117 static const BYTE bits[32];
1118 HWND hwTab;
1119 INT i;
1120 TCITEMA item;
1121 HICON hicon;
1122 HIMAGELIST himl = pImageList_Create(16, 16, ILC_COLOR, 3, 4);
1123
1124 hicon = CreateIcon(NULL, 16, 16, 1, 1, bits, bits);
1125 pImageList_ReplaceIcon(himl, -1, hicon);
1126 pImageList_ReplaceIcon(himl, -1, hicon);
1127 pImageList_ReplaceIcon(himl, -1, hicon);
1128
1129 hwTab = create_tabcontrol(TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE);
1130 SendMessageA(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
1131
1132 memset(&item, 0, sizeof(TCITEMA));
1133 item.mask = TCIF_IMAGE;
1134
1135 for(i = 0; i < 3; i++) {
1136 SendMessageA(hwTab, TCM_GETITEMA, i, (LPARAM)&item);
1137 expect(i, item.iImage);
1138 }
1139
1140 /* remove image middle image */
1141 SendMessageA(hwTab, TCM_REMOVEIMAGE, 1, 0);
1142 i = pImageList_GetImageCount(himl);
1143 ok(i == 2, "Unexpected image count %d.\n", i);
1144 item.iImage = -1;
1145 SendMessageA(hwTab, TCM_GETITEMA, 0, (LPARAM)&item);
1146 expect(0, item.iImage);
1147 item.iImage = 0;
1148 SendMessageA(hwTab, TCM_GETITEMA, 1, (LPARAM)&item);
1149 expect(-1, item.iImage);
1150 item.iImage = 0;
1151 SendMessageA(hwTab, TCM_GETITEMA, 2, (LPARAM)&item);
1152 expect(1, item.iImage);
1153 /* remove first image */
1154 SendMessageA(hwTab, TCM_REMOVEIMAGE, 0, 0);
1155 i = pImageList_GetImageCount(himl);
1156 ok(i == 1, "Unexpected image count %d.\n", i);
1157 item.iImage = 0;
1158 SendMessageA(hwTab, TCM_GETITEMA, 0, (LPARAM)&item);
1159 expect(-1, item.iImage);
1160 item.iImage = 0;
1161 SendMessageA(hwTab, TCM_GETITEMA, 1, (LPARAM)&item);
1162 expect(-1, item.iImage);
1163 item.iImage = -1;
1164 SendMessageA(hwTab, TCM_GETITEMA, 2, (LPARAM)&item);
1165 expect(0, item.iImage);
1166 /* remove the last one */
1167 SendMessageA(hwTab, TCM_REMOVEIMAGE, 0, 0);
1168 i = pImageList_GetImageCount(himl);
1169 ok(i == 0, "Unexpected image count %d.\n", i);
1170 for(i = 0; i < 3; i++) {
1171 item.iImage = 0;
1172 SendMessageA(hwTab, TCM_GETITEMA, i, (LPARAM)&item);
1173 expect(-1, item.iImage);
1174 }
1175
1176 DestroyWindow(hwTab);
1177 pImageList_Destroy(himl);
1178 DestroyIcon(hicon);
1179 }
1180
test_delete_selection(void)1181 static void test_delete_selection(void)
1182 {
1183 HWND hTab;
1184 INT ret;
1185
1186 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, 4);
1187 ok(hTab != NULL, "Failed to create tab control\n");
1188
1189 ret = SendMessageA(hTab, TCM_SETCURSEL, 3, 0);
1190 expect(0, ret);
1191 ret = SendMessageA(hTab, TCM_GETCURSEL, 0, 0);
1192 expect(3, ret);
1193 /* delete selected item - selection goes to -1 */
1194 ret = SendMessageA(hTab, TCM_DELETEITEM, 3, 0);
1195 expect(TRUE, ret);
1196
1197 ret = SendMessageA(hTab, TCM_GETCURSEL, 0, 0);
1198 expect(-1, ret);
1199
1200 DestroyWindow(hTab);
1201 }
1202
test_TCM_SETITEMEXTRA(void)1203 static void test_TCM_SETITEMEXTRA(void)
1204 {
1205 HWND hTab;
1206 DWORD ret;
1207
1208 hTab = CreateWindowA(
1209 WC_TABCONTROLA,
1210 "TestTab",
1211 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | TCS_FIXEDWIDTH,
1212 10, 10, 300, 100,
1213 parent_wnd, NULL, NULL, 0);
1214
1215 /* zero is valid size too */
1216 ret = SendMessageA(hTab, TCM_SETITEMEXTRA, 0, 0);
1217 if (ret == FALSE)
1218 {
1219 win_skip("TCM_SETITEMEXTRA not supported\n");
1220 DestroyWindow(hTab);
1221 return;
1222 }
1223
1224 ret = SendMessageA(hTab, TCM_SETITEMEXTRA, -1, 0);
1225 ok(ret == FALSE, "got %d\n", ret);
1226
1227 ret = SendMessageA(hTab, TCM_SETITEMEXTRA, 2, 0);
1228 ok(ret == TRUE, "got %d\n", ret);
1229 DestroyWindow(hTab);
1230
1231 /* it's not possible to change extra data size for control with tabs */
1232 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, 4);
1233 ok(hTab != NULL, "Failed to create tab control\n");
1234
1235 ret = SendMessageA(hTab, TCM_SETITEMEXTRA, 2, 0);
1236 ok(ret == FALSE, "got %d\n", ret);
1237 DestroyWindow(hTab);
1238 }
1239
test_TCS_OWNERDRAWFIXED(void)1240 static void test_TCS_OWNERDRAWFIXED(void)
1241 {
1242 LPARAM lparam;
1243 ULONG_PTR itemdata, itemdata2;
1244 TCITEMA item;
1245 HWND hTab;
1246 BOOL ret;
1247
1248 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH|TCS_OWNERDRAWFIXED, TCIF_TEXT|TCIF_IMAGE, 4);
1249 ok(hTab != NULL, "Failed to create tab control\n");
1250
1251 ok(GetParent(hTab) == NULL, "got %p, expected null parent\n", GetParent(hTab));
1252
1253 /* set some item data */
1254 memset(&lparam, 0xde, sizeof(LPARAM));
1255
1256 item.mask = TCIF_PARAM;
1257 item.lParam = lparam;
1258 ret = SendMessageA(hTab, TCM_SETITEMA, 0, (LPARAM)&item);
1259 ok(ret == TRUE, "got %d\n", ret);
1260
1261 memset(&g_drawitem, 0, sizeof(g_drawitem));
1262
1263 ShowWindow(hTab, SW_SHOW);
1264 RedrawWindow(hTab, NULL, 0, RDW_UPDATENOW);
1265
1266 itemdata = 0;
1267 memset(&itemdata, 0xde, 4);
1268 ok(g_drawitem.itemData == itemdata, "got 0x%lx, expected 0x%lx\n", g_drawitem.itemData, itemdata);
1269
1270 DestroyWindow(hTab);
1271
1272 /* now with custom extra data length */
1273 hTab = CreateWindowA(
1274 WC_TABCONTROLA,
1275 "TestTab",
1276 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | TCS_FIXEDWIDTH | TCS_OWNERDRAWFIXED,
1277 10, 10, 300, 100,
1278 parent_wnd, NULL, NULL, 0);
1279
1280 ok(GetParent(hTab) == NULL, "got %p, expected null parent\n", GetParent(hTab));
1281
1282 ret = SendMessageA(hTab, TCM_SETITEMEXTRA, sizeof(LPARAM)+1, 0);
1283 ok(ret == TRUE, "got %d\n", ret);
1284
1285 /* set some item data */
1286 memset(&lparam, 0xde, sizeof(LPARAM));
1287 item.mask = TCIF_PARAM;
1288 item.lParam = lparam;
1289
1290 ret = SendMessageA(hTab, TCM_INSERTITEMA, 0, (LPARAM)&item);
1291 ok(ret == 0, "got %d\n", ret);
1292
1293 memset(&g_drawitem, 0, sizeof(g_drawitem));
1294
1295 ShowWindow(hTab, SW_SHOW);
1296 RedrawWindow(hTab, NULL, 0, RDW_UPDATENOW);
1297
1298 memset(&itemdata, 0xde, sizeof(ULONG_PTR));
1299 ok(*(ULONG_PTR*)g_drawitem.itemData == itemdata, "got 0x%lx, expected 0x%lx\n", g_drawitem.itemData, itemdata);
1300
1301 DestroyWindow(hTab);
1302
1303 /* same thing, but size smaller than default */
1304 hTab = CreateWindowA(
1305 WC_TABCONTROLA,
1306 "TestTab",
1307 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | TCS_FIXEDWIDTH | TCS_OWNERDRAWFIXED,
1308 10, 10, 300, 100,
1309 parent_wnd, NULL, NULL, 0);
1310
1311 ok(GetParent(hTab) == NULL, "got %p, expected null parent\n", GetParent(hTab));
1312
1313 ret = SendMessageA(hTab, TCM_SETITEMEXTRA, sizeof(LPARAM)-1, 0);
1314 ok(ret == TRUE, "got %d\n", ret);
1315
1316 memset(&lparam, 0xde, sizeof(lparam));
1317 item.mask = TCIF_PARAM;
1318 item.lParam = lparam;
1319
1320 ret = SendMessageA(hTab, TCM_INSERTITEMA, 0, (LPARAM)&item);
1321 ok(ret == 0, "got %d\n", ret);
1322
1323 memset(&g_drawitem, 0, sizeof(g_drawitem));
1324
1325 ShowWindow(hTab, SW_SHOW);
1326 RedrawWindow(hTab, NULL, 0, RDW_UPDATENOW);
1327
1328 itemdata = itemdata2 = 0;
1329 memset(&itemdata, 0xde, 4);
1330 memset(&itemdata2, 0xde, sizeof(LPARAM)-1);
1331 ok(g_drawitem.itemData == itemdata || broken(g_drawitem.itemData == itemdata2) /* win98 */,
1332 "got 0x%lx, expected 0x%lx\n", g_drawitem.itemData, itemdata);
1333
1334 DestroyWindow(hTab);
1335 }
1336
test_WM_CONTEXTMENU(void)1337 static void test_WM_CONTEXTMENU(void)
1338 {
1339 HWND hTab;
1340
1341 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, 4);
1342 ok(hTab != NULL, "Failed to create tab control\n");
1343
1344 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1345
1346 SendMessageA(hTab, WM_RBUTTONUP, 0, 0);
1347
1348 ok_sequence(sequences, TAB_SEQ_INDEX, rbuttonup_seq, "WM_RBUTTONUP response sequence", FALSE);
1349
1350 DestroyWindow(hTab);
1351 }
1352
1353 struct tabcreate_style {
1354 DWORD style;
1355 DWORD act_style;
1356 };
1357
1358 static const struct tabcreate_style create_styles[] =
1359 {
1360 { WS_CHILD|TCS_BOTTOM|TCS_VERTICAL, WS_CHILD|WS_CLIPSIBLINGS|TCS_BOTTOM|TCS_VERTICAL|TCS_MULTILINE },
1361 { WS_CHILD|TCS_VERTICAL, WS_CHILD|WS_CLIPSIBLINGS|TCS_VERTICAL|TCS_MULTILINE },
1362 { 0 }
1363 };
1364
test_create(void)1365 static void test_create(void)
1366 {
1367 const struct tabcreate_style *ptr = create_styles;
1368 DWORD style;
1369 HWND hTab;
1370
1371 while (ptr->style)
1372 {
1373 hTab = CreateWindowA(WC_TABCONTROLA, "TestTab", ptr->style,
1374 10, 10, 300, 100, parent_wnd, NULL, NULL, 0);
1375 style = GetWindowLongA(hTab, GWL_STYLE);
1376 ok(style == ptr->act_style, "expected style 0x%08x, got style 0x%08x\n", ptr->act_style, style);
1377
1378 DestroyWindow(hTab);
1379 ptr++;
1380 }
1381 }
1382
init_functions(void)1383 static void init_functions(void)
1384 {
1385 HMODULE hComCtl32 = LoadLibraryA("comctl32.dll");
1386
1387 #define X(f) p##f = (void*)GetProcAddress(hComCtl32, #f);
1388 X(ImageList_Create);
1389 X(ImageList_Destroy);
1390 X(ImageList_GetImageCount);
1391 X(ImageList_ReplaceIcon);
1392 #undef X
1393 }
1394
test_TCN_SELCHANGING(void)1395 static void test_TCN_SELCHANGING(void)
1396 {
1397 const INT nTabs = 5;
1398 HWND hTab;
1399 INT ret;
1400
1401 hTab = createFilledTabControl(parent_wnd, WS_CHILD|TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
1402 ok(hTab != NULL, "Failed to create tab control\n");
1403
1404 /* Initially first tab is focused. */
1405 ret = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
1406 ok(ret == 0, "Unexpected tab focus %d.\n", ret);
1407
1408 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1409
1410 /* Setting focus to currently focused item should do nothing. */
1411 ret = SendMessageA(hTab, TCM_SETCURFOCUS, 0, 0);
1412 ok(ret == 0, "Unexpected ret value %d.\n", ret);
1413
1414 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Set focus to focused tab sequence", FALSE);
1415
1416 /* Allow selection change. */
1417 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1418
1419 tcn_selchanging_result = 0;
1420 ret = SendMessageA(hTab, TCM_SETCURFOCUS, nTabs - 1, 0);
1421 ok(ret == 0, "Unexpected ret value %d.\n", ret);
1422
1423 ok_sequence(sequences, PARENT_SEQ_INDEX, full_selchange_parent_seq, "Focus change allowed sequence", FALSE);
1424
1425 ret = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
1426 ok(ret == nTabs - 1, "Unexpected focused tab %d.\n", ret);
1427 ret = SendMessageA(hTab, TCM_GETCURSEL, 0, 0);
1428 ok(ret == nTabs - 1, "Unexpected selected tab %d.\n", ret);
1429
1430 /* Forbid selection change. */
1431 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1432
1433 tcn_selchanging_result = 1;
1434 ret = SendMessageA(hTab, TCM_SETCURFOCUS, 0, 0);
1435 ok(ret == 0, "Unexpected ret value %d.\n", ret);
1436
1437 ok_sequence(sequences, PARENT_SEQ_INDEX, selchanging_parent_seq, "Focus change disallowed sequence", FALSE);
1438
1439 ret = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
1440 todo_wine
1441 ok(ret == nTabs - 1, "Unexpected focused tab %d.\n", ret);
1442 ret = SendMessageA(hTab, TCM_GETCURSEL, 0, 0);
1443 todo_wine
1444 ok(ret == nTabs - 1, "Unexpected selected tab %d.\n", ret);
1445
1446 /* Removing focus sends only TCN_SELCHANGE */
1447 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1448
1449 ret = SendMessageA(hTab, TCM_SETCURFOCUS, -1, 0);
1450 ok(ret == 0, "Unexpected ret value %d.\n", ret);
1451
1452 ok_sequence(sequences, PARENT_SEQ_INDEX, selchange_parent_seq, "Remove focus sequence", FALSE);
1453
1454 ret = SendMessageA(hTab, TCM_GETCURFOCUS, 0, 0);
1455 ok(ret == -1, "Unexpected focused tab %d.\n", ret);
1456
1457 tcn_selchanging_result = 0;
1458
1459 DestroyWindow(hTab);
1460 }
1461
test_TCM_GETROWCOUNT(void)1462 static void test_TCM_GETROWCOUNT(void)
1463 {
1464 const INT nTabs = 5;
1465 HWND hTab;
1466 INT count;
1467
1468 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1469
1470 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
1471 ok(hTab != NULL, "Failed to create tab control\n");
1472
1473 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1474
1475 count = SendMessageA(hTab, TCM_GETROWCOUNT, 0, 0);
1476 ok(count == 1, "Unexpected row count %d.\n", count);
1477
1478 ok_sequence(sequences, TAB_SEQ_INDEX, get_row_count_seq, "Get rowCount test sequence", FALSE);
1479 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Get rowCount test parent sequence", FALSE);
1480
1481 DestroyWindow(hTab);
1482 }
1483
START_TEST(tab)1484 START_TEST(tab)
1485 {
1486 LOGFONTA logfont;
1487
1488 lstrcpyA(logfont.lfFaceName, "Arial");
1489 memset(&logfont, 0, sizeof(logfont));
1490 logfont.lfHeight = -12;
1491 logfont.lfWeight = FW_NORMAL;
1492 logfont.lfCharSet = ANSI_CHARSET;
1493 hFont = CreateFontIndirectA(&logfont);
1494
1495 init_functions();
1496
1497 init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
1498
1499 parent_wnd = createParentWindow();
1500 ok(parent_wnd != NULL, "Failed to create parent window!\n");
1501
1502 test_width();
1503 test_curfocus();
1504 test_cursel();
1505 test_extendedstyle();
1506 test_unicodeformat();
1507 test_getset_item();
1508 test_getset_tooltips();
1509 test_adjustrect();
1510 test_insert_focus();
1511 test_delete_focus();
1512 test_delete_selection();
1513 test_removeimage();
1514 test_TCM_SETITEMEXTRA();
1515 test_TCS_OWNERDRAWFIXED();
1516 test_WM_CONTEXTMENU();
1517 test_create();
1518 test_TCN_SELCHANGING();
1519 test_TCM_GETROWCOUNT();
1520
1521 DestroyWindow(parent_wnd);
1522 }
1523