1 /* Unit test suite for tab control.
3 * Copyright 2003 Vitaliy Margolen
4 * Copyright 2007 Hagop Hagopian
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.
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.
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
26 #include "wine/test.h"
29 #define DEFAULT_MIN_TAB_WIDTH 54
30 #define TAB_PADDING_X 6
31 #define EXTRA_ICON_PADDING 3
34 #define NUM_MSG_SEQUENCES 2
35 #define PARENT_SEQ_INDEX 0
36 #define TAB_SEQ_INDEX 1
38 #define expect(expected, got) ok ( expected == got, "Expected %d, got %d\n", expected, got)
39 #define expect_str(expected, got)\
40 ok ( strcmp(expected, got) == 0, "Expected '%s', got '%s'\n", expected, got)
42 #define TabWidthPadded(padd_x, num) (DEFAULT_MIN_TAB_WIDTH - (TAB_PADDING_X - (padd_x)) * num)
44 #define TabCheckSetSize(hwnd, SetWidth, SetHeight, ExpWidth, ExpHeight, Msg)\
45 SendMessage (hwnd, TCM_SETITEMSIZE, 0,\
46 (LPARAM) MAKELPARAM((SetWidth >= 0) ? SetWidth:0, (SetHeight >= 0) ? SetHeight:0));\
47 if (winetest_interactive) RedrawWindow (hwnd, NULL, 0, RDW_UPDATENOW);\
48 CheckSize(hwnd, ExpWidth, ExpHeight, Msg);
50 #define CheckSize(hwnd,width,height,msg)\
51 SendMessage (hwnd, TCM_GETITEMRECT, 0, (LPARAM) &rTab);\
52 if ((width >= 0) && (height < 0))\
53 ok (width == rTab.right - rTab.left, "%s: Expected width [%d] got [%d]\n",\
54 msg, (int)width, rTab.right - rTab.left);\
55 else if ((height >= 0) && (width < 0))\
56 ok (height == rTab.bottom - rTab.top, "%s: Expected height [%d] got [%d]\n",\
57 msg, (int)height, rTab.bottom - rTab.top);\
59 ok ((width == rTab.right - rTab.left) &&\
60 (height == rTab.bottom - rTab.top ),\
61 "%s: Expected [%d,%d] got [%d,%d]\n", msg, (int)width, (int)height,\
62 rTab.right - rTab.left, rTab.bottom - rTab.top);
65 static DRAWITEMSTRUCT g_drawitem;
66 static HWND parent_wnd;
68 static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
70 static const struct message create_parent_wnd_seq[] = {
71 { WM_GETMINMAXINFO, sent },
72 { WM_NCCREATE, sent },
73 { WM_NCCALCSIZE, sent|wparam, 0 },
75 { WM_SHOWWINDOW, sent|wparam, 1 },
76 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
77 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
78 { WM_ACTIVATEAPP, sent|wparam, 1 },
79 { WM_NCACTIVATE, sent|wparam, 1 },
80 { WM_ACTIVATE, sent|wparam, 1 },
81 { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
82 { WM_IME_NOTIFY, sent|defwinproc|optional },
83 { WM_SETFOCUS, sent|wparam|defwinproc, 0 },
84 /* Win9x adds SWP_NOZORDER below */
85 { WM_WINDOWPOSCHANGED, sent},
86 { WM_NCCALCSIZE, sent|wparam|optional, 1 },
92 static const struct message add_tab_to_parent[] = {
93 { TCM_INSERTITEMA, sent },
94 { TCM_INSERTITEMA, sent|optional },
95 { WM_NOTIFYFORMAT, sent|defwinproc },
96 { WM_QUERYUISTATE, sent|wparam|lparam|defwinproc|optional, 0, 0 },
97 { WM_PARENTNOTIFY, sent|defwinproc },
98 { TCM_INSERTITEMA, sent },
99 { TCM_INSERTITEMA, sent },
100 { TCM_INSERTITEMA, sent },
101 { TCM_INSERTITEMA, sent|optional },
105 static const struct message add_tab_to_parent_interactive[] = {
106 { TCM_INSERTITEMA, sent },
107 { TCM_INSERTITEMA, sent },
108 { WM_NOTIFYFORMAT, sent|defwinproc },
109 { WM_QUERYUISTATE, sent|wparam|lparam|defwinproc, 0, 0 },
110 { WM_PARENTNOTIFY, sent|defwinproc },
111 { TCM_INSERTITEMA, sent },
112 { TCM_INSERTITEMA, sent },
113 { TCM_INSERTITEMA, sent },
114 { WM_SHOWWINDOW, sent},
115 { WM_WINDOWPOSCHANGING, sent},
116 { WM_WINDOWPOSCHANGING, sent},
117 { WM_NCACTIVATE, sent},
118 { WM_ACTIVATE, sent},
119 { WM_IME_SETCONTEXT, sent|defwinproc|optional},
120 { WM_IME_NOTIFY, sent|defwinproc|optional},
121 { WM_SETFOCUS, sent|defwinproc},
122 { WM_WINDOWPOSCHANGED, sent},
128 static const struct message add_tab_control_parent_seq[] = {
129 { WM_NOTIFYFORMAT, sent },
130 { WM_QUERYUISTATE, sent|wparam|lparam|optional, 0, 0 },
134 static const struct message add_tab_control_parent_seq_interactive[] = {
135 { WM_NOTIFYFORMAT, sent },
136 { WM_QUERYUISTATE, sent|wparam|lparam, 0, 0 },
137 { WM_WINDOWPOSCHANGING, sent|optional},
138 { WM_NCACTIVATE, sent},
139 { WM_ACTIVATE, sent},
140 { WM_WINDOWPOSCHANGING, sent|optional},
141 { WM_KILLFOCUS, sent},
142 { WM_IME_SETCONTEXT, sent|optional},
143 { WM_IME_NOTIFY, sent|optional},
147 static const struct message empty_sequence[] = {
151 static const struct message set_min_tab_width_seq[] = {
152 { TCM_SETMINTABWIDTH, sent|wparam, 0 },
153 { TCM_SETMINTABWIDTH, sent|wparam, 0 },
157 static const struct message get_item_count_seq[] = {
158 { TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
162 static const struct message get_row_count_seq[] = {
163 { TCM_GETROWCOUNT, sent|wparam|lparam, 0, 0 },
167 static const struct message get_item_rect_seq[] = {
168 { TCM_GETITEMRECT, sent },
169 { TCM_GETITEMRECT, sent },
173 static const struct message getset_cur_focus_seq[] = {
174 { TCM_SETCURFOCUS, sent|lparam, 0 },
175 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
176 { TCM_SETCURFOCUS, sent|lparam, 0 },
177 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
178 { TCM_SETCURSEL, sent|lparam, 0 },
179 { TCM_SETCURFOCUS, sent|lparam, 0 },
180 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
184 static const struct message getset_cur_sel_seq[] = {
185 { TCM_SETCURSEL, sent|lparam, 0 },
186 { TCM_GETCURSEL, sent|wparam|lparam, 0, 0 },
187 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
188 { TCM_SETCURSEL, sent|lparam, 0 },
189 { TCM_GETCURSEL, sent|wparam|lparam, 0, 0 },
190 { TCM_SETCURSEL, sent|lparam, 0 },
191 { TCM_SETCURSEL, sent|lparam, 0 },
192 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
196 static const struct message getset_extended_style_seq[] = {
197 { TCM_GETEXTENDEDSTYLE, sent|wparam|lparam, 0, 0 },
198 { TCM_SETEXTENDEDSTYLE, sent },
199 { TCM_GETEXTENDEDSTYLE, sent|wparam|lparam, 0, 0 },
200 { TCM_SETEXTENDEDSTYLE, sent },
201 { TCM_GETEXTENDEDSTYLE, sent|wparam|lparam, 0, 0 },
205 static const struct message getset_unicode_format_seq[] = {
206 { CCM_SETUNICODEFORMAT, sent|lparam, 0 },
207 { CCM_GETUNICODEFORMAT, sent|wparam|lparam, 0, 0 },
208 { CCM_SETUNICODEFORMAT, sent|lparam, 0 },
209 { CCM_GETUNICODEFORMAT, sent|wparam|lparam, 0, 0 },
210 { CCM_SETUNICODEFORMAT, sent|lparam, 0 },
214 static const struct message getset_item_seq[] = {
215 { TCM_SETITEMA, sent },
216 { TCM_GETITEMA, sent },
217 { TCM_GETITEMA, sent },
221 static const struct message getset_tooltip_seq[] = {
222 { WM_NOTIFYFORMAT, sent|optional },
223 { WM_QUERYUISTATE, sent|wparam|lparam|optional, 0, 0 },
224 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
225 { WM_NOTIFYFORMAT, sent|optional },
226 { TCM_SETTOOLTIPS, sent|lparam, 0 },
227 { TCM_GETTOOLTIPS, sent|wparam|lparam, 0, 0 },
228 { TCM_SETTOOLTIPS, sent|lparam, 0 },
229 { TCM_GETTOOLTIPS, sent|wparam|lparam, 0, 0 },
233 static const struct message getset_tooltip_parent_seq[] = {
234 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
238 static const struct message insert_focus_seq[] = {
239 { TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
240 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
241 { TCM_INSERTITEM, sent|wparam, 1 },
242 { WM_NOTIFYFORMAT, sent|defwinproc|optional },
243 { WM_QUERYUISTATE, sent|defwinproc|optional },
244 { WM_PARENTNOTIFY, sent|defwinproc|optional },
245 { TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
246 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
247 { TCM_INSERTITEM, sent|wparam, 2 },
248 { WM_NOTIFYFORMAT, sent|defwinproc|optional },
249 { WM_QUERYUISTATE, sent|defwinproc|optional, },
250 { WM_PARENTNOTIFY, sent|defwinproc|optional },
251 { TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
252 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
253 { TCM_SETCURFOCUS, sent|wparam|lparam, -1, 0 },
254 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
255 { TCM_INSERTITEM, sent|wparam, 3 },
256 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
260 static const struct message delete_focus_seq[] = {
261 { TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
262 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
263 { TCM_DELETEITEM, sent|wparam|lparam, 1, 0 },
264 { TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
265 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
266 { TCM_SETCURFOCUS, sent|wparam|lparam, -1, 0 },
267 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
268 { TCM_DELETEITEM, sent|wparam|lparam, 0, 0 },
269 { TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
270 { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
276 create_tabcontrol (DWORD style, DWORD mask)
280 static char text1[] = "Tab 1",
281 text2[] = "Wide Tab 2",
284 handle = CreateWindow (
287 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | style,
289 NULL, NULL, NULL, 0);
293 SetWindowLong(handle, GWL_STYLE, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | style);
294 SendMessage (handle, WM_SETFONT, 0, (LPARAM) hFont);
296 tcNewTab.mask = mask;
297 tcNewTab.pszText = text1;
299 SendMessage (handle, TCM_INSERTITEM, 0, (LPARAM) &tcNewTab);
300 tcNewTab.pszText = text2;
302 SendMessage (handle, TCM_INSERTITEM, 1, (LPARAM) &tcNewTab);
303 tcNewTab.pszText = text3;
305 SendMessage (handle, TCM_INSERTITEM, 2, (LPARAM) &tcNewTab);
307 if (winetest_interactive)
309 ShowWindow (handle, SW_SHOW);
310 RedrawWindow (handle, NULL, 0, RDW_UPDATENOW);
317 static LRESULT WINAPI parentWindowProcess(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
319 static LONG defwndproc_counter = 0;
323 /* do not log painting messages */
324 if (message != WM_PAINT &&
325 message != WM_ERASEBKGND &&
326 message != WM_NCPAINT &&
327 message != WM_NCHITTEST &&
328 message != WM_GETTEXT &&
329 message != WM_GETICON &&
330 message != WM_DEVICECHANGE)
332 trace("parent: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam);
334 msg.message = message;
335 msg.flags = sent|wparam|lparam;
336 if (defwndproc_counter) msg.flags |= defwinproc;
339 add_message(sequences, PARENT_SEQ_INDEX, &msg);
342 /* dump sent structure data */
343 if (message == WM_DRAWITEM)
344 g_drawitem = *(DRAWITEMSTRUCT*)lParam;
346 defwndproc_counter++;
347 ret = DefWindowProcA(hwnd, message, wParam, lParam);
348 defwndproc_counter--;
353 static BOOL registerParentWindowClass(void)
358 cls.lpfnWndProc = parentWindowProcess;
361 cls.hInstance = GetModuleHandleA(NULL);
363 cls.hCursor = LoadCursorA(0, IDC_ARROW);
364 cls.hbrBackground = GetStockObject(WHITE_BRUSH);
365 cls.lpszMenuName = NULL;
366 cls.lpszClassName = "Tab test parent class";
367 return RegisterClassA(&cls);
370 static HWND createParentWindow(void)
372 if (!registerParentWindowClass())
375 return CreateWindowEx(0, "Tab test parent class",
376 "Tab test parent window",
377 WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
378 WS_MAXIMIZEBOX | WS_VISIBLE,
380 GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL);
383 static LRESULT WINAPI tabSubclassProcess(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
385 WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
386 static LONG defwndproc_counter = 0;
390 /* do not log painting messages */
391 if (message != WM_PAINT &&
392 message != WM_ERASEBKGND &&
393 message != WM_NCPAINT &&
394 message != WM_NCHITTEST &&
395 message != WM_GETTEXT &&
396 message != WM_GETICON &&
397 message != WM_DEVICECHANGE)
399 trace("tab: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam);
401 msg.message = message;
402 msg.flags = sent|wparam|lparam;
403 if (defwndproc_counter) msg.flags |= defwinproc;
406 add_message(sequences, TAB_SEQ_INDEX, &msg);
409 defwndproc_counter++;
410 ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
411 defwndproc_counter--;
416 static HWND createFilledTabControl(HWND parent_wnd, DWORD style, DWORD mask, INT nTabs)
424 GetClientRect(parent_wnd, &rect);
426 tabHandle = CreateWindow (
429 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | style,
430 0, 0, rect.right, rect.bottom,
431 parent_wnd, NULL, NULL, 0);
435 oldproc = (WNDPROC)SetWindowLongPtrA(tabHandle, GWLP_WNDPROC, (LONG_PTR)tabSubclassProcess);
436 SetWindowLongPtrA(tabHandle, GWLP_USERDATA, (LONG_PTR)oldproc);
438 tcNewTab.mask = mask;
440 for (i = 0; i < nTabs; i++)
442 char tabName[MAX_TABLEN];
444 sprintf(tabName, "Tab %d", i+1);
445 tcNewTab.pszText = tabName;
447 SendMessage (tabHandle, TCM_INSERTITEM, i, (LPARAM) &tcNewTab);
450 if (winetest_interactive)
452 ShowWindow (tabHandle, SW_SHOW);
453 RedrawWindow (tabHandle, NULL, 0, RDW_UPDATENOW);
460 static HWND create_tooltip (HWND hTab, char toolTipText[])
465 LPTSTR lptstr = toolTipText;
468 /* Creating a tooltip window*/
469 hwndTT = CreateWindowEx(
473 WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
474 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
475 hTab, NULL, 0, NULL);
481 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
483 GetClientRect (hTab, &rect);
485 /* Initialize members of toolinfo*/
486 ti.cbSize = sizeof(TOOLINFO);
487 ti.uFlags = TTF_SUBCLASS;
491 ti.lpszText = lptstr;
495 /* Add toolinfo structure to the tooltip control */
496 SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) &ti);
501 static void test_tab(INT nMinTabWidth)
505 HIMAGELIST himl = ImageList_Create(21, 21, ILC_COLOR, 3, 4);
511 hwTab = create_tabcontrol(TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE);
512 SendMessage(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth);
513 /* Get System default MinTabWidth */
514 if (nMinTabWidth < 0)
515 nMinTabWidth = SendMessage(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth);
518 dpi = GetDeviceCaps(hdc, LOGPIXELSX);
519 hOldFont = SelectObject(hdc, (HFONT)SendMessage(hwTab, WM_GETFONT, 0, 0));
520 GetTextExtentPoint32A(hdc, "Tab 1", strlen("Tab 1"), &size);
521 trace("Tab1 text size: size.cx=%d size.cy=%d\n", size.cx, size.cy);
522 SelectObject(hdc, hOldFont);
523 ReleaseDC(hwTab, hdc);
525 trace (" TCS_FIXEDWIDTH tabs no icon...\n");
526 CheckSize(hwTab, dpi, -1, "default width");
527 TabCheckSetSize(hwTab, 50, 20, 50, 20, "set size");
528 TabCheckSetSize(hwTab, 0, 1, 0, 1, "min size");
530 SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
532 trace (" TCS_FIXEDWIDTH tabs with icon...\n");
533 TabCheckSetSize(hwTab, 50, 30, 50, 30, "set size > icon");
534 TabCheckSetSize(hwTab, 20, 20, 25, 20, "set size < icon");
535 TabCheckSetSize(hwTab, 0, 1, 25, 1, "min size");
537 DestroyWindow (hwTab);
539 hwTab = create_tabcontrol(TCS_FIXEDWIDTH | TCS_BUTTONS, TCIF_TEXT|TCIF_IMAGE);
540 SendMessage(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth);
543 dpi = GetDeviceCaps(hdc, LOGPIXELSX);
544 ReleaseDC(hwTab, hdc);
545 trace (" TCS_FIXEDWIDTH buttons no icon...\n");
546 CheckSize(hwTab, dpi, -1, "default width");
547 TabCheckSetSize(hwTab, 20, 20, 20, 20, "set size 1");
548 TabCheckSetSize(hwTab, 10, 50, 10, 50, "set size 2");
549 TabCheckSetSize(hwTab, 0, 1, 0, 1, "min size");
551 SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
553 trace (" TCS_FIXEDWIDTH buttons with icon...\n");
554 TabCheckSetSize(hwTab, 50, 30, 50, 30, "set size > icon");
555 TabCheckSetSize(hwTab, 20, 20, 25, 20, "set size < icon");
556 TabCheckSetSize(hwTab, 0, 1, 25, 1, "min size");
557 SendMessage(hwTab, TCM_SETPADDING, 0, MAKELPARAM(4,4));
558 TabCheckSetSize(hwTab, 0, 1, 25, 1, "set padding, min size");
560 DestroyWindow (hwTab);
562 hwTab = create_tabcontrol(TCS_FIXEDWIDTH | TCS_BOTTOM, TCIF_TEXT|TCIF_IMAGE);
563 SendMessage(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth);
566 dpi = GetDeviceCaps(hdc, LOGPIXELSX);
567 ReleaseDC(hwTab, hdc);
568 trace (" TCS_FIXEDWIDTH | TCS_BOTTOM tabs...\n");
569 CheckSize(hwTab, dpi, -1, "no icon, default width");
571 TabCheckSetSize(hwTab, 20, 20, 20, 20, "no icon, set size 1");
572 TabCheckSetSize(hwTab, 10, 50, 10, 50, "no icon, set size 2");
573 TabCheckSetSize(hwTab, 0, 1, 0, 1, "no icon, min size");
575 SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
577 TabCheckSetSize(hwTab, 50, 30, 50, 30, "with icon, set size > icon");
578 TabCheckSetSize(hwTab, 20, 20, 25, 20, "with icon, set size < icon");
579 TabCheckSetSize(hwTab, 0, 1, 25, 1, "with icon, min size");
580 SendMessage(hwTab, TCM_SETPADDING, 0, MAKELPARAM(4,4));
581 TabCheckSetSize(hwTab, 0, 1, 25, 1, "set padding, min size");
583 DestroyWindow (hwTab);
585 hwTab = create_tabcontrol(0, TCIF_TEXT|TCIF_IMAGE);
586 SendMessage(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth);
588 trace (" non fixed width, with text...\n");
589 exp = max(size.cx +TAB_PADDING_X*2, (nMinTabWidth < 0) ? DEFAULT_MIN_TAB_WIDTH : nMinTabWidth);
590 SendMessage( hwTab, TCM_GETITEMRECT, 0, (LPARAM)&rTab );
591 ok( rTab.right - rTab.left == exp || broken(rTab.right - rTab.left == DEFAULT_MIN_TAB_WIDTH),
592 "no icon, default width: Expected width [%d] got [%d]\n", exp, rTab.right - rTab.left );
596 INT nTabWidth = (nMinTabWidth < 0) ? TabWidthPadded(i, 2) : nMinTabWidth;
598 SendMessage(hwTab, TCM_SETIMAGELIST, 0, 0);
599 SendMessage(hwTab, TCM_SETPADDING, 0, MAKELPARAM(i,i));
601 TabCheckSetSize(hwTab, 50, 20, max(size.cx + i*2, nTabWidth), 20, "no icon, set size");
602 TabCheckSetSize(hwTab, 0, 1, max(size.cx + i*2, nTabWidth), 1, "no icon, min size");
604 SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
605 nTabWidth = (nMinTabWidth < 0) ? TabWidthPadded(i, 3) : nMinTabWidth;
607 TabCheckSetSize(hwTab, 50, 30, max(size.cx + 21 + i*3, nTabWidth), 30, "with icon, set size > icon");
608 TabCheckSetSize(hwTab, 20, 20, max(size.cx + 21 + i*3, nTabWidth), 20, "with icon, set size < icon");
609 TabCheckSetSize(hwTab, 0, 1, max(size.cx + 21 + i*3, nTabWidth), 1, "with icon, min size");
611 DestroyWindow (hwTab);
613 hwTab = create_tabcontrol(0, TCIF_IMAGE);
614 SendMessage(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth);
616 trace (" non fixed width, no text...\n");
617 exp = (nMinTabWidth < 0) ? DEFAULT_MIN_TAB_WIDTH : nMinTabWidth;
618 SendMessage( hwTab, TCM_GETITEMRECT, 0, (LPARAM)&rTab );
619 ok( rTab.right - rTab.left == exp || broken(rTab.right - rTab.left == DEFAULT_MIN_TAB_WIDTH),
620 "no icon, default width: Expected width [%d] got [%d]\n", exp, rTab.right - rTab.left );
624 INT nTabWidth = (nMinTabWidth < 0) ? TabWidthPadded(i, 2) : nMinTabWidth;
626 SendMessage(hwTab, TCM_SETIMAGELIST, 0, 0);
627 SendMessage(hwTab, TCM_SETPADDING, 0, MAKELPARAM(i,i));
629 TabCheckSetSize(hwTab, 50, 20, nTabWidth, 20, "no icon, set size");
630 TabCheckSetSize(hwTab, 0, 1, nTabWidth, 1, "no icon, min size");
632 SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
633 if (i > 1 && nMinTabWidth > 0 && nMinTabWidth < DEFAULT_MIN_TAB_WIDTH)
634 nTabWidth += EXTRA_ICON_PADDING *(i-1);
636 TabCheckSetSize(hwTab, 50, 30, nTabWidth, 30, "with icon, set size > icon");
637 TabCheckSetSize(hwTab, 20, 20, nTabWidth, 20, "with icon, set size < icon");
638 TabCheckSetSize(hwTab, 0, 1, nTabWidth, 1, "with icon, min size");
641 DestroyWindow (hwTab);
643 ImageList_Destroy(himl);
647 static void test_width(void)
649 trace ("Testing with default MinWidth\n");
651 trace ("Testing with MinWidth set to -3\n");
653 trace ("Testing with MinWidth set to 24\n");
655 trace ("Testing with MinWidth set to 54\n");
657 trace ("Testing with MinWidth set to 94\n");
661 static void test_curfocus(void)
667 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
668 ok(hTab != NULL, "Failed to create tab control\n");
670 flush_sequences(sequences, NUM_MSG_SEQUENCES);
672 /* Testing CurFocus with largest appropriate value */
673 SendMessage(hTab, TCM_SETCURFOCUS, nTabs-1, 0);
674 focusIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
675 expect(nTabs-1, focusIndex);
677 /* Testing CurFocus with negative value */
678 SendMessage(hTab, TCM_SETCURFOCUS, -10, 0);
679 focusIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
680 expect(-1, focusIndex);
682 /* Testing CurFocus with value larger than number of tabs */
683 focusIndex = SendMessage(hTab, TCM_SETCURSEL, 1, 0);
684 expect(-1, focusIndex);
686 SendMessage(hTab, TCM_SETCURFOCUS, nTabs+1, 0);
687 focusIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
688 expect(1, focusIndex);
690 ok_sequence(sequences, TAB_SEQ_INDEX, getset_cur_focus_seq, "Getset curFoc test sequence", FALSE);
695 static void test_cursel(void)
703 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
704 ok(hTab != NULL, "Failed to create tab control\n");
706 flush_sequences(sequences, NUM_MSG_SEQUENCES);
708 /* Testing CurSel with largest appropriate value */
709 selectionIndex = SendMessage(hTab, TCM_SETCURSEL, nTabs-1, 0);
710 expect(0, selectionIndex);
711 selectionIndex = SendMessage(hTab, TCM_GETCURSEL, 0, 0);
712 expect(nTabs-1, selectionIndex);
714 /* Focus should switch with selection */
715 focusIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
716 expect(nTabs-1, focusIndex);
718 /* Testing CurSel with negative value */
719 SendMessage(hTab, TCM_SETCURSEL, -10, 0);
720 selectionIndex = SendMessage(hTab, TCM_GETCURSEL, 0, 0);
721 expect(-1, selectionIndex);
723 /* Testing CurSel with value larger than number of tabs */
724 selectionIndex = SendMessage(hTab, TCM_SETCURSEL, 1, 0);
725 expect(-1, selectionIndex);
727 selectionIndex = SendMessage(hTab, TCM_SETCURSEL, nTabs+1, 0);
728 expect(-1, selectionIndex);
729 selectionIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
730 expect(1, selectionIndex);
732 ok_sequence(sequences, TAB_SEQ_INDEX, getset_cur_sel_seq, "Getset curSel test sequence", FALSE);
733 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset curSel test parent sequence", FALSE);
735 /* selected item should have TCIS_BUTTONPRESSED state
736 It doesn't depend on button state */
737 memset(&tcItem, 0, sizeof(TCITEM));
738 tcItem.mask = TCIF_STATE;
739 tcItem.dwStateMask = TCIS_BUTTONPRESSED;
740 selectionIndex = SendMessage(hTab, TCM_GETCURSEL, 0, 0);
741 SendMessage(hTab, TCM_GETITEM, selectionIndex, (LPARAM) &tcItem);
742 ok (tcItem.dwState & TCIS_BUTTONPRESSED || broken(tcItem.dwState == 0), /* older comctl32 */
743 "Selected item should have TCIS_BUTTONPRESSED\n");
748 static void test_extendedstyle(void)
751 DWORD prevExtendedStyle;
755 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
756 ok(hTab != NULL, "Failed to create tab control\n");
758 flush_sequences(sequences, NUM_MSG_SEQUENCES);
760 /* Testing Flat Separators */
761 extendedStyle = SendMessage(hTab, TCM_GETEXTENDEDSTYLE, 0, 0);
762 prevExtendedStyle = SendMessage(hTab, TCM_SETEXTENDEDSTYLE, 0, TCS_EX_FLATSEPARATORS);
763 expect(extendedStyle, prevExtendedStyle);
765 extendedStyle = SendMessage(hTab, TCM_GETEXTENDEDSTYLE, 0, 0);
766 expect(TCS_EX_FLATSEPARATORS, extendedStyle);
768 /* Testing Register Drop */
769 prevExtendedStyle = SendMessage(hTab, TCM_SETEXTENDEDSTYLE, 0, TCS_EX_REGISTERDROP);
770 expect(extendedStyle, prevExtendedStyle);
772 extendedStyle = SendMessage(hTab, TCM_GETEXTENDEDSTYLE, 0, 0);
774 expect(TCS_EX_REGISTERDROP, extendedStyle);
777 ok_sequence(sequences, TAB_SEQ_INDEX, getset_extended_style_seq, "Getset extendedStyle test sequence", FALSE);
778 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset extendedStyle test parent sequence", FALSE);
783 static void test_unicodeformat(void)
789 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
790 ok(hTab != NULL, "Failed to create tab control\n");
792 flush_sequences(sequences, NUM_MSG_SEQUENCES);
794 unicodeFormat = SendMessage(hTab, TCM_SETUNICODEFORMAT, TRUE, 0);
796 expect(0, unicodeFormat);
798 unicodeFormat = SendMessage(hTab, TCM_GETUNICODEFORMAT, 0, 0);
799 expect(1, unicodeFormat);
801 unicodeFormat = SendMessage(hTab, TCM_SETUNICODEFORMAT, FALSE, 0);
802 expect(1, unicodeFormat);
803 unicodeFormat = SendMessage(hTab, TCM_GETUNICODEFORMAT, 0, 0);
804 expect(0, unicodeFormat);
806 unicodeFormat = SendMessage(hTab, TCM_SETUNICODEFORMAT, TRUE, 0);
807 expect(0, unicodeFormat);
809 ok_sequence(sequences, TAB_SEQ_INDEX, getset_unicode_format_seq, "Getset unicodeFormat test sequence", FALSE);
810 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset unicodeFormat test parent sequence", FALSE);
815 static void test_getset_item(void)
817 char szText[32] = "New Label";
824 hTab = CreateWindowA(
827 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | TCS_FIXEDWIDTH | TCS_OWNERDRAWFIXED,
829 parent_wnd, NULL, NULL, 0);
831 ok(GetParent(hTab) == NULL, "got %p, expected null parent\n", GetParent(hTab));
833 ret = SendMessageA(hTab, TCM_SETITEMEXTRA, sizeof(LPARAM)-1, 0);
834 ok(ret == TRUE, "got %d\n", ret);
836 /* set some item data */
838 tcItem.mask = TCIF_PARAM;
840 ret = SendMessageA(hTab, TCM_INSERTITEMA, 0, (LPARAM)&tcItem);
841 ok(ret == 0, "got %d\n", ret);
843 /* all sizeof(LPARAM) returned anyway when using sizeof(LPARAM)-1 size */
844 memset(&lparam, 0xaa, sizeof(lparam));
845 tcItem.lParam = lparam;
846 tcItem.mask = TCIF_PARAM;
847 ret = SendMessage(hTab, TCM_GETITEM, 0, (LPARAM)&tcItem);
849 /* everything higher specified size is preserved */
850 memset(&lparam, 0xff, sizeof(lparam)-1);
851 ok(tcItem.lParam == lparam, "Expected 0x%lx, got 0x%lx\n", lparam, tcItem.lParam);
855 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
856 ok(hTab != NULL, "Failed to create tab control\n");
858 /* passing invalid index should result in initialization to zero
859 for members mentioned in mask requested */
861 /* valid range here is [0,4] */
862 memset(&tcItem, 0xcc, sizeof(tcItem));
863 tcItem.mask = TCIF_PARAM;
864 ret = SendMessage(hTab, TCM_GETITEM, 5, (LPARAM)&tcItem);
866 ok(tcItem.lParam == 0, "Expected zero lParam, got %lu\n", tcItem.lParam);
868 memset(&tcItem, 0xcc, sizeof(tcItem));
869 tcItem.mask = TCIF_IMAGE;
870 ret = SendMessage(hTab, TCM_GETITEM, 5, (LPARAM)&tcItem);
872 expect(0, tcItem.iImage);
874 memset(&tcItem, 0xcc, sizeof(tcItem));
875 tcItem.mask = TCIF_TEXT;
876 tcItem.pszText = szText;
878 ret = SendMessage(hTab, TCM_GETITEM, 5, (LPARAM)&tcItem);
880 expect('a', szText[0]);
882 memset(&tcItem, 0xcc, sizeof(tcItem));
883 tcItem.mask = TCIF_STATE;
884 tcItem.dwStateMask = 0;
885 tcItem.dwState = TCIS_BUTTONPRESSED;
886 ret = SendMessage(hTab, TCM_GETITEM, 5, (LPARAM)&tcItem);
888 ok(tcItem.dwState == 0, "Expected zero dwState, got %u\n", tcItem.dwState);
890 memset(&tcItem, 0xcc, sizeof(tcItem));
891 tcItem.mask = TCIF_STATE;
892 tcItem.dwStateMask = TCIS_BUTTONPRESSED;
893 tcItem.dwState = TCIS_BUTTONPRESSED;
894 ret = SendMessage(hTab, TCM_GETITEM, 5, (LPARAM)&tcItem);
896 ok(tcItem.dwState == 0, "Expected zero dwState\n");
898 /* check with negative index to be sure */
899 memset(&tcItem, 0xcc, sizeof(tcItem));
900 tcItem.mask = TCIF_PARAM;
901 ret = SendMessage(hTab, TCM_GETITEM, -1, (LPARAM)&tcItem);
903 ok(tcItem.lParam == 0, "Expected zero lParam, got %lu\n", tcItem.lParam);
905 memset(&tcItem, 0xcc, sizeof(tcItem));
906 tcItem.mask = TCIF_PARAM;
907 ret = SendMessage(hTab, TCM_GETITEM, -2, (LPARAM)&tcItem);
909 ok(tcItem.lParam == 0, "Expected zero lParam, got %lu\n", tcItem.lParam);
911 flush_sequences(sequences, NUM_MSG_SEQUENCES);
913 tcItem.mask = TCIF_TEXT;
914 tcItem.pszText = &szText[0];
915 tcItem.cchTextMax = sizeof(szText);
917 strcpy(szText, "New Label");
918 ok ( SendMessage(hTab, TCM_SETITEM, 0, (LPARAM) &tcItem), "Setting new item failed.\n");
919 ok ( SendMessage(hTab, TCM_GETITEM, 0, (LPARAM) &tcItem), "Getting item failed.\n");
920 expect_str("New Label", tcItem.pszText);
922 ok ( SendMessage(hTab, TCM_GETITEM, 1, (LPARAM) &tcItem), "Getting item failed.\n");
923 expect_str("Tab 2", tcItem.pszText);
925 ok_sequence(sequences, TAB_SEQ_INDEX, getset_item_seq, "Getset item test sequence", FALSE);
926 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset item test parent sequence", FALSE);
928 /* TCIS_BUTTONPRESSED doesn't depend on tab style */
929 memset(&tcItem, 0, sizeof(tcItem));
930 tcItem.mask = TCIF_STATE;
931 tcItem.dwStateMask = TCIS_BUTTONPRESSED;
932 tcItem.dwState = TCIS_BUTTONPRESSED;
933 ok ( SendMessage(hTab, TCM_SETITEM, 0, (LPARAM) &tcItem), "Setting new item failed.\n");
935 ok ( SendMessage(hTab, TCM_GETITEM, 0, (LPARAM) &tcItem), "Getting item failed.\n");
938 ok (tcItem.dwState == TCIS_BUTTONPRESSED, "TCIS_BUTTONPRESSED should be set.\n");
939 /* next highlight item, test that dwStateMask actually masks */
940 tcItem.mask = TCIF_STATE;
941 tcItem.dwStateMask = TCIS_HIGHLIGHTED;
942 tcItem.dwState = TCIS_HIGHLIGHTED;
943 ok ( SendMessage(hTab, TCM_SETITEM, 0, (LPARAM) &tcItem), "Setting new item failed.\n");
945 ok ( SendMessage(hTab, TCM_GETITEM, 0, (LPARAM) &tcItem), "Getting item failed.\n");
946 ok (tcItem.dwState == TCIS_HIGHLIGHTED, "TCIS_HIGHLIGHTED should be set.\n");
947 tcItem.mask = TCIF_STATE;
948 tcItem.dwStateMask = TCIS_BUTTONPRESSED;
950 ok ( SendMessage(hTab, TCM_GETITEM, 0, (LPARAM) &tcItem), "Getting item failed.\n");
951 ok (tcItem.dwState == TCIS_BUTTONPRESSED, "TCIS_BUTTONPRESSED should be set.\n");
953 else win_skip( "Item state mask not supported\n" );
958 static void test_getset_tooltips(void)
960 char toolTipText[32] = "ToolTip Text Test";
964 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
965 ok(hTab != NULL, "Failed to create tab control\n");
967 flush_sequences(sequences, NUM_MSG_SEQUENCES);
969 toolTip = create_tooltip(hTab, toolTipText);
970 SendMessage(hTab, TCM_SETTOOLTIPS, (LPARAM) toolTip, 0);
971 ok (toolTip == (HWND) SendMessage(hTab,TCM_GETTOOLTIPS,0,0), "ToolTip was set incorrectly.\n");
973 SendMessage(hTab, TCM_SETTOOLTIPS, 0, 0);
974 ok (NULL == (HWND) SendMessage(hTab,TCM_GETTOOLTIPS,0,0), "ToolTip was set incorrectly.\n");
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);
982 static void test_misc(void)
992 ok(parent_wnd != NULL, "no parent window!\n");
993 flush_sequences(sequences, NUM_MSG_SEQUENCES);
995 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
996 ok(hTab != NULL, "Failed to create tab control\n");
998 if(!winetest_interactive)
999 ok_sequence(sequences, TAB_SEQ_INDEX, add_tab_to_parent,
1000 "Tab sequence, after adding tab control to parent", TRUE);
1002 ok_sequence(sequences, TAB_SEQ_INDEX, add_tab_to_parent_interactive,
1003 "Tab sequence, after adding tab control to parent", TRUE);
1005 if(!winetest_interactive)
1006 ok_sequence(sequences, PARENT_SEQ_INDEX, add_tab_control_parent_seq,
1007 "Parent after sequence, adding tab control to parent", TRUE);
1009 ok_sequence(sequences, PARENT_SEQ_INDEX, add_tab_control_parent_seq_interactive,
1010 "Parent after sequence, adding tab control to parent", TRUE);
1012 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1013 ok(SendMessage(hTab, TCM_SETMINTABWIDTH, 0, -1) > 0,"TCM_SETMINTABWIDTH returned < 0\n");
1014 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Set minTabWidth test parent sequence", FALSE);
1016 /* Testing GetItemCount */
1017 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1018 nTabsRetrieved = SendMessage(hTab, TCM_GETITEMCOUNT, 0, 0);
1019 expect(nTabs, nTabsRetrieved);
1020 ok_sequence(sequences, TAB_SEQ_INDEX, get_item_count_seq, "Get itemCount test sequence", FALSE);
1021 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset itemCount test parent sequence", FALSE);
1023 /* Testing GetRowCount */
1024 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1025 rowCount = SendMessage(hTab, TCM_GETROWCOUNT, 0, 0);
1026 expect(1, rowCount);
1027 ok_sequence(sequences, TAB_SEQ_INDEX, get_row_count_seq, "Get rowCount test sequence", FALSE);
1028 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Get rowCount test parent sequence", FALSE);
1030 /* Testing GetItemRect */
1031 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1032 ok(SendMessage(hTab, TCM_GETITEMRECT, 0, (LPARAM) &rTab), "GetItemRect failed.\n");
1035 dpi = GetDeviceCaps(hdc, LOGPIXELSX);
1036 ReleaseDC(hTab, hdc);
1037 CheckSize(hTab, dpi, -1 , "Default Width");
1038 ok_sequence(sequences, TAB_SEQ_INDEX, get_item_rect_seq, "Get itemRect test sequence", FALSE);
1039 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Get itemRect test parent sequence", FALSE);
1041 DestroyWindow(hTab);
1044 static void test_adjustrect(void)
1049 ok(parent_wnd != NULL, "no parent window!\n");
1051 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, 0, 0);
1052 ok(hTab != NULL, "Failed to create tab control\n");
1054 r = SendMessage(hTab, TCM_ADJUSTRECT, FALSE, 0);
1057 r = SendMessage(hTab, TCM_ADJUSTRECT, TRUE, 0);
1061 static void test_insert_focus(void)
1067 DWORD mask = TCIF_TEXT|TCIF_IMAGE;
1068 static char tabName[] = "TAB";
1069 tcNewTab.mask = mask;
1070 tcNewTab.pszText = tabName;
1072 ok(parent_wnd != NULL, "no parent window!\n");
1074 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, mask, 0);
1075 ok(hTab != NULL, "Failed to create tab control\n");
1077 r = SendMessage(hTab, TCM_GETCURSEL, 0, 0);
1080 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1082 nTabsRetrieved = SendMessage(hTab, TCM_GETITEMCOUNT, 0, 0);
1083 expect(0, nTabsRetrieved);
1085 r = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
1088 tcNewTab.iImage = 1;
1089 r = SendMessage(hTab, TCM_INSERTITEM, 1, (LPARAM) &tcNewTab);
1092 nTabsRetrieved = SendMessage(hTab, TCM_GETITEMCOUNT, 0, 0);
1093 expect(1, nTabsRetrieved);
1095 r = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
1098 tcNewTab.iImage = 2;
1099 r = SendMessage(hTab, TCM_INSERTITEM, 2, (LPARAM) &tcNewTab);
1102 nTabsRetrieved = SendMessage(hTab, TCM_GETITEMCOUNT, 0, 0);
1103 expect(2, nTabsRetrieved);
1105 r = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
1108 r = SendMessage(hTab, TCM_SETCURFOCUS, -1, 0);
1111 r = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
1114 tcNewTab.iImage = 3;
1115 r = SendMessage(hTab, TCM_INSERTITEM, 3, (LPARAM) &tcNewTab);
1118 r = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
1121 ok_sequence(sequences, TAB_SEQ_INDEX, insert_focus_seq, "insert_focus test sequence", FALSE);
1122 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "insert_focus parent test sequence", TRUE);
1124 DestroyWindow(hTab);
1127 static void test_delete_focus(void)
1133 ok(parent_wnd != NULL, "no parent window!\n");
1135 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, 2);
1136 ok(hTab != NULL, "Failed to create tab control\n");
1138 flush_sequences(sequences, NUM_MSG_SEQUENCES);
1140 nTabsRetrieved = SendMessage(hTab, TCM_GETITEMCOUNT, 0, 0);
1141 expect(2, nTabsRetrieved);
1143 r = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
1146 r = SendMessage(hTab, TCM_DELETEITEM, 1, 0);
1149 nTabsRetrieved = SendMessage(hTab, TCM_GETITEMCOUNT, 0, 0);
1150 expect(1, nTabsRetrieved);
1152 r = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
1155 r = SendMessage(hTab, TCM_SETCURFOCUS, -1, 0);
1158 r = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
1161 r = SendMessage(hTab, TCM_DELETEITEM, 0, 0);
1164 nTabsRetrieved = SendMessage(hTab, TCM_GETITEMCOUNT, 0, 0);
1165 expect(0, nTabsRetrieved);
1167 r = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
1170 ok_sequence(sequences, TAB_SEQ_INDEX, delete_focus_seq, "delete_focus test sequence", FALSE);
1171 ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "delete_focus parent test sequence", TRUE);
1173 DestroyWindow(hTab);
1176 static void test_removeimage(void)
1178 static const BYTE bits[32];
1183 HIMAGELIST himl = ImageList_Create(16, 16, ILC_COLOR, 3, 4);
1185 hicon = CreateIcon(NULL, 16, 16, 1, 1, bits, bits);
1186 ImageList_AddIcon(himl, hicon);
1187 ImageList_AddIcon(himl, hicon);
1188 ImageList_AddIcon(himl, hicon);
1190 hwTab = create_tabcontrol(TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE);
1191 SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
1193 memset(&item, 0, sizeof(TCITEM));
1194 item.mask = TCIF_IMAGE;
1196 for(i = 0; i < 3; i++) {
1197 SendMessage(hwTab, TCM_GETITEM, i, (LPARAM)&item);
1198 expect(i, item.iImage);
1201 /* remove image middle image */
1202 SendMessage(hwTab, TCM_REMOVEIMAGE, 1, 0);
1203 expect(2, ImageList_GetImageCount(himl));
1205 SendMessage(hwTab, TCM_GETITEM, 0, (LPARAM)&item);
1206 expect(0, item.iImage);
1208 SendMessage(hwTab, TCM_GETITEM, 1, (LPARAM)&item);
1209 expect(-1, item.iImage);
1211 SendMessage(hwTab, TCM_GETITEM, 2, (LPARAM)&item);
1212 expect(1, item.iImage);
1213 /* remove first image */
1214 SendMessage(hwTab, TCM_REMOVEIMAGE, 0, 0);
1215 expect(1, ImageList_GetImageCount(himl));
1217 SendMessage(hwTab, TCM_GETITEM, 0, (LPARAM)&item);
1218 expect(-1, item.iImage);
1220 SendMessage(hwTab, TCM_GETITEM, 1, (LPARAM)&item);
1221 expect(-1, item.iImage);
1223 SendMessage(hwTab, TCM_GETITEM, 2, (LPARAM)&item);
1224 expect(0, item.iImage);
1225 /* remove the last one */
1226 SendMessage(hwTab, TCM_REMOVEIMAGE, 0, 0);
1227 expect(0, ImageList_GetImageCount(himl));
1228 for(i = 0; i < 3; i++) {
1230 SendMessage(hwTab, TCM_GETITEM, i, (LPARAM)&item);
1231 expect(-1, item.iImage);
1234 DestroyWindow(hwTab);
1235 ImageList_Destroy(himl);
1239 static void test_delete_selection(void)
1244 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, 4);
1245 ok(hTab != NULL, "Failed to create tab control\n");
1247 ret = SendMessage(hTab, TCM_SETCURSEL, 3, 0);
1249 ret = SendMessage(hTab, TCM_GETCURSEL, 0, 0);
1251 /* delete selected item - selection goes to -1 */
1252 ret = SendMessage(hTab, TCM_DELETEITEM, 3, 0);
1255 ret = SendMessage(hTab, TCM_GETCURSEL, 0, 0);
1258 DestroyWindow(hTab);
1261 static void test_TCM_SETITEMEXTRA(void)
1266 hTab = CreateWindowA(
1269 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | TCS_FIXEDWIDTH,
1271 parent_wnd, NULL, NULL, 0);
1273 /* zero is valid size too */
1274 ret = SendMessageA(hTab, TCM_SETITEMEXTRA, 0, 0);
1277 win_skip("TCM_SETITEMEXTRA not supported\n");
1278 DestroyWindow(hTab);
1282 ret = SendMessageA(hTab, TCM_SETITEMEXTRA, -1, 0);
1283 ok(ret == FALSE, "got %d\n", ret);
1285 ret = SendMessageA(hTab, TCM_SETITEMEXTRA, 2, 0);
1286 ok(ret == TRUE, "got %d\n", ret);
1287 DestroyWindow(hTab);
1289 /* it's not possible to change extra data size for control with tabs */
1290 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, 4);
1291 ok(hTab != NULL, "Failed to create tab control\n");
1293 ret = SendMessageA(hTab, TCM_SETITEMEXTRA, 2, 0);
1294 ok(ret == FALSE, "got %d\n", ret);
1295 DestroyWindow(hTab);
1298 static void test_TCS_OWNERDRAWFIXED(void)
1300 LPARAM lparam, lparam2;
1305 hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH|TCS_OWNERDRAWFIXED, TCIF_TEXT|TCIF_IMAGE, 4);
1306 ok(hTab != NULL, "Failed to create tab control\n");
1308 ok(GetParent(hTab) == NULL, "got %p, expected null parent\n", GetParent(hTab));
1310 /* set some item data */
1311 memset(&lparam, 0xde, sizeof(LPARAM));
1313 item.mask = TCIF_PARAM;
1314 item.lParam = lparam;
1315 ret = SendMessageA(hTab, TCM_SETITEMA, 0, (LPARAM)&item);
1316 ok(ret == TRUE, "got %d\n", ret);
1318 memset(&g_drawitem, 0, sizeof(g_drawitem));
1320 ShowWindow(hTab, SW_SHOW);
1321 RedrawWindow(hTab, NULL, 0, RDW_UPDATENOW);
1324 memset(&lparam, 0xde, 4);
1325 ok(g_drawitem.itemData == lparam, "got %lx, expected %lx\n", g_drawitem.itemData, lparam);
1327 DestroyWindow(hTab);
1329 /* now with custom extra data length */
1330 hTab = CreateWindowA(
1333 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | TCS_FIXEDWIDTH | TCS_OWNERDRAWFIXED,
1335 parent_wnd, NULL, NULL, 0);
1337 ok(GetParent(hTab) == NULL, "got %p, expected null parent\n", GetParent(hTab));
1339 ret = SendMessageA(hTab, TCM_SETITEMEXTRA, sizeof(LPARAM)+1, 0);
1340 ok(ret == TRUE, "got %d\n", ret);
1342 /* set some item data */
1343 memset(&lparam, 0xde, sizeof(LPARAM));
1344 item.mask = TCIF_PARAM;
1345 item.lParam = lparam;
1347 ret = SendMessageA(hTab, TCM_INSERTITEMA, 0, (LPARAM)&item);
1348 ok(ret == 0, "got %d\n", ret);
1350 memset(&g_drawitem, 0, sizeof(g_drawitem));
1352 ShowWindow(hTab, SW_SHOW);
1353 RedrawWindow(hTab, NULL, 0, RDW_UPDATENOW);
1355 ok(*(ULONG_PTR*)g_drawitem.itemData == lparam, "got %lx, expected %lx\n", g_drawitem.itemData, lparam);
1357 DestroyWindow(hTab);
1359 /* same thing, but size smaller than default */
1360 hTab = CreateWindowA(
1363 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | TCS_FIXEDWIDTH | TCS_OWNERDRAWFIXED,
1365 parent_wnd, NULL, NULL, 0);
1367 ok(GetParent(hTab) == NULL, "got %p, expected null parent\n", GetParent(hTab));
1369 ret = SendMessageA(hTab, TCM_SETITEMEXTRA, sizeof(LPARAM)-1, 0);
1370 ok(ret == TRUE, "got %d\n", ret);
1372 memset(&lparam, 0xde, sizeof(lparam));
1373 item.mask = TCIF_PARAM;
1374 item.lParam = lparam;
1376 ret = SendMessageA(hTab, TCM_INSERTITEMA, 0, (LPARAM)&item);
1377 ok(ret == 0, "got %d\n", ret);
1379 memset(&g_drawitem, 0, sizeof(g_drawitem));
1381 ShowWindow(hTab, SW_SHOW);
1382 RedrawWindow(hTab, NULL, 0, RDW_UPDATENOW);
1385 memset(&lparam, 0xde, 4);
1386 memset(&lparam2, 0xde, sizeof(LPARAM)-1);
1387 ok(g_drawitem.itemData == lparam || broken(g_drawitem.itemData == lparam2) /* win98 */,
1388 "got 0x%lx, expected 0x%lx\n", g_drawitem.itemData, lparam);
1390 DestroyWindow(hTab);
1397 lstrcpyA(logfont.lfFaceName, "Arial");
1398 memset(&logfont, 0, sizeof(logfont));
1399 logfont.lfHeight = -12;
1400 logfont.lfWeight = FW_NORMAL;
1401 logfont.lfCharSet = ANSI_CHARSET;
1402 hFont = CreateFontIndirectA(&logfont);
1404 InitCommonControls();
1408 init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
1410 parent_wnd = createParentWindow();
1411 ok(parent_wnd != NULL, "Failed to create parent window!\n");
1415 test_extendedstyle();
1416 test_unicodeformat();
1418 test_getset_tooltips();
1423 test_insert_focus();
1424 test_delete_focus();
1425 test_delete_selection();
1427 test_TCM_SETITEMEXTRA();
1428 test_TCS_OWNERDRAWFIXED();
1430 DestroyWindow(parent_wnd);