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
24 #include "wine/test.h"
26 #define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
28 static void test_create_tooltip(void)
31 DWORD style
, exp_style
;
33 parent
= CreateWindowExA(0, "static", NULL
, WS_POPUP
,
38 hwnd
= CreateWindowExA(0, TOOLTIPS_CLASSA
, NULL
, 0x7fffffff | WS_POPUP
,
40 parent
, NULL
, NULL
, 0);
43 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
44 trace("style = %08x\n", style
);
45 exp_style
= 0x7fffffff | WS_POPUP
;
46 exp_style
&= ~(WS_CHILD
| WS_MAXIMIZE
| WS_BORDER
| WS_DLGFRAME
);
47 ok(style
== exp_style
|| broken(style
== (exp_style
| WS_BORDER
)), /* nt4 */
48 "wrong style %08x/%08x\n", style
, exp_style
);
52 hwnd
= CreateWindowExA(0, TOOLTIPS_CLASSA
, NULL
, 0,
54 parent
, NULL
, NULL
, 0);
57 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
58 trace("style = %08x\n", style
);
59 ok(style
== (WS_POPUP
| WS_CLIPSIBLINGS
| WS_BORDER
),
60 "wrong style %08x\n", style
);
64 DestroyWindow(parent
);
67 /* try to make sure pending X events have been processed before continuing */
68 static void flush_events(int waitTime
)
72 DWORD time
= GetTickCount() + waitTime
;
76 if (MsgWaitForMultipleObjects( 0, NULL
, FALSE
, min(100,diff
), QS_ALLEVENTS
) == WAIT_TIMEOUT
) break;
77 while (PeekMessageA( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageA( &msg
);
78 diff
= time
- GetTickCount();
83 static LRESULT CD_Result
;
86 #define TEST_CDDS_PREPAINT 0x00000001
87 #define TEST_CDDS_POSTPAINT 0x00000002
88 #define TEST_CDDS_PREERASE 0x00000004
89 #define TEST_CDDS_POSTERASE 0x00000008
90 #define TEST_CDDS_ITEMPREPAINT 0x00000010
91 #define TEST_CDDS_ITEMPOSTPAINT 0x00000020
92 #define TEST_CDDS_ITEMPREERASE 0x00000040
93 #define TEST_CDDS_ITEMPOSTERASE 0x00000080
94 #define TEST_CDDS_SUBITEM 0x00000100
96 static LRESULT CALLBACK
custom_draw_wnd_proc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
105 if (((NMHDR
*)lParam
)->code
== NM_CUSTOMDRAW
) {
106 NMTTCUSTOMDRAW
*ttcd
= (NMTTCUSTOMDRAW
*) lParam
;
107 ok(ttcd
->nmcd
.hdr
.hwndFrom
== g_hwnd
, "Unexpected hwnd source %p (%p)\n",
108 ttcd
->nmcd
.hdr
.hwndFrom
, g_hwnd
);
109 ok(ttcd
->nmcd
.hdr
.idFrom
== 0x1234ABCD, "Unexpected id %x\n", (int)ttcd
->nmcd
.hdr
.idFrom
);
111 switch (ttcd
->nmcd
.dwDrawStage
) {
112 case CDDS_PREPAINT
: CD_Stages
|= TEST_CDDS_PREPAINT
; break;
113 case CDDS_POSTPAINT
: CD_Stages
|= TEST_CDDS_POSTPAINT
; break;
114 case CDDS_PREERASE
: CD_Stages
|= TEST_CDDS_PREERASE
; break;
115 case CDDS_POSTERASE
: CD_Stages
|= TEST_CDDS_POSTERASE
; break;
116 case CDDS_ITEMPREPAINT
: CD_Stages
|= TEST_CDDS_ITEMPREPAINT
; break;
117 case CDDS_ITEMPOSTPAINT
: CD_Stages
|= TEST_CDDS_ITEMPOSTPAINT
; break;
118 case CDDS_ITEMPREERASE
: CD_Stages
|= TEST_CDDS_ITEMPREERASE
; break;
119 case CDDS_ITEMPOSTERASE
: CD_Stages
|= TEST_CDDS_ITEMPOSTERASE
; break;
120 case CDDS_SUBITEM
: CD_Stages
|= TEST_CDDS_SUBITEM
; break;
121 default: CD_Stages
= -1;
124 if (ttcd
->nmcd
.dwDrawStage
== CDDS_PREPAINT
) return CD_Result
;
129 return DefWindowProcA(hWnd
, msg
, wParam
, lParam
);
135 static void test_customdraw(void) {
137 LRESULT FirstReturnValue
;
139 } expectedResults
[] = {
140 /* Valid notification responses */
141 {CDRF_DODEFAULT
, TEST_CDDS_PREPAINT
},
142 {CDRF_SKIPDEFAULT
, TEST_CDDS_PREPAINT
},
143 {CDRF_NOTIFYPOSTPAINT
, TEST_CDDS_PREPAINT
| TEST_CDDS_POSTPAINT
},
145 /* Invalid notification responses */
146 {CDRF_NOTIFYITEMDRAW
, TEST_CDDS_PREPAINT
},
147 {CDRF_NOTIFYPOSTERASE
, TEST_CDDS_PREPAINT
},
148 {CDRF_NEWFONT
, TEST_CDDS_PREPAINT
}
151 DWORD iterationNumber
;
155 /* Create a class to use the custom draw wndproc */
156 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
159 wc
.hInstance
= GetModuleHandleA(NULL
);
161 wc
.hCursor
= LoadCursorA(NULL
, (LPCSTR
)IDC_ARROW
);
162 wc
.hbrBackground
= GetSysColorBrush(COLOR_WINDOW
);
163 wc
.lpszMenuName
= NULL
;
164 wc
.lpszClassName
= "CustomDrawClass";
165 wc
.lpfnWndProc
= custom_draw_wnd_proc
;
168 for (iterationNumber
= 0;
169 iterationNumber
< sizeof(expectedResults
)/sizeof(expectedResults
[0]);
172 HWND parent
, hwndTip
;
174 TTTOOLINFOA toolInfo
= { 0 };
176 /* Create a main window */
177 parent
= CreateWindowExA(0, "CustomDrawClass", NULL
,
178 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
|
179 WS_MAXIMIZEBOX
| WS_VISIBLE
,
182 NULL
, NULL
, NULL
, 0);
183 ok(parent
!= NULL
, "Creation of main window failed\n");
186 ShowWindow(parent
, SW_SHOWNORMAL
);
190 hwndTip
= CreateWindowExA(WS_EX_TOPMOST
, TOOLTIPS_CLASSA
,
191 NULL
, TTS_NOPREFIX
| TTS_ALWAYSTIP
,
192 CW_USEDEFAULT
, CW_USEDEFAULT
,
193 CW_USEDEFAULT
, CW_USEDEFAULT
,
194 parent
, NULL
, GetModuleHandleA(NULL
), 0);
195 ok(hwndTip
!= NULL
, "Creation of tooltip window failed\n");
197 /* Set up parms for the wndproc to handle */
199 CD_Result
= expectedResults
[iterationNumber
].FirstReturnValue
;
202 /* Make it topmost, as per the MSDN */
203 SetWindowPos(hwndTip
, HWND_TOPMOST
, 0, 0, 0, 0,
204 SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
);
207 toolInfo
.cbSize
= TTTOOLINFOA_V1_SIZE
;
208 toolInfo
.hwnd
= parent
;
209 toolInfo
.hinst
= GetModuleHandleA(NULL
);
210 toolInfo
.uFlags
= TTF_SUBCLASS
;
211 toolInfo
.uId
= 0x1234ABCD;
212 toolInfo
.lpszText
= (LPSTR
)"This is a test tooltip";
213 toolInfo
.lParam
= 0xdeadbeef;
214 GetClientRect (parent
, &toolInfo
.rect
);
215 lResult
= SendMessageA(hwndTip
, TTM_ADDTOOLA
, 0, (LPARAM
)&toolInfo
);
216 ok(lResult
, "Adding the tool to the tooltip failed\n");
218 /* Make tooltip appear quickly */
219 SendMessageA(hwndTip
, TTM_SETDELAYTIME
, TTDT_INITIAL
, MAKELPARAM(1,0));
221 /* Put cursor inside window, tooltip will appear immediately */
222 GetWindowRect( parent
, &rect
);
223 SetCursorPos( (rect
.left
+ rect
.right
) / 2, (rect
.top
+ rect
.bottom
) / 2 );
228 /* Check CustomDraw results */
229 ok(CD_Stages
== expectedResults
[iterationNumber
].ExpectedCalls
||
230 broken(CD_Stages
== (expectedResults
[iterationNumber
].ExpectedCalls
& ~TEST_CDDS_POSTPAINT
)), /* nt4 */
231 "CustomDraw run %d stages %x, expected %x\n", iterationNumber
, CD_Stages
,
232 expectedResults
[iterationNumber
].ExpectedCalls
);
236 DestroyWindow(hwndTip
);
237 DestroyWindow(parent
);
243 static const CHAR testcallbackA
[] = "callback";
245 static LRESULT WINAPI
parent_wnd_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
247 if (message
== WM_NOTIFY
&& lParam
)
249 NMTTDISPINFOA
*ttnmdi
= (NMTTDISPINFOA
*)lParam
;
251 if (ttnmdi
->hdr
.code
== TTN_GETDISPINFOA
)
252 lstrcpyA(ttnmdi
->lpszText
, testcallbackA
);
255 return DefWindowProcA(hwnd
, message
, wParam
, lParam
);
258 static BOOL
register_parent_wnd_class(void)
263 cls
.lpfnWndProc
= parent_wnd_proc
;
266 cls
.hInstance
= GetModuleHandleA(NULL
);
268 cls
.hCursor
= LoadCursorA(0, (LPCSTR
)IDC_ARROW
);
269 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
270 cls
.lpszMenuName
= NULL
;
271 cls
.lpszClassName
= "Tooltips test parent class";
272 return RegisterClassA(&cls
);
275 static HWND
create_parent_window(void)
277 if (!register_parent_wnd_class())
280 return CreateWindowExA(0, "Tooltips test parent class",
281 "Tooltips test parent window",
282 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
|
283 WS_MAXIMIZEBOX
| WS_VISIBLE
,
285 GetDesktopWindow(), NULL
, GetModuleHandleA(NULL
), NULL
);
288 static void test_gettext(void)
291 TTTOOLINFOA toolinfoA
;
292 TTTOOLINFOW toolinfoW
;
295 WCHAR bufW
[10] = { 0 };
296 static const CHAR testtipA
[] = "testtip";
298 notify
= create_parent_window();
299 ok(notify
!= NULL
, "Expected notification window to be created\n");
301 /* For bug 14790 - lpszText is NULL */
302 hwnd
= CreateWindowExA(0, TOOLTIPS_CLASSA
, NULL
, 0,
304 NULL
, NULL
, NULL
, 0);
307 /* use sizeof(TTTOOLINFOA) instead of TTTOOLINFOA_V1_SIZE so that adding it fails on Win9x */
308 /* otherwise it crashes on the NULL lpszText */
309 toolinfoA
.cbSize
= sizeof(TTTOOLINFOA
);
310 toolinfoA
.hwnd
= NULL
;
311 toolinfoA
.hinst
= GetModuleHandleA(NULL
);
312 toolinfoA
.uFlags
= 0;
313 toolinfoA
.uId
= 0x1234ABCD;
314 toolinfoA
.lpszText
= NULL
;
315 toolinfoA
.lParam
= 0xdeadbeef;
316 GetClientRect(hwnd
, &toolinfoA
.rect
);
317 r
= SendMessageA(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&toolinfoA
);
320 toolinfoA
.hwnd
= NULL
;
321 toolinfoA
.uId
= 0x1234ABCD;
322 toolinfoA
.lpszText
= bufA
;
323 SendMessageA(hwnd
, TTM_GETTEXTA
, 0, (LPARAM
)&toolinfoA
);
324 ok(strcmp(toolinfoA
.lpszText
, "") == 0, "lpszText should be an empty string\n");
326 toolinfoA
.lpszText
= bufA
;
327 SendMessageA(hwnd
, TTM_GETTOOLINFOA
, 0, (LPARAM
)&toolinfoA
);
328 ok(toolinfoA
.lpszText
== NULL
,
329 "expected NULL, got %p\n", toolinfoA
.lpszText
);
333 win_skip( "Old comctl32, not testing NULL text\n" );
334 DestroyWindow( hwnd
);
338 /* add another tool with text */
339 toolinfoA
.cbSize
= sizeof(TTTOOLINFOA
);
340 toolinfoA
.hwnd
= NULL
;
341 toolinfoA
.hinst
= GetModuleHandleA(NULL
);
342 toolinfoA
.uFlags
= 0;
343 toolinfoA
.uId
= 0x1235ABCD;
344 strcpy(bufA
, testtipA
);
345 toolinfoA
.lpszText
= bufA
;
346 toolinfoA
.lParam
= 0xdeadbeef;
347 GetClientRect(hwnd
, &toolinfoA
.rect
);
348 r
= SendMessageA(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&toolinfoA
);
349 ok(r
, "Adding the tool to the tooltip failed\n");
354 length
= SendMessageA(hwnd
, WM_GETTEXTLENGTH
, 0, 0);
355 ok(length
== 0, "Expected 0, got %d\n", length
);
357 toolinfoA
.hwnd
= NULL
;
358 toolinfoA
.uId
= 0x1235ABCD;
359 toolinfoA
.lpszText
= bufA
;
360 SendMessageA(hwnd
, TTM_GETTEXTA
, 0, (LPARAM
)&toolinfoA
);
361 ok(strcmp(toolinfoA
.lpszText
, testtipA
) == 0, "lpszText should be an empty string\n");
363 memset(bufA
, 0x1f, sizeof(bufA
));
364 toolinfoA
.lpszText
= bufA
;
365 SendMessageA(hwnd
, TTM_GETTOOLINFOA
, 0, (LPARAM
)&toolinfoA
);
366 ok(strcmp(toolinfoA
.lpszText
, testtipA
) == 0,
367 "expected %s, got %p\n", testtipA
, toolinfoA
.lpszText
);
369 length
= SendMessageA(hwnd
, WM_GETTEXTLENGTH
, 0, 0);
370 ok(length
== 0, "Expected 0, got %d\n", length
);
373 /* add another with callback text */
374 toolinfoA
.cbSize
= sizeof(TTTOOLINFOA
);
375 toolinfoA
.hwnd
= notify
;
376 toolinfoA
.hinst
= GetModuleHandleA(NULL
);
377 toolinfoA
.uFlags
= 0;
378 toolinfoA
.uId
= 0x1236ABCD;
379 toolinfoA
.lpszText
= LPSTR_TEXTCALLBACKA
;
380 toolinfoA
.lParam
= 0xdeadbeef;
381 GetClientRect(hwnd
, &toolinfoA
.rect
);
382 r
= SendMessageA(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&toolinfoA
);
383 ok(r
, "Adding the tool to the tooltip failed\n");
386 toolinfoA
.hwnd
= notify
;
387 toolinfoA
.uId
= 0x1236ABCD;
388 toolinfoA
.lpszText
= bufA
;
389 SendMessageA(hwnd
, TTM_GETTEXTA
, 0, (LPARAM
)&toolinfoA
);
390 ok(strcmp(toolinfoA
.lpszText
, testcallbackA
) == 0,
391 "lpszText should be an (%s) string\n", testcallbackA
);
393 toolinfoA
.lpszText
= bufA
;
394 SendMessageA(hwnd
, TTM_GETTOOLINFOA
, 0, (LPARAM
)&toolinfoA
);
395 ok(toolinfoA
.lpszText
== LPSTR_TEXTCALLBACKA
,
396 "expected LPSTR_TEXTCALLBACKA, got %p\n", toolinfoA
.lpszText
);
400 DestroyWindow(notify
);
402 SetLastError(0xdeadbeef);
403 hwnd
= CreateWindowExW(0, TOOLTIPS_CLASSW
, NULL
, 0,
405 NULL
, NULL
, NULL
, 0);
407 if (!hwnd
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
) {
408 win_skip("CreateWindowExW is not implemented\n");
414 toolinfoW
.cbSize
= sizeof(TTTOOLINFOW
);
415 toolinfoW
.hwnd
= NULL
;
416 toolinfoW
.hinst
= GetModuleHandleA(NULL
);
417 toolinfoW
.uFlags
= 0;
418 toolinfoW
.uId
= 0x1234ABCD;
419 toolinfoW
.lpszText
= NULL
;
420 toolinfoW
.lParam
= 0xdeadbeef;
421 GetClientRect(hwnd
, &toolinfoW
.rect
);
422 r
= SendMessageW(hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&toolinfoW
);
423 ok(!r
, "Adding the tool to the tooltip succeeded!\n");
425 if (0) /* crashes on NT4 */
427 toolinfoW
.hwnd
= NULL
;
428 toolinfoW
.uId
= 0x1234ABCD;
429 toolinfoW
.lpszText
= bufW
;
430 SendMessageW(hwnd
, TTM_GETTEXTW
, 0, (LPARAM
)&toolinfoW
);
431 ok(toolinfoW
.lpszText
[0] == 0, "lpszText should be an empty string\n");
437 static void test_ttm_gettoolinfo(void)
444 hwnd
= CreateWindowExA(0, TOOLTIPS_CLASSA
, NULL
, 0,
446 NULL
, NULL
, NULL
, 0);
448 ti
.cbSize
= TTTOOLINFOA_V2_SIZE
;
450 ti
.hinst
= GetModuleHandleA(NULL
);
454 ti
.lParam
= 0x1abe11ed;
455 GetClientRect(hwnd
, &ti
.rect
);
456 r
= SendMessageA(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
);
457 ok(r
, "Adding the tool to the tooltip failed\n");
459 ti
.cbSize
= TTTOOLINFOA_V2_SIZE
;
460 ti
.lParam
= 0xaaaaaaaa;
461 r
= SendMessageA(hwnd
, TTM_GETTOOLINFOA
, 0, (LPARAM
)&ti
);
462 ok(r
, "Getting tooltip info failed\n");
463 ok(0x1abe11ed == ti
.lParam
||
464 broken(0x1abe11ed != ti
.lParam
), /* comctl32 < 5.81 */
465 "Expected 0x1abe11ed, got %lx\n", ti
.lParam
);
467 tiW
.cbSize
= TTTOOLINFOW_V2_SIZE
;
469 tiW
.uId
= 0x1234ABCD;
470 tiW
.lParam
= 0xaaaaaaaa;
471 r
= SendMessageA(hwnd
, TTM_GETTOOLINFOW
, 0, (LPARAM
)&tiW
);
472 ok(r
, "Getting tooltip info failed\n");
473 ok(0x1abe11ed == tiW
.lParam
||
474 broken(0x1abe11ed != tiW
.lParam
), /* comctl32 < 5.81 */
475 "Expected 0x1abe11ed, got %lx\n", tiW
.lParam
);
477 ti
.cbSize
= TTTOOLINFOA_V2_SIZE
;
479 ti
.lParam
= 0x55555555;
480 SendMessageA(hwnd
, TTM_SETTOOLINFOA
, 0, (LPARAM
)&ti
);
482 ti
.cbSize
= TTTOOLINFOA_V2_SIZE
;
483 ti
.lParam
= 0xdeadbeef;
484 r
= SendMessageA(hwnd
, TTM_GETTOOLINFOA
, 0, (LPARAM
)&ti
);
485 ok(r
, "Getting tooltip info failed\n");
486 ok(0x55555555 == ti
.lParam
||
487 broken(0x55555555 != ti
.lParam
), /* comctl32 < 5.81 */
488 "Expected 0x55555555, got %lx\n", ti
.lParam
);
492 /* 1. test size parameter validation rules (ansi messages) */
493 hwnd
= CreateWindowExA(0, TOOLTIPS_CLASSA
, NULL
, 0,
495 NULL
, NULL
, NULL
, 0);
497 ti
.cbSize
= TTTOOLINFOA_V1_SIZE
- 1;
499 ti
.hinst
= GetModuleHandleA(NULL
);
503 ti
.lParam
= 0xdeadbeef;
504 GetClientRect(hwnd
, &ti
.rect
);
505 r
= SendMessageA(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
);
506 ok(r
, "Adding the tool to the tooltip failed\n");
507 r
= SendMessageA(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
510 ti
.cbSize
= TTTOOLINFOA_V1_SIZE
- 1;
513 SendMessageA(hwnd
, TTM_DELTOOLA
, 0, (LPARAM
)&ti
);
514 r
= SendMessageA(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
517 ti
.cbSize
= TTTOOLINFOA_V2_SIZE
- 1;
519 ti
.hinst
= GetModuleHandleA(NULL
);
523 ti
.lParam
= 0xdeadbeef;
524 GetClientRect(hwnd
, &ti
.rect
);
525 r
= SendMessageA(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
);
526 ok(r
, "Adding the tool to the tooltip failed\n");
527 r
= SendMessageA(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
530 ti
.cbSize
= TTTOOLINFOA_V2_SIZE
- 1;
533 SendMessageA(hwnd
, TTM_DELTOOLA
, 0, (LPARAM
)&ti
);
534 r
= SendMessageA(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
537 ti
.cbSize
= TTTOOLINFOA_V2_SIZE
+ 1;
539 ti
.hinst
= GetModuleHandleA(NULL
);
543 ti
.lParam
= 0xdeadbeef;
544 GetClientRect(hwnd
, &ti
.rect
);
545 r
= SendMessageA(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&ti
);
546 ok(r
, "Adding the tool to the tooltip failed\n");
547 r
= SendMessageA(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
550 ti
.cbSize
= TTTOOLINFOA_V2_SIZE
+ 1;
553 SendMessageA(hwnd
, TTM_DELTOOLA
, 0, (LPARAM
)&ti
);
554 r
= SendMessageA(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
559 /* 2. test size parameter validation rules (w-messages) */
560 hwnd
= CreateWindowExW(0, TOOLTIPS_CLASSW
, NULL
, 0,
562 NULL
, NULL
, NULL
, 0);
565 win_skip("CreateWindowExW() not supported. Skipping.\n");
569 tiW
.cbSize
= TTTOOLINFOW_V1_SIZE
- 1;
571 tiW
.hinst
= GetModuleHandleA(NULL
);
573 tiW
.uId
= 0x1234ABCD;
575 tiW
.lParam
= 0xdeadbeef;
576 GetClientRect(hwnd
, &tiW
.rect
);
577 r
= SendMessageW(hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&tiW
);
578 ok(r
, "Adding the tool to the tooltip failed\n");
579 r
= SendMessageW(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
582 tiW
.cbSize
= TTTOOLINFOW_V1_SIZE
- 1;
584 tiW
.uId
= 0x1234ABCD;
585 SendMessageW(hwnd
, TTM_DELTOOLW
, 0, (LPARAM
)&tiW
);
586 r
= SendMessageW(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
589 tiW
.cbSize
= TTTOOLINFOW_V2_SIZE
- 1;
591 tiW
.hinst
= GetModuleHandleA(NULL
);
593 tiW
.uId
= 0x1234ABCD;
595 tiW
.lParam
= 0xdeadbeef;
596 GetClientRect(hwnd
, &tiW
.rect
);
597 r
= SendMessageW(hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&tiW
);
598 ok(r
, "Adding the tool to the tooltip failed\n");
599 r
= SendMessageW(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
602 tiW
.cbSize
= TTTOOLINFOW_V2_SIZE
- 1;
604 tiW
.uId
= 0x1234ABCD;
605 SendMessageW(hwnd
, TTM_DELTOOLW
, 0, (LPARAM
)&tiW
);
606 r
= SendMessageW(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
609 tiW
.cbSize
= TTTOOLINFOW_V2_SIZE
+ 1;
611 tiW
.hinst
= GetModuleHandleA(NULL
);
613 tiW
.uId
= 0x1234ABCD;
615 tiW
.lParam
= 0xdeadbeef;
616 GetClientRect(hwnd
, &tiW
.rect
);
617 r
= SendMessageW(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&tiW
);
618 ok(r
, "Adding the tool to the tooltip failed\n");
619 r
= SendMessageW(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
621 /* looks like TTM_DELTOOLW doesn't work with invalid size */
622 tiW
.cbSize
= TTTOOLINFOW_V2_SIZE
+ 1;
624 tiW
.uId
= 0x1234ABCD;
625 SendMessageW(hwnd
, TTM_DELTOOLW
, 0, (LPARAM
)&tiW
);
626 r
= SendMessageW(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
629 tiW
.cbSize
= TTTOOLINFOW_V2_SIZE
;
631 tiW
.uId
= 0x1234ABCD;
632 SendMessageW(hwnd
, TTM_DELTOOLW
, 0, (LPARAM
)&tiW
);
633 r
= SendMessageW(hwnd
, TTM_GETTOOLCOUNT
, 0, 0);
639 static void test_longtextA(void)
641 static const char longtextA
[] =
642 "According to MSDN, TTM_ENUMTOOLS claims that TOOLINFO's lpszText is maximum "
643 "80 chars including null. In fact, the buffer is not null-terminated.";
645 TTTOOLINFOA toolinfoA
= { 0 };
649 hwnd
= CreateWindowExA(0, TOOLTIPS_CLASSA
, NULL
, 0,
651 NULL
, NULL
, NULL
, 0);
652 toolinfoA
.cbSize
= sizeof(TTTOOLINFOA
);
653 toolinfoA
.hwnd
= NULL
;
654 toolinfoA
.hinst
= GetModuleHandleA(NULL
);
655 toolinfoA
.uFlags
= 0;
656 toolinfoA
.uId
= 0x1234ABCD;
657 strcpy(bufA
, longtextA
);
658 toolinfoA
.lpszText
= bufA
;
659 toolinfoA
.lParam
= 0xdeadbeef;
660 GetClientRect(hwnd
, &toolinfoA
.rect
);
661 r
= SendMessageA(hwnd
, TTM_ADDTOOLA
, 0, (LPARAM
)&toolinfoA
);
665 memset(bufA
, 0, sizeof(bufA
));
666 toolinfoA
.hwnd
= NULL
;
667 toolinfoA
.uId
= 0xABCD1234;
668 toolinfoA
.lpszText
= bufA
;
669 SendMessageA(hwnd
, TTM_ENUMTOOLSA
, 0, (LPARAM
)&toolinfoA
);
670 textlen
= lstrlenA(toolinfoA
.lpszText
);
671 ok(textlen
== 80, "lpszText has %d chars\n", textlen
);
672 ok(toolinfoA
.uId
== 0x1234ABCD,
673 "uId should be retrieved, got %p\n", (void*)toolinfoA
.uId
);
675 memset(bufA
, 0, sizeof(bufA
));
676 toolinfoA
.hwnd
= NULL
;
677 toolinfoA
.uId
= 0x1234ABCD;
678 toolinfoA
.lpszText
= bufA
;
679 SendMessageA(hwnd
, TTM_GETTOOLINFOA
, 0, (LPARAM
)&toolinfoA
);
680 textlen
= lstrlenA(toolinfoA
.lpszText
);
681 ok(textlen
== 80, "lpszText has %d chars\n", textlen
);
683 memset(bufA
, 0, sizeof(bufA
));
684 toolinfoA
.hwnd
= NULL
;
685 toolinfoA
.uId
= 0x1234ABCD;
686 toolinfoA
.lpszText
= bufA
;
687 SendMessageA(hwnd
, TTM_GETTEXTA
, 0, (LPARAM
)&toolinfoA
);
688 textlen
= lstrlenA(toolinfoA
.lpszText
);
689 ok(textlen
== 80, "lpszText has %d chars\n", textlen
);
695 static void test_longtextW(void)
697 static const char longtextA
[] =
698 "According to MSDN, TTM_ENUMTOOLS claims that TOOLINFO's lpszText is maximum "
699 "80 chars including null. Actually, this is not applied for wide version.";
701 TTTOOLINFOW toolinfoW
= { 0 };
706 hwnd
= CreateWindowExW(0, TOOLTIPS_CLASSW
, NULL
, 0,
708 NULL
, NULL
, NULL
, 0);
711 win_skip("CreateWindowExW() not supported. Skipping.\n");
715 toolinfoW
.cbSize
= TTTOOLINFOW_V2_SIZE
;
716 toolinfoW
.hwnd
= NULL
;
717 toolinfoW
.hinst
= GetModuleHandleW(NULL
);
718 toolinfoW
.uFlags
= 0;
719 toolinfoW
.uId
= 0x1234ABCD;
720 MultiByteToWideChar(CP_ACP
, 0, longtextA
, -1, bufW
, sizeof(bufW
)/sizeof(bufW
[0]));
721 lenW
= lstrlenW(bufW
);
722 toolinfoW
.lpszText
= bufW
;
723 toolinfoW
.lParam
= 0xdeadbeef;
724 GetClientRect(hwnd
, &toolinfoW
.rect
);
725 r
= SendMessageW(hwnd
, TTM_ADDTOOLW
, 0, (LPARAM
)&toolinfoW
);
729 memset(bufW
, 0, sizeof(bufW
));
730 toolinfoW
.hwnd
= NULL
;
731 toolinfoW
.uId
= 0xABCD1234;
732 toolinfoW
.lpszText
= bufW
;
733 SendMessageW(hwnd
, TTM_ENUMTOOLSW
, 0, (LPARAM
)&toolinfoW
);
734 textlen
= lstrlenW(toolinfoW
.lpszText
);
735 ok(textlen
== lenW
, "lpszText has %d chars\n", textlen
);
736 ok(toolinfoW
.uId
== 0x1234ABCD,
737 "uId should be retrieved, got %p\n", (void*)toolinfoW
.uId
);
739 memset(bufW
, 0, sizeof(bufW
));
740 toolinfoW
.hwnd
= NULL
;
741 toolinfoW
.uId
= 0x1234ABCD;
742 toolinfoW
.lpszText
= bufW
;
743 SendMessageW(hwnd
, TTM_GETTOOLINFOW
, 0, (LPARAM
)&toolinfoW
);
744 textlen
= lstrlenW(toolinfoW
.lpszText
);
745 ok(textlen
== lenW
, "lpszText has %d chars\n", textlen
);
747 memset(bufW
, 0, sizeof(bufW
));
748 toolinfoW
.hwnd
= NULL
;
749 toolinfoW
.uId
= 0x1234ABCD;
750 toolinfoW
.lpszText
= bufW
;
751 SendMessageW(hwnd
, TTM_GETTEXTW
, 0, (LPARAM
)&toolinfoW
);
752 textlen
= lstrlenW(toolinfoW
.lpszText
);
753 ok(textlen
== lenW
||
754 broken(textlen
== 0 && toolinfoW
.lpszText
== NULL
), /* nt4, kb186177 */
755 "lpszText has %d chars\n", textlen
);
761 static BOOL
almost_eq(int a
, int b
)
763 return a
-5<b
&& a
+5>b
;
766 static void test_track(void)
768 WCHAR textW
[] = {'t','e','x','t',0};
769 TTTOOLINFOW info
= { 0 };
774 parent
= CreateWindowExW(0, WC_STATICW
, NULL
, WS_CAPTION
| WS_VISIBLE
,
775 50, 50, 300, 300, NULL
, NULL
, NULL
, 0);
776 ok(parent
!= NULL
, "creation of parent window failed\n");
778 ShowWindow(parent
, SW_SHOWNORMAL
);
781 tt
= CreateWindowExW(WS_EX_TOPMOST
, TOOLTIPS_CLASSW
, NULL
, TTS_NOPREFIX
| TTS_ALWAYSTIP
,
782 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
783 parent
, NULL
, GetModuleHandleW(NULL
), 0);
784 ok(tt
!= NULL
, "creation of tooltip window failed\n");
786 info
.cbSize
= TTTOOLINFOW_V1_SIZE
;
787 info
.uFlags
= TTF_IDISHWND
| TTF_TRACK
| TTF_ABSOLUTE
;
789 info
.hinst
= GetModuleHandleW(NULL
);
790 info
.lpszText
= textW
;
791 info
.uId
= (UINT_PTR
)parent
;
792 GetClientRect(parent
, &info
.rect
);
794 res
= SendMessageW(tt
, TTM_ADDTOOLW
, 0, (LPARAM
)&info
);
795 ok(res
, "adding the tool to the tooltip failed\n");
797 SendMessageW(tt
, TTM_SETDELAYTIME
, TTDT_INITIAL
, MAKELPARAM(1,0));
798 SendMessageW(tt
, TTM_TRACKACTIVATE
, (WPARAM
)TRUE
, (LPARAM
)&info
);
799 SendMessageW(tt
, TTM_TRACKPOSITION
, 0, MAKELPARAM(10, 10));
801 GetWindowRect(tt
, &pos
);
802 ok(almost_eq(pos
.left
, 10), "pos.left = %d\n", pos
.left
);
803 ok(almost_eq(pos
.top
, 10), "pos.top = %d\n", pos
.top
);
805 info
.uFlags
= TTF_IDISHWND
| TTF_ABSOLUTE
;
806 SendMessageW(tt
, TTM_SETTOOLINFOW
, 0, (LPARAM
)&info
);
807 SendMessageW(tt
, TTM_TRACKPOSITION
, 0, MAKELPARAM(10, 10));
809 GetWindowRect(tt
, &pos
);
810 ok(!almost_eq(pos
.left
, 10), "pos.left = %d\n", pos
.left
);
811 ok(!almost_eq(pos
.top
, 10), "pos.top = %d\n", pos
.top
);
814 DestroyWindow(parent
);
819 InitCommonControls();
821 test_create_tooltip();
824 test_ttm_gettoolinfo();