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
;
356 add_message(sequences
, PARENT_SEQ_INDEX
, &msg
);
359 /* dump sent structure data */
360 if (message
== WM_DRAWITEM
)
361 g_drawitem
= *(DRAWITEMSTRUCT
*)lParam
;
363 defwndproc_counter
++;
364 ret
= DefWindowProcA(hwnd
, message
, wParam
, lParam
);
365 defwndproc_counter
--;
370 static BOOL
registerParentWindowClass(void)
375 cls
.lpfnWndProc
= parentWindowProcess
;
378 cls
.hInstance
= GetModuleHandleA(NULL
);
380 cls
.hCursor
= LoadCursorA(0, IDC_ARROW
);
381 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
382 cls
.lpszMenuName
= NULL
;
383 cls
.lpszClassName
= "Tab test parent class";
384 return RegisterClassA(&cls
);
387 static HWND
createParentWindow(void)
389 if (!registerParentWindowClass())
392 return CreateWindowEx(0, "Tab test parent class",
393 "Tab test parent window",
394 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
|
395 WS_MAXIMIZEBOX
| WS_VISIBLE
,
397 GetDesktopWindow(), NULL
, GetModuleHandleA(NULL
), NULL
);
400 static LRESULT WINAPI
tabSubclassProcess(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
402 WNDPROC oldproc
= (WNDPROC
)GetWindowLongPtrA(hwnd
, GWLP_USERDATA
);
403 static LONG defwndproc_counter
= 0;
407 /* do not log painting messages */
408 if (message
!= WM_PAINT
&&
409 message
!= WM_ERASEBKGND
&&
410 message
!= WM_NCPAINT
&&
411 message
!= WM_NCHITTEST
&&
412 message
!= WM_GETTEXT
&&
413 message
!= WM_GETICON
&&
414 message
!= WM_DEVICECHANGE
)
416 trace("tab: %p, %04x, %08lx, %08lx\n", hwnd
, message
, wParam
, lParam
);
418 msg
.message
= message
;
419 msg
.flags
= sent
|wparam
|lparam
;
420 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
424 add_message(sequences
, TAB_SEQ_INDEX
, &msg
);
427 defwndproc_counter
++;
428 ret
= CallWindowProcA(oldproc
, hwnd
, message
, wParam
, lParam
);
429 defwndproc_counter
--;
434 static HWND
createFilledTabControl(HWND parent_wnd
, DWORD style
, DWORD mask
, INT nTabs
)
442 GetClientRect(parent_wnd
, &rect
);
444 tabHandle
= CreateWindow (
447 WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| TCS_FOCUSNEVER
| style
,
448 0, 0, rect
.right
, rect
.bottom
,
449 parent_wnd
, NULL
, NULL
, 0);
453 oldproc
= (WNDPROC
)SetWindowLongPtrA(tabHandle
, GWLP_WNDPROC
, (LONG_PTR
)tabSubclassProcess
);
454 SetWindowLongPtrA(tabHandle
, GWLP_USERDATA
, (LONG_PTR
)oldproc
);
456 tcNewTab
.mask
= mask
;
458 for (i
= 0; i
< nTabs
; i
++)
460 char tabName
[MAX_TABLEN
];
462 sprintf(tabName
, "Tab %d", i
+1);
463 tcNewTab
.pszText
= tabName
;
465 SendMessage (tabHandle
, TCM_INSERTITEM
, i
, (LPARAM
) &tcNewTab
);
468 if (winetest_interactive
)
470 ShowWindow (tabHandle
, SW_SHOW
);
471 RedrawWindow (tabHandle
, NULL
, 0, RDW_UPDATENOW
);
478 static HWND
create_tooltip (HWND hTab
, char toolTipText
[])
483 LPTSTR lptstr
= toolTipText
;
486 /* Creating a tooltip window*/
487 hwndTT
= CreateWindowEx(
491 WS_POPUP
| TTS_NOPREFIX
| TTS_ALWAYSTIP
,
492 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
493 hTab
, NULL
, 0, NULL
);
499 SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
);
501 GetClientRect (hTab
, &rect
);
503 /* Initialize members of toolinfo*/
504 ti
.cbSize
= sizeof(TOOLINFO
);
505 ti
.uFlags
= TTF_SUBCLASS
;
509 ti
.lpszText
= lptstr
;
513 /* Add toolinfo structure to the tooltip control */
514 SendMessage(hwndTT
, TTM_ADDTOOL
, 0, (LPARAM
) &ti
);
519 static void test_tab(INT nMinTabWidth
)
523 HIMAGELIST himl
= ImageList_Create(21, 21, ILC_COLOR
, 3, 4);
529 hwTab
= create_tabcontrol(TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
);
530 SendMessage(hwTab
, TCM_SETMINTABWIDTH
, 0, nMinTabWidth
);
531 /* Get System default MinTabWidth */
532 if (nMinTabWidth
< 0)
533 nMinTabWidth
= SendMessage(hwTab
, TCM_SETMINTABWIDTH
, 0, nMinTabWidth
);
536 dpi
= GetDeviceCaps(hdc
, LOGPIXELSX
);
537 hOldFont
= SelectObject(hdc
, (HFONT
)SendMessage(hwTab
, WM_GETFONT
, 0, 0));
538 GetTextExtentPoint32A(hdc
, "Tab 1", strlen("Tab 1"), &size
);
539 trace("Tab1 text size: size.cx=%d size.cy=%d\n", size
.cx
, size
.cy
);
540 SelectObject(hdc
, hOldFont
);
541 ReleaseDC(hwTab
, hdc
);
543 trace (" TCS_FIXEDWIDTH tabs no icon...\n");
544 CHECKSIZE(hwTab
, dpi
, -1, "default width");
545 TABCHECKSETSIZE(hwTab
, 50, 20, 50, 20, "set size");
546 TABCHECKSETSIZE(hwTab
, 0, 1, 0, 1, "min size");
548 SendMessage(hwTab
, TCM_SETIMAGELIST
, 0, (LPARAM
)himl
);
550 trace (" TCS_FIXEDWIDTH tabs with icon...\n");
551 TABCHECKSETSIZE(hwTab
, 50, 30, 50, 30, "set size > icon");
552 TABCHECKSETSIZE(hwTab
, 20, 20, 25, 20, "set size < icon");
553 TABCHECKSETSIZE(hwTab
, 0, 1, 25, 1, "min size");
555 DestroyWindow (hwTab
);
557 hwTab
= create_tabcontrol(TCS_FIXEDWIDTH
| TCS_BUTTONS
, TCIF_TEXT
|TCIF_IMAGE
);
558 SendMessage(hwTab
, TCM_SETMINTABWIDTH
, 0, nMinTabWidth
);
561 dpi
= GetDeviceCaps(hdc
, LOGPIXELSX
);
562 ReleaseDC(hwTab
, hdc
);
563 trace (" TCS_FIXEDWIDTH buttons no icon...\n");
564 CHECKSIZE(hwTab
, dpi
, -1, "default width");
565 TABCHECKSETSIZE(hwTab
, 20, 20, 20, 20, "set size 1");
566 TABCHECKSETSIZE(hwTab
, 10, 50, 10, 50, "set size 2");
567 TABCHECKSETSIZE(hwTab
, 0, 1, 0, 1, "min size");
569 SendMessage(hwTab
, TCM_SETIMAGELIST
, 0, (LPARAM
)himl
);
571 trace (" TCS_FIXEDWIDTH buttons with icon...\n");
572 TABCHECKSETSIZE(hwTab
, 50, 30, 50, 30, "set size > icon");
573 TABCHECKSETSIZE(hwTab
, 20, 20, 25, 20, "set size < icon");
574 TABCHECKSETSIZE(hwTab
, 0, 1, 25, 1, "min size");
575 SendMessage(hwTab
, TCM_SETPADDING
, 0, MAKELPARAM(4,4));
576 TABCHECKSETSIZE(hwTab
, 0, 1, 25, 1, "set padding, min size");
578 DestroyWindow (hwTab
);
580 hwTab
= create_tabcontrol(TCS_FIXEDWIDTH
| TCS_BOTTOM
, TCIF_TEXT
|TCIF_IMAGE
);
581 SendMessage(hwTab
, TCM_SETMINTABWIDTH
, 0, nMinTabWidth
);
584 dpi
= GetDeviceCaps(hdc
, LOGPIXELSX
);
585 ReleaseDC(hwTab
, hdc
);
586 trace (" TCS_FIXEDWIDTH | TCS_BOTTOM tabs...\n");
587 CHECKSIZE(hwTab
, dpi
, -1, "no icon, default width");
589 TABCHECKSETSIZE(hwTab
, 20, 20, 20, 20, "no icon, set size 1");
590 TABCHECKSETSIZE(hwTab
, 10, 50, 10, 50, "no icon, set size 2");
591 TABCHECKSETSIZE(hwTab
, 0, 1, 0, 1, "no icon, min size");
593 SendMessage(hwTab
, TCM_SETIMAGELIST
, 0, (LPARAM
)himl
);
595 TABCHECKSETSIZE(hwTab
, 50, 30, 50, 30, "with icon, set size > icon");
596 TABCHECKSETSIZE(hwTab
, 20, 20, 25, 20, "with icon, set size < icon");
597 TABCHECKSETSIZE(hwTab
, 0, 1, 25, 1, "with icon, min size");
598 SendMessage(hwTab
, TCM_SETPADDING
, 0, MAKELPARAM(4,4));
599 TABCHECKSETSIZE(hwTab
, 0, 1, 25, 1, "set padding, min size");
601 DestroyWindow (hwTab
);
603 hwTab
= create_tabcontrol(0, TCIF_TEXT
|TCIF_IMAGE
);
604 SendMessage(hwTab
, TCM_SETMINTABWIDTH
, 0, nMinTabWidth
);
606 trace (" non fixed width, with text...\n");
607 exp
= max(size
.cx
+TAB_PADDING_X
*2, (nMinTabWidth
< 0) ? DEFAULT_MIN_TAB_WIDTH
: nMinTabWidth
);
608 SendMessage( hwTab
, TCM_GETITEMRECT
, 0, (LPARAM
)&rTab
);
609 ok( rTab
.right
- rTab
.left
== exp
|| broken(rTab
.right
- rTab
.left
== DEFAULT_MIN_TAB_WIDTH
),
610 "no icon, default width: Expected width [%d] got [%d]\n", exp
, rTab
.right
- rTab
.left
);
614 INT nTabWidth
= (nMinTabWidth
< 0) ? TabWidthPadded(i
, 2) : nMinTabWidth
;
616 SendMessage(hwTab
, TCM_SETIMAGELIST
, 0, 0);
617 SendMessage(hwTab
, TCM_SETPADDING
, 0, MAKELPARAM(i
,i
));
619 TABCHECKSETSIZE(hwTab
, 50, 20, max(size
.cx
+ i
*2, nTabWidth
), 20, "no icon, set size");
620 TABCHECKSETSIZE(hwTab
, 0, 1, max(size
.cx
+ i
*2, nTabWidth
), 1, "no icon, min size");
622 SendMessage(hwTab
, TCM_SETIMAGELIST
, 0, (LPARAM
)himl
);
623 nTabWidth
= (nMinTabWidth
< 0) ? TabWidthPadded(i
, 3) : nMinTabWidth
;
625 TABCHECKSETSIZE(hwTab
, 50, 30, max(size
.cx
+ 21 + i
*3, nTabWidth
), 30, "with icon, set size > icon");
626 TABCHECKSETSIZE(hwTab
, 20, 20, max(size
.cx
+ 21 + i
*3, nTabWidth
), 20, "with icon, set size < icon");
627 TABCHECKSETSIZE(hwTab
, 0, 1, max(size
.cx
+ 21 + i
*3, nTabWidth
), 1, "with icon, min size");
629 DestroyWindow (hwTab
);
631 hwTab
= create_tabcontrol(0, TCIF_IMAGE
);
632 SendMessage(hwTab
, TCM_SETMINTABWIDTH
, 0, nMinTabWidth
);
634 trace (" non fixed width, no text...\n");
635 exp
= (nMinTabWidth
< 0) ? DEFAULT_MIN_TAB_WIDTH
: nMinTabWidth
;
636 SendMessage( hwTab
, TCM_GETITEMRECT
, 0, (LPARAM
)&rTab
);
637 ok( rTab
.right
- rTab
.left
== exp
|| broken(rTab
.right
- rTab
.left
== DEFAULT_MIN_TAB_WIDTH
),
638 "no icon, default width: Expected width [%d] got [%d]\n", exp
, rTab
.right
- rTab
.left
);
642 INT nTabWidth
= (nMinTabWidth
< 0) ? TabWidthPadded(i
, 2) : nMinTabWidth
;
644 SendMessage(hwTab
, TCM_SETIMAGELIST
, 0, 0);
645 SendMessage(hwTab
, TCM_SETPADDING
, 0, MAKELPARAM(i
,i
));
647 TABCHECKSETSIZE(hwTab
, 50, 20, nTabWidth
, 20, "no icon, set size");
648 TABCHECKSETSIZE(hwTab
, 0, 1, nTabWidth
, 1, "no icon, min size");
650 SendMessage(hwTab
, TCM_SETIMAGELIST
, 0, (LPARAM
)himl
);
651 if (i
> 1 && nMinTabWidth
> 0 && nMinTabWidth
< DEFAULT_MIN_TAB_WIDTH
)
652 nTabWidth
+= EXTRA_ICON_PADDING
*(i
-1);
654 TABCHECKSETSIZE(hwTab
, 50, 30, nTabWidth
, 30, "with icon, set size > icon");
655 TABCHECKSETSIZE(hwTab
, 20, 20, nTabWidth
, 20, "with icon, set size < icon");
656 TABCHECKSETSIZE(hwTab
, 0, 1, nTabWidth
, 1, "with icon, min size");
659 DestroyWindow (hwTab
);
661 ImageList_Destroy(himl
);
664 static void test_width(void)
666 trace ("Testing with default MinWidth\n");
668 trace ("Testing with MinWidth set to -3\n");
670 trace ("Testing with MinWidth set to 24\n");
672 trace ("Testing with MinWidth set to 54\n");
674 trace ("Testing with MinWidth set to 94\n");
678 static void test_curfocus(void)
684 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, nTabs
);
685 ok(hTab
!= NULL
, "Failed to create tab control\n");
687 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
689 /* Testing CurFocus with largest appropriate value */
690 SendMessage(hTab
, TCM_SETCURFOCUS
, nTabs
-1, 0);
691 focusIndex
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
692 expect(nTabs
-1, focusIndex
);
694 /* Testing CurFocus with negative value */
695 SendMessage(hTab
, TCM_SETCURFOCUS
, -10, 0);
696 focusIndex
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
697 expect(-1, focusIndex
);
699 /* Testing CurFocus with value larger than number of tabs */
700 focusIndex
= SendMessage(hTab
, TCM_SETCURSEL
, 1, 0);
701 expect(-1, focusIndex
);
703 SendMessage(hTab
, TCM_SETCURFOCUS
, nTabs
+1, 0);
704 focusIndex
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
705 expect(1, focusIndex
);
707 ok_sequence(sequences
, TAB_SEQ_INDEX
, getset_cur_focus_seq
, "Getset curFoc test sequence", FALSE
);
712 static void test_cursel(void)
720 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, nTabs
);
721 ok(hTab
!= NULL
, "Failed to create tab control\n");
723 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
725 /* Testing CurSel with largest appropriate value */
726 selectionIndex
= SendMessage(hTab
, TCM_SETCURSEL
, nTabs
-1, 0);
727 expect(0, selectionIndex
);
728 selectionIndex
= SendMessage(hTab
, TCM_GETCURSEL
, 0, 0);
729 expect(nTabs
-1, selectionIndex
);
731 /* Focus should switch with selection */
732 focusIndex
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
733 expect(nTabs
-1, focusIndex
);
735 /* Testing CurSel with negative value */
736 SendMessage(hTab
, TCM_SETCURSEL
, -10, 0);
737 selectionIndex
= SendMessage(hTab
, TCM_GETCURSEL
, 0, 0);
738 expect(-1, selectionIndex
);
740 /* Testing CurSel with value larger than number of tabs */
741 selectionIndex
= SendMessage(hTab
, TCM_SETCURSEL
, 1, 0);
742 expect(-1, selectionIndex
);
744 selectionIndex
= SendMessage(hTab
, TCM_SETCURSEL
, nTabs
+1, 0);
745 expect(-1, selectionIndex
);
746 selectionIndex
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
747 expect(1, selectionIndex
);
749 ok_sequence(sequences
, TAB_SEQ_INDEX
, getset_cur_sel_seq
, "Getset curSel test sequence", FALSE
);
750 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_sequence
, "Getset curSel test parent sequence", FALSE
);
752 /* selected item should have TCIS_BUTTONPRESSED state
753 It doesn't depend on button state */
754 memset(&tcItem
, 0, sizeof(TCITEM
));
755 tcItem
.mask
= TCIF_STATE
;
756 tcItem
.dwStateMask
= TCIS_BUTTONPRESSED
;
757 selectionIndex
= SendMessage(hTab
, TCM_GETCURSEL
, 0, 0);
758 SendMessage(hTab
, TCM_GETITEM
, selectionIndex
, (LPARAM
) &tcItem
);
759 ok (tcItem
.dwState
& TCIS_BUTTONPRESSED
|| broken(tcItem
.dwState
== 0), /* older comctl32 */
760 "Selected item should have TCIS_BUTTONPRESSED\n");
765 static void test_extendedstyle(void)
768 DWORD prevExtendedStyle
;
772 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, nTabs
);
773 ok(hTab
!= NULL
, "Failed to create tab control\n");
775 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
777 /* Testing Flat Separators */
778 extendedStyle
= SendMessage(hTab
, TCM_GETEXTENDEDSTYLE
, 0, 0);
779 prevExtendedStyle
= SendMessage(hTab
, TCM_SETEXTENDEDSTYLE
, 0, TCS_EX_FLATSEPARATORS
);
780 expect(extendedStyle
, prevExtendedStyle
);
782 extendedStyle
= SendMessage(hTab
, TCM_GETEXTENDEDSTYLE
, 0, 0);
783 expect(TCS_EX_FLATSEPARATORS
, extendedStyle
);
785 /* Testing Register Drop */
786 prevExtendedStyle
= SendMessage(hTab
, TCM_SETEXTENDEDSTYLE
, 0, TCS_EX_REGISTERDROP
);
787 expect(extendedStyle
, prevExtendedStyle
);
789 extendedStyle
= SendMessage(hTab
, TCM_GETEXTENDEDSTYLE
, 0, 0);
791 expect(TCS_EX_REGISTERDROP
, extendedStyle
);
794 ok_sequence(sequences
, TAB_SEQ_INDEX
, getset_extended_style_seq
, "Getset extendedStyle test sequence", FALSE
);
795 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_sequence
, "Getset extendedStyle test parent sequence", FALSE
);
800 static void test_unicodeformat(void)
806 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, nTabs
);
807 ok(hTab
!= NULL
, "Failed to create tab control\n");
809 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
811 unicodeFormat
= SendMessage(hTab
, TCM_SETUNICODEFORMAT
, TRUE
, 0);
813 expect(0, unicodeFormat
);
815 unicodeFormat
= SendMessage(hTab
, TCM_GETUNICODEFORMAT
, 0, 0);
816 expect(1, unicodeFormat
);
818 unicodeFormat
= SendMessage(hTab
, TCM_SETUNICODEFORMAT
, FALSE
, 0);
819 expect(1, unicodeFormat
);
820 unicodeFormat
= SendMessage(hTab
, TCM_GETUNICODEFORMAT
, 0, 0);
821 expect(0, unicodeFormat
);
823 unicodeFormat
= SendMessage(hTab
, TCM_SETUNICODEFORMAT
, TRUE
, 0);
824 expect(0, unicodeFormat
);
826 ok_sequence(sequences
, TAB_SEQ_INDEX
, getset_unicode_format_seq
, "Getset unicodeFormat test sequence", FALSE
);
827 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_sequence
, "Getset unicodeFormat test parent sequence", FALSE
);
832 static void test_getset_item(void)
834 char szText
[32] = "New Label";
841 hTab
= CreateWindowA(
844 WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| TCS_FOCUSNEVER
| TCS_FIXEDWIDTH
| TCS_OWNERDRAWFIXED
,
846 parent_wnd
, NULL
, NULL
, 0);
848 ok(GetParent(hTab
) == NULL
, "got %p, expected null parent\n", GetParent(hTab
));
850 ret
= SendMessageA(hTab
, TCM_SETITEMEXTRA
, sizeof(LPARAM
)-1, 0);
851 ok(ret
== TRUE
, "got %d\n", ret
);
853 /* set some item data */
855 tcItem
.mask
= TCIF_PARAM
;
857 ret
= SendMessageA(hTab
, TCM_INSERTITEMA
, 0, (LPARAM
)&tcItem
);
858 ok(ret
== 0, "got %d\n", ret
);
860 /* all sizeof(LPARAM) returned anyway when using sizeof(LPARAM)-1 size */
861 memset(&lparam
, 0xaa, sizeof(lparam
));
862 tcItem
.lParam
= lparam
;
863 tcItem
.mask
= TCIF_PARAM
;
864 ret
= SendMessage(hTab
, TCM_GETITEM
, 0, (LPARAM
)&tcItem
);
866 /* everything higher specified size is preserved */
867 memset(&lparam
, 0xff, sizeof(lparam
)-1);
868 ok(tcItem
.lParam
== lparam
, "Expected 0x%lx, got 0x%lx\n", lparam
, tcItem
.lParam
);
872 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, nTabs
);
873 ok(hTab
!= NULL
, "Failed to create tab control\n");
875 /* passing invalid index should result in initialization to zero
876 for members mentioned in mask requested */
878 /* valid range here is [0,4] */
879 memset(&tcItem
, 0xcc, sizeof(tcItem
));
880 tcItem
.mask
= TCIF_PARAM
;
881 ret
= SendMessage(hTab
, TCM_GETITEM
, 5, (LPARAM
)&tcItem
);
883 ok(tcItem
.lParam
== 0, "Expected zero lParam, got %lu\n", tcItem
.lParam
);
885 memset(&tcItem
, 0xcc, sizeof(tcItem
));
886 tcItem
.mask
= TCIF_IMAGE
;
887 ret
= SendMessage(hTab
, TCM_GETITEM
, 5, (LPARAM
)&tcItem
);
889 expect(0, tcItem
.iImage
);
891 memset(&tcItem
, 0xcc, sizeof(tcItem
));
892 tcItem
.mask
= TCIF_TEXT
;
893 tcItem
.pszText
= szText
;
895 ret
= SendMessage(hTab
, TCM_GETITEM
, 5, (LPARAM
)&tcItem
);
897 expect('a', szText
[0]);
899 memset(&tcItem
, 0xcc, sizeof(tcItem
));
900 tcItem
.mask
= TCIF_STATE
;
901 tcItem
.dwStateMask
= 0;
902 tcItem
.dwState
= TCIS_BUTTONPRESSED
;
903 ret
= SendMessage(hTab
, TCM_GETITEM
, 5, (LPARAM
)&tcItem
);
905 ok(tcItem
.dwState
== 0, "Expected zero dwState, got %u\n", tcItem
.dwState
);
907 memset(&tcItem
, 0xcc, sizeof(tcItem
));
908 tcItem
.mask
= TCIF_STATE
;
909 tcItem
.dwStateMask
= TCIS_BUTTONPRESSED
;
910 tcItem
.dwState
= TCIS_BUTTONPRESSED
;
911 ret
= SendMessage(hTab
, TCM_GETITEM
, 5, (LPARAM
)&tcItem
);
913 ok(tcItem
.dwState
== 0, "Expected zero dwState\n");
915 /* check with negative index to be sure */
916 memset(&tcItem
, 0xcc, sizeof(tcItem
));
917 tcItem
.mask
= TCIF_PARAM
;
918 ret
= SendMessage(hTab
, TCM_GETITEM
, -1, (LPARAM
)&tcItem
);
920 ok(tcItem
.lParam
== 0, "Expected zero lParam, got %lu\n", tcItem
.lParam
);
922 memset(&tcItem
, 0xcc, sizeof(tcItem
));
923 tcItem
.mask
= TCIF_PARAM
;
924 ret
= SendMessage(hTab
, TCM_GETITEM
, -2, (LPARAM
)&tcItem
);
926 ok(tcItem
.lParam
== 0, "Expected zero lParam, got %lu\n", tcItem
.lParam
);
928 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
930 tcItem
.mask
= TCIF_TEXT
;
931 tcItem
.pszText
= &szText
[0];
932 tcItem
.cchTextMax
= sizeof(szText
);
934 strcpy(szText
, "New Label");
935 ok ( SendMessage(hTab
, TCM_SETITEM
, 0, (LPARAM
) &tcItem
), "Setting new item failed.\n");
936 ok ( SendMessage(hTab
, TCM_GETITEM
, 0, (LPARAM
) &tcItem
), "Getting item failed.\n");
937 expect_str("New Label", tcItem
.pszText
);
939 ok ( SendMessage(hTab
, TCM_GETITEM
, 1, (LPARAM
) &tcItem
), "Getting item failed.\n");
940 expect_str("Tab 2", tcItem
.pszText
);
942 ok_sequence(sequences
, TAB_SEQ_INDEX
, getset_item_seq
, "Getset item test sequence", FALSE
);
943 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_sequence
, "Getset item test parent sequence", FALSE
);
945 /* TCIS_BUTTONPRESSED doesn't depend on tab style */
946 memset(&tcItem
, 0, sizeof(tcItem
));
947 tcItem
.mask
= TCIF_STATE
;
948 tcItem
.dwStateMask
= TCIS_BUTTONPRESSED
;
949 tcItem
.dwState
= TCIS_BUTTONPRESSED
;
950 ok ( SendMessage(hTab
, TCM_SETITEM
, 0, (LPARAM
) &tcItem
), "Setting new item failed.\n");
952 ok ( SendMessage(hTab
, TCM_GETITEM
, 0, (LPARAM
) &tcItem
), "Getting item failed.\n");
955 ok (tcItem
.dwState
== TCIS_BUTTONPRESSED
, "TCIS_BUTTONPRESSED should be set.\n");
956 /* next highlight item, test that dwStateMask actually masks */
957 tcItem
.mask
= TCIF_STATE
;
958 tcItem
.dwStateMask
= TCIS_HIGHLIGHTED
;
959 tcItem
.dwState
= TCIS_HIGHLIGHTED
;
960 ok ( SendMessage(hTab
, TCM_SETITEM
, 0, (LPARAM
) &tcItem
), "Setting new item failed.\n");
962 ok ( SendMessage(hTab
, TCM_GETITEM
, 0, (LPARAM
) &tcItem
), "Getting item failed.\n");
963 ok (tcItem
.dwState
== TCIS_HIGHLIGHTED
, "TCIS_HIGHLIGHTED should be set.\n");
964 tcItem
.mask
= TCIF_STATE
;
965 tcItem
.dwStateMask
= TCIS_BUTTONPRESSED
;
967 ok ( SendMessage(hTab
, TCM_GETITEM
, 0, (LPARAM
) &tcItem
), "Getting item failed.\n");
968 ok (tcItem
.dwState
== TCIS_BUTTONPRESSED
, "TCIS_BUTTONPRESSED should be set.\n");
970 else win_skip( "Item state mask not supported\n" );
975 static void test_getset_tooltips(void)
977 char toolTipText
[32] = "ToolTip Text Test";
981 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, nTabs
);
982 ok(hTab
!= NULL
, "Failed to create tab control\n");
984 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
986 toolTip
= create_tooltip(hTab
, toolTipText
);
987 SendMessage(hTab
, TCM_SETTOOLTIPS
, (LPARAM
) toolTip
, 0);
988 ok (toolTip
== (HWND
) SendMessage(hTab
,TCM_GETTOOLTIPS
,0,0), "ToolTip was set incorrectly.\n");
990 SendMessage(hTab
, TCM_SETTOOLTIPS
, 0, 0);
991 ok (NULL
== (HWND
) SendMessage(hTab
,TCM_GETTOOLTIPS
,0,0), "ToolTip was set incorrectly.\n");
993 ok_sequence(sequences
, TAB_SEQ_INDEX
, getset_tooltip_seq
, "Getset tooltip test sequence", TRUE
);
994 ok_sequence(sequences
, PARENT_SEQ_INDEX
, getset_tooltip_parent_seq
, "Getset tooltip test parent sequence", TRUE
);
999 static void test_misc(void)
1001 const INT nTabs
= 5;
1009 ok(parent_wnd
!= NULL
, "no parent window!\n");
1010 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1012 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, nTabs
);
1013 ok(hTab
!= NULL
, "Failed to create tab control\n");
1015 if(!winetest_interactive
)
1016 ok_sequence(sequences
, TAB_SEQ_INDEX
, add_tab_to_parent
,
1017 "Tab sequence, after adding tab control to parent", TRUE
);
1019 ok_sequence(sequences
, TAB_SEQ_INDEX
, add_tab_to_parent_interactive
,
1020 "Tab sequence, after adding tab control to parent", TRUE
);
1022 if(!winetest_interactive
)
1023 ok_sequence(sequences
, PARENT_SEQ_INDEX
, add_tab_control_parent_seq
,
1024 "Parent after sequence, adding tab control to parent", TRUE
);
1026 ok_sequence(sequences
, PARENT_SEQ_INDEX
, add_tab_control_parent_seq_interactive
,
1027 "Parent after sequence, adding tab control to parent", TRUE
);
1029 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1030 ok(SendMessage(hTab
, TCM_SETMINTABWIDTH
, 0, -1) > 0,"TCM_SETMINTABWIDTH returned < 0\n");
1031 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_sequence
, "Set minTabWidth test parent sequence", FALSE
);
1033 /* Testing GetItemCount */
1034 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1035 nTabsRetrieved
= SendMessage(hTab
, TCM_GETITEMCOUNT
, 0, 0);
1036 expect(nTabs
, nTabsRetrieved
);
1037 ok_sequence(sequences
, TAB_SEQ_INDEX
, get_item_count_seq
, "Get itemCount test sequence", FALSE
);
1038 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_sequence
, "Getset itemCount test parent sequence", FALSE
);
1040 /* Testing GetRowCount */
1041 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1042 rowCount
= SendMessage(hTab
, TCM_GETROWCOUNT
, 0, 0);
1043 expect(1, rowCount
);
1044 ok_sequence(sequences
, TAB_SEQ_INDEX
, get_row_count_seq
, "Get rowCount test sequence", FALSE
);
1045 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_sequence
, "Get rowCount test parent sequence", FALSE
);
1047 /* Testing GetItemRect */
1048 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1049 ok(SendMessage(hTab
, TCM_GETITEMRECT
, 0, (LPARAM
) &rTab
), "GetItemRect failed.\n");
1052 dpi
= GetDeviceCaps(hdc
, LOGPIXELSX
);
1053 ReleaseDC(hTab
, hdc
);
1054 CHECKSIZE(hTab
, dpi
, -1 , "Default Width");
1055 ok_sequence(sequences
, TAB_SEQ_INDEX
, get_item_rect_seq
, "Get itemRect test sequence", FALSE
);
1056 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_sequence
, "Get itemRect test parent sequence", FALSE
);
1058 DestroyWindow(hTab
);
1061 static void test_adjustrect(void)
1066 ok(parent_wnd
!= NULL
, "no parent window!\n");
1068 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, 0, 0);
1069 ok(hTab
!= NULL
, "Failed to create tab control\n");
1071 r
= SendMessage(hTab
, TCM_ADJUSTRECT
, FALSE
, 0);
1074 r
= SendMessage(hTab
, TCM_ADJUSTRECT
, TRUE
, 0);
1078 static void test_insert_focus(void)
1084 DWORD mask
= TCIF_TEXT
|TCIF_IMAGE
;
1085 static char tabName
[] = "TAB";
1086 tcNewTab
.mask
= mask
;
1087 tcNewTab
.pszText
= tabName
;
1089 ok(parent_wnd
!= NULL
, "no parent window!\n");
1091 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, mask
, 0);
1092 ok(hTab
!= NULL
, "Failed to create tab control\n");
1094 r
= SendMessage(hTab
, TCM_GETCURSEL
, 0, 0);
1097 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1099 nTabsRetrieved
= SendMessage(hTab
, TCM_GETITEMCOUNT
, 0, 0);
1100 expect(0, nTabsRetrieved
);
1102 r
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
1105 tcNewTab
.iImage
= 1;
1106 r
= SendMessage(hTab
, TCM_INSERTITEM
, 1, (LPARAM
) &tcNewTab
);
1109 nTabsRetrieved
= SendMessage(hTab
, TCM_GETITEMCOUNT
, 0, 0);
1110 expect(1, nTabsRetrieved
);
1112 r
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
1115 tcNewTab
.iImage
= 2;
1116 r
= SendMessage(hTab
, TCM_INSERTITEM
, 2, (LPARAM
) &tcNewTab
);
1119 nTabsRetrieved
= SendMessage(hTab
, TCM_GETITEMCOUNT
, 0, 0);
1120 expect(2, nTabsRetrieved
);
1122 r
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
1125 r
= SendMessage(hTab
, TCM_SETCURFOCUS
, -1, 0);
1128 r
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
1131 tcNewTab
.iImage
= 3;
1132 r
= SendMessage(hTab
, TCM_INSERTITEM
, 3, (LPARAM
) &tcNewTab
);
1135 r
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
1138 ok_sequence(sequences
, TAB_SEQ_INDEX
, insert_focus_seq
, "insert_focus test sequence", FALSE
);
1139 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_sequence
, "insert_focus parent test sequence", TRUE
);
1141 DestroyWindow(hTab
);
1144 static void test_delete_focus(void)
1150 ok(parent_wnd
!= NULL
, "no parent window!\n");
1152 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, 2);
1153 ok(hTab
!= NULL
, "Failed to create tab control\n");
1155 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1157 nTabsRetrieved
= SendMessage(hTab
, TCM_GETITEMCOUNT
, 0, 0);
1158 expect(2, nTabsRetrieved
);
1160 r
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
1163 r
= SendMessage(hTab
, TCM_DELETEITEM
, 1, 0);
1166 nTabsRetrieved
= SendMessage(hTab
, TCM_GETITEMCOUNT
, 0, 0);
1167 expect(1, nTabsRetrieved
);
1169 r
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
1172 r
= SendMessage(hTab
, TCM_SETCURFOCUS
, -1, 0);
1175 r
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
1178 r
= SendMessage(hTab
, TCM_DELETEITEM
, 0, 0);
1181 nTabsRetrieved
= SendMessage(hTab
, TCM_GETITEMCOUNT
, 0, 0);
1182 expect(0, nTabsRetrieved
);
1184 r
= SendMessage(hTab
, TCM_GETCURFOCUS
, 0, 0);
1187 ok_sequence(sequences
, TAB_SEQ_INDEX
, delete_focus_seq
, "delete_focus test sequence", FALSE
);
1188 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_sequence
, "delete_focus parent test sequence", TRUE
);
1190 DestroyWindow(hTab
);
1193 static void test_removeimage(void)
1195 static const BYTE bits
[32];
1200 HIMAGELIST himl
= ImageList_Create(16, 16, ILC_COLOR
, 3, 4);
1202 hicon
= CreateIcon(NULL
, 16, 16, 1, 1, bits
, bits
);
1203 ImageList_AddIcon(himl
, hicon
);
1204 ImageList_AddIcon(himl
, hicon
);
1205 ImageList_AddIcon(himl
, hicon
);
1207 hwTab
= create_tabcontrol(TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
);
1208 SendMessage(hwTab
, TCM_SETIMAGELIST
, 0, (LPARAM
)himl
);
1210 memset(&item
, 0, sizeof(TCITEM
));
1211 item
.mask
= TCIF_IMAGE
;
1213 for(i
= 0; i
< 3; i
++) {
1214 SendMessage(hwTab
, TCM_GETITEM
, i
, (LPARAM
)&item
);
1215 expect(i
, item
.iImage
);
1218 /* remove image middle image */
1219 SendMessage(hwTab
, TCM_REMOVEIMAGE
, 1, 0);
1220 expect(2, ImageList_GetImageCount(himl
));
1222 SendMessage(hwTab
, TCM_GETITEM
, 0, (LPARAM
)&item
);
1223 expect(0, item
.iImage
);
1225 SendMessage(hwTab
, TCM_GETITEM
, 1, (LPARAM
)&item
);
1226 expect(-1, item
.iImage
);
1228 SendMessage(hwTab
, TCM_GETITEM
, 2, (LPARAM
)&item
);
1229 expect(1, item
.iImage
);
1230 /* remove first image */
1231 SendMessage(hwTab
, TCM_REMOVEIMAGE
, 0, 0);
1232 expect(1, ImageList_GetImageCount(himl
));
1234 SendMessage(hwTab
, TCM_GETITEM
, 0, (LPARAM
)&item
);
1235 expect(-1, item
.iImage
);
1237 SendMessage(hwTab
, TCM_GETITEM
, 1, (LPARAM
)&item
);
1238 expect(-1, item
.iImage
);
1240 SendMessage(hwTab
, TCM_GETITEM
, 2, (LPARAM
)&item
);
1241 expect(0, item
.iImage
);
1242 /* remove the last one */
1243 SendMessage(hwTab
, TCM_REMOVEIMAGE
, 0, 0);
1244 expect(0, ImageList_GetImageCount(himl
));
1245 for(i
= 0; i
< 3; i
++) {
1247 SendMessage(hwTab
, TCM_GETITEM
, i
, (LPARAM
)&item
);
1248 expect(-1, item
.iImage
);
1251 DestroyWindow(hwTab
);
1252 ImageList_Destroy(himl
);
1256 static void test_delete_selection(void)
1261 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, 4);
1262 ok(hTab
!= NULL
, "Failed to create tab control\n");
1264 ret
= SendMessage(hTab
, TCM_SETCURSEL
, 3, 0);
1266 ret
= SendMessage(hTab
, TCM_GETCURSEL
, 0, 0);
1268 /* delete selected item - selection goes to -1 */
1269 ret
= SendMessage(hTab
, TCM_DELETEITEM
, 3, 0);
1272 ret
= SendMessage(hTab
, TCM_GETCURSEL
, 0, 0);
1275 DestroyWindow(hTab
);
1278 static void test_TCM_SETITEMEXTRA(void)
1283 hTab
= CreateWindowA(
1286 WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| TCS_FOCUSNEVER
| TCS_FIXEDWIDTH
,
1288 parent_wnd
, NULL
, NULL
, 0);
1290 /* zero is valid size too */
1291 ret
= SendMessageA(hTab
, TCM_SETITEMEXTRA
, 0, 0);
1294 win_skip("TCM_SETITEMEXTRA not supported\n");
1295 DestroyWindow(hTab
);
1299 ret
= SendMessageA(hTab
, TCM_SETITEMEXTRA
, -1, 0);
1300 ok(ret
== FALSE
, "got %d\n", ret
);
1302 ret
= SendMessageA(hTab
, TCM_SETITEMEXTRA
, 2, 0);
1303 ok(ret
== TRUE
, "got %d\n", ret
);
1304 DestroyWindow(hTab
);
1306 /* it's not possible to change extra data size for control with tabs */
1307 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, 4);
1308 ok(hTab
!= NULL
, "Failed to create tab control\n");
1310 ret
= SendMessageA(hTab
, TCM_SETITEMEXTRA
, 2, 0);
1311 ok(ret
== FALSE
, "got %d\n", ret
);
1312 DestroyWindow(hTab
);
1315 static void test_TCS_OWNERDRAWFIXED(void)
1318 ULONG_PTR itemdata
, itemdata2
;
1323 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
|TCS_OWNERDRAWFIXED
, TCIF_TEXT
|TCIF_IMAGE
, 4);
1324 ok(hTab
!= NULL
, "Failed to create tab control\n");
1326 ok(GetParent(hTab
) == NULL
, "got %p, expected null parent\n", GetParent(hTab
));
1328 /* set some item data */
1329 memset(&lparam
, 0xde, sizeof(LPARAM
));
1331 item
.mask
= TCIF_PARAM
;
1332 item
.lParam
= lparam
;
1333 ret
= SendMessageA(hTab
, TCM_SETITEMA
, 0, (LPARAM
)&item
);
1334 ok(ret
== TRUE
, "got %d\n", ret
);
1336 memset(&g_drawitem
, 0, sizeof(g_drawitem
));
1338 ShowWindow(hTab
, SW_SHOW
);
1339 RedrawWindow(hTab
, NULL
, 0, RDW_UPDATENOW
);
1342 memset(&itemdata
, 0xde, 4);
1343 ok(g_drawitem
.itemData
== itemdata
, "got 0x%lx, expected 0x%lx\n", g_drawitem
.itemData
, itemdata
);
1345 DestroyWindow(hTab
);
1347 /* now with custom extra data length */
1348 hTab
= CreateWindowA(
1351 WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| TCS_FOCUSNEVER
| TCS_FIXEDWIDTH
| TCS_OWNERDRAWFIXED
,
1353 parent_wnd
, NULL
, NULL
, 0);
1355 ok(GetParent(hTab
) == NULL
, "got %p, expected null parent\n", GetParent(hTab
));
1357 ret
= SendMessageA(hTab
, TCM_SETITEMEXTRA
, sizeof(LPARAM
)+1, 0);
1358 ok(ret
== TRUE
, "got %d\n", ret
);
1360 /* set some item data */
1361 memset(&lparam
, 0xde, sizeof(LPARAM
));
1362 item
.mask
= TCIF_PARAM
;
1363 item
.lParam
= lparam
;
1365 ret
= SendMessageA(hTab
, TCM_INSERTITEMA
, 0, (LPARAM
)&item
);
1366 ok(ret
== 0, "got %d\n", ret
);
1368 memset(&g_drawitem
, 0, sizeof(g_drawitem
));
1370 ShowWindow(hTab
, SW_SHOW
);
1371 RedrawWindow(hTab
, NULL
, 0, RDW_UPDATENOW
);
1373 memset(&itemdata
, 0xde, sizeof(ULONG_PTR
));
1374 ok(*(ULONG_PTR
*)g_drawitem
.itemData
== itemdata
, "got 0x%lx, expected 0x%lx\n", g_drawitem
.itemData
, itemdata
);
1376 DestroyWindow(hTab
);
1378 /* same thing, but size smaller than default */
1379 hTab
= CreateWindowA(
1382 WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| TCS_FOCUSNEVER
| TCS_FIXEDWIDTH
| TCS_OWNERDRAWFIXED
,
1384 parent_wnd
, NULL
, NULL
, 0);
1386 ok(GetParent(hTab
) == NULL
, "got %p, expected null parent\n", GetParent(hTab
));
1388 ret
= SendMessageA(hTab
, TCM_SETITEMEXTRA
, sizeof(LPARAM
)-1, 0);
1389 ok(ret
== TRUE
, "got %d\n", ret
);
1391 memset(&lparam
, 0xde, sizeof(lparam
));
1392 item
.mask
= TCIF_PARAM
;
1393 item
.lParam
= lparam
;
1395 ret
= SendMessageA(hTab
, TCM_INSERTITEMA
, 0, (LPARAM
)&item
);
1396 ok(ret
== 0, "got %d\n", ret
);
1398 memset(&g_drawitem
, 0, sizeof(g_drawitem
));
1400 ShowWindow(hTab
, SW_SHOW
);
1401 RedrawWindow(hTab
, NULL
, 0, RDW_UPDATENOW
);
1403 itemdata
= itemdata2
= 0;
1404 memset(&itemdata
, 0xde, 4);
1405 memset(&itemdata2
, 0xde, sizeof(LPARAM
)-1);
1406 ok(g_drawitem
.itemData
== itemdata
|| broken(g_drawitem
.itemData
== itemdata2
) /* win98 */,
1407 "got 0x%lx, expected 0x%lx\n", g_drawitem
.itemData
, itemdata
);
1409 DestroyWindow(hTab
);
1412 static void test_WM_CONTEXTMENU(void)
1416 hTab
= createFilledTabControl(parent_wnd
, TCS_FIXEDWIDTH
, TCIF_TEXT
|TCIF_IMAGE
, 4);
1417 ok(hTab
!= NULL
, "Failed to create tab control\n");
1419 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1421 SendMessageA(hTab
, WM_RBUTTONUP
, 0, 0);
1423 ok_sequence(sequences
, TAB_SEQ_INDEX
, rbuttonup_seq
, "WM_RBUTTONUP response sequence", FALSE
);
1425 DestroyWindow(hTab
);
1428 struct tabcreate_style
{
1433 static const struct tabcreate_style create_styles
[] =
1435 { WS_CHILD
|TCS_BOTTOM
|TCS_VERTICAL
, WS_CHILD
|WS_CLIPSIBLINGS
|TCS_BOTTOM
|TCS_VERTICAL
|TCS_MULTILINE
},
1436 { WS_CHILD
|TCS_VERTICAL
, WS_CHILD
|WS_CLIPSIBLINGS
|TCS_VERTICAL
|TCS_MULTILINE
},
1440 static void test_create(void)
1442 const struct tabcreate_style
*ptr
= create_styles
;
1448 hTab
= CreateWindowA(WC_TABCONTROLA
, "TestTab", ptr
->style
,
1449 10, 10, 300, 100, parent_wnd
, NULL
, NULL
, 0);
1450 style
= GetWindowLongA(hTab
, GWL_STYLE
);
1451 ok(style
== ptr
->act_style
, "expected style 0x%08x, got style 0x%08x\n", ptr
->act_style
, style
);
1453 DestroyWindow(hTab
);
1462 lstrcpyA(logfont
.lfFaceName
, "Arial");
1463 memset(&logfont
, 0, sizeof(logfont
));
1464 logfont
.lfHeight
= -12;
1465 logfont
.lfWeight
= FW_NORMAL
;
1466 logfont
.lfCharSet
= ANSI_CHARSET
;
1467 hFont
= CreateFontIndirectA(&logfont
);
1469 InitCommonControls();
1473 init_msg_sequences(sequences
, NUM_MSG_SEQUENCES
);
1475 parent_wnd
= createParentWindow();
1476 ok(parent_wnd
!= NULL
, "Failed to create parent window!\n");
1480 test_extendedstyle();
1481 test_unicodeformat();
1483 test_getset_tooltips();
1488 test_insert_focus();
1489 test_delete_focus();
1490 test_delete_selection();
1492 test_TCM_SETITEMEXTRA();
1493 test_TCS_OWNERDRAWFIXED();
1494 test_WM_CONTEXTMENU();
1497 DestroyWindow(parent_wnd
);