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 = CreateWindowEx(0, "static", NULL, WS_POPUP,
38 hwnd = CreateWindowEx(0, TOOLTIPS_CLASS, NULL, 0x7fffffff | WS_POPUP,
40 parent, NULL, NULL, 0);
43 style = GetWindowLong(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 = CreateWindowEx(0, TOOLTIPS_CLASS, NULL, 0,
54 parent, NULL, NULL, 0);
57 style = GetWindowLong(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 (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &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 CustomDrawWndProc(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, IDC_ARROW);
162 wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
163 wc.lpszMenuName = NULL;
164 wc.lpszClassName = "CustomDrawClass";
165 wc.lpfnWndProc = CustomDrawWndProc;
168 for (iterationNumber = 0;
169 iterationNumber < sizeof(expectedResults)/sizeof(expectedResults[0]);
172 HWND parent, hwndTip;
174 TOOLINFO toolInfo = { 0 };
176 /* Create a main window */
177 parent = CreateWindowEx(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 = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS,
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 = TTTOOLINFO_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 = SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM)&toolInfo);
216 ok(lResult, "Adding the tool to the tooltip failed\n");
218 /* Make tooltip appear quickly */
219 SendMessage(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 lstrcpy(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, 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 CreateWindowEx(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_ADDTOOL, 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_ADDTOOL, 0, (LPARAM)&toolinfoA);
349 ok(r, "Adding the tool to the tooltip failed\n");
354 length = SendMessage(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 = SendMessage(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_ADDTOOL, 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_ADDTOOL, 0, (LPARAM)&toolinfoW);
423 ok(r, "Adding the tool to the tooltip failed\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 = SendMessage(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti);
506 ok(r, "Adding the tool to the tooltip failed\n");
507 r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0);
510 ti.cbSize = TTTOOLINFOA_V1_SIZE - 1;
513 SendMessage(hwnd, TTM_DELTOOLA, 0, (LPARAM)&ti);
514 r = SendMessage(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 = SendMessage(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti);
526 ok(r, "Adding the tool to the tooltip failed\n");
527 r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0);
530 ti.cbSize = TTTOOLINFOA_V2_SIZE - 1;
533 SendMessage(hwnd, TTM_DELTOOLA, 0, (LPARAM)&ti);
534 r = SendMessage(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 = SendMessage(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti);
546 ok(r, "Adding the tool to the tooltip failed\n");
547 r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0);
550 ti.cbSize = TTTOOLINFOA_V2_SIZE + 1;
553 SendMessage(hwnd, TTM_DELTOOLA, 0, (LPARAM)&ti);
554 r = SendMessage(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);
763 InitCommonControls();
765 test_create_tooltip();
768 test_ttm_gettoolinfo();