2 * Copyright 2005 Dmitry Timoshkov
3 * Copyright 2008 Jason Edmeades
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "resources.h"
25 #include "wine/test.h"
30 #define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
38 static struct msg_sequence
*sequences
[NUM_MSG_SEQUENCES
];
40 static void test_create_tooltip(BOOL is_v6
)
43 DWORD style
, exp_style
;
45 parent
= CreateWindowExA(0, "static", NULL
, WS_POPUP
,
48 ok(parent
!= NULL
, "failed to create parent wnd\n");
50 hwnd
= CreateWindowExA(0, TOOLTIPS_CLASSA
, NULL
, 0x7fffffff | WS_POPUP
,
52 parent
, NULL
, NULL
, 0);
53 ok(hwnd
!= NULL
, "failed to create tooltip wnd\n");
55 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
56 exp_style
= 0x7fffffff | WS_POPUP
;
57 exp_style
&= ~(WS_CHILD
| WS_MAXIMIZE
| WS_BORDER
| WS_DLGFRAME
);
58 ok(style
== exp_style
|| broken(style
== (exp_style
| WS_BORDER
)), /* nt4 */
59 "wrong style %08x/%08x\n", style
, exp_style
);
63 hwnd
= CreateWindowExA(0, TOOLTIPS_CLASSA
, NULL
, 0,
65 parent
, NULL
, NULL
, 0);
66 ok(hwnd
!= NULL
, "failed to create tooltip wnd\n");
68 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
69 exp_style
= WS_POPUP
| WS_CLIPSIBLINGS
;
71 exp_style
|= WS_BORDER
;
73 ok(style
== exp_style
|| broken(style
== (exp_style
| WS_BORDER
)) /* XP */,
74 "Unexpected window style %#x.\n", style
);
78 DestroyWindow(parent
);
81 /* try to make sure pending X events have been processed before continuing */
82 static void flush_events(int waitTime
)
86 DWORD time
= GetTickCount() + waitTime
;
90 if (MsgWaitForMultipleObjects( 0, NULL
, FALSE
, min(100,diff
), QS_ALLEVENTS
) == WAIT_TIMEOUT
) break;
91 while (PeekMessageA( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageA( &msg
);
92 diff
= time
- GetTickCount();
97 static LRESULT CD_Result
;
100 #define TEST_CDDS_PREPAINT 0x00000001
101 #define TEST_CDDS_POSTPAINT 0x00000002
102 #define TEST_CDDS_PREERASE 0x00000004
103 #define TEST_CDDS_POSTERASE 0x00000008
104 #define TEST_CDDS_ITEMPREPAINT 0x00000010
105 #define TEST_CDDS_ITEMPOSTPAINT 0x00000020
106 #define TEST_CDDS_ITEMPREERASE 0x00000040
107 #define TEST_CDDS_ITEMPOSTERASE 0x00000080
108 #define TEST_CDDS_SUBITEM 0x00000100
110 static LRESULT CALLBACK
custom_draw_wnd_proc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
119 if (((NMHDR
*)lParam
)->code
== NM_CUSTOMDRAW
) {
120 NMTTCUSTOMDRAW
*ttcd
= (NMTTCUSTOMDRAW
*) lParam
;
121 ok(ttcd
->nmcd
.hdr
.hwndFrom
== g_hwnd
, "Unexpected hwnd source %p (%p)\n",
122 ttcd
->nmcd
.hdr
.hwndFrom
, g_hwnd
);
123 ok(ttcd
->nmcd
.hdr
.idFrom
== 0x1234ABCD, "Unexpected id %x\n", (int)ttcd
->nmcd
.hdr
.idFrom
);
125 switch (ttcd
->nmcd
.dwDrawStage
) {
126 case CDDS_PREPAINT
: CD_Stages
|= TEST_CDDS_PREPAINT
; break;
127 case CDDS_POSTPAINT
: CD_Stages
|= TEST_CDDS_POSTPAINT
; break;
128 case CDDS_PREERASE
: CD_Stages
|= TEST_CDDS_PREERASE
; break;
129 case CDDS_POSTERASE
: CD_Stages
|= TEST_CDDS_POSTERASE
; break;
130 case CDDS_ITEMPREPAINT
: CD_Stages
|= TEST_CDDS_ITEMPREPAINT
; break;
131 case CDDS_ITEMPOSTPAINT
: CD_Stages
|= TEST_CDDS_ITEMPOSTPAINT
; break;
132 case CDDS_ITEMPREERASE
: CD_Stages
|= TEST_CDDS_ITEMPREERASE
; break;
133 case CDDS_ITEMPOSTERASE
: CD_Stages
|= TEST_CDDS_ITEMPOSTERASE
; break;
134 case CDDS_SUBITEM
: CD_Stages
|= TEST_CDDS_SUBITEM
; break;
135 default: CD_Stages
= -1;
138 if (ttcd
->nmcd
.dwDrawStage
== CDDS_PREPAINT
) return CD_Result
;
143 return DefWindowProcA(hWnd
, msg
, wParam
, lParam
);
149 static void test_customdraw(void) {
151 LRESULT FirstReturnValue
;
153 } expectedResults
[] = {
154 /* Valid notification responses */
155 {CDRF_DODEFAULT
, TEST_CDDS_PREPAINT
},
156 {CDRF_SKIPDEFAULT
, TEST_CDDS_PREPAINT
},
157 {CDRF_NOTIFYPOSTPAINT
, TEST_CDDS_PREPAINT
| TEST_CDDS_POSTPAINT
},
159 /* Invalid notification responses */
160 {CDRF_NOTIFYITEMDRAW
, TEST_CDDS_PREPAINT
},
161 {CDRF_NOTIFYPOSTERASE
, TEST_CDDS_PREPAINT
},
162 {CDRF_NEWFONT
, TEST_CDDS_PREPAINT
}
165 DWORD iterationNumber
;
170 /* Create a class to use the custom draw wndproc */
171 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
174 wc
.hInstance
= GetModuleHandleA(NULL
);
176 wc
.hCursor
= LoadCursorA(NULL
, (LPCSTR
)IDC_ARROW
);
177 wc
.hbrBackground
= GetSysColorBrush(COLOR_WINDOW
);
178 wc
.lpszMenuName
= NULL
;
179 wc
.lpszClassName
= "CustomDrawClass";
180 wc
.lpfnWndProc
= custom_draw_wnd_proc
;
183 GetCursorPos(&orig_pos
);
185 for (iterationNumber
= 0;
186 iterationNumber
< ARRAY_SIZE(expectedResults
);
189 HWND parent
, hwndTip
;
191 TTTOOLINFOA toolInfo
= { 0 };
193 /* Create a main window */
194 parent
= CreateWindowExA(0, "CustomDrawClass", NULL
,
195 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
|
196 WS_MAXIMIZEBOX
| WS_VISIBLE
,
199 NULL
, NULL
, NULL
, 0);
200 ok(parent
!= NULL
, "%d: Creation of main window failed\n", iterationNumber
);
203 ShowWindow(parent
, SW_SHOWNORMAL
);
207 hwndTip
= CreateWindowExA(WS_EX_TOPMOST
, TOOLTIPS_CLASSA
,
208 NULL
, TTS_NOPREFIX
| TTS_ALWAYSTIP
,
209 CW_USEDEFAULT
, CW_USEDEFAULT
,
210 CW_USEDEFAULT
, CW_USEDEFAULT
,
211 parent
, NULL
, GetModuleHandleA(NULL
), 0);
212 ok(hwndTip
!= NULL
, "%d: Creation of tooltip window failed\n", iterationNumber
);
214 /* Set up parms for the wndproc to handle */
216 CD_Result
= expectedResults
[iterationNumber
].FirstReturnValue
;
219 /* Make it topmost, as per the MSDN */
220 SetWindowPos(hwndTip
, HWND_TOPMOST
, 0, 0, 0, 0,
221 SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
);
224 toolInfo
.cbSize
= TTTOOLINFOA_V1_SIZE
;
225 toolInfo
.hwnd
= parent
;
226 toolInfo
.hinst
= GetModuleHandleA(NULL
);
227 toolInfo
.uFlags
= TTF_SUBCLASS
;
228 toolInfo
.uId
= 0x1234ABCD;
229 toolInfo
.lpszText
= (LPSTR
)"This is a test tooltip";
230 toolInfo
.lParam
= 0xdeadbeef;
231 GetClientRect (parent
, &toolInfo
.rect
);
232 ret
= SendMessageA(hwndTip
, TTM_ADDTOOLA
, 0, (LPARAM
)&toolInfo
);
233 ok(ret
, "%d: Failed to add the tool.\n", iterationNumber
);
235 /* Make tooltip appear quickly */
236 SendMessageA(hwndTip
, TTM_SETDELAYTIME
, TTDT_INITIAL
, MAKELPARAM(1,0));
238 /* Put cursor inside window, tooltip will appear immediately */
239 GetWindowRect( parent
, &rect
);
240 SetCursorPos( (rect
.left
+ rect
.right
) / 2, (rect
.top
+ rect
.bottom
) / 2 );
245 /* Check CustomDraw results */
246 ok(CD_Stages
== expectedResults
[iterationNumber
].ExpectedCalls
||
247 broken(CD_Stages
== (expectedResults
[iterationNumber
].ExpectedCalls
& ~TEST_CDDS_POSTPAINT
)), /* nt4 */
248 "%d: CustomDraw stages %x, expected %x\n", iterationNumber
, CD_Stages
,
249 expectedResults
[iterationNumber
].ExpectedCalls
);
252 ret
= SendMessageA(hwndTip
, TTM_GETCURRENTTOOLA
, 0, 0);
253 ok(ret
, "%d: Failed to get current tool %#lx.\n", iterationNumber
, ret
);
255 memset(&toolInfo
, 0xcc, sizeof(toolInfo
));
256 toolInfo
.cbSize
= sizeof(toolInfo
);
257 toolInfo
.lpszText
= NULL
;
258 toolInfo
.lpReserved
= (void *)0xdeadbeef;
259 SendMessageA(hwndTip
, TTM_GETCURRENTTOOLA
, 0, (LPARAM
)&toolInfo
);
260 ok(toolInfo
.hwnd
== parent
, "%d: Unexpected hwnd %p.\n", iterationNumber
, toolInfo
.hwnd
);
261 ok(toolInfo
.hinst
== GetModuleHandleA(NULL
), "%d: Unexpected hinst %p.\n", iterationNumber
, toolInfo
.hinst
);
262 ok(toolInfo
.uId
== 0x1234abcd, "%d: Unexpected uId %lx.\n", iterationNumber
, toolInfo
.uId
);
263 ok(toolInfo
.lParam
== 0, "%d: Unexpected lParam %lx.\n", iterationNumber
, toolInfo
.lParam
);
264 ok(toolInfo
.lpReserved
== (void *)0xdeadbeef, "%d: Unexpected lpReserved %p.\n", iterationNumber
, toolInfo
.lpReserved
);
267 DestroyWindow(hwndTip
);
268 DestroyWindow(parent
);
271 SetCursorPos(orig_pos
.x
, orig_pos
.y
);
274 static const CHAR testcallbackA
[] = "callback";
276 static RECT g_ttip_rect
;
277 static LRESULT WINAPI
parent_wnd_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
279 static LONG defwndproc_counter
= 0;
283 if (message
== WM_NOTIFY
&& lParam
)
285 NMTTDISPINFOA
*ttnmdi
= (NMTTDISPINFOA
*)lParam
;
286 NMHDR
*hdr
= (NMHDR
*)lParam
;
289 if (hdr
->code
!= NM_CUSTOMDRAW
)
291 msg
.message
= message
;
292 msg
.flags
= sent
|wparam
|lparam
;
293 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
297 add_message(sequences
, PARENT_SEQ_INDEX
, &msg
);
302 case TTN_GETDISPINFOA
:
303 lstrcpyA(ttnmdi
->lpszText
, testcallbackA
);
306 GetWindowRect(hdr
->hwndFrom
, &rect
);
307 ok(!EqualRect(&g_ttip_rect
, &rect
), "Unexpected window rectangle.\n");
312 defwndproc_counter
++;
313 if (IsWindowUnicode(hwnd
))
314 ret
= DefWindowProcW(hwnd
, message
, wParam
, lParam
);
316 ret
= DefWindowProcA(hwnd
, message
, wParam
, lParam
);
317 defwndproc_counter
--;
322 static void register_parent_wnd_class(void)
328 cls
.lpfnWndProc
= parent_wnd_proc
;
331 cls
.hInstance
= GetModuleHandleA(NULL
);
333 cls
.hCursor
= LoadCursorA(0, (LPCSTR
)IDC_ARROW
);
334 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
335 cls
.lpszMenuName
= NULL
;
336 cls
.lpszClassName
= "Tooltips test parent class";
337 ret
= RegisterClassA(&cls
);
338 ok(ret
, "Failed to register test parent class.\n");
341 static HWND
create_parent_window(void)
343 return CreateWindowExA(0, "Tooltips test parent class",
344 "Tooltips test parent window",
345 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
|
346 WS_MAXIMIZEBOX
| WS_VISIBLE
,
348 GetDesktopWindow(), NULL
, GetModuleHandleA(NULL
), NULL
);
351 static void test_gettext(void)
353 static const CHAR testtip2A
[] = "testtip\ttest2";
354 static const CHAR testtipA
[] = "testtip";
356 TTTOOLINFOA toolinfoA
;
357 TTTOOLINFOW toolinfoW
;
360 WCHAR bufW
[10] = { 0 };
363 notify
= create_parent_window();
364 ok(notify
!= NULL
, "Expected notification window to be created\n");
366 /* For bug 14790 - lpszText is NULL */
367 hwnd
= CreateWindowExA(0, TOOLTIPS_CLASSA
, NULL
, 0,
369 NULL
, NULL
, NULL
, 0);
370 ok(hwnd
!= NULL
, "failed to create tooltip wnd\n");
372 /* use sizeof(TTTOOLINFOA) instead of TTTOOLINFOA_V1_SIZE so that adding it fails on Win9x */
373 /* otherwise it crashes on the NULL lpszText */
374 toolinfoA
.cbSize
= sizeof(TTTOOLINFOA
);
375 toolinfoA
.hwnd
= NULL
;
376 toolinfoA
.hinst
= GetModuleHandleA(NULL
);
377 toolinfoA
.uFlags
= 0;
378 toolinfoA
.uId
= 0x1234ABCD;
379 toolinfoA
.lpszText
= NULL
;
380 toolinfoA
.lParam
= 0xdeadbeef;
381 GetClientRect(hwnd
, &toolinfoA
.rect
);
382 r
= SendMessageA(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&toolinfoA
);
383 ok(r
, "got %ld\n", r
);
385 toolinfoA
.hwnd
= NULL
;
386 toolinfoA
.uId
= 0x1234abcd;
387 toolinfoA
.lpszText
= bufA
;
388 r
= SendMessageA(hwnd
, TTM_GETTEXTA
, 0, (LPARAM
)&toolinfoA
);
389 ok(!r
, "got %ld\n", r
);
390 ok(!*toolinfoA
.lpszText
, "lpszText should be empty, got %s\n", toolinfoA
.lpszText
);
392 toolinfoA
.lpszText
= bufA
;
393 r
= SendMessageA(hwnd
, TTM_GETTOOLINFOA
, 0, (LPARAM
)&toolinfoA
);
395 ok(!r
, "got %ld\n", r
);
396 ok(toolinfoA
.lpszText
== NULL
, "expected NULL, got %p\n", toolinfoA
.lpszText
);
398 /* NULL hinst, valid resource id for text */
399 toolinfoA
.cbSize
= sizeof(TTTOOLINFOA
);
400 toolinfoA
.hwnd
= NULL
;
401 toolinfoA
.hinst
= NULL
;
402 toolinfoA
.uFlags
= 0;
403 toolinfoA
.uId
= 0x1233abcd;
404 toolinfoA
.lpszText
= MAKEINTRESOURCEA(IDS_TBADD1
);
405 toolinfoA
.lParam
= 0xdeadbeef;
406 GetClientRect(hwnd
, &toolinfoA
.rect
);
407 r
= SendMessageA(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&toolinfoA
);
408 ok(r
, "failed to add a tool\n");
410 toolinfoA
.hwnd
= NULL
;
411 toolinfoA
.uId
= 0x1233abcd;
412 toolinfoA
.lpszText
= bufA
;
413 r
= SendMessageA(hwnd
, TTM_GETTEXTA
, 0, (LPARAM
)&toolinfoA
);
414 ok(!r
, "got %ld\n", r
);
415 ok(!strcmp(toolinfoA
.lpszText
, "abc"), "got wrong text, %s\n", toolinfoA
.lpszText
);
417 toolinfoA
.hinst
= (HINSTANCE
)0xdeadbee;
418 r
= SendMessageA(hwnd
, TTM_GETTOOLINFOA
, 0, (LPARAM
)&toolinfoA
);
420 ok(!r
, "got %ld\n", r
);
421 ok(toolinfoA
.hinst
== NULL
, "expected NULL, got %p\n", toolinfoA
.hinst
);
423 r
= SendMessageA(hwnd
, TTM_DELTOOLA
, 0, (LPARAM
)&toolinfoA
);
424 ok(!r
, "got %ld\n", r
);
426 /* add another tool with text */
427 toolinfoA
.cbSize
= sizeof(TTTOOLINFOA
);
428 toolinfoA
.hwnd
= NULL
;
429 toolinfoA
.hinst
= GetModuleHandleA(NULL
);
430 toolinfoA
.uFlags
= 0;
431 toolinfoA
.uId
= 0x1235ABCD;
432 strcpy(bufA
, testtipA
);
433 toolinfoA
.lpszText
= bufA
;
434 toolinfoA
.lParam
= 0xdeadbeef;
435 GetClientRect(hwnd
, &toolinfoA
.rect
);
436 r
= SendMessageA(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&toolinfoA
);
437 ok(r
, "Adding the tool to the tooltip failed\n");
439 length
= SendMessageA(hwnd
, WM_GETTEXTLENGTH
, 0, 0);
440 ok(length
== 0, "Expected 0, got %d\n", length
);
442 toolinfoA
.hwnd
= NULL
;
443 toolinfoA
.uId
= 0x1235abcd;
444 toolinfoA
.lpszText
= bufA
;
445 r
= SendMessageA(hwnd
, TTM_GETTEXTA
, 0, (LPARAM
)&toolinfoA
);
446 ok(!r
, "got %ld\n", r
);
447 ok(!strcmp(toolinfoA
.lpszText
, testtipA
), "expected %s, got %p\n", testtipA
, toolinfoA
.lpszText
);
449 memset(bufA
, 0x1f, sizeof(bufA
));
450 toolinfoA
.lpszText
= bufA
;
451 r
= SendMessageA(hwnd
, TTM_GETTOOLINFOA
, 0, (LPARAM
)&toolinfoA
);
453 ok(!r
, "got %ld\n", r
);
454 ok(!strcmp(toolinfoA
.lpszText
, testtipA
), "expected %s, got %p\n", testtipA
, toolinfoA
.lpszText
);
456 length
= SendMessageA(hwnd
, WM_GETTEXTLENGTH
, 0, 0);
457 ok(length
== 0, "Expected 0, got %d\n", length
);
459 /* add another with callback text */
460 toolinfoA
.cbSize
= sizeof(TTTOOLINFOA
);
461 toolinfoA
.hwnd
= notify
;
462 toolinfoA
.hinst
= GetModuleHandleA(NULL
);
463 toolinfoA
.uFlags
= 0;
464 toolinfoA
.uId
= 0x1236ABCD;
465 toolinfoA
.lpszText
= LPSTR_TEXTCALLBACKA
;
466 toolinfoA
.lParam
= 0xdeadbeef;
467 GetClientRect(hwnd
, &toolinfoA
.rect
);
468 r
= SendMessageA(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&toolinfoA
);
469 ok(r
, "Adding the tool to the tooltip failed\n");
471 toolinfoA
.hwnd
= notify
;
472 toolinfoA
.uId
= 0x1236abcd;
473 toolinfoA
.lpszText
= bufA
;
474 r
= SendMessageA(hwnd
, TTM_GETTEXTA
, 0, (LPARAM
)&toolinfoA
);
475 ok(!r
, "got %ld\n", r
);
476 ok(!strcmp(toolinfoA
.lpszText
, testcallbackA
), "lpszText should be an (%s) string\n", testcallbackA
);
478 toolinfoA
.lpszText
= bufA
;
479 r
= SendMessageA(hwnd
, TTM_GETTOOLINFOA
, 0, (LPARAM
)&toolinfoA
);
481 ok(!r
, "got %ld\n", r
);
482 ok(toolinfoA
.lpszText
== LPSTR_TEXTCALLBACKA
, "expected LPSTR_TEXTCALLBACKA, got %p\n", toolinfoA
.lpszText
);
485 DestroyWindow(notify
);
487 hwnd
= CreateWindowExW(0, TOOLTIPS_CLASSW
, NULL
, 0,
489 NULL
, NULL
, NULL
, 0);
490 ok(hwnd
!= NULL
, "failed to create tooltip wnd\n");
492 toolinfoW
.cbSize
= TTTOOLINFOW_V2_SIZE
+ 1;
493 toolinfoW
.hwnd
= NULL
;
494 toolinfoW
.hinst
= GetModuleHandleA(NULL
);
495 toolinfoW
.uFlags
= 0;
496 toolinfoW
.uId
= 0x1234ABCD;
497 toolinfoW
.lpszText
= NULL
;
498 toolinfoW
.lParam
= 0xdeadbeef;
499 GetClientRect(hwnd
, &toolinfoW
.rect
);
500 r
= SendMessageW(hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&toolinfoW
);
501 /* Wine currently checks for V3 structure size, which matches what V6 control does.
502 Older implementation was never updated to support lpReserved field. */
504 ok(!r
, "Adding the tool to the tooltip succeeded!\n");
506 if (0) /* crashes on NT4 */
508 toolinfoW
.hwnd
= NULL
;
509 toolinfoW
.uId
= 0x1234ABCD;
510 toolinfoW
.lpszText
= bufW
;
511 SendMessageW(hwnd
, TTM_GETTEXTW
, 0, (LPARAM
)&toolinfoW
);
512 ok(toolinfoW
.lpszText
[0] == 0, "lpszText should be an empty string\n");
515 /* text with embedded tabs */
516 toolinfoA
.cbSize
= sizeof(TTTOOLINFOA
);
517 toolinfoA
.hwnd
= NULL
;
518 toolinfoA
.hinst
= GetModuleHandleA(NULL
);
519 toolinfoA
.uFlags
= 0;
520 toolinfoA
.uId
= 0x1235abce;
521 strcpy(bufA
, testtip2A
);
522 toolinfoA
.lpszText
= bufA
;
523 toolinfoA
.lParam
= 0xdeadbeef;
524 GetClientRect(hwnd
, &toolinfoA
.rect
);
525 r
= SendMessageA(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&toolinfoA
);
526 ok(r
, "got %ld\n", r
);
528 toolinfoA
.hwnd
= NULL
;
529 toolinfoA
.uId
= 0x1235abce;
530 toolinfoA
.lpszText
= bufA
;
531 r
= SendMessageA(hwnd
, TTM_GETTEXTA
, 0, (LPARAM
)&toolinfoA
);
532 ok(!r
, "got %ld\n", r
);
533 ok(!strcmp(toolinfoA
.lpszText
, testtipA
), "expected %s, got %s\n", testtipA
, toolinfoA
.lpszText
);
535 /* enable TTS_NOPREFIX, original text is retained */
536 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
537 SetWindowLongA(hwnd
, GWL_STYLE
, style
| TTS_NOPREFIX
);
539 toolinfoA
.hwnd
= NULL
;
540 toolinfoA
.uId
= 0x1235abce;
541 toolinfoA
.lpszText
= bufA
;
542 r
= SendMessageA(hwnd
, TTM_GETTEXTA
, 0, (LPARAM
)&toolinfoA
);
543 ok(!r
, "got %ld\n", r
);
544 ok(!strcmp(toolinfoA
.lpszText
, testtip2A
), "expected %s, got %s\n", testtip2A
, toolinfoA
.lpszText
);
549 static void test_ttm_gettoolinfo(void)
556 hwnd
= CreateWindowExA(0, TOOLTIPS_CLASSA
, NULL
, 0, 10, 10, 300, 100, NULL
, NULL
, NULL
, 0);
557 ok(hwnd
!= NULL
, "Failed to create tooltip control.\n");
559 ti
.cbSize
= TTTOOLINFOA_V2_SIZE
;
561 ti
.hinst
= GetModuleHandleA(NULL
);
565 ti
.lParam
= 0x1abe11ed;
566 GetClientRect(hwnd
, &ti
.rect
);
567 r
= SendMessageA(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
);
568 ok(r
, "Adding the tool to the tooltip failed\n");
570 ti
.cbSize
= TTTOOLINFOA_V2_SIZE
;
571 ti
.lParam
= 0xaaaaaaaa;
572 r
= SendMessageA(hwnd
, TTM_GETTOOLINFOA
, 0, (LPARAM
)&ti
);
573 ok(r
, "Getting tooltip info failed\n");
574 ok(0x1abe11ed == ti
.lParam
||
575 broken(0x1abe11ed != ti
.lParam
), /* comctl32 < 5.81 */
576 "Expected 0x1abe11ed, got %lx\n", ti
.lParam
);
578 tiW
.cbSize
= TTTOOLINFOW_V2_SIZE
;
580 tiW
.uId
= 0x1234ABCD;
581 tiW
.lParam
= 0xaaaaaaaa;
583 r
= SendMessageA(hwnd
, TTM_GETTOOLINFOW
, 0, (LPARAM
)&tiW
);
584 ok(r
, "Getting tooltip info failed\n");
585 ok(0x1abe11ed == tiW
.lParam
||
586 broken(0x1abe11ed != tiW
.lParam
), /* comctl32 < 5.81 */
587 "Expected 0x1abe11ed, got %lx\n", tiW
.lParam
);
589 ti
.cbSize
= TTTOOLINFOA_V2_SIZE
;
591 ti
.lParam
= 0x55555555;
592 SendMessageA(hwnd
, TTM_SETTOOLINFOA
, 0, (LPARAM
)&ti
);
594 ti
.cbSize
= TTTOOLINFOA_V2_SIZE
;
595 ti
.lParam
= 0xdeadbeef;
596 r
= SendMessageA(hwnd
, TTM_GETTOOLINFOA
, 0, (LPARAM
)&ti
);
597 ok(r
, "Getting tooltip info failed\n");
598 ok(0x55555555 == ti
.lParam
||
599 broken(0x55555555 != ti
.lParam
), /* comctl32 < 5.81 */
600 "Expected 0x55555555, got %lx\n", ti
.lParam
);
604 /* 1. test size parameter validation rules (ansi messages) */
605 hwnd
= CreateWindowExA(0, TOOLTIPS_CLASSA
, NULL
, 0,
607 NULL
, NULL
, NULL
, 0);
609 ti
.cbSize
= TTTOOLINFOA_V1_SIZE
- 1;
611 ti
.hinst
= GetModuleHandleA(NULL
);
615 ti
.lParam
= 0xdeadbeef;
616 GetClientRect(hwnd
, &ti
.rect
);
617 r
= SendMessageA(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
);
618 ok(r
, "Adding the tool to the tooltip failed\n");
619 r
= SendMessageA(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
622 ti
.cbSize
= TTTOOLINFOA_V1_SIZE
- 1;
625 SendMessageA(hwnd
, TTM_DELTOOLA
, 0, (LPARAM
)&ti
);
626 r
= SendMessageA(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
629 ti
.cbSize
= TTTOOLINFOA_V2_SIZE
- 1;
631 ti
.hinst
= GetModuleHandleA(NULL
);
635 ti
.lParam
= 0xdeadbeef;
636 GetClientRect(hwnd
, &ti
.rect
);
637 r
= SendMessageA(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
);
638 ok(r
, "Adding the tool to the tooltip failed\n");
639 r
= SendMessageA(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
642 ti
.cbSize
= TTTOOLINFOA_V2_SIZE
- 1;
645 SendMessageA(hwnd
, TTM_DELTOOLA
, 0, (LPARAM
)&ti
);
646 r
= SendMessageA(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
649 ti
.cbSize
= TTTOOLINFOA_V2_SIZE
+ 1;
651 ti
.hinst
= GetModuleHandleA(NULL
);
655 ti
.lParam
= 0xdeadbeef;
656 GetClientRect(hwnd
, &ti
.rect
);
657 r
= SendMessageA(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
);
658 ok(r
, "Adding the tool to the tooltip failed\n");
659 r
= SendMessageA(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
662 ti
.cbSize
= TTTOOLINFOA_V2_SIZE
+ 1;
665 SendMessageA(hwnd
, TTM_DELTOOLA
, 0, (LPARAM
)&ti
);
666 r
= SendMessageA(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
671 /* 2. test size parameter validation rules (w-messages) */
672 hwnd
= CreateWindowExW(0, TOOLTIPS_CLASSW
, NULL
, 0,
674 NULL
, NULL
, NULL
, 0);
675 ok(hwnd
!= NULL
, "Failed to create tooltip window.\n");
677 tiW
.cbSize
= TTTOOLINFOW_V1_SIZE
- 1;
679 tiW
.hinst
= GetModuleHandleA(NULL
);
681 tiW
.uId
= 0x1234ABCD;
683 tiW
.lParam
= 0xdeadbeef;
684 GetClientRect(hwnd
, &tiW
.rect
);
685 r
= SendMessageW(hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&tiW
);
686 ok(r
, "Adding the tool to the tooltip failed\n");
687 r
= SendMessageW(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
690 tiW
.cbSize
= TTTOOLINFOW_V1_SIZE
- 1;
692 tiW
.uId
= 0x1234ABCD;
693 SendMessageW(hwnd
, TTM_DELTOOLW
, 0, (LPARAM
)&tiW
);
694 r
= SendMessageW(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
697 tiW
.cbSize
= TTTOOLINFOW_V2_SIZE
- 1;
699 tiW
.hinst
= GetModuleHandleA(NULL
);
701 tiW
.uId
= 0x1234ABCD;
703 tiW
.lParam
= 0xdeadbeef;
704 GetClientRect(hwnd
, &tiW
.rect
);
705 r
= SendMessageW(hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&tiW
);
706 ok(r
, "Adding the tool to the tooltip failed\n");
707 r
= SendMessageW(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
710 tiW
.cbSize
= TTTOOLINFOW_V2_SIZE
- 1;
712 tiW
.uId
= 0x1234ABCD;
713 SendMessageW(hwnd
, TTM_DELTOOLW
, 0, (LPARAM
)&tiW
);
714 r
= SendMessageW(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
717 tiW
.cbSize
= TTTOOLINFOW_V2_SIZE
+ 1;
719 tiW
.hinst
= GetModuleHandleA(NULL
);
721 tiW
.uId
= 0x1234ABCD;
723 tiW
.lParam
= 0xdeadbeef;
724 GetClientRect(hwnd
, &tiW
.rect
);
725 r
= SendMessageW(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&tiW
);
726 ok(r
, "Adding the tool to the tooltip failed\n");
727 r
= SendMessageW(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
729 /* looks like TTM_DELTOOLW doesn't work with invalid size */
730 tiW
.cbSize
= TTTOOLINFOW_V2_SIZE
+ 1;
732 tiW
.uId
= 0x1234ABCD;
733 SendMessageW(hwnd
, TTM_DELTOOLW
, 0, (LPARAM
)&tiW
);
734 r
= SendMessageW(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
737 tiW
.cbSize
= TTTOOLINFOW_V2_SIZE
;
739 tiW
.uId
= 0x1234ABCD;
740 SendMessageW(hwnd
, TTM_DELTOOLW
, 0, (LPARAM
)&tiW
);
741 r
= SendMessageW(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
747 static void test_longtextA(void)
749 static const char longtextA
[] =
750 "According to MSDN, TTM_ENUMTOOLS claims that TOOLINFO's lpszText is maximum "
751 "80 chars including null. In fact, the buffer is not null-terminated.";
753 TTTOOLINFOA toolinfoA
= { 0 };
757 hwnd
= CreateWindowExA(0, TOOLTIPS_CLASSA
, NULL
, 0,
759 NULL
, NULL
, NULL
, 0);
760 toolinfoA
.cbSize
= sizeof(TTTOOLINFOA
);
761 toolinfoA
.hwnd
= NULL
;
762 toolinfoA
.hinst
= GetModuleHandleA(NULL
);
763 toolinfoA
.uFlags
= 0;
764 toolinfoA
.uId
= 0x1234ABCD;
765 strcpy(bufA
, longtextA
);
766 toolinfoA
.lpszText
= bufA
;
767 toolinfoA
.lParam
= 0xdeadbeef;
768 GetClientRect(hwnd
, &toolinfoA
.rect
);
769 r
= SendMessageA(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&toolinfoA
);
773 memset(bufA
, 0, sizeof(bufA
));
774 toolinfoA
.hwnd
= NULL
;
775 toolinfoA
.uId
= 0xABCD1234;
776 toolinfoA
.lpszText
= bufA
;
777 SendMessageA(hwnd
, TTM_ENUMTOOLSA
, 0, (LPARAM
)&toolinfoA
);
778 textlen
= lstrlenA(toolinfoA
.lpszText
);
779 ok(textlen
== 80, "lpszText has %d chars\n", textlen
);
780 ok(toolinfoA
.uId
== 0x1234ABCD,
781 "uId should be retrieved, got %p\n", (void*)toolinfoA
.uId
);
783 memset(bufA
, 0, sizeof(bufA
));
784 toolinfoA
.hwnd
= NULL
;
785 toolinfoA
.uId
= 0x1234ABCD;
786 toolinfoA
.lpszText
= bufA
;
787 SendMessageA(hwnd
, TTM_GETTOOLINFOA
, 0, (LPARAM
)&toolinfoA
);
788 textlen
= lstrlenA(toolinfoA
.lpszText
);
789 ok(textlen
== 80, "lpszText has %d chars\n", textlen
);
791 memset(bufA
, 0, sizeof(bufA
));
792 toolinfoA
.hwnd
= NULL
;
793 toolinfoA
.uId
= 0x1234ABCD;
794 toolinfoA
.lpszText
= bufA
;
795 SendMessageA(hwnd
, TTM_GETTEXTA
, 0, (LPARAM
)&toolinfoA
);
796 textlen
= lstrlenA(toolinfoA
.lpszText
);
797 ok(textlen
== 80, "lpszText has %d chars\n", textlen
);
803 static void test_longtextW(void)
805 static const char longtextA
[] =
806 "According to MSDN, TTM_ENUMTOOLS claims that TOOLINFO's lpszText is maximum "
807 "80 chars including null. Actually, this is not applied for wide version.";
809 TTTOOLINFOW toolinfoW
= { 0 };
814 hwnd
= CreateWindowExW(0, TOOLTIPS_CLASSW
, NULL
, 0,
816 NULL
, NULL
, NULL
, 0);
817 ok(hwnd
!= NULL
, "Failed to create tooltip window.\n");
819 toolinfoW
.cbSize
= TTTOOLINFOW_V2_SIZE
;
820 toolinfoW
.hwnd
= NULL
;
821 toolinfoW
.hinst
= GetModuleHandleW(NULL
);
822 toolinfoW
.uFlags
= 0;
823 toolinfoW
.uId
= 0x1234ABCD;
824 MultiByteToWideChar(CP_ACP
, 0, longtextA
, -1, bufW
, ARRAY_SIZE(bufW
));
825 lenW
= lstrlenW(bufW
);
826 toolinfoW
.lpszText
= bufW
;
827 toolinfoW
.lParam
= 0xdeadbeef;
828 GetClientRect(hwnd
, &toolinfoW
.rect
);
829 r
= SendMessageW(hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&toolinfoW
);
833 memset(bufW
, 0, sizeof(bufW
));
834 toolinfoW
.hwnd
= NULL
;
835 toolinfoW
.uId
= 0xABCD1234;
836 toolinfoW
.lpszText
= bufW
;
837 SendMessageW(hwnd
, TTM_ENUMTOOLSW
, 0, (LPARAM
)&toolinfoW
);
838 textlen
= lstrlenW(toolinfoW
.lpszText
);
839 ok(textlen
== lenW
, "lpszText has %d chars\n", textlen
);
840 ok(toolinfoW
.uId
== 0x1234ABCD,
841 "uId should be retrieved, got %p\n", (void*)toolinfoW
.uId
);
843 memset(bufW
, 0, sizeof(bufW
));
844 toolinfoW
.hwnd
= NULL
;
845 toolinfoW
.uId
= 0x1234ABCD;
846 toolinfoW
.lpszText
= bufW
;
847 SendMessageW(hwnd
, TTM_GETTOOLINFOW
, 0, (LPARAM
)&toolinfoW
);
848 textlen
= lstrlenW(toolinfoW
.lpszText
);
849 ok(textlen
== lenW
, "lpszText has %d chars\n", textlen
);
851 memset(bufW
, 0, sizeof(bufW
));
852 toolinfoW
.hwnd
= NULL
;
853 toolinfoW
.uId
= 0x1234ABCD;
854 toolinfoW
.lpszText
= bufW
;
855 SendMessageW(hwnd
, TTM_GETTEXTW
, 0, (LPARAM
)&toolinfoW
);
856 textlen
= lstrlenW(toolinfoW
.lpszText
);
857 ok(textlen
== lenW
||
858 broken(textlen
== 0 && toolinfoW
.lpszText
== NULL
), /* nt4, kb186177 */
859 "lpszText has %d chars\n", textlen
);
865 static BOOL
almost_eq(int a
, int b
)
867 return a
-5<b
&& a
+5>b
;
870 static void test_track(void)
872 WCHAR textW
[] = {'t','e','x','t',0};
873 TTTOOLINFOW info
= { 0 };
878 parent
= CreateWindowExW(0, WC_STATICW
, NULL
, WS_CAPTION
| WS_VISIBLE
,
879 50, 50, 300, 300, NULL
, NULL
, NULL
, 0);
880 ok(parent
!= NULL
, "creation of parent window failed\n");
882 ShowWindow(parent
, SW_SHOWNORMAL
);
885 tt
= CreateWindowExW(WS_EX_TOPMOST
, TOOLTIPS_CLASSW
, NULL
, TTS_NOPREFIX
| TTS_ALWAYSTIP
,
886 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
887 parent
, NULL
, GetModuleHandleW(NULL
), 0);
888 ok(tt
!= NULL
, "creation of tooltip window failed\n");
890 info
.cbSize
= TTTOOLINFOW_V1_SIZE
;
891 info
.uFlags
= TTF_IDISHWND
| TTF_TRACK
| TTF_ABSOLUTE
;
893 info
.hinst
= GetModuleHandleW(NULL
);
894 info
.lpszText
= textW
;
895 info
.uId
= (UINT_PTR
)parent
;
896 GetClientRect(parent
, &info
.rect
);
898 res
= SendMessageW(tt
, TTM_ADDTOOLW
, 0, (LPARAM
)&info
);
899 ok(res
, "adding the tool to the tooltip failed\n");
901 SendMessageW(tt
, TTM_SETDELAYTIME
, TTDT_INITIAL
, MAKELPARAM(1,0));
902 SendMessageW(tt
, TTM_TRACKACTIVATE
, (WPARAM
)TRUE
, (LPARAM
)&info
);
903 SendMessageW(tt
, TTM_TRACKPOSITION
, 0, MAKELPARAM(10, 10));
905 GetWindowRect(tt
, &pos
);
906 ok(almost_eq(pos
.left
, 10), "pos.left = %d\n", pos
.left
);
907 ok(almost_eq(pos
.top
, 10), "pos.top = %d\n", pos
.top
);
909 info
.uFlags
= TTF_IDISHWND
| TTF_ABSOLUTE
;
910 SendMessageW(tt
, TTM_SETTOOLINFOW
, 0, (LPARAM
)&info
);
911 SendMessageW(tt
, TTM_TRACKPOSITION
, 0, MAKELPARAM(10, 10));
913 GetWindowRect(tt
, &pos
);
914 ok(!almost_eq(pos
.left
, 10), "pos.left = %d\n", pos
.left
);
915 ok(!almost_eq(pos
.top
, 10), "pos.top = %d\n", pos
.top
);
918 DestroyWindow(parent
);
921 static LRESULT CALLBACK
info_wnd_proc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
930 return DefWindowProcA(hWnd
, msg
, wParam
, lParam
);
935 static void test_setinfo(BOOL is_v6
)
939 HWND parent
, parent2
, hwndTip
, hwndTip2
;
940 TTTOOLINFOA toolInfo
= { 0 };
941 TTTOOLINFOA toolInfo2
= { 0 };
944 /* Create a class to use the custom draw wndproc */
945 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
948 wc
.hInstance
= GetModuleHandleA(NULL
);
950 wc
.hCursor
= LoadCursorA(NULL
, (LPCSTR
)IDC_ARROW
);
951 wc
.hbrBackground
= GetSysColorBrush(COLOR_WINDOW
);
952 wc
.lpszMenuName
= NULL
;
953 wc
.lpszClassName
= "SetInfoClass";
954 wc
.lpfnWndProc
= info_wnd_proc
;
957 /* Create a main window */
958 parent
= CreateWindowExA(0, "SetInfoClass", NULL
,
959 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
|
960 WS_MAXIMIZEBOX
| WS_VISIBLE
,
963 NULL
, NULL
, NULL
, 0);
964 ok(parent
!= NULL
, "Creation of main window failed\n");
966 parent2
= CreateWindowExA(0, "SetInfoClass", NULL
,
967 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
|
968 WS_MAXIMIZEBOX
| WS_VISIBLE
,
971 NULL
, NULL
, NULL
, 0);
972 ok(parent2
!= NULL
, "Creation of main window failed\n");
975 ShowWindow(parent2
, SW_SHOWNORMAL
);
979 hwndTip
= CreateWindowExA(WS_EX_TOPMOST
, TOOLTIPS_CLASSA
,
980 NULL
, TTS_NOPREFIX
| TTS_ALWAYSTIP
,
981 CW_USEDEFAULT
, CW_USEDEFAULT
,
982 CW_USEDEFAULT
, CW_USEDEFAULT
,
983 parent
, NULL
, GetModuleHandleA(NULL
), 0);
984 ok(hwndTip
!= NULL
, "Creation of tooltip window failed\n");
986 hwndTip2
= CreateWindowExA(WS_EX_TOPMOST
, TOOLTIPS_CLASSA
,
987 NULL
, TTS_NOPREFIX
| TTS_ALWAYSTIP
,
988 CW_USEDEFAULT
, CW_USEDEFAULT
,
989 CW_USEDEFAULT
, CW_USEDEFAULT
,
990 parent
, NULL
, GetModuleHandleA(NULL
), 0);
991 ok(hwndTip2
!= NULL
, "Creation of tooltip window failed\n");
994 /* Make it topmost, as per the MSDN */
995 SetWindowPos(hwndTip
, HWND_TOPMOST
, 0, 0, 0, 0,
996 SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
);
999 toolInfo
.cbSize
= TTTOOLINFOA_V1_SIZE
;
1000 toolInfo
.hwnd
= parent
;
1001 toolInfo
.hinst
= GetModuleHandleA(NULL
);
1002 toolInfo
.uFlags
= TTF_SUBCLASS
;
1003 toolInfo
.uId
= 0x1234ABCD;
1004 toolInfo
.lpszText
= (LPSTR
)"This is a test tooltip";
1005 toolInfo
.lParam
= 0xdeadbeef;
1006 GetClientRect (parent
, &toolInfo
.rect
);
1007 lResult
= SendMessageA(hwndTip
, TTM_ADDTOOLA
, 0, (LPARAM
)&toolInfo
);
1008 ok(lResult
, "Adding the tool to the tooltip failed\n");
1010 toolInfo
.cbSize
= TTTOOLINFOA_V1_SIZE
;
1011 toolInfo
.hwnd
= parent2
;
1012 toolInfo
.hinst
= GetModuleHandleA(NULL
);
1013 toolInfo
.uFlags
= 0;
1014 toolInfo
.uId
= 0x1234ABCE;
1015 toolInfo
.lpszText
= (LPSTR
)"This is a test tooltip";
1016 toolInfo
.lParam
= 0xdeadbeef;
1017 GetClientRect (parent
, &toolInfo
.rect
);
1018 lResult
= SendMessageA(hwndTip
, TTM_ADDTOOLA
, 0, (LPARAM
)&toolInfo
);
1019 ok(lResult
, "Adding the tool to the tooltip failed\n");
1021 /* Try to Remove Subclass */
1022 toolInfo2
.cbSize
= TTTOOLINFOA_V1_SIZE
;
1023 toolInfo2
.hwnd
= parent
;
1024 toolInfo2
.uId
= 0x1234ABCD;
1025 lResult
= SendMessageA(hwndTip
, TTM_GETTOOLINFOA
, 0, (LPARAM
)&toolInfo2
);
1026 ok(lResult
, "GetToolInfo failed\n");
1027 ok(toolInfo2
.uFlags
& TTF_SUBCLASS
|| broken(is_v6
&& !(toolInfo2
.uFlags
& TTF_SUBCLASS
)) /* XP */,
1028 "uFlags does not have subclass\n");
1029 wndProc
= (WNDPROC
)GetWindowLongPtrA(parent
, GWLP_WNDPROC
);
1030 ok (wndProc
!= info_wnd_proc
, "Window Proc is wrong\n");
1032 toolInfo2
.uFlags
&= ~TTF_SUBCLASS
;
1033 SendMessageA(hwndTip
, TTM_SETTOOLINFOA
, 0, (LPARAM
)&toolInfo2
);
1034 lResult
= SendMessageA(hwndTip
, TTM_GETTOOLINFOA
, 0, (LPARAM
)&toolInfo2
);
1035 ok(lResult
, "GetToolInfo failed\n");
1036 ok(!(toolInfo2
.uFlags
& TTF_SUBCLASS
), "uFlags has subclass\n");
1037 wndProc
= (WNDPROC
)GetWindowLongPtrA(parent
, GWLP_WNDPROC
);
1038 ok (wndProc
!= info_wnd_proc
, "Window Proc is wrong\n");
1040 /* Try to Add Subclass */
1042 /* Make it topmost, as per the MSDN */
1043 SetWindowPos(hwndTip2
, HWND_TOPMOST
, 0, 0, 0, 0,
1044 SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
);
1046 toolInfo2
.cbSize
= TTTOOLINFOA_V1_SIZE
;
1047 toolInfo2
.hwnd
= parent2
;
1048 toolInfo2
.uId
= 0x1234ABCE;
1049 lResult
= SendMessageA(hwndTip
, TTM_GETTOOLINFOA
, 0, (LPARAM
)&toolInfo2
);
1050 ok(lResult
, "GetToolInfo failed\n");
1051 ok(!(toolInfo2
.uFlags
& TTF_SUBCLASS
), "uFlags has subclass\n");
1052 wndProc
= (WNDPROC
)GetWindowLongPtrA(parent2
, GWLP_WNDPROC
);
1053 ok (wndProc
== info_wnd_proc
, "Window Proc is wrong\n");
1055 toolInfo2
.uFlags
|= TTF_SUBCLASS
;
1056 SendMessageA(hwndTip
, TTM_SETTOOLINFOA
, 0, (LPARAM
)&toolInfo2
);
1057 lResult
= SendMessageA(hwndTip
, TTM_GETTOOLINFOA
, 0, (LPARAM
)&toolInfo2
);
1058 ok(lResult
, "GetToolInfo failed\n");
1059 ok(toolInfo2
.uFlags
& TTF_SUBCLASS
, "uFlags does not have subclass\n");
1060 wndProc
= (WNDPROC
)GetWindowLongPtrA(parent2
, GWLP_WNDPROC
);
1061 ok (wndProc
== info_wnd_proc
, "Window Proc is wrong\n");
1064 DestroyWindow(hwndTip
);
1065 DestroyWindow(hwndTip2
);
1066 DestroyWindow(parent
);
1067 DestroyWindow(parent2
);
1070 static void test_margin(void)
1076 hwnd
= CreateWindowExA(0, TOOLTIPS_CLASSA
, NULL
, 0,
1078 NULL
, NULL
, NULL
, 0);
1079 ok(hwnd
!= NULL
, "failed to create tooltip wnd\n");
1081 ret
= SendMessageA(hwnd
, TTM_SETMARGIN
, 0, 0);
1082 ok(!ret
, "got %d\n", ret
);
1084 SetRect(&r
, -1, -1, 1, 1);
1085 ret
= SendMessageA(hwnd
, TTM_SETMARGIN
, 0, (LPARAM
)&r
);
1086 ok(!ret
, "got %d\n", ret
);
1089 ret
= SendMessageA(hwnd
, TTM_GETMARGIN
, 0, (LPARAM
)&r1
);
1090 ok(!ret
, "got %d\n", ret
);
1091 ok(EqualRect(&r
, &r1
), "got %s, was %s\n", wine_dbgstr_rect(&r1
), wine_dbgstr_rect(&r
));
1093 ret
= SendMessageA(hwnd
, TTM_SETMARGIN
, 0, 0);
1094 ok(!ret
, "got %d\n", ret
);
1097 ret
= SendMessageA(hwnd
, TTM_GETMARGIN
, 0, (LPARAM
)&r1
);
1098 ok(!ret
, "got %d\n", ret
);
1099 ok(EqualRect(&r
, &r1
), "got %s, was %s\n", wine_dbgstr_rect(&r1
), wine_dbgstr_rect(&r
));
1101 ret
= SendMessageA(hwnd
, TTM_GETMARGIN
, 0, 0);
1102 ok(!ret
, "got %d\n", ret
);
1104 DestroyWindow(hwnd
);
1107 static void test_TTM_ADDTOOL(BOOL is_v6
)
1115 parent
= CreateWindowExA(0, "Static", NULL
, WS_POPUP
, 0, 0, 0, 0, NULL
, NULL
, NULL
, 0);
1116 ok(parent
!= NULL
, "failed to create parent wnd\n");
1118 hwnd
= CreateWindowExA(WS_EX_TOPMOST
, TOOLTIPS_CLASSA
, NULL
, TTS_NOPREFIX
| TTS_ALWAYSTIP
,
1119 0, 0, 100, 100, NULL
, NULL
, GetModuleHandleA(NULL
), 0);
1120 ok(hwnd
!= NULL
, "Failed to create tooltip window.\n");
1122 for (size
= 0; size
<= TTTOOLINFOW_V3_SIZE
+ 1; size
++)
1126 ti
.hinst
= GetModuleHandleA(NULL
);
1128 ti
.uId
= 0x1234abce;
1129 ti
.lpszText
= (LPSTR
)"Test";
1130 ti
.lParam
= 0xdeadbeef;
1131 GetClientRect(hwnd
, &ti
.rect
);
1133 ret
= SendMessageA(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
);
1134 ok(ret
, "Failed to add a tool, size %d.\n", size
);
1136 ret
= SendMessageA(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
1137 ok(ret
== 1, "Unexpected tool count %d, size %d.\n", ret
, size
);
1139 ret
= SendMessageA(hwnd
, TTM_DELTOOLA
, 0, (LPARAM
)&ti
);
1140 ok(!ret
, "Unexpected ret value %d.\n", ret
);
1142 ret
= SendMessageA(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
1143 ok(ret
== 0, "Unexpected tool count %d, size %d.\n", ret
, size
);
1146 /* W variant checks cbSize. */
1147 max_size
= is_v6
? TTTOOLINFOW_V3_SIZE
: TTTOOLINFOW_V2_SIZE
;
1148 for (size
= 0; size
<= max_size
+ 1; size
++)
1152 tiW
.hinst
= GetModuleHandleA(NULL
);
1154 tiW
.uId
= 0x1234abce;
1155 tiW
.lpszText
= (LPWSTR
)L
"Test";
1156 tiW
.lParam
= 0xdeadbeef;
1157 GetClientRect(hwnd
, &tiW
.rect
);
1159 ret
= SendMessageA(hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&tiW
);
1160 todo_wine_if(!is_v6
&& size
> max_size
)
1161 ok(size
<= max_size
? ret
: !ret
, "%d: Unexpected ret value %d, size %d, max size %d.\n", is_v6
, ret
, size
, max_size
);
1164 ret
= SendMessageA(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
1165 ok(ret
== 1, "Unexpected tool count %d.\n", ret
);
1167 ret
= SendMessageA(hwnd
, TTM_DELTOOLA
, 0, (LPARAM
)&tiW
);
1168 ok(!ret
, "Unexpected ret value %d.\n", ret
);
1170 ret
= SendMessageA(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
1171 ok(ret
== 0, "Unexpected tool count %d.\n", ret
);
1175 DestroyWindow(hwnd
);
1178 static const struct message ttn_show_parent_seq
[] =
1180 { WM_NOTIFY
, sent
|id
, 0, 0, TTN_SHOW
},
1184 static void test_TTN_SHOW(void)
1191 hwnd
= create_parent_window();
1192 ok(hwnd
!= NULL
, "Failed to create parent window.\n");
1194 /* Put cursor outside the window */
1195 GetWindowRect(hwnd
, &rect
);
1196 SetCursorPos(rect
.right
+ 200, 0);
1198 ShowWindow(hwnd
, SW_SHOWNORMAL
);
1201 /* Create tooltip */
1202 hwndTip
= CreateWindowExA(WS_EX_TOPMOST
, TOOLTIPS_CLASSA
, NULL
, TTS_ALWAYSTIP
, 10, 10, 300, 300,
1203 hwnd
, NULL
, NULL
, 0);
1204 ok(hwndTip
!= NULL
, "Failed to create tooltip window.\n");
1206 SetWindowPos(hwndTip
, HWND_TOPMOST
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
);
1208 ti
.cbSize
= sizeof(TTTOOLINFOA
);
1210 ti
.hinst
= GetModuleHandleA(NULL
);
1211 ti
.uFlags
= TTF_SUBCLASS
;
1212 ti
.uId
= 0x1234abcd;
1213 ti
.lpszText
= (LPSTR
)"This is a test tooltip";
1214 ti
.lParam
= 0xdeadbeef;
1215 GetClientRect(hwnd
, &ti
.rect
);
1216 ret
= SendMessageA(hwndTip
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
);
1217 ok(ret
, "Failed to add a tool.\n");
1219 /* Make tooltip appear quickly */
1220 SendMessageA(hwndTip
, TTM_SETDELAYTIME
, TTDT_INITIAL
, MAKELPARAM(1, 0));
1222 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1224 /* Put cursor inside window, tooltip will appear immediately */
1225 GetWindowRect(hwnd
, &rect
);
1226 SetCursorPos((rect
.left
+ rect
.right
) / 2, (rect
.top
+ rect
.bottom
) / 2);
1229 ok_sequence(sequences
, PARENT_SEQ_INDEX
, ttn_show_parent_seq
, "TTN_SHOW parent seq", FALSE
);
1231 DestroyWindow(hwndTip
);
1232 DestroyWindow(hwnd
);
1235 START_TEST(tooltips
)
1237 ULONG_PTR ctx_cookie
;
1240 init_msg_sequences(sequences
, NUM_MSG_SEQUENCES
);
1242 LoadLibraryA("comctl32.dll");
1244 register_parent_wnd_class();
1246 test_create_tooltip(FALSE
);
1249 test_ttm_gettoolinfo();
1253 test_setinfo(FALSE
);
1255 test_TTM_ADDTOOL(FALSE
);
1258 if (!load_v6_module(&ctx_cookie
, &hCtx
))
1261 test_create_tooltip(TRUE
);
1267 test_TTM_ADDTOOL(TRUE
);
1270 unload_v6_module(ctx_cookie
, hCtx
);