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 static void CheckSize(HWND hwnd
, INT width
, INT height
, const char *msg
, int line
)
48 SendMessage(hwnd
, TCM_GETITEMRECT
, 0, (LPARAM
)&r
);
49 if (width
>= 0 && height
< 0)
50 ok_(__FILE__
,line
) (width
== r
.right
- r
.left
, "%s: Expected width [%d] got [%d]\n",
51 msg
, width
, r
.right
- r
.left
);
52 else if (height
>= 0 && width
< 0)
53 ok_(__FILE__
,line
) (height
== r
.bottom
- r
.top
, "%s: Expected height [%d] got [%d]\n",
54 msg
, height
, r
.bottom
- r
.top
);
56 ok_(__FILE__
,line
) ((width
== r
.right
- r
.left
) && (height
== r
.bottom
- r
.top
),
57 "%s: Expected [%d,%d] got [%d,%d]\n", msg
, width
, height
,
58 r
.right
- r
.left
, r
.bottom
- r
.top
);
61 #define CHECKSIZE(hwnd,width,height,msg) CheckSize(hwnd,width,height,msg,__LINE__)
63 static void TabCheckSetSize(HWND hwnd
, INT set_width
, INT set_height
, INT exp_width
,
64 INT exp_height
, const char *msg
, int line
)
66 SendMessage(hwnd
, TCM_SETITEMSIZE
, 0,
67 (LPARAM
) MAKELPARAM((set_width
>= 0) ? set_width
: 0, (set_height
>= 0) ? set_height
: 0));
68 if (winetest_interactive
) RedrawWindow (hwnd
, NULL
, 0, RDW_UPDATENOW
);
69 CheckSize(hwnd
, exp_width
, exp_height
, msg
, line
);
72 #define TABCHECKSETSIZE(hwnd,set_width,set_height,exp_width,exp_height,msg) \
73 TabCheckSetSize(hwnd,set_width,set_height,exp_width,exp_height,msg,__LINE__)
76 static DRAWITEMSTRUCT g_drawitem
;
77 static HWND parent_wnd
;
79 static struct msg_sequence
*sequences
[NUM_MSG_SEQUENCES
];
81 static const struct message create_parent_wnd_seq
[] = {
82 { WM_GETMINMAXINFO
, sent
},
83 { WM_NCCREATE
, sent
},
84 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
86 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
87 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0 },
88 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0 },
89 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
90 { WM_NCACTIVATE
, sent
|wparam
, 1 },
91 { WM_ACTIVATE
, sent
|wparam
, 1 },
92 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
93 { WM_IME_NOTIFY
, sent
|defwinproc
|optional
},
94 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
95 /* Win9x adds SWP_NOZORDER below */
96 { WM_WINDOWPOSCHANGED
, sent
},
97 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
103 static const struct message add_tab_to_parent
[] = {
104 { TCM_INSERTITEMA
, sent
},
105 { TCM_INSERTITEMA
, sent
|optional
},
106 { WM_NOTIFYFORMAT
, sent
|defwinproc
},
107 { WM_QUERYUISTATE
, sent
|wparam
|lparam
|defwinproc
|optional
, 0, 0 },
108 { WM_PARENTNOTIFY
, sent
|defwinproc
},
109 { TCM_INSERTITEMA
, sent
},
110 { TCM_INSERTITEMA
, sent
},
111 { TCM_INSERTITEMA
, sent
},
112 { TCM_INSERTITEMA
, sent
|optional
},
116 static const struct message add_tab_to_parent_interactive
[] = {
117 { TCM_INSERTITEMA
, sent
},
118 { TCM_INSERTITEMA
, sent
},
119 { WM_NOTIFYFORMAT
, sent
|defwinproc
},
120 { WM_QUERYUISTATE
, sent
|wparam
|lparam
|defwinproc
, 0, 0 },
121 { WM_PARENTNOTIFY
, sent
|defwinproc
},
122 { TCM_INSERTITEMA
, sent
},
123 { TCM_INSERTITEMA
, sent
},
124 { TCM_INSERTITEMA
, sent
},
125 { WM_SHOWWINDOW
, sent
},
126 { WM_WINDOWPOSCHANGING
, sent
},
127 { WM_WINDOWPOSCHANGING
, sent
},
128 { WM_NCACTIVATE
, sent
},
129 { WM_ACTIVATE
, sent
},
130 { WM_IME_SETCONTEXT
, sent
|defwinproc
|optional
},
131 { WM_IME_NOTIFY
, sent
|defwinproc
|optional
},
132 { WM_SETFOCUS
, sent
|defwinproc
},
133 { WM_WINDOWPOSCHANGED
, sent
},
139 static const struct message add_tab_control_parent_seq
[] = {
140 { WM_NOTIFYFORMAT
, sent
},
141 { WM_QUERYUISTATE
, sent
|wparam
|lparam
|optional
, 0, 0 },
145 static const struct message add_tab_control_parent_seq_interactive
[] = {
146 { WM_NOTIFYFORMAT
, sent
},
147 { WM_QUERYUISTATE
, sent
|wparam
|lparam
, 0, 0 },
148 { WM_WINDOWPOSCHANGING
, sent
|optional
},
149 { WM_NCACTIVATE
, sent
},
150 { WM_ACTIVATE
, sent
},
151 { WM_WINDOWPOSCHANGING
, sent
|optional
},
152 { WM_KILLFOCUS
, sent
},
153 { WM_IME_SETCONTEXT
, sent
|optional
},
154 { WM_IME_NOTIFY
, sent
|optional
},
158 static const struct message empty_sequence
[] = {
162 static const struct message set_min_tab_width_seq
[] = {
163 { TCM_SETMINTABWIDTH
, sent
|wparam
, 0 },
164 { TCM_SETMINTABWIDTH
, sent
|wparam
, 0 },
168 static const struct message get_item_count_seq
[] = {
169 { TCM_GETITEMCOUNT
, sent
|wparam
|lparam
, 0, 0 },
173 static const struct message get_row_count_seq
[] = {
174 { TCM_GETROWCOUNT
, sent
|wparam
|lparam
, 0, 0 },
178 static const struct message get_item_rect_seq
[] = {
179 { TCM_GETITEMRECT
, sent
},
180 { TCM_GETITEMRECT
, sent
},
184 static const struct message getset_cur_focus_seq
[] = {
185 { TCM_SETCURFOCUS
, sent
|lparam
, 0 },
186 { TCM_GETCURFOCUS
, sent
|wparam
|lparam
, 0, 0 },
187 { TCM_SETCURFOCUS
, sent
|lparam
, 0 },
188 { TCM_GETCURFOCUS
, sent
|wparam
|lparam
, 0, 0 },
189 { TCM_SETCURSEL
, sent
|lparam
, 0 },
190 { TCM_SETCURFOCUS
, sent
|lparam
, 0 },
191 { TCM_GETCURFOCUS
, sent
|wparam
|lparam
, 0, 0 },
195 static const struct message getset_cur_sel_seq
[] = {
196 { TCM_SETCURSEL
, sent
|lparam
, 0 },
197 { TCM_GETCURSEL
, sent
|wparam
|lparam
, 0, 0 },
198 { TCM_GETCURFOCUS
, sent
|wparam
|lparam
, 0, 0 },
199 { TCM_SETCURSEL
, sent
|lparam
, 0 },
200 { TCM_GETCURSEL
, sent
|wparam
|lparam
, 0, 0 },
201 { TCM_SETCURSEL
, sent
|lparam
, 0 },
202 { TCM_SETCURSEL
, sent
|lparam
, 0 },
203 { TCM_GETCURFOCUS
, sent
|wparam
|lparam
, 0, 0 },
207 static const struct message getset_extended_style_seq
[] = {
208 { TCM_GETEXTENDEDSTYLE
, sent
|wparam
|lparam
, 0, 0 },
209 { TCM_SETEXTENDEDSTYLE
, sent
},
210 { TCM_GETEXTENDEDSTYLE
, sent
|wparam
|lparam
, 0, 0 },
211 { TCM_SETEXTENDEDSTYLE
, sent
},
212 { TCM_GETEXTENDEDSTYLE
, sent
|wparam
|lparam
, 0, 0 },
216 static const struct message getset_unicode_format_seq
[] = {
217 { CCM_SETUNICODEFORMAT
, sent
|lparam
, 0 },
218 { CCM_GETUNICODEFORMAT
, sent
|wparam
|lparam
, 0, 0 },
219 { CCM_SETUNICODEFORMAT
, sent
|lparam
, 0 },
220 { CCM_GETUNICODEFORMAT
, sent
|wparam
|lparam
, 0, 0 },
221 { CCM_SETUNICODEFORMAT
, sent
|lparam
, 0 },
225 static const struct message getset_item_seq
[] = {
226 { TCM_SETITEMA
, sent
},
227 { TCM_GETITEMA
, sent
},
228 { TCM_GETITEMA
, sent
},
232 static const struct message getset_tooltip_seq
[] = {
233 { WM_NOTIFYFORMAT
, sent
|optional
},
234 { WM_QUERYUISTATE
, sent
|wparam
|lparam
|optional
, 0, 0 },
235 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0 },
236 { WM_NOTIFYFORMAT
, sent
|optional
},
237 { TCM_SETTOOLTIPS
, sent
|lparam
, 0 },
238 { TCM_GETTOOLTIPS
, sent
|wparam
|lparam
, 0, 0 },
239 { TCM_SETTOOLTIPS
, sent
|lparam
, 0 },
240 { TCM_GETTOOLTIPS
, sent
|wparam
|lparam
, 0, 0 },
244 static const struct message getset_tooltip_parent_seq
[] = {
245 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0 },
249 static const struct message insert_focus_seq
[] = {
250 { TCM_GETITEMCOUNT
, sent
|wparam
|lparam
, 0, 0 },
251 { TCM_GETCURFOCUS
, sent
|wparam
|lparam
, 0, 0 },
252 { TCM_INSERTITEM
, sent
|wparam
, 1 },
253 { WM_NOTIFYFORMAT
, sent
|defwinproc
|optional
},
254 { WM_QUERYUISTATE
, sent
|defwinproc
|optional
},
255 { WM_PARENTNOTIFY
, sent
|defwinproc
|optional
},
256 { TCM_GETITEMCOUNT
, sent
|wparam
|lparam
, 0, 0 },
257 { TCM_GETCURFOCUS
, sent
|wparam
|lparam
, 0, 0 },
258 { TCM_INSERTITEM
, sent
|wparam
, 2 },
259 { WM_NOTIFYFORMAT
, sent
|defwinproc
|optional
},
260 { WM_QUERYUISTATE
, sent
|defwinproc
|optional
, },
261 { WM_PARENTNOTIFY
, sent
|defwinproc
|optional
},
262 { TCM_GETITEMCOUNT
, sent
|wparam
|lparam
, 0, 0 },
263 { TCM_GETCURFOCUS
, sent
|wparam
|lparam
, 0, 0 },
264 { TCM_SETCURFOCUS
, sent
|wparam
|lparam
, -1, 0 },
265 { TCM_GETCURFOCUS
, sent
|wparam
|lparam
, 0, 0 },
266 { TCM_INSERTITEM
, sent
|wparam
, 3 },
267 { TCM_GETCURFOCUS
, sent
|wparam
|lparam
, 0, 0 },
271 static const struct message delete_focus_seq
[] = {
272 { TCM_GETITEMCOUNT
, sent
|wparam
|lparam
, 0, 0 },
273 { TCM_GETCURFOCUS
, sent
|wparam
|lparam
, 0, 0 },
274 { TCM_DELETEITEM
, sent
|wparam
|lparam
, 1, 0 },
275 { TCM_GETITEMCOUNT
, sent
|wparam
|lparam
, 0, 0 },
276 { TCM_GETCURFOCUS
, sent
|wparam
|lparam
, 0, 0 },
277 { TCM_SETCURFOCUS
, sent
|wparam
|lparam
, -1, 0 },
278 { TCM_GETCURFOCUS
, sent
|wparam
|lparam
, 0, 0 },
279 { TCM_DELETEITEM
, sent
|wparam
|lparam
, 0, 0 },
280 { TCM_GETITEMCOUNT
, sent
|wparam
|lparam
, 0, 0 },
281 { TCM_GETCURFOCUS
, sent
|wparam
|lparam
, 0, 0 },
285 static const struct message rbuttonup_seq
[] = {
286 { WM_RBUTTONUP
, sent
|wparam
|lparam
, 0, 0 },
287 { WM_CONTEXTMENU
, sent
|defwinproc
},
292 create_tabcontrol (DWORD style
, DWORD mask
)
296 static char text1
[] = "Tab 1",
297 text2
[] = "Wide Tab 2",
300 handle
= CreateWindow (
303 WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| TCS_FOCUSNEVER
| style
,
305 NULL
, NULL
, NULL
, 0);
309 SetWindowLong(handle
, GWL_STYLE
, WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| TCS_FOCUSNEVER
| style
);
310 SendMessage (handle
, WM_SETFONT
, 0, (LPARAM
) hFont
);
312 tcNewTab
.mask
= mask
;
313 tcNewTab
.pszText
= text1
;
315 SendMessage (handle
, TCM_INSERTITEM
, 0, (LPARAM
) &tcNewTab
);
316 tcNewTab
.pszText
= text2
;
318 SendMessage (handle
, TCM_INSERTITEM
, 1, (LPARAM
) &tcNewTab
);
319 tcNewTab
.pszText
= text3
;
321 SendMessage (handle
, TCM_INSERTITEM
, 2, (LPARAM
) &tcNewTab
);
323 if (winetest_interactive
)
325 ShowWindow (handle
, SW_SHOW
);
326 RedrawWindow (handle
, NULL
, 0, RDW_UPDATENOW
);
333 static LRESULT WINAPI
parentWindowProcess(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
335 static LONG defwndproc_counter
= 0;
339 /* do not log painting messages */
340 if (message
!= WM_PAINT
&&
341 message
!= WM_ERASEBKGND
&&
342 message
!= WM_NCPAINT
&&
343 message
!= WM_NCHITTEST
&&
344 message
!= WM_GETTEXT
&&
345 message
!= WM_GETICON
&&
346 message
!= WM_DEVICECHANGE
)
348 trace("parent: %p, %04x, %08lx, %08lx\n", hwnd
, message
, wParam
, lParam
);
350 msg
.message
= message
;
351 msg
.flags
= sent
|wparam
|lparam
;
352 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
355 add_message(sequences
, PARENT_SEQ_INDEX
, &msg
);
358 /* dump sent structure data */
359 if (message
== WM_DRAWITEM
)
360 g_drawitem
= *(DRAWITEMSTRUCT
*)lParam
;
362 defwndproc_counter
++;
363 ret
= DefWindowProcA(hwnd
, message
, wParam
, lParam
);
364 defwndproc_counter
--;
369 static BOOL
registerParentWindowClass(void)
374 cls
.lpfnWndProc
= parentWindowProcess
;
377 cls
.hInstance
= GetModuleHandleA(NULL
);
379 cls
.hCursor
= LoadCursorA(0, IDC_ARROW
);
380 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
381 cls
.lpszMenuName
= NULL
;
382 cls
.lpszClassName
= "Tab test parent class";
383 return RegisterClassA(&cls
);
386 static HWND
createParentWindow(void)
388 if (!registerParentWindowClass())
391 return CreateWindowEx(0, "Tab test parent class",
392 "Tab test parent window",
393 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
|
394 WS_MAXIMIZEBOX
| WS_VISIBLE
,
396 GetDesktopWindow(), NULL
, GetModuleHandleA(NULL
), NULL
);
399 static LRESULT WINAPI
tabSubclassProcess(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
401 WNDPROC oldproc
= (WNDPROC
)GetWindowLongPtrA(hwnd
, GWLP_USERDATA
);
402 static LONG defwndproc_counter
= 0;
406 /* do not log painting messages */
407 if (message
!= WM_PAINT
&&
408 message
!= WM_ERASEBKGND
&&
409 message
!= WM_NCPAINT
&&
410 message
!= WM_NCHITTEST
&&
411 message
!= WM_GETTEXT
&&
412 message
!= WM_GETICON
&&
413 message
!= WM_DEVICECHANGE
)
415 trace("tab: %p, %04x, %08lx, %08lx\n", hwnd
, message
, wParam
, lParam
);
417 msg
.message
= message
;
418 msg
.flags
= sent
|wparam
|lparam
;
419 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
422 add_message(sequences
, TAB_SEQ_INDEX
, &msg
);
425 defwndproc_counter
++;
426 ret
= CallWindowProcA(oldproc
, hwnd
, message
, wParam
, lParam
);
427 defwndproc_counter
--;
432 static HWND
createFilledTabControl(HWND parent_wnd
, DWORD style
, DWORD mask
, INT nTabs
)
440 GetClientRect(parent_wnd
, &rect
);
442 tabHandle
= CreateWindow (
445 WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| TCS_FOCUSNEVER
| style
,
446 0, 0, rect
.right
, rect
.bottom
,
447 parent_wnd
, NULL
, NULL
, 0);
451 oldproc
= (WNDPROC
)SetWindowLongPtrA(tabHandle
, GWLP_WNDPROC
, (LONG_PTR
)tabSubclassProcess
);
452 SetWindowLongPtrA(tabHandle
, GWLP_USERDATA
, (LONG_PTR
)oldproc
);
454 tcNewTab
.mask
= mask
;
456 for (i
= 0; i
< nTabs
; i
++)
458 char tabName
[MAX_TABLEN
];
460 sprintf(tabName
, "Tab %d", i
+1);
461 tcNewTab
.pszText
= tabName
;
463 SendMessage (tabHandle
, TCM_INSERTITEM
, i
, (LPARAM
) &tcNewTab
);
466 if (winetest_interactive
)
468 ShowWindow (tabHandle
, SW_SHOW
);
469 RedrawWindow (tabHandle
, NULL
, 0, RDW_UPDATENOW
);
476 static HWND
create_tooltip (HWND hTab
, char toolTipText
[])
481 LPTSTR lptstr
= toolTipText
;
484 /* Creating a tooltip window*/
485 hwndTT
= CreateWindowEx(
489 WS_POPUP
| TTS_NOPREFIX
| TTS_ALWAYSTIP
,
490 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
491 hTab
, NULL
, 0, NULL
);
497 SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
);
499 GetClientRect (hTab
, &rect
);
501 /* Initialize members of toolinfo*/
502 ti
.cbSize
= sizeof(TOOLINFO
);
503 ti
.uFlags
= TTF_SUBCLASS
;
507 ti
.lpszText
= lptstr
;
511 /* Add toolinfo structure to the tooltip control */
512 SendMessage(hwndTT
, TTM_ADDTOOL
, 0, (LPARAM
) &ti
);
517 static void test_tab(INT nMinTabWidth
)
521 HIMAGELIST himl
= ImageList_Create(21, 21, ILC_COLOR
, 3, 4);
527 hwTab
= create_tabcontrol(TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
);
528 SendMessage(hwTab
, TCM_SETMINTABWIDTH
, 0, nMinTabWidth
);
529 /* Get System default MinTabWidth */
530 if (nMinTabWidth
< 0)
531 nMinTabWidth
= SendMessage(hwTab
, TCM_SETMINTABWIDTH
, 0, nMinTabWidth
);
534 dpi
= GetDeviceCaps(hdc
, LOGPIXELSX
);
535 hOldFont
= SelectObject(hdc
, (HFONT
)SendMessage(hwTab
, WM_GETFONT
, 0, 0));
536 GetTextExtentPoint32A(hdc
, "Tab 1", strlen("Tab 1"), &size
);
537 trace("Tab1 text size: size.cx=%d size.cy=%d\n", size
.cx
, size
.cy
);
538 SelectObject(hdc
, hOldFont
);
539 ReleaseDC(hwTab
, hdc
);
541 trace (" TCS_FIXEDWIDTH tabs no icon...\n");
542 CHECKSIZE(hwTab
, dpi
, -1, "default width");
543 TABCHECKSETSIZE(hwTab
, 50, 20, 50, 20, "set size");
544 TABCHECKSETSIZE(hwTab
, 0, 1, 0, 1, "min size");
546 SendMessage(hwTab
, TCM_SETIMAGELIST
, 0, (LPARAM
)himl
);
548 trace (" TCS_FIXEDWIDTH tabs with icon...\n");
549 TABCHECKSETSIZE(hwTab
, 50, 30, 50, 30, "set size > icon");
550 TABCHECKSETSIZE(hwTab
, 20, 20, 25, 20, "set size < icon");
551 TABCHECKSETSIZE(hwTab
, 0, 1, 25, 1, "min size");
553 DestroyWindow (hwTab
);
555 hwTab
= create_tabcontrol(TCS_FIXEDWIDTH
| TCS_BUTTONS
, TCIF_TEXT
|TCIF_IMAGE
);
556 SendMessage(hwTab
, TCM_SETMINTABWIDTH
, 0, nMinTabWidth
);
559 dpi
= GetDeviceCaps(hdc
, LOGPIXELSX
);
560 ReleaseDC(hwTab
, hdc
);
561 trace (" TCS_FIXEDWIDTH buttons no icon...\n");
562 CHECKSIZE(hwTab
, dpi
, -1, "default width");
563 TABCHECKSETSIZE(hwTab
, 20, 20, 20, 20, "set size 1");
564 TABCHECKSETSIZE(hwTab
, 10, 50, 10, 50, "set size 2");
565 TABCHECKSETSIZE(hwTab
, 0, 1, 0, 1, "min size");
567 SendMessage(hwTab
, TCM_SETIMAGELIST
, 0, (LPARAM
)himl
);
569 trace (" TCS_FIXEDWIDTH buttons with icon...\n");
570 TABCHECKSETSIZE(hwTab
, 50, 30, 50, 30, "set size > icon");
571 TABCHECKSETSIZE(hwTab
, 20, 20, 25, 20, "set size < icon");
572 TABCHECKSETSIZE(hwTab
, 0, 1, 25, 1, "min size");
573 SendMessage(hwTab
, TCM_SETPADDING
, 0, MAKELPARAM(4,4));
574 TABCHECKSETSIZE(hwTab
, 0, 1, 25, 1, "set padding, min size");
576 DestroyWindow (hwTab
);
578 hwTab
= create_tabcontrol(TCS_FIXEDWIDTH
| TCS_BOTTOM
, TCIF_TEXT
|TCIF_IMAGE
);
579 SendMessage(hwTab
, TCM_SETMINTABWIDTH
, 0, nMinTabWidth
);
582 dpi
= GetDeviceCaps(hdc
, LOGPIXELSX
);
583 ReleaseDC(hwTab
, hdc
);
584 trace (" TCS_FIXEDWIDTH | TCS_BOTTOM tabs...\n");
585 CHECKSIZE(hwTab
, dpi
, -1, "no icon, default width");
587 TABCHECKSETSIZE(hwTab
, 20, 20, 20, 20, "no icon, set size 1");
588 TABCHECKSETSIZE(hwTab
, 10, 50, 10, 50, "no icon, set size 2");
589 TABCHECKSETSIZE(hwTab
, 0, 1, 0, 1, "no icon, min size");
591 SendMessage(hwTab
, TCM_SETIMAGELIST
, 0, (LPARAM
)himl
);
593 TABCHECKSETSIZE(hwTab
, 50, 30, 50, 30, "with icon, set size > icon");
594 TABCHECKSETSIZE(hwTab
, 20, 20, 25, 20, "with icon, set size < icon");
595 TABCHECKSETSIZE(hwTab
, 0, 1, 25, 1, "with icon, min size");
596 SendMessage(hwTab
, TCM_SETPADDING
, 0, MAKELPARAM(4,4));
597 TABCHECKSETSIZE(hwTab
, 0, 1, 25, 1, "set padding, min size");
599 DestroyWindow (hwTab
);
601 hwTab
= create_tabcontrol(0, TCIF_TEXT
|TCIF_IMAGE
);
602 SendMessage(hwTab
, TCM_SETMINTABWIDTH
, 0, nMinTabWidth
);
604 trace (" non fixed width, with text...\n");
605 exp
= max(size
.cx
+TAB_PADDING_X
*2, (nMinTabWidth
< 0) ? DEFAULT_MIN_TAB_WIDTH
: nMinTabWidth
);
606 SendMessage( hwTab
, TCM_GETITEMRECT
, 0, (LPARAM
)&rTab
);
607 ok( rTab
.right
- rTab
.left
== exp
|| broken(rTab
.right
- rTab
.left
== DEFAULT_MIN_TAB_WIDTH
),
608 "no icon, default width: Expected width [%d] got [%d]\n", exp
, rTab
.right
- rTab
.left
);
612 INT nTabWidth
= (nMinTabWidth
< 0) ? TabWidthPadded(i
, 2) : nMinTabWidth
;
614 SendMessage(hwTab
, TCM_SETIMAGELIST
, 0, 0);
615 SendMessage(hwTab
, TCM_SETPADDING
, 0, MAKELPARAM(i
,i
));
617 TABCHECKSETSIZE(hwTab
, 50, 20, max(size
.cx
+ i
*2, nTabWidth
), 20, "no icon, set size");
618 TABCHECKSETSIZE(hwTab
, 0, 1, max(size
.cx
+ i
*2, nTabWidth
), 1, "no icon, min size");
620 SendMessage(hwTab
, TCM_SETIMAGELIST
, 0, (LPARAM
)himl
);
621 nTabWidth
= (nMinTabWidth
< 0) ? TabWidthPadded(i
, 3) : nMinTabWidth
;
623 TABCHECKSETSIZE(hwTab
, 50, 30, max(size
.cx
+ 21 + i
*3, nTabWidth
), 30, "with icon, set size > icon");
624 TABCHECKSETSIZE(hwTab
, 20, 20, max(size
.cx
+ 21 + i
*3, nTabWidth
), 20, "with icon, set size < icon");
625 TABCHECKSETSIZE(hwTab
, 0, 1, max(size
.cx
+ 21 + i
*3, nTabWidth
), 1, "with icon, min size");
627 DestroyWindow (hwTab
);
629 hwTab
= create_tabcontrol(0, TCIF_IMAGE
);
630 SendMessage(hwTab
, TCM_SETMINTABWIDTH
, 0, nMinTabWidth
);
632 trace (" non fixed width, no text...\n");
633 exp
= (nMinTabWidth
< 0) ? DEFAULT_MIN_TAB_WIDTH
: nMinTabWidth
;
634 SendMessage( hwTab
, TCM_GETITEMRECT
, 0, (LPARAM
)&rTab
);
635 ok( rTab
.right
- rTab
.left
== exp
|| broken(rTab
.right
- rTab
.left
== DEFAULT_MIN_TAB_WIDTH
),
636 "no icon, default width: Expected width [%d] got [%d]\n", exp
, rTab
.right
- rTab
.left
);
640 INT nTabWidth
= (nMinTabWidth
< 0) ? TabWidthPadded(i
, 2) : nMinTabWidth
;
642 SendMessage(hwTab
, TCM_SETIMAGELIST
, 0, 0);
643 SendMessage(hwTab
, TCM_SETPADDING
, 0, MAKELPARAM(i
,i
));
645 TABCHECKSETSIZE(hwTab
, 50, 20, nTabWidth
, 20, "no icon, set size");
646 TABCHECKSETSIZE(hwTab
, 0, 1, nTabWidth
, 1, "no icon, min size");
648 SendMessage(hwTab
, TCM_SETIMAGELIST
, 0, (LPARAM
)himl
);
649 if (i
> 1 && nMinTabWidth
> 0 && nMinTabWidth
< DEFAULT_MIN_TAB_WIDTH
)
650 nTabWidth
+= EXTRA_ICON_PADDING
*(i
-1);
652 TABCHECKSETSIZE(hwTab
, 50, 30, nTabWidth
, 30, "with icon, set size > icon");
653 TABCHECKSETSIZE(hwTab
, 20, 20, nTabWidth
, 20, "with icon, set size < icon");
654 TABCHECKSETSIZE(hwTab
, 0, 1, nTabWidth
, 1, "with icon, min size");
657 DestroyWindow (hwTab
);
659 ImageList_Destroy(himl
);
662 static void test_width(void)
664 trace ("Testing with default MinWidth\n");
666 trace ("Testing with MinWidth set to -3\n");
668 trace ("Testing with MinWidth set to 24\n");
670 trace ("Testing with MinWidth set to 54\n");
672 trace ("Testing with MinWidth set to 94\n");
676 static void test_curfocus(void)
682 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, nTabs
);
683 ok(hTab
!= NULL
, "Failed to create tab control\n");
685 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
687 /* Testing CurFocus with largest appropriate value */
688 SendMessage(hTab
, TCM_SETCURFOCUS
, nTabs
-1, 0);
689 focusIndex
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
690 expect(nTabs
-1, focusIndex
);
692 /* Testing CurFocus with negative value */
693 SendMessage(hTab
, TCM_SETCURFOCUS
, -10, 0);
694 focusIndex
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
695 expect(-1, focusIndex
);
697 /* Testing CurFocus with value larger than number of tabs */
698 focusIndex
= SendMessage(hTab
, TCM_SETCURSEL
, 1, 0);
699 expect(-1, focusIndex
);
701 SendMessage(hTab
, TCM_SETCURFOCUS
, nTabs
+1, 0);
702 focusIndex
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
703 expect(1, focusIndex
);
705 ok_sequence(sequences
, TAB_SEQ_INDEX
, getset_cur_focus_seq
, "Getset curFoc test sequence", FALSE
);
710 static void test_cursel(void)
718 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, nTabs
);
719 ok(hTab
!= NULL
, "Failed to create tab control\n");
721 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
723 /* Testing CurSel with largest appropriate value */
724 selectionIndex
= SendMessage(hTab
, TCM_SETCURSEL
, nTabs
-1, 0);
725 expect(0, selectionIndex
);
726 selectionIndex
= SendMessage(hTab
, TCM_GETCURSEL
, 0, 0);
727 expect(nTabs
-1, selectionIndex
);
729 /* Focus should switch with selection */
730 focusIndex
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
731 expect(nTabs
-1, focusIndex
);
733 /* Testing CurSel with negative value */
734 SendMessage(hTab
, TCM_SETCURSEL
, -10, 0);
735 selectionIndex
= SendMessage(hTab
, TCM_GETCURSEL
, 0, 0);
736 expect(-1, selectionIndex
);
738 /* Testing CurSel with value larger than number of tabs */
739 selectionIndex
= SendMessage(hTab
, TCM_SETCURSEL
, 1, 0);
740 expect(-1, selectionIndex
);
742 selectionIndex
= SendMessage(hTab
, TCM_SETCURSEL
, nTabs
+1, 0);
743 expect(-1, selectionIndex
);
744 selectionIndex
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
745 expect(1, selectionIndex
);
747 ok_sequence(sequences
, TAB_SEQ_INDEX
, getset_cur_sel_seq
, "Getset curSel test sequence", FALSE
);
748 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_sequence
, "Getset curSel test parent sequence", FALSE
);
750 /* selected item should have TCIS_BUTTONPRESSED state
751 It doesn't depend on button state */
752 memset(&tcItem
, 0, sizeof(TCITEM
));
753 tcItem
.mask
= TCIF_STATE
;
754 tcItem
.dwStateMask
= TCIS_BUTTONPRESSED
;
755 selectionIndex
= SendMessage(hTab
, TCM_GETCURSEL
, 0, 0);
756 SendMessage(hTab
, TCM_GETITEM
, selectionIndex
, (LPARAM
) &tcItem
);
757 ok (tcItem
.dwState
& TCIS_BUTTONPRESSED
|| broken(tcItem
.dwState
== 0), /* older comctl32 */
758 "Selected item should have TCIS_BUTTONPRESSED\n");
763 static void test_extendedstyle(void)
766 DWORD prevExtendedStyle
;
770 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, nTabs
);
771 ok(hTab
!= NULL
, "Failed to create tab control\n");
773 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
775 /* Testing Flat Separators */
776 extendedStyle
= SendMessage(hTab
, TCM_GETEXTENDEDSTYLE
, 0, 0);
777 prevExtendedStyle
= SendMessage(hTab
, TCM_SETEXTENDEDSTYLE
, 0, TCS_EX_FLATSEPARATORS
);
778 expect(extendedStyle
, prevExtendedStyle
);
780 extendedStyle
= SendMessage(hTab
, TCM_GETEXTENDEDSTYLE
, 0, 0);
781 expect(TCS_EX_FLATSEPARATORS
, extendedStyle
);
783 /* Testing Register Drop */
784 prevExtendedStyle
= SendMessage(hTab
, TCM_SETEXTENDEDSTYLE
, 0, TCS_EX_REGISTERDROP
);
785 expect(extendedStyle
, prevExtendedStyle
);
787 extendedStyle
= SendMessage(hTab
, TCM_GETEXTENDEDSTYLE
, 0, 0);
789 expect(TCS_EX_REGISTERDROP
, extendedStyle
);
792 ok_sequence(sequences
, TAB_SEQ_INDEX
, getset_extended_style_seq
, "Getset extendedStyle test sequence", FALSE
);
793 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_sequence
, "Getset extendedStyle test parent sequence", FALSE
);
798 static void test_unicodeformat(void)
804 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, nTabs
);
805 ok(hTab
!= NULL
, "Failed to create tab control\n");
807 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
809 unicodeFormat
= SendMessage(hTab
, TCM_SETUNICODEFORMAT
, TRUE
, 0);
811 expect(0, unicodeFormat
);
813 unicodeFormat
= SendMessage(hTab
, TCM_GETUNICODEFORMAT
, 0, 0);
814 expect(1, unicodeFormat
);
816 unicodeFormat
= SendMessage(hTab
, TCM_SETUNICODEFORMAT
, FALSE
, 0);
817 expect(1, unicodeFormat
);
818 unicodeFormat
= SendMessage(hTab
, TCM_GETUNICODEFORMAT
, 0, 0);
819 expect(0, unicodeFormat
);
821 unicodeFormat
= SendMessage(hTab
, TCM_SETUNICODEFORMAT
, TRUE
, 0);
822 expect(0, unicodeFormat
);
824 ok_sequence(sequences
, TAB_SEQ_INDEX
, getset_unicode_format_seq
, "Getset unicodeFormat test sequence", FALSE
);
825 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_sequence
, "Getset unicodeFormat test parent sequence", FALSE
);
830 static void test_getset_item(void)
832 char szText
[32] = "New Label";
839 hTab
= CreateWindowA(
842 WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| TCS_FOCUSNEVER
| TCS_FIXEDWIDTH
| TCS_OWNERDRAWFIXED
,
844 parent_wnd
, NULL
, NULL
, 0);
846 ok(GetParent(hTab
) == NULL
, "got %p, expected null parent\n", GetParent(hTab
));
848 ret
= SendMessageA(hTab
, TCM_SETITEMEXTRA
, sizeof(LPARAM
)-1, 0);
849 ok(ret
== TRUE
, "got %d\n", ret
);
851 /* set some item data */
853 tcItem
.mask
= TCIF_PARAM
;
855 ret
= SendMessageA(hTab
, TCM_INSERTITEMA
, 0, (LPARAM
)&tcItem
);
856 ok(ret
== 0, "got %d\n", ret
);
858 /* all sizeof(LPARAM) returned anyway when using sizeof(LPARAM)-1 size */
859 memset(&lparam
, 0xaa, sizeof(lparam
));
860 tcItem
.lParam
= lparam
;
861 tcItem
.mask
= TCIF_PARAM
;
862 ret
= SendMessage(hTab
, TCM_GETITEM
, 0, (LPARAM
)&tcItem
);
864 /* everything higher specified size is preserved */
865 memset(&lparam
, 0xff, sizeof(lparam
)-1);
866 ok(tcItem
.lParam
== lparam
, "Expected 0x%lx, got 0x%lx\n", lparam
, tcItem
.lParam
);
870 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, nTabs
);
871 ok(hTab
!= NULL
, "Failed to create tab control\n");
873 /* passing invalid index should result in initialization to zero
874 for members mentioned in mask requested */
876 /* valid range here is [0,4] */
877 memset(&tcItem
, 0xcc, sizeof(tcItem
));
878 tcItem
.mask
= TCIF_PARAM
;
879 ret
= SendMessage(hTab
, TCM_GETITEM
, 5, (LPARAM
)&tcItem
);
881 ok(tcItem
.lParam
== 0, "Expected zero lParam, got %lu\n", tcItem
.lParam
);
883 memset(&tcItem
, 0xcc, sizeof(tcItem
));
884 tcItem
.mask
= TCIF_IMAGE
;
885 ret
= SendMessage(hTab
, TCM_GETITEM
, 5, (LPARAM
)&tcItem
);
887 expect(0, tcItem
.iImage
);
889 memset(&tcItem
, 0xcc, sizeof(tcItem
));
890 tcItem
.mask
= TCIF_TEXT
;
891 tcItem
.pszText
= szText
;
893 ret
= SendMessage(hTab
, TCM_GETITEM
, 5, (LPARAM
)&tcItem
);
895 expect('a', szText
[0]);
897 memset(&tcItem
, 0xcc, sizeof(tcItem
));
898 tcItem
.mask
= TCIF_STATE
;
899 tcItem
.dwStateMask
= 0;
900 tcItem
.dwState
= TCIS_BUTTONPRESSED
;
901 ret
= SendMessage(hTab
, TCM_GETITEM
, 5, (LPARAM
)&tcItem
);
903 ok(tcItem
.dwState
== 0, "Expected zero dwState, got %u\n", tcItem
.dwState
);
905 memset(&tcItem
, 0xcc, sizeof(tcItem
));
906 tcItem
.mask
= TCIF_STATE
;
907 tcItem
.dwStateMask
= TCIS_BUTTONPRESSED
;
908 tcItem
.dwState
= TCIS_BUTTONPRESSED
;
909 ret
= SendMessage(hTab
, TCM_GETITEM
, 5, (LPARAM
)&tcItem
);
911 ok(tcItem
.dwState
== 0, "Expected zero dwState\n");
913 /* check with negative index to be sure */
914 memset(&tcItem
, 0xcc, sizeof(tcItem
));
915 tcItem
.mask
= TCIF_PARAM
;
916 ret
= SendMessage(hTab
, TCM_GETITEM
, -1, (LPARAM
)&tcItem
);
918 ok(tcItem
.lParam
== 0, "Expected zero lParam, got %lu\n", tcItem
.lParam
);
920 memset(&tcItem
, 0xcc, sizeof(tcItem
));
921 tcItem
.mask
= TCIF_PARAM
;
922 ret
= SendMessage(hTab
, TCM_GETITEM
, -2, (LPARAM
)&tcItem
);
924 ok(tcItem
.lParam
== 0, "Expected zero lParam, got %lu\n", tcItem
.lParam
);
926 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
928 tcItem
.mask
= TCIF_TEXT
;
929 tcItem
.pszText
= &szText
[0];
930 tcItem
.cchTextMax
= sizeof(szText
);
932 strcpy(szText
, "New Label");
933 ok ( SendMessage(hTab
, TCM_SETITEM
, 0, (LPARAM
) &tcItem
), "Setting new item failed.\n");
934 ok ( SendMessage(hTab
, TCM_GETITEM
, 0, (LPARAM
) &tcItem
), "Getting item failed.\n");
935 expect_str("New Label", tcItem
.pszText
);
937 ok ( SendMessage(hTab
, TCM_GETITEM
, 1, (LPARAM
) &tcItem
), "Getting item failed.\n");
938 expect_str("Tab 2", tcItem
.pszText
);
940 ok_sequence(sequences
, TAB_SEQ_INDEX
, getset_item_seq
, "Getset item test sequence", FALSE
);
941 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_sequence
, "Getset item test parent sequence", FALSE
);
943 /* TCIS_BUTTONPRESSED doesn't depend on tab style */
944 memset(&tcItem
, 0, sizeof(tcItem
));
945 tcItem
.mask
= TCIF_STATE
;
946 tcItem
.dwStateMask
= TCIS_BUTTONPRESSED
;
947 tcItem
.dwState
= TCIS_BUTTONPRESSED
;
948 ok ( SendMessage(hTab
, TCM_SETITEM
, 0, (LPARAM
) &tcItem
), "Setting new item failed.\n");
950 ok ( SendMessage(hTab
, TCM_GETITEM
, 0, (LPARAM
) &tcItem
), "Getting item failed.\n");
953 ok (tcItem
.dwState
== TCIS_BUTTONPRESSED
, "TCIS_BUTTONPRESSED should be set.\n");
954 /* next highlight item, test that dwStateMask actually masks */
955 tcItem
.mask
= TCIF_STATE
;
956 tcItem
.dwStateMask
= TCIS_HIGHLIGHTED
;
957 tcItem
.dwState
= TCIS_HIGHLIGHTED
;
958 ok ( SendMessage(hTab
, TCM_SETITEM
, 0, (LPARAM
) &tcItem
), "Setting new item failed.\n");
960 ok ( SendMessage(hTab
, TCM_GETITEM
, 0, (LPARAM
) &tcItem
), "Getting item failed.\n");
961 ok (tcItem
.dwState
== TCIS_HIGHLIGHTED
, "TCIS_HIGHLIGHTED should be set.\n");
962 tcItem
.mask
= TCIF_STATE
;
963 tcItem
.dwStateMask
= TCIS_BUTTONPRESSED
;
965 ok ( SendMessage(hTab
, TCM_GETITEM
, 0, (LPARAM
) &tcItem
), "Getting item failed.\n");
966 ok (tcItem
.dwState
== TCIS_BUTTONPRESSED
, "TCIS_BUTTONPRESSED should be set.\n");
968 else win_skip( "Item state mask not supported\n" );
973 static void test_getset_tooltips(void)
975 char toolTipText
[32] = "ToolTip Text Test";
979 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, nTabs
);
980 ok(hTab
!= NULL
, "Failed to create tab control\n");
982 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
984 toolTip
= create_tooltip(hTab
, toolTipText
);
985 SendMessage(hTab
, TCM_SETTOOLTIPS
, (LPARAM
) toolTip
, 0);
986 ok (toolTip
== (HWND
) SendMessage(hTab
,TCM_GETTOOLTIPS
,0,0), "ToolTip was set incorrectly.\n");
988 SendMessage(hTab
, TCM_SETTOOLTIPS
, 0, 0);
989 ok (NULL
== (HWND
) SendMessage(hTab
,TCM_GETTOOLTIPS
,0,0), "ToolTip was set incorrectly.\n");
991 ok_sequence(sequences
, TAB_SEQ_INDEX
, getset_tooltip_seq
, "Getset tooltip test sequence", TRUE
);
992 ok_sequence(sequences
, PARENT_SEQ_INDEX
, getset_tooltip_parent_seq
, "Getset tooltip test parent sequence", TRUE
);
997 static void test_misc(void)
1007 ok(parent_wnd
!= NULL
, "no parent window!\n");
1008 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1010 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, nTabs
);
1011 ok(hTab
!= NULL
, "Failed to create tab control\n");
1013 if(!winetest_interactive
)
1014 ok_sequence(sequences
, TAB_SEQ_INDEX
, add_tab_to_parent
,
1015 "Tab sequence, after adding tab control to parent", TRUE
);
1017 ok_sequence(sequences
, TAB_SEQ_INDEX
, add_tab_to_parent_interactive
,
1018 "Tab sequence, after adding tab control to parent", TRUE
);
1020 if(!winetest_interactive
)
1021 ok_sequence(sequences
, PARENT_SEQ_INDEX
, add_tab_control_parent_seq
,
1022 "Parent after sequence, adding tab control to parent", TRUE
);
1024 ok_sequence(sequences
, PARENT_SEQ_INDEX
, add_tab_control_parent_seq_interactive
,
1025 "Parent after sequence, adding tab control to parent", TRUE
);
1027 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1028 ok(SendMessage(hTab
, TCM_SETMINTABWIDTH
, 0, -1) > 0,"TCM_SETMINTABWIDTH returned < 0\n");
1029 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_sequence
, "Set minTabWidth test parent sequence", FALSE
);
1031 /* Testing GetItemCount */
1032 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1033 nTabsRetrieved
= SendMessage(hTab
, TCM_GETITEMCOUNT
, 0, 0);
1034 expect(nTabs
, nTabsRetrieved
);
1035 ok_sequence(sequences
, TAB_SEQ_INDEX
, get_item_count_seq
, "Get itemCount test sequence", FALSE
);
1036 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_sequence
, "Getset itemCount test parent sequence", FALSE
);
1038 /* Testing GetRowCount */
1039 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1040 rowCount
= SendMessage(hTab
, TCM_GETROWCOUNT
, 0, 0);
1041 expect(1, rowCount
);
1042 ok_sequence(sequences
, TAB_SEQ_INDEX
, get_row_count_seq
, "Get rowCount test sequence", FALSE
);
1043 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_sequence
, "Get rowCount test parent sequence", FALSE
);
1045 /* Testing GetItemRect */
1046 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1047 ok(SendMessage(hTab
, TCM_GETITEMRECT
, 0, (LPARAM
) &rTab
), "GetItemRect failed.\n");
1050 dpi
= GetDeviceCaps(hdc
, LOGPIXELSX
);
1051 ReleaseDC(hTab
, hdc
);
1052 CHECKSIZE(hTab
, dpi
, -1 , "Default Width");
1053 ok_sequence(sequences
, TAB_SEQ_INDEX
, get_item_rect_seq
, "Get itemRect test sequence", FALSE
);
1054 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_sequence
, "Get itemRect test parent sequence", FALSE
);
1056 DestroyWindow(hTab
);
1059 static void test_adjustrect(void)
1064 ok(parent_wnd
!= NULL
, "no parent window!\n");
1066 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, 0, 0);
1067 ok(hTab
!= NULL
, "Failed to create tab control\n");
1069 r
= SendMessage(hTab
, TCM_ADJUSTRECT
, FALSE
, 0);
1072 r
= SendMessage(hTab
, TCM_ADJUSTRECT
, TRUE
, 0);
1076 static void test_insert_focus(void)
1082 DWORD mask
= TCIF_TEXT
|TCIF_IMAGE
;
1083 static char tabName
[] = "TAB";
1084 tcNewTab
.mask
= mask
;
1085 tcNewTab
.pszText
= tabName
;
1087 ok(parent_wnd
!= NULL
, "no parent window!\n");
1089 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, mask
, 0);
1090 ok(hTab
!= NULL
, "Failed to create tab control\n");
1092 r
= SendMessage(hTab
, TCM_GETCURSEL
, 0, 0);
1095 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1097 nTabsRetrieved
= SendMessage(hTab
, TCM_GETITEMCOUNT
, 0, 0);
1098 expect(0, nTabsRetrieved
);
1100 r
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
1103 tcNewTab
.iImage
= 1;
1104 r
= SendMessage(hTab
, TCM_INSERTITEM
, 1, (LPARAM
) &tcNewTab
);
1107 nTabsRetrieved
= SendMessage(hTab
, TCM_GETITEMCOUNT
, 0, 0);
1108 expect(1, nTabsRetrieved
);
1110 r
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
1113 tcNewTab
.iImage
= 2;
1114 r
= SendMessage(hTab
, TCM_INSERTITEM
, 2, (LPARAM
) &tcNewTab
);
1117 nTabsRetrieved
= SendMessage(hTab
, TCM_GETITEMCOUNT
, 0, 0);
1118 expect(2, nTabsRetrieved
);
1120 r
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
1123 r
= SendMessage(hTab
, TCM_SETCURFOCUS
, -1, 0);
1126 r
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
1129 tcNewTab
.iImage
= 3;
1130 r
= SendMessage(hTab
, TCM_INSERTITEM
, 3, (LPARAM
) &tcNewTab
);
1133 r
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
1136 ok_sequence(sequences
, TAB_SEQ_INDEX
, insert_focus_seq
, "insert_focus test sequence", FALSE
);
1137 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_sequence
, "insert_focus parent test sequence", TRUE
);
1139 DestroyWindow(hTab
);
1142 static void test_delete_focus(void)
1148 ok(parent_wnd
!= NULL
, "no parent window!\n");
1150 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, 2);
1151 ok(hTab
!= NULL
, "Failed to create tab control\n");
1153 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1155 nTabsRetrieved
= SendMessage(hTab
, TCM_GETITEMCOUNT
, 0, 0);
1156 expect(2, nTabsRetrieved
);
1158 r
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
1161 r
= SendMessage(hTab
, TCM_DELETEITEM
, 1, 0);
1164 nTabsRetrieved
= SendMessage(hTab
, TCM_GETITEMCOUNT
, 0, 0);
1165 expect(1, nTabsRetrieved
);
1167 r
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
1170 r
= SendMessage(hTab
, TCM_SETCURFOCUS
, -1, 0);
1173 r
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
1176 r
= SendMessage(hTab
, TCM_DELETEITEM
, 0, 0);
1179 nTabsRetrieved
= SendMessage(hTab
, TCM_GETITEMCOUNT
, 0, 0);
1180 expect(0, nTabsRetrieved
);
1182 r
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
1185 ok_sequence(sequences
, TAB_SEQ_INDEX
, delete_focus_seq
, "delete_focus test sequence", FALSE
);
1186 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_sequence
, "delete_focus parent test sequence", TRUE
);
1188 DestroyWindow(hTab
);
1191 static void test_removeimage(void)
1193 static const BYTE bits
[32];
1198 HIMAGELIST himl
= ImageList_Create(16, 16, ILC_COLOR
, 3, 4);
1200 hicon
= CreateIcon(NULL
, 16, 16, 1, 1, bits
, bits
);
1201 ImageList_AddIcon(himl
, hicon
);
1202 ImageList_AddIcon(himl
, hicon
);
1203 ImageList_AddIcon(himl
, hicon
);
1205 hwTab
= create_tabcontrol(TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
);
1206 SendMessage(hwTab
, TCM_SETIMAGELIST
, 0, (LPARAM
)himl
);
1208 memset(&item
, 0, sizeof(TCITEM
));
1209 item
.mask
= TCIF_IMAGE
;
1211 for(i
= 0; i
< 3; i
++) {
1212 SendMessage(hwTab
, TCM_GETITEM
, i
, (LPARAM
)&item
);
1213 expect(i
, item
.iImage
);
1216 /* remove image middle image */
1217 SendMessage(hwTab
, TCM_REMOVEIMAGE
, 1, 0);
1218 expect(2, ImageList_GetImageCount(himl
));
1220 SendMessage(hwTab
, TCM_GETITEM
, 0, (LPARAM
)&item
);
1221 expect(0, item
.iImage
);
1223 SendMessage(hwTab
, TCM_GETITEM
, 1, (LPARAM
)&item
);
1224 expect(-1, item
.iImage
);
1226 SendMessage(hwTab
, TCM_GETITEM
, 2, (LPARAM
)&item
);
1227 expect(1, item
.iImage
);
1228 /* remove first image */
1229 SendMessage(hwTab
, TCM_REMOVEIMAGE
, 0, 0);
1230 expect(1, ImageList_GetImageCount(himl
));
1232 SendMessage(hwTab
, TCM_GETITEM
, 0, (LPARAM
)&item
);
1233 expect(-1, item
.iImage
);
1235 SendMessage(hwTab
, TCM_GETITEM
, 1, (LPARAM
)&item
);
1236 expect(-1, item
.iImage
);
1238 SendMessage(hwTab
, TCM_GETITEM
, 2, (LPARAM
)&item
);
1239 expect(0, item
.iImage
);
1240 /* remove the last one */
1241 SendMessage(hwTab
, TCM_REMOVEIMAGE
, 0, 0);
1242 expect(0, ImageList_GetImageCount(himl
));
1243 for(i
= 0; i
< 3; i
++) {
1245 SendMessage(hwTab
, TCM_GETITEM
, i
, (LPARAM
)&item
);
1246 expect(-1, item
.iImage
);
1249 DestroyWindow(hwTab
);
1250 ImageList_Destroy(himl
);
1254 static void test_delete_selection(void)
1259 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, 4);
1260 ok(hTab
!= NULL
, "Failed to create tab control\n");
1262 ret
= SendMessage(hTab
, TCM_SETCURSEL
, 3, 0);
1264 ret
= SendMessage(hTab
, TCM_GETCURSEL
, 0, 0);
1266 /* delete selected item - selection goes to -1 */
1267 ret
= SendMessage(hTab
, TCM_DELETEITEM
, 3, 0);
1270 ret
= SendMessage(hTab
, TCM_GETCURSEL
, 0, 0);
1273 DestroyWindow(hTab
);
1276 static void test_TCM_SETITEMEXTRA(void)
1281 hTab
= CreateWindowA(
1284 WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| TCS_FOCUSNEVER
| TCS_FIXEDWIDTH
,
1286 parent_wnd
, NULL
, NULL
, 0);
1288 /* zero is valid size too */
1289 ret
= SendMessageA(hTab
, TCM_SETITEMEXTRA
, 0, 0);
1292 win_skip("TCM_SETITEMEXTRA not supported\n");
1293 DestroyWindow(hTab
);
1297 ret
= SendMessageA(hTab
, TCM_SETITEMEXTRA
, -1, 0);
1298 ok(ret
== FALSE
, "got %d\n", ret
);
1300 ret
= SendMessageA(hTab
, TCM_SETITEMEXTRA
, 2, 0);
1301 ok(ret
== TRUE
, "got %d\n", ret
);
1302 DestroyWindow(hTab
);
1304 /* it's not possible to change extra data size for control with tabs */
1305 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, 4);
1306 ok(hTab
!= NULL
, "Failed to create tab control\n");
1308 ret
= SendMessageA(hTab
, TCM_SETITEMEXTRA
, 2, 0);
1309 ok(ret
== FALSE
, "got %d\n", ret
);
1310 DestroyWindow(hTab
);
1313 static void test_TCS_OWNERDRAWFIXED(void)
1316 ULONG_PTR itemdata
, itemdata2
;
1321 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
|TCS_OWNERDRAWFIXED
, TCIF_TEXT
|TCIF_IMAGE
, 4);
1322 ok(hTab
!= NULL
, "Failed to create tab control\n");
1324 ok(GetParent(hTab
) == NULL
, "got %p, expected null parent\n", GetParent(hTab
));
1326 /* set some item data */
1327 memset(&lparam
, 0xde, sizeof(LPARAM
));
1329 item
.mask
= TCIF_PARAM
;
1330 item
.lParam
= lparam
;
1331 ret
= SendMessageA(hTab
, TCM_SETITEMA
, 0, (LPARAM
)&item
);
1332 ok(ret
== TRUE
, "got %d\n", ret
);
1334 memset(&g_drawitem
, 0, sizeof(g_drawitem
));
1336 ShowWindow(hTab
, SW_SHOW
);
1337 RedrawWindow(hTab
, NULL
, 0, RDW_UPDATENOW
);
1340 memset(&itemdata
, 0xde, 4);
1341 ok(g_drawitem
.itemData
== itemdata
, "got 0x%lx, expected 0x%lx\n", g_drawitem
.itemData
, itemdata
);
1343 DestroyWindow(hTab
);
1345 /* now with custom extra data length */
1346 hTab
= CreateWindowA(
1349 WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| TCS_FOCUSNEVER
| TCS_FIXEDWIDTH
| TCS_OWNERDRAWFIXED
,
1351 parent_wnd
, NULL
, NULL
, 0);
1353 ok(GetParent(hTab
) == NULL
, "got %p, expected null parent\n", GetParent(hTab
));
1355 ret
= SendMessageA(hTab
, TCM_SETITEMEXTRA
, sizeof(LPARAM
)+1, 0);
1356 ok(ret
== TRUE
, "got %d\n", ret
);
1358 /* set some item data */
1359 memset(&lparam
, 0xde, sizeof(LPARAM
));
1360 item
.mask
= TCIF_PARAM
;
1361 item
.lParam
= lparam
;
1363 ret
= SendMessageA(hTab
, TCM_INSERTITEMA
, 0, (LPARAM
)&item
);
1364 ok(ret
== 0, "got %d\n", ret
);
1366 memset(&g_drawitem
, 0, sizeof(g_drawitem
));
1368 ShowWindow(hTab
, SW_SHOW
);
1369 RedrawWindow(hTab
, NULL
, 0, RDW_UPDATENOW
);
1371 memset(&itemdata
, 0xde, sizeof(ULONG_PTR
));
1372 ok(*(ULONG_PTR
*)g_drawitem
.itemData
== itemdata
, "got 0x%lx, expected 0x%lx\n", g_drawitem
.itemData
, itemdata
);
1374 DestroyWindow(hTab
);
1376 /* same thing, but size smaller than default */
1377 hTab
= CreateWindowA(
1380 WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| TCS_FOCUSNEVER
| TCS_FIXEDWIDTH
| TCS_OWNERDRAWFIXED
,
1382 parent_wnd
, NULL
, NULL
, 0);
1384 ok(GetParent(hTab
) == NULL
, "got %p, expected null parent\n", GetParent(hTab
));
1386 ret
= SendMessageA(hTab
, TCM_SETITEMEXTRA
, sizeof(LPARAM
)-1, 0);
1387 ok(ret
== TRUE
, "got %d\n", ret
);
1389 memset(&lparam
, 0xde, sizeof(lparam
));
1390 item
.mask
= TCIF_PARAM
;
1391 item
.lParam
= lparam
;
1393 ret
= SendMessageA(hTab
, TCM_INSERTITEMA
, 0, (LPARAM
)&item
);
1394 ok(ret
== 0, "got %d\n", ret
);
1396 memset(&g_drawitem
, 0, sizeof(g_drawitem
));
1398 ShowWindow(hTab
, SW_SHOW
);
1399 RedrawWindow(hTab
, NULL
, 0, RDW_UPDATENOW
);
1401 itemdata
= itemdata2
= 0;
1402 memset(&itemdata
, 0xde, 4);
1403 memset(&itemdata2
, 0xde, sizeof(LPARAM
)-1);
1404 ok(g_drawitem
.itemData
== itemdata
|| broken(g_drawitem
.itemData
== itemdata2
) /* win98 */,
1405 "got 0x%lx, expected 0x%lx\n", g_drawitem
.itemData
, itemdata
);
1407 DestroyWindow(hTab
);
1410 static void test_WM_CONTEXTMENU(void)
1414 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, 4);
1415 ok(hTab
!= NULL
, "Failed to create tab control\n");
1417 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1419 SendMessageA(hTab
, WM_RBUTTONUP
, 0, 0);
1421 ok_sequence(sequences
, TAB_SEQ_INDEX
, rbuttonup_seq
, "WM_RBUTTONUP response sequence", FALSE
);
1423 DestroyWindow(hTab
);
1426 struct tabcreate_style
{
1431 static const struct tabcreate_style create_styles
[] =
1433 { WS_CHILD
|TCS_BOTTOM
|TCS_VERTICAL
, WS_CHILD
|WS_CLIPSIBLINGS
|TCS_BOTTOM
|TCS_VERTICAL
|TCS_MULTILINE
},
1434 { WS_CHILD
|TCS_VERTICAL
, WS_CHILD
|WS_CLIPSIBLINGS
|TCS_VERTICAL
|TCS_MULTILINE
},
1438 static void test_create(void)
1440 const struct tabcreate_style
*ptr
= create_styles
;
1446 hTab
= CreateWindowA(WC_TABCONTROLA
, "TestTab", ptr
->style
,
1447 10, 10, 300, 100, parent_wnd
, NULL
, NULL
, 0);
1448 style
= GetWindowLongA(hTab
, GWL_STYLE
);
1449 ok(style
== ptr
->act_style
, "expected style 0x%08x, got style 0x%08x\n", ptr
->act_style
, style
);
1451 DestroyWindow(hTab
);
1460 lstrcpyA(logfont
.lfFaceName
, "Arial");
1461 memset(&logfont
, 0, sizeof(logfont
));
1462 logfont
.lfHeight
= -12;
1463 logfont
.lfWeight
= FW_NORMAL
;
1464 logfont
.lfCharSet
= ANSI_CHARSET
;
1465 hFont
= CreateFontIndirectA(&logfont
);
1467 InitCommonControls();
1471 init_msg_sequences(sequences
, NUM_MSG_SEQUENCES
);
1473 parent_wnd
= createParentWindow();
1474 ok(parent_wnd
!= NULL
, "Failed to create parent window!\n");
1478 test_extendedstyle();
1479 test_unicodeformat();
1481 test_getset_tooltips();
1486 test_insert_focus();
1487 test_delete_focus();
1488 test_delete_selection();
1490 test_TCM_SETITEMEXTRA();
1491 test_TCS_OWNERDRAWFIXED();
1492 test_WM_CONTEXTMENU();
1495 DestroyWindow(parent_wnd
);