596598f1ade078ada74c83dcc44844ba05615b61
[reactos.git] / rostests / winetests / comctl32 / tooltips.c
1 /*
2 * Copyright 2005 Dmitry Timoshkov
3 * Copyright 2008 Jason Edmeades
4 *
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.
9 *
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.
14 *
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
18 */
19
20 #include <assert.h>
21 #include <windows.h>
22 #include <commctrl.h>
23
24 #include "wine/test.h"
25
26 #define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
27
28 static void test_create_tooltip(void)
29 {
30 HWND parent, hwnd;
31 DWORD style, exp_style;
32
33 parent = CreateWindowEx(0, "static", NULL, WS_POPUP,
34 0, 0, 0, 0,
35 NULL, NULL, NULL, 0);
36 assert(parent);
37
38 hwnd = CreateWindowEx(0, TOOLTIPS_CLASS, NULL, 0x7fffffff | WS_POPUP,
39 10, 10, 300, 100,
40 parent, NULL, NULL, 0);
41 assert(hwnd);
42
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);
49
50 DestroyWindow(hwnd);
51
52 hwnd = CreateWindowEx(0, TOOLTIPS_CLASS, NULL, 0,
53 10, 10, 300, 100,
54 parent, NULL, NULL, 0);
55 assert(hwnd);
56
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);
61
62 DestroyWindow(hwnd);
63
64 DestroyWindow(parent);
65 }
66
67 /* try to make sure pending X events have been processed before continuing */
68 static void flush_events(int waitTime)
69 {
70 MSG msg;
71 int diff = waitTime;
72 DWORD time = GetTickCount() + waitTime;
73
74 while (diff > 0)
75 {
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();
79 }
80 }
81
82 static int CD_Stages;
83 static LRESULT CD_Result;
84 static HWND g_hwnd;
85
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
95
96 static LRESULT CALLBACK CustomDrawWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
97 {
98 switch(msg) {
99
100 case WM_DESTROY:
101 PostQuitMessage(0);
102 break;
103
104 case WM_NOTIFY:
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);
110
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;
122 }
123
124 if (ttcd->nmcd.dwDrawStage == CDDS_PREPAINT) return CD_Result;
125 }
126 /* drop through */
127
128 default:
129 return DefWindowProcA(hWnd, msg, wParam, lParam);
130 }
131
132 return 0L;
133 }
134
135 static void test_customdraw(void) {
136 static struct {
137 LRESULT FirstReturnValue;
138 int ExpectedCalls;
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},
144
145 /* Invalid notification responses */
146 {CDRF_NOTIFYITEMDRAW, TEST_CDDS_PREPAINT},
147 {CDRF_NOTIFYPOSTERASE, TEST_CDDS_PREPAINT},
148 {CDRF_NEWFONT, TEST_CDDS_PREPAINT}
149 };
150
151 DWORD iterationNumber;
152 WNDCLASSA wc;
153 LRESULT lResult;
154
155 /* Create a class to use the custom draw wndproc */
156 wc.style = CS_HREDRAW | CS_VREDRAW;
157 wc.cbClsExtra = 0;
158 wc.cbWndExtra = 0;
159 wc.hInstance = GetModuleHandleA(NULL);
160 wc.hIcon = 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;
166 RegisterClass(&wc);
167
168 for (iterationNumber = 0;
169 iterationNumber < sizeof(expectedResults)/sizeof(expectedResults[0]);
170 iterationNumber++) {
171
172 HWND parent, hwndTip;
173 RECT rect;
174 TOOLINFO toolInfo = { 0 };
175
176 /* Create a main window */
177 parent = CreateWindowEx(0, "CustomDrawClass", NULL,
178 WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
179 WS_MAXIMIZEBOX | WS_VISIBLE,
180 50, 50,
181 300, 300,
182 NULL, NULL, NULL, 0);
183 ok(parent != NULL, "Creation of main window failed\n");
184
185 /* Make it show */
186 ShowWindow(parent, SW_SHOWNORMAL);
187 flush_events(100);
188
189 /* Create Tooltip */
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");
196
197 /* Set up parms for the wndproc to handle */
198 CD_Stages = 0;
199 CD_Result = expectedResults[iterationNumber].FirstReturnValue;
200 g_hwnd = hwndTip;
201
202 /* Make it topmost, as per the MSDN */
203 SetWindowPos(hwndTip, HWND_TOPMOST, 0, 0, 0, 0,
204 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
205
206 /* Create a tool */
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");
217
218 /* Make tooltip appear quickly */
219 SendMessage(hwndTip, TTM_SETDELAYTIME, TTDT_INITIAL, MAKELPARAM(1,0));
220
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 );
224 flush_events(200);
225
226 if (CD_Stages)
227 {
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);
233 }
234
235 /* Clean up */
236 DestroyWindow(hwndTip);
237 DestroyWindow(parent);
238 }
239
240
241 }
242
243 static const CHAR testcallbackA[] = "callback";
244
245 static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
246 {
247 if (message == WM_NOTIFY && lParam)
248 {
249 NMTTDISPINFOA *ttnmdi = (NMTTDISPINFOA*)lParam;
250
251 if (ttnmdi->hdr.code == TTN_GETDISPINFOA)
252 lstrcpy(ttnmdi->lpszText, testcallbackA);
253 }
254
255 return DefWindowProcA(hwnd, message, wParam, lParam);
256 }
257
258 static BOOL register_parent_wnd_class(void)
259 {
260 WNDCLASSA cls;
261
262 cls.style = 0;
263 cls.lpfnWndProc = parent_wnd_proc;
264 cls.cbClsExtra = 0;
265 cls.cbWndExtra = 0;
266 cls.hInstance = GetModuleHandleA(NULL);
267 cls.hIcon = 0;
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);
273 }
274
275 static HWND create_parent_window(void)
276 {
277 if (!register_parent_wnd_class())
278 return NULL;
279
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,
284 0, 0, 100, 100,
285 GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL);
286 }
287
288 static void test_gettext(void)
289 {
290 HWND hwnd, notify;
291 TTTOOLINFOA toolinfoA;
292 TTTOOLINFOW toolinfoW;
293 LRESULT r;
294 CHAR bufA[10] = "";
295 WCHAR bufW[10] = { 0 };
296 static const CHAR testtipA[] = "testtip";
297
298 notify = create_parent_window();
299 ok(notify != NULL, "Expected notification window to be created\n");
300
301 /* For bug 14790 - lpszText is NULL */
302 hwnd = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0,
303 10, 10, 300, 100,
304 NULL, NULL, NULL, 0);
305 assert(hwnd);
306
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);
318 if (r)
319 {
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");
325 }
326 else
327 {
328 win_skip( "Old comctl32, not testing NULL text\n" );
329 DestroyWindow( hwnd );
330 return;
331 }
332
333 /* add another tool with text */
334 toolinfoA.cbSize = sizeof(TTTOOLINFOA);
335 toolinfoA.hwnd = NULL;
336 toolinfoA.hinst = GetModuleHandleA(NULL);
337 toolinfoA.uFlags = 0;
338 toolinfoA.uId = 0x1235ABCD;
339 strcpy(bufA, testtipA);
340 toolinfoA.lpszText = bufA;
341 toolinfoA.lParam = 0xdeadbeef;
342 GetClientRect(hwnd, &toolinfoA.rect);
343 r = SendMessageA(hwnd, TTM_ADDTOOL, 0, (LPARAM)&toolinfoA);
344 ok(r, "Adding the tool to the tooltip failed\n");
345 if (r)
346 {
347 DWORD length;
348
349 length = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0);
350 ok(length == 0, "Expected 0, got %d\n", length);
351
352 toolinfoA.hwnd = NULL;
353 toolinfoA.uId = 0x1235ABCD;
354 toolinfoA.lpszText = bufA;
355 SendMessageA(hwnd, TTM_GETTEXTA, 0, (LPARAM)&toolinfoA);
356 ok(strcmp(toolinfoA.lpszText, testtipA) == 0, "lpszText should be an empty string\n");
357
358 length = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0);
359 ok(length == 0, "Expected 0, got %d\n", length);
360 }
361
362 /* add another with callback text */
363 toolinfoA.cbSize = sizeof(TTTOOLINFOA);
364 toolinfoA.hwnd = notify;
365 toolinfoA.hinst = GetModuleHandleA(NULL);
366 toolinfoA.uFlags = 0;
367 toolinfoA.uId = 0x1236ABCD;
368 toolinfoA.lpszText = LPSTR_TEXTCALLBACKA;
369 toolinfoA.lParam = 0xdeadbeef;
370 GetClientRect(hwnd, &toolinfoA.rect);
371 r = SendMessageA(hwnd, TTM_ADDTOOL, 0, (LPARAM)&toolinfoA);
372 ok(r, "Adding the tool to the tooltip failed\n");
373 if (r)
374 {
375 toolinfoA.hwnd = notify;
376 toolinfoA.uId = 0x1236ABCD;
377 toolinfoA.lpszText = bufA;
378 SendMessageA(hwnd, TTM_GETTEXTA, 0, (LPARAM)&toolinfoA);
379 ok(strcmp(toolinfoA.lpszText, testcallbackA) == 0,
380 "lpszText should be an (%s) string\n", testcallbackA);
381 }
382
383 DestroyWindow(hwnd);
384 DestroyWindow(notify);
385
386 SetLastError(0xdeadbeef);
387 hwnd = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, 0,
388 10, 10, 300, 100,
389 NULL, NULL, NULL, 0);
390
391 if (!hwnd && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
392 win_skip("CreateWindowExW is not implemented\n");
393 return;
394 }
395
396 assert(hwnd);
397
398 toolinfoW.cbSize = sizeof(TTTOOLINFOW);
399 toolinfoW.hwnd = NULL;
400 toolinfoW.hinst = GetModuleHandleA(NULL);
401 toolinfoW.uFlags = 0;
402 toolinfoW.uId = 0x1234ABCD;
403 toolinfoW.lpszText = NULL;
404 toolinfoW.lParam = 0xdeadbeef;
405 GetClientRect(hwnd, &toolinfoW.rect);
406 r = SendMessageW(hwnd, TTM_ADDTOOL, 0, (LPARAM)&toolinfoW);
407 ok(r, "Adding the tool to the tooltip failed\n");
408
409 if (0) /* crashes on NT4 */
410 {
411 toolinfoW.hwnd = NULL;
412 toolinfoW.uId = 0x1234ABCD;
413 toolinfoW.lpszText = bufW;
414 SendMessageW(hwnd, TTM_GETTEXTW, 0, (LPARAM)&toolinfoW);
415 ok(toolinfoW.lpszText[0] == 0, "lpszText should be an empty string\n");
416 }
417
418 DestroyWindow(hwnd);
419 }
420
421 static void test_ttm_gettoolinfo(void)
422 {
423 TTTOOLINFOA ti;
424 TTTOOLINFOW tiW;
425 HWND hwnd;
426 DWORD r;
427
428 hwnd = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0,
429 10, 10, 300, 100,
430 NULL, NULL, NULL, 0);
431
432 ti.cbSize = TTTOOLINFOA_V2_SIZE;
433 ti.hwnd = NULL;
434 ti.hinst = GetModuleHandleA(NULL);
435 ti.uFlags = 0;
436 ti.uId = 0x1234ABCD;
437 ti.lpszText = NULL;
438 ti.lParam = 0x1abe11ed;
439 GetClientRect(hwnd, &ti.rect);
440 r = SendMessageA(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti);
441 ok(r, "Adding the tool to the tooltip failed\n");
442
443 ti.cbSize = TTTOOLINFOA_V2_SIZE;
444 ti.lParam = 0xaaaaaaaa;
445 r = SendMessageA(hwnd, TTM_GETTOOLINFOA, 0, (LPARAM)&ti);
446 ok(r, "Getting tooltip info failed\n");
447 ok(0x1abe11ed == ti.lParam ||
448 broken(0x1abe11ed != ti.lParam), /* comctl32 < 5.81 */
449 "Expected 0x1abe11ed, got %lx\n", ti.lParam);
450
451 tiW.cbSize = TTTOOLINFOW_V2_SIZE;
452 tiW.hwnd = NULL;
453 tiW.uId = 0x1234ABCD;
454 tiW.lParam = 0xaaaaaaaa;
455 r = SendMessageA(hwnd, TTM_GETTOOLINFOW, 0, (LPARAM)&tiW);
456 ok(r, "Getting tooltip info failed\n");
457 ok(0x1abe11ed == tiW.lParam ||
458 broken(0x1abe11ed != tiW.lParam), /* comctl32 < 5.81 */
459 "Expected 0x1abe11ed, got %lx\n", tiW.lParam);
460
461 ti.cbSize = TTTOOLINFOA_V2_SIZE;
462 ti.uId = 0x1234ABCD;
463 ti.lParam = 0x55555555;
464 SendMessageA(hwnd, TTM_SETTOOLINFOA, 0, (LPARAM)&ti);
465
466 ti.cbSize = TTTOOLINFOA_V2_SIZE;
467 ti.lParam = 0xdeadbeef;
468 r = SendMessageA(hwnd, TTM_GETTOOLINFOA, 0, (LPARAM)&ti);
469 ok(r, "Getting tooltip info failed\n");
470 ok(0x55555555 == ti.lParam ||
471 broken(0x55555555 != ti.lParam), /* comctl32 < 5.81 */
472 "Expected 0x55555555, got %lx\n", ti.lParam);
473
474 DestroyWindow(hwnd);
475
476 /* 1. test size parameter validation rules (ansi messages) */
477 hwnd = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0,
478 10, 10, 300, 100,
479 NULL, NULL, NULL, 0);
480
481 ti.cbSize = TTTOOLINFOA_V1_SIZE - 1;
482 ti.hwnd = NULL;
483 ti.hinst = GetModuleHandleA(NULL);
484 ti.uFlags = 0;
485 ti.uId = 0x1234ABCD;
486 ti.lpszText = NULL;
487 ti.lParam = 0xdeadbeef;
488 GetClientRect(hwnd, &ti.rect);
489 r = SendMessage(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti);
490 ok(r, "Adding the tool to the tooltip failed\n");
491 r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0);
492 expect(1, r);
493
494 ti.cbSize = TTTOOLINFOA_V1_SIZE - 1;
495 ti.hwnd = NULL;
496 ti.uId = 0x1234ABCD;
497 SendMessage(hwnd, TTM_DELTOOLA, 0, (LPARAM)&ti);
498 r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0);
499 expect(0, r);
500
501 ti.cbSize = TTTOOLINFOA_V2_SIZE - 1;
502 ti.hwnd = NULL;
503 ti.hinst = GetModuleHandleA(NULL);
504 ti.uFlags = 0;
505 ti.uId = 0x1234ABCD;
506 ti.lpszText = NULL;
507 ti.lParam = 0xdeadbeef;
508 GetClientRect(hwnd, &ti.rect);
509 r = SendMessage(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti);
510 ok(r, "Adding the tool to the tooltip failed\n");
511 r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0);
512 expect(1, r);
513
514 ti.cbSize = TTTOOLINFOA_V2_SIZE - 1;
515 ti.hwnd = NULL;
516 ti.uId = 0x1234ABCD;
517 SendMessage(hwnd, TTM_DELTOOLA, 0, (LPARAM)&ti);
518 r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0);
519 expect(0, r);
520
521 ti.cbSize = TTTOOLINFOA_V2_SIZE + 1;
522 ti.hwnd = NULL;
523 ti.hinst = GetModuleHandleA(NULL);
524 ti.uFlags = 0;
525 ti.uId = 0x1234ABCD;
526 ti.lpszText = NULL;
527 ti.lParam = 0xdeadbeef;
528 GetClientRect(hwnd, &ti.rect);
529 r = SendMessage(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti);
530 ok(r, "Adding the tool to the tooltip failed\n");
531 r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0);
532 expect(1, r);
533
534 ti.cbSize = TTTOOLINFOA_V2_SIZE + 1;
535 ti.hwnd = NULL;
536 ti.uId = 0x1234ABCD;
537 SendMessage(hwnd, TTM_DELTOOLA, 0, (LPARAM)&ti);
538 r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0);
539 expect(0, r);
540
541 DestroyWindow(hwnd);
542
543 /* 2. test size parameter validation rules (w-messages) */
544 hwnd = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, 0,
545 10, 10, 300, 100,
546 NULL, NULL, NULL, 0);
547 if(!hwnd)
548 {
549 win_skip("CreateWindowExW() not supported. Skipping.\n");
550 return;
551 }
552
553 tiW.cbSize = TTTOOLINFOW_V1_SIZE - 1;
554 tiW.hwnd = NULL;
555 tiW.hinst = GetModuleHandleA(NULL);
556 tiW.uFlags = 0;
557 tiW.uId = 0x1234ABCD;
558 tiW.lpszText = NULL;
559 tiW.lParam = 0xdeadbeef;
560 GetClientRect(hwnd, &tiW.rect);
561 r = SendMessageW(hwnd, TTM_ADDTOOLW, 0, (LPARAM)&tiW);
562 ok(r, "Adding the tool to the tooltip failed\n");
563 r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0);
564 expect(1, r);
565
566 tiW.cbSize = TTTOOLINFOW_V1_SIZE - 1;
567 tiW.hwnd = NULL;
568 tiW.uId = 0x1234ABCD;
569 SendMessageW(hwnd, TTM_DELTOOLW, 0, (LPARAM)&tiW);
570 r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0);
571 expect(0, r);
572
573 tiW.cbSize = TTTOOLINFOW_V2_SIZE - 1;
574 tiW.hwnd = NULL;
575 tiW.hinst = GetModuleHandleA(NULL);
576 tiW.uFlags = 0;
577 tiW.uId = 0x1234ABCD;
578 tiW.lpszText = NULL;
579 tiW.lParam = 0xdeadbeef;
580 GetClientRect(hwnd, &tiW.rect);
581 r = SendMessageW(hwnd, TTM_ADDTOOLW, 0, (LPARAM)&tiW);
582 ok(r, "Adding the tool to the tooltip failed\n");
583 r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0);
584 expect(1, r);
585
586 tiW.cbSize = TTTOOLINFOW_V2_SIZE - 1;
587 tiW.hwnd = NULL;
588 tiW.uId = 0x1234ABCD;
589 SendMessageW(hwnd, TTM_DELTOOLW, 0, (LPARAM)&tiW);
590 r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0);
591 expect(0, r);
592
593 tiW.cbSize = TTTOOLINFOW_V2_SIZE + 1;
594 tiW.hwnd = NULL;
595 tiW.hinst = GetModuleHandleA(NULL);
596 tiW.uFlags = 0;
597 tiW.uId = 0x1234ABCD;
598 tiW.lpszText = NULL;
599 tiW.lParam = 0xdeadbeef;
600 GetClientRect(hwnd, &tiW.rect);
601 r = SendMessageW(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&tiW);
602 ok(r, "Adding the tool to the tooltip failed\n");
603 r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0);
604 expect(1, r);
605 /* looks like TTM_DELTOOLW doesn't work with invalid size */
606 tiW.cbSize = TTTOOLINFOW_V2_SIZE + 1;
607 tiW.hwnd = NULL;
608 tiW.uId = 0x1234ABCD;
609 SendMessageW(hwnd, TTM_DELTOOLW, 0, (LPARAM)&tiW);
610 r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0);
611 expect(1, r);
612
613 tiW.cbSize = TTTOOLINFOW_V2_SIZE;
614 tiW.hwnd = NULL;
615 tiW.uId = 0x1234ABCD;
616 SendMessageW(hwnd, TTM_DELTOOLW, 0, (LPARAM)&tiW);
617 r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0);
618 expect(0, r);
619
620 DestroyWindow(hwnd);
621 }
622
623 START_TEST(tooltips)
624 {
625 InitCommonControls();
626
627 test_create_tooltip();
628 test_customdraw();
629 test_gettext();
630 test_ttm_gettoolinfo();
631 }