source: trunk/src/comctl32/tooltips.cpp@ 3145

Last change on this file since 3145 was 3145, checked in by cbratschi, 25 years ago

trackbar buddy fix, tooltip enhancements

File size: 68.1 KB
Line 
1/* $Id: tooltips.cpp,v 1.3 2000-03-17 17:13:26 cbratschi Exp $ */
2/*
3 * Tool tip control
4 *
5 * Copyright 1998 Eric Kohl
6 * Copyright 1999 Achim Hasenmueller
7 * Copyright 1999 Christoph Bratschi
8 *
9 * TODO:
10 * - Custom draw support.
11 *
12 * Testing:
13 * - Run tests using Waite Group Windows95 API Bible Volume 2.
14 * The second cdrom (chapter 3) contains executables activate.exe,
15 * curtool.exe, deltool.exe, enumtools.exe, getinfo.exe, getiptxt.exe,
16 * hittest.exe, needtext.exe, newrect.exe, updtext.exe and winfrpt.exe.
17 */
18
19/* WINE 20000130 level */
20
21#include <string.h>
22
23#include "winbase.h"
24#include "commctrl.h"
25#include "tooltips.h"
26#include "comctl32.h"
27
28#define ID_TIMERSHOW 1 /* show delay timer */
29#define ID_TIMERPOP 2 /* auto pop timer */
30#define ID_TIMERLEAVE 3 /* tool leave timer */
31
32
33extern LPSTR COMCTL32_aSubclass; /* global subclassing atom */
34
35/* property name of tooltip window handle */
36/*#define TT_SUBCLASS_PROP "CC32SubclassInfo" */
37
38#define TOOLTIPS_GetInfoPtr(hWindow) ((TOOLTIPS_INFO *)GetWindowLongA (hWindow, 0))
39
40LRESULT CALLBACK
41TOOLTIPS_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
42
43
44static VOID TOOLTIPS_Draw (HWND hwnd, HDC hdc)
45{
46 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(hwnd);
47 RECT rc;
48 INT oldBkMode;
49 HFONT hOldFont;
50 HBRUSH hBrush;
51 UINT uFlags = DT_EXTERNALLEADING;
52
53 if (infoPtr->nMaxTipWidth > -1) uFlags |= DT_WORDBREAK;
54 if (GetWindowLongA(hwnd,GWL_STYLE) & TTS_NOPREFIX) uFlags |= DT_NOPREFIX;
55 GetClientRect(hwnd,&rc);
56
57 /* fill the background */
58 hBrush = CreateSolidBrush(infoPtr->clrBk);
59 FillRect(hdc,&rc,hBrush);
60 DeleteObject(hBrush);
61
62 /* calculate text rectangle */
63 rc.left += (2+infoPtr->rcMargin.left);
64 rc.top += (2+infoPtr->rcMargin.top);
65 rc.right -= (2+infoPtr->rcMargin.right);
66 rc.bottom -= (2+infoPtr->rcMargin.bottom);
67
68 /* draw text */
69 oldBkMode = SetBkMode(hdc,TRANSPARENT);
70 SetTextColor(hdc,infoPtr->clrText);
71 hOldFont = SelectObject(hdc,infoPtr->hFont);
72 DrawTextW(hdc,infoPtr->szTipText,-1,&rc,uFlags);
73 SelectObject(hdc,hOldFont);
74 if (oldBkMode != TRANSPARENT) SetBkMode(hdc,oldBkMode);
75}
76
77
78static VOID
79TOOLTIPS_GetTipText(HWND hwnd,TOOLTIPS_INFO *infoPtr,INT nTool)
80{
81 TTTOOL_INFO *toolPtr = &infoPtr->tools[nTool];
82
83 if ((toolPtr->hinst) && (HIWORD((UINT)toolPtr->lpszText) == 0))
84 {
85 /* load a resource */
86
87 LoadStringW(toolPtr->hinst,(UINT)toolPtr->lpszText,infoPtr->szTipText,INFOTIPSIZE);
88 } else if (toolPtr->lpszText)
89 {
90 if (toolPtr->lpszText == LPSTR_TEXTCALLBACKW)
91 {
92 NMTTDISPINFOA ttnmdi;
93
94 /* fill NMHDR struct */
95 ZeroMemory (&ttnmdi,sizeof(NMTTDISPINFOA));
96 ttnmdi.hdr.hwndFrom = hwnd;
97 ttnmdi.hdr.idFrom = toolPtr->uId;
98 ttnmdi.hdr.code = TTN_GETDISPINFOA;
99 ttnmdi.lpszText = (LPSTR)&ttnmdi.szText;
100 ttnmdi.uFlags = toolPtr->uFlags;
101 ttnmdi.lParam = toolPtr->lParam;
102 SendMessageA (toolPtr->hwnd,WM_NOTIFY,(WPARAM)toolPtr->uId,(LPARAM)&ttnmdi);
103
104 if ((ttnmdi.hinst) && (HIWORD((UINT)ttnmdi.szText) == 0))
105 {
106 LoadStringW (ttnmdi.hinst,(UINT)ttnmdi.szText,infoPtr->szTipText,INFOTIPSIZE);
107 if (ttnmdi.uFlags & TTF_DI_SETITEM)
108 {
109 toolPtr->hinst = ttnmdi.hinst;
110 toolPtr->lpszText = (LPWSTR)ttnmdi.szText;
111 }
112 } else if (ttnmdi.szText[0])
113 {
114 lstrcpynAtoW(infoPtr->szTipText,ttnmdi.szText,INFOTIPSIZE);
115 if (ttnmdi.uFlags & TTF_DI_SETITEM)
116 {
117 INT len = lstrlenA(ttnmdi.szText);
118 toolPtr->hinst = 0;
119 toolPtr->lpszText = (WCHAR*)COMCTL32_Alloc((len+1)* sizeof(WCHAR));
120 lstrcpyAtoW(toolPtr->lpszText,ttnmdi.szText);
121 }
122 } else if (ttnmdi.lpszText == 0)
123 {
124 /* no text available */
125 infoPtr->szTipText[0] = '\0';
126 } else if (ttnmdi.lpszText != LPSTR_TEXTCALLBACKA)
127 {
128 lstrcpynAtoW(infoPtr->szTipText,ttnmdi.lpszText,INFOTIPSIZE);
129 if (ttnmdi.uFlags & TTF_DI_SETITEM)
130 {
131 INT len = lstrlenA(ttnmdi.lpszText);
132 toolPtr->hinst = 0;
133 toolPtr->lpszText = (WCHAR*)COMCTL32_Alloc((len+1)*sizeof(WCHAR));
134 lstrcpyAtoW(toolPtr->lpszText,ttnmdi.lpszText);
135 }
136 } else
137 {
138 //ERR (tooltips, "recursive text callback!\n");
139 infoPtr->szTipText[0] = '\0';
140 }
141 } else
142 {
143 /* the item is a usual (unicode) text */
144 lstrcpynW(infoPtr->szTipText,toolPtr->lpszText,INFOTIPSIZE);
145 }
146 }
147 else
148 {
149 /* no text available */
150 infoPtr->szTipText[0] = '\0';
151 }
152
153// TRACE (tooltips, "\"%s\"\n", debugstr_w(infoPtr->szTipText));
154}
155
156static VOID
157TOOLTIPS_CalcTipRect (HWND hwnd,TOOLTIPS_INFO *infoPtr,TTTOOL_INFO *toolPtr,LPRECT lpRect)
158{
159 HDC hdc;
160 HFONT hOldFont;
161 UINT uFlags = DT_EXTERNALLEADING | DT_CALCRECT;
162 RECT rc = {0,0,0,0};
163 SIZE size;
164
165 if (infoPtr->nMaxTipWidth > -1)
166 {
167 rc.right = infoPtr->nMaxTipWidth;
168 uFlags |= DT_WORDBREAK;
169 }
170 if (GetWindowLongA(hwnd,GWL_STYLE) & TTS_NOPREFIX) uFlags |= DT_NOPREFIX;
171 //TRACE (tooltips, "\"%s\"\n", debugstr_w(infoPtr->szTipText));
172
173 hdc = GetDC(hwnd);
174 hOldFont = SelectObject(hdc,infoPtr->hFont);
175 DrawTextW(hdc,infoPtr->szTipText,-1,&rc,uFlags);
176 SelectObject(hdc,hOldFont);
177 ReleaseDC(hwnd,hdc);
178
179 size.cx = rc.right-rc.left+4+infoPtr->rcMargin.left+infoPtr->rcMargin.right;
180 size.cy = rc.bottom-rc.top+4+infoPtr->rcMargin.bottom+infoPtr->rcMargin.top;
181
182 if (toolPtr->uFlags & TTF_ABSOLUTE)
183 {
184 rc.left = infoPtr->xTrackPos;
185 rc.top = infoPtr->yTrackPos;
186
187 if (toolPtr->uFlags & TTF_ALIGNMASK)
188 {
189 //CB: Odin only (Win32 does something similar but with an undocumented mechanism)
190
191 if (toolPtr->uFlags & TTF_ALIGNLEFT)
192 rc.left -= size.cx;
193 else if (toolPtr->uFlags & TTF_HCENTER)
194 rc.left -= size.cx/2;
195
196 if (toolPtr->uFlags & TTF_ALIGNTOP)
197 rc.top -= size.cy;
198 else if (toolPtr->uFlags & TTF_VCENTER)
199 rc.top -= size.cy/2;
200
201 } else
202 {
203 if (toolPtr->uFlags & TTF_CENTERTIP)
204 {
205 rc.left -= (size.cx/2);
206 rc.top -= (size.cy/2);
207 }
208 }
209 } else
210 {
211 RECT rcTool;
212
213 if (toolPtr->uFlags & TTF_IDISHWND)
214 {
215 GetWindowRect((HWND)toolPtr->uId,&rcTool); //screen coordinates
216 } else
217 {
218 rcTool = toolPtr->rect;
219 MapWindowPoints(toolPtr->hwnd,(HWND)0,(LPPOINT)&rcTool,2);
220 }
221
222 if (toolPtr->uFlags & TTF_CENTERTIP)
223 {
224 if (infoPtr->bTrackActive)
225 {
226 GetCursorPos((LPPOINT)&rc);
227 rc.top += 20;
228 rc.left -= (size.cx / 2);
229 rc.top -= (size.cy / 2);
230 } else
231 {
232 rc.left = (rcTool.left + rcTool.right-size.cx)/ 2;
233 rc.top = rcTool.bottom+2;
234 }
235
236 } else
237 {
238 GetCursorPos((LPPOINT)&rc);
239 rc.top += 20;
240 }
241
242 /* smart placement */
243 if (infoPtr->bTrackActive)
244 {
245 if ((rc.left + size.cx > rcTool.left) && (rc.left < rcTool.right) &&
246 (rc.top + size.cy > rcTool.top) && (rc.top < rcTool.bottom))
247 rc.left = rcTool.right;
248 }
249 }
250
251 //TRACE (tooltips, "pos %d - %d\n", rect.left, rect.top);
252
253 rc.right = rc.left+size.cx;
254 rc.bottom = rc.top+size.cy;
255
256 AdjustWindowRectEx (&rc,GetWindowLongA(hwnd,GWL_STYLE),
257 FALSE,GetWindowLongA(hwnd,GWL_EXSTYLE));
258
259 *lpRect = rc;
260}
261
262static VOID
263TOOLTIPS_CalcTipSize (HWND hwnd, TOOLTIPS_INFO *infoPtr, LPSIZE lpSize)
264{
265 HDC hdc;
266 HFONT hOldFont;
267 UINT uFlags = DT_EXTERNALLEADING | DT_CALCRECT;
268 RECT rc = {0, 0, 0, 0};
269
270 if (infoPtr->nMaxTipWidth > -1) {
271 rc.right = infoPtr->nMaxTipWidth;
272 uFlags |= DT_WORDBREAK;
273 }
274 if (GetWindowLongA (hwnd, GWL_STYLE) & TTS_NOPREFIX)
275 uFlags |= DT_NOPREFIX;
276 //TRACE("\"%s\"\n", debugstr_w(infoPtr->szTipText));
277
278 hdc = GetDC (hwnd);
279 hOldFont = SelectObject (hdc, infoPtr->hFont);
280 DrawTextW (hdc, infoPtr->szTipText, -1, &rc, uFlags);
281 SelectObject (hdc, hOldFont);
282 ReleaseDC (hwnd, hdc);
283
284 lpSize->cx = rc.right - rc.left + 4 +
285 infoPtr->rcMargin.left + infoPtr->rcMargin.right;
286 lpSize->cy = rc.bottom - rc.top + 4 +
287 infoPtr->rcMargin.bottom + infoPtr->rcMargin.top;
288}
289
290static VOID
291TOOLTIPS_Show (HWND hwnd, TOOLTIPS_INFO *infoPtr)
292{
293 TTTOOL_INFO *toolPtr;
294 RECT rect, wndrect;
295 SIZE size;
296 HDC hdc;
297 NMHDR hdr;
298
299 if (infoPtr->nTool == -1) {
300// TRACE("invalid tool (-1)!\n");
301 return;
302 }
303
304 infoPtr->nCurrentTool = infoPtr->nTool;
305
306// TRACE("Show tooltip pre %d!\n", infoPtr->nTool);
307
308 TOOLTIPS_GetTipText (hwnd, infoPtr, infoPtr->nCurrentTool);
309
310 if (infoPtr->szTipText[0] == L'\0') {
311 infoPtr->nCurrentTool = -1;
312 return;
313 }
314
315// TRACE("Show tooltip %d!\n", infoPtr->nCurrentTool);
316 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
317
318 hdr.hwndFrom = hwnd;
319 hdr.idFrom = toolPtr->uId;
320 hdr.code = TTN_SHOW;
321 SendMessageA (toolPtr->hwnd, WM_NOTIFY,
322 (WPARAM)toolPtr->uId, (LPARAM)&hdr);
323
324// TRACE("\"%s\"\n", debugstr_w(infoPtr->szTipText));
325
326 TOOLTIPS_CalcTipSize (hwnd, infoPtr, &size);
327// TRACE("size %d - %d\n", size.cx, size.cy);
328
329 if (toolPtr->uFlags & TTF_CENTERTIP) {
330 RECT rc;
331
332 if (toolPtr->uFlags & TTF_IDISHWND)
333 GetWindowRect ((HWND)toolPtr->uId, &rc);
334 else {
335 rc = toolPtr->rect;
336 MapWindowPoints (toolPtr->hwnd, (HWND)0, (LPPOINT)&rc, 2);
337 }
338 rect.left = (rc.left + rc.right - size.cx) / 2;
339 rect.top = rc.bottom + 2;
340 }
341 else {
342 GetCursorPos ((LPPOINT)&rect);
343 rect.top += 20;
344 }
345
346// TRACE("pos %d - %d\n", rect.left, rect.top);
347
348 rect.right = rect.left + size.cx;
349 rect.bottom = rect.top + size.cy;
350
351 /* check position */
352 wndrect.right = GetSystemMetrics( SM_CXSCREEN );
353 if( rect.right > wndrect.right ) {
354 rect.left -= rect.right - wndrect.right + 2;
355 rect.right = wndrect.right - 2;
356 }
357 wndrect.bottom = GetSystemMetrics( SM_CYSCREEN );
358 if( rect.bottom > wndrect.bottom ) {
359 RECT rc;
360
361 if (toolPtr->uFlags & TTF_IDISHWND)
362 GetWindowRect ((HWND)toolPtr->uId, &rc);
363 else {
364 rc = toolPtr->rect;
365 MapWindowPoints (toolPtr->hwnd, (HWND)0, (LPPOINT)&rc, 2);
366 }
367 rect.bottom = rc.top - 2;
368 rect.top = rect.bottom - size.cy;
369 }
370
371 AdjustWindowRectEx (&rect, GetWindowLongA (hwnd, GWL_STYLE),
372 FALSE, GetWindowLongA (hwnd, GWL_EXSTYLE));
373
374 SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
375 rect.right - rect.left, rect.bottom - rect.top,
376 SWP_SHOWWINDOW | SWP_NOACTIVATE);
377
378 /* repaint the tooltip */
379 hdc = GetDC (hwnd);
380 TOOLTIPS_Draw(hwnd, hdc);
381 ReleaseDC (hwnd, hdc);
382
383 SetTimer (hwnd, ID_TIMERPOP, infoPtr->nAutoPopTime, 0);
384}
385
386
387static VOID
388TOOLTIPS_Hide (HWND hwnd, TOOLTIPS_INFO *infoPtr)
389{
390 TTTOOL_INFO *toolPtr;
391 NMHDR hdr;
392
393 if (infoPtr->nCurrentTool == -1)
394 return;
395
396 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
397// TRACE (tooltips, "Hide tooltip %d!\n", infoPtr->nCurrentTool);
398 KillTimer (hwnd, ID_TIMERPOP);
399
400 hdr.hwndFrom = hwnd;
401 hdr.idFrom = toolPtr->uId;
402 hdr.code = TTN_POP;
403 SendMessageA (toolPtr->hwnd, WM_NOTIFY,
404 (WPARAM)toolPtr->uId, (LPARAM)&hdr);
405
406 infoPtr->nCurrentTool = -1;
407
408 SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0,
409 SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOACTIVATE);
410}
411
412
413static VOID
414TOOLTIPS_TrackShow (HWND hwnd, TOOLTIPS_INFO *infoPtr)
415{
416 TTTOOL_INFO *toolPtr;
417 RECT rect;
418 HDC hdc;
419 NMHDR hdr;
420
421 if (infoPtr->nTrackTool == -1)
422 {
423 //TRACE (tooltips, "invalid tracking tool (-1)!\n");
424 return;
425 }
426
427 //TRACE (tooltips, "show tracking tooltip pre %d!\n", infoPtr->nTrackTool);
428
429 TOOLTIPS_GetTipText(hwnd,infoPtr,infoPtr->nTrackTool);
430
431 if (infoPtr->szTipText[0] == '\0')
432 {
433 infoPtr->nTrackTool = -1;
434 return;
435 }
436
437 //TRACE (tooltips, "show tracking tooltip %d!\n", infoPtr->nTrackTool);
438 toolPtr = &infoPtr->tools[infoPtr->nTrackTool];
439
440 hdr.hwndFrom = hwnd;
441 hdr.idFrom = toolPtr->uId;
442 hdr.code = TTN_SHOW;
443 SendMessageA(toolPtr->hwnd,WM_NOTIFY,(WPARAM)toolPtr->uId,(LPARAM)&hdr);
444
445 //TRACE (tooltips, "\"%s\"\n", debugstr_w(infoPtr->szTipText));
446
447 TOOLTIPS_CalcTipRect(hwnd,infoPtr,toolPtr,&rect);
448
449 SetWindowPos (hwnd,HWND_TOP,rect.left,rect.top,
450 rect.right-rect.left,rect.bottom-rect.top,
451 SWP_SHOWWINDOW | SWP_NOACTIVATE );
452
453 hdc = GetDC (hwnd);
454 TOOLTIPS_Draw(hwnd, hdc);
455 ReleaseDC (hwnd, hdc);
456}
457
458
459static VOID
460TOOLTIPS_TrackHide (HWND hwnd, TOOLTIPS_INFO *infoPtr)
461{
462 TTTOOL_INFO *toolPtr;
463 NMHDR hdr;
464
465 if (infoPtr->nTrackTool == -1)
466 return;
467
468 toolPtr = &infoPtr->tools[infoPtr->nTrackTool];
469// TRACE (tooltips, "hide tracking tooltip %d!\n", infoPtr->nTrackTool);
470
471 hdr.hwndFrom = hwnd;
472 hdr.idFrom = toolPtr->uId;
473 hdr.code = TTN_POP;
474 SendMessageA (toolPtr->hwnd, WM_NOTIFY,
475 (WPARAM)toolPtr->uId, (LPARAM)&hdr);
476
477 SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0,
478 SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOACTIVATE);
479}
480
481
482static INT
483TOOLTIPS_GetToolFromInfoA (TOOLTIPS_INFO *infoPtr, LPTTTOOLINFOA lpToolInfo)
484{
485 TTTOOL_INFO *toolPtr;
486 INT nTool;
487
488 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
489 toolPtr = &infoPtr->tools[nTool];
490
491 if (!(toolPtr->uFlags & TTF_IDISHWND) &&
492 (lpToolInfo->hwnd == toolPtr->hwnd) &&
493 (lpToolInfo->uId == toolPtr->uId))
494 return nTool;
495 }
496
497 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
498 toolPtr = &infoPtr->tools[nTool];
499
500 if ((toolPtr->uFlags & TTF_IDISHWND) &&
501 (lpToolInfo->uId == toolPtr->uId))
502 return nTool;
503 }
504
505 return -1;
506}
507
508
509static INT
510TOOLTIPS_GetToolFromInfoW (TOOLTIPS_INFO *infoPtr, LPTTTOOLINFOW lpToolInfo)
511{
512 TTTOOL_INFO *toolPtr;
513 INT nTool;
514
515 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
516 toolPtr = &infoPtr->tools[nTool];
517
518 if (!(toolPtr->uFlags & TTF_IDISHWND) &&
519 (lpToolInfo->hwnd == toolPtr->hwnd) &&
520 (lpToolInfo->uId == toolPtr->uId))
521 return nTool;
522 }
523
524 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
525 toolPtr = &infoPtr->tools[nTool];
526
527 if ((toolPtr->uFlags & TTF_IDISHWND) &&
528 (lpToolInfo->uId == toolPtr->uId))
529 return nTool;
530 }
531
532 return -1;
533}
534
535
536static INT
537TOOLTIPS_GetToolFromPoint (TOOLTIPS_INFO *infoPtr, HWND hwnd, LPPOINT lpPt)
538{
539 TTTOOL_INFO *toolPtr;
540 INT nTool;
541
542 //@@@AH 2000/02/25 make sure we don't get garbage in
543 if (!infoPtr)
544 {
545 dprintf(("Tooltips:GetToolFromPoint: infoPtr == NULL!!!\n"));
546 return 0;
547 }
548
549 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
550 toolPtr = &infoPtr->tools[nTool];
551
552 if (!(toolPtr->uFlags & TTF_IDISHWND)) {
553 if (hwnd != toolPtr->hwnd)
554 continue;
555 if (!PtInRect (&toolPtr->rect, *lpPt))
556 continue;
557 return nTool;
558 }
559 }
560
561 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
562 toolPtr = &infoPtr->tools[nTool];
563
564 if (toolPtr->uFlags & TTF_IDISHWND) {
565 if ((HWND)toolPtr->uId == hwnd)
566 return nTool;
567 }
568 }
569
570 return -1;
571}
572
573
574static INT
575TOOLTIPS_GetToolFromMessage (TOOLTIPS_INFO *infoPtr, HWND hwndTool)
576{
577 DWORD dwPos;
578 POINT pt;
579
580 dwPos = GetMessagePos ();
581 pt.x = (INT)LOWORD(dwPos);
582 pt.y = (INT)HIWORD(dwPos);
583 ScreenToClient (hwndTool, &pt);
584
585 return TOOLTIPS_GetToolFromPoint (infoPtr, hwndTool, &pt);
586}
587
588
589static BOOL
590TOOLTIPS_IsWindowActive (HWND hwnd)
591{
592 HWND hwndActive = GetActiveWindow ();
593 if (!hwndActive)
594 return FALSE;
595 if (hwndActive == hwnd)
596 return TRUE;
597 return IsChild (hwndActive, hwnd);
598}
599
600
601static INT
602TOOLTIPS_CheckTool (HWND hwnd, BOOL bShowTest)
603{
604 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
605 POINT pt;
606 HWND hwndTool;
607 INT nTool;
608
609 GetCursorPos (&pt);
610 hwndTool = SendMessageA (hwnd, TTM_WINDOWFROMPOINT, 0, (LPARAM)&pt);
611 if (hwndTool == 0)
612 return -1;
613
614 ScreenToClient (hwndTool, &pt);
615 nTool = TOOLTIPS_GetToolFromPoint (infoPtr, hwndTool, &pt);
616 if (nTool == -1)
617 return -1;
618
619 if (!(GetWindowLongA (hwnd, GWL_STYLE) & TTS_ALWAYSTIP) && bShowTest) {
620 if (!TOOLTIPS_IsWindowActive (GetWindow (hwnd, GW_OWNER)))
621 return -1;
622 }
623
624// TRACE (tooltips, "tool %d\n", nTool);
625
626 return nTool;
627}
628
629
630static LRESULT
631TOOLTIPS_Activate (HWND hwnd, WPARAM wParam, LPARAM lParam)
632{
633 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(hwnd);
634
635 infoPtr->bActive = (BOOL)wParam;
636
637// if (infoPtr->bActive)
638// TRACE (tooltips, "activate!\n");
639
640 if (!(infoPtr->bActive) && (infoPtr->nCurrentTool != -1))
641 TOOLTIPS_Hide (hwnd, infoPtr);
642
643 return 0;
644}
645
646
647static VOID TOOLTIPS_Subclass(HWND hwnd,TTTOOL_INFO *toolPtr)
648{
649 if (toolPtr->uFlags & TTF_SUBCLASS)
650 {
651 if (toolPtr->uFlags & TTF_IDISHWND)
652 {
653 LPTT_SUBCLASS_INFO lpttsi =
654 (LPTT_SUBCLASS_INFO)GetPropA((HWND)toolPtr->uId,COMCTL32_aSubclass);
655 if (lpttsi == NULL)
656 {
657 lpttsi = (LPTT_SUBCLASS_INFO)COMCTL32_Alloc(sizeof(TT_SUBCLASS_INFO));
658 lpttsi->wpOrigProc =
659 (WNDPROC)SetWindowLongA ((HWND)toolPtr->uId,
660 GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc);
661 lpttsi->hwndToolTip = hwnd;
662 lpttsi->uRefCount++;
663 SetPropA ((HWND)toolPtr->uId,COMCTL32_aSubclass,(HANDLE)lpttsi);
664 }
665// else
666// WARN (tooltips, "A window tool must only be listed once!\n");
667 } else
668 {
669 LPTT_SUBCLASS_INFO lpttsi =
670 (LPTT_SUBCLASS_INFO)GetPropA (toolPtr->hwnd, COMCTL32_aSubclass);
671 if (lpttsi == NULL)
672 {
673 lpttsi = (LPTT_SUBCLASS_INFO)COMCTL32_Alloc(sizeof(TT_SUBCLASS_INFO));
674 lpttsi->wpOrigProc =
675 (WNDPROC)SetWindowLongA (toolPtr->hwnd,
676 GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc);
677 lpttsi->hwndToolTip = hwnd;
678 lpttsi->uRefCount++;
679 SetPropA(toolPtr->hwnd,COMCTL32_aSubclass,(HANDLE)lpttsi);
680 } else lpttsi->uRefCount++;
681 }
682// TRACE (tooltips, "subclassing installed!\n");
683 }
684}
685
686static VOID TOOLTIPS_Desubclass(TTTOOL_INFO *toolPtr)
687{
688 if (toolPtr->uFlags & TTF_SUBCLASS)
689 {
690 if (toolPtr->uFlags & TTF_IDISHWND)
691 {
692 LPTT_SUBCLASS_INFO lpttsi =
693 (LPTT_SUBCLASS_INFO)GetPropA((HWND)toolPtr->uId,COMCTL32_aSubclass);
694 if (lpttsi)
695 {
696 SetWindowLongA ((HWND)toolPtr->uId,GWL_WNDPROC,(LONG)lpttsi->wpOrigProc);
697 RemovePropA ((HWND)toolPtr->uId,COMCTL32_aSubclass);
698 COMCTL32_Free(&lpttsi);
699 }
700// else
701// ERR (tooltips, "Invalid data handle!\n");
702 } else
703 {
704 LPTT_SUBCLASS_INFO lpttsi =
705 (LPTT_SUBCLASS_INFO)GetPropA(toolPtr->hwnd,COMCTL32_aSubclass);
706 if (lpttsi)
707 {
708 if (lpttsi->uRefCount == 1)
709 {
710 SetWindowLongA((HWND)toolPtr->uId,GWL_WNDPROC,(LONG)lpttsi->wpOrigProc);
711 RemovePropA((HWND)toolPtr->uId,COMCTL32_aSubclass);
712 COMCTL32_Free(&lpttsi);
713 } else lpttsi->uRefCount--;
714 }
715// else
716// ERR (tooltips, "Invalid data handle!\n");
717 }
718 }
719}
720
721static LRESULT
722TOOLTIPS_AddToolA(HWND hwnd,WPARAM wParam,LPARAM lParam)
723{
724 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(hwnd);
725 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
726 TTTOOL_INFO *toolPtr;
727
728 if (lpToolInfo == NULL) return FALSE;
729 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA) return FALSE;
730
731// TRACE (tooltips, "add tool (%x) %x %d%s!\n",
732// hwnd, lpToolInfo->hwnd, lpToolInfo->uId,
733// (lpToolInfo->uFlags & TTF_IDISHWND) ? " TTF_IDISHWND" : "");
734
735 if (infoPtr->uNumTools == 0)
736 {
737 infoPtr->tools = (TTTOOL_INFO*)COMCTL32_Alloc(sizeof(TTTOOL_INFO));
738 toolPtr = infoPtr->tools;
739 } else
740 {
741 TTTOOL_INFO *oldTools = infoPtr->tools;
742 INT x;
743
744 toolPtr = NULL;
745
746 //check if toolinfo already exists
747 for (x = 0;x < infoPtr->uNumTools;x++)
748 {
749 if (lpToolInfo->hwnd == infoPtr->tools[x].hwnd && lpToolInfo->uId == infoPtr->tools[x].uId)
750 {
751 //return toolPtr
752 toolPtr = &infoPtr->tools[x];
753 //free allocated memory
754 TOOLTIPS_Desubclass(toolPtr);
755 if ((toolPtr->hinst) && (toolPtr->lpszText))
756 {
757 if (toolPtr->lpszText != LPSTR_TEXTCALLBACKW) COMCTL32_Free(toolPtr->lpszText);
758 }
759
760 break;
761 }
762 }
763
764 if (toolPtr == NULL)
765 {
766 infoPtr->tools = (TTTOOL_INFO*)COMCTL32_Alloc (sizeof(TTTOOL_INFO)*(infoPtr->uNumTools+1));
767 memcpy(infoPtr->tools,oldTools,infoPtr->uNumTools*sizeof(TTTOOL_INFO));
768 COMCTL32_Free(oldTools);
769 toolPtr = &infoPtr->tools[infoPtr->uNumTools];
770 }
771 }
772
773 infoPtr->uNumTools++;
774
775 /* copy tool data */
776 toolPtr->uFlags = lpToolInfo->uFlags;
777 toolPtr->hwnd = lpToolInfo->hwnd;
778 toolPtr->uId = lpToolInfo->uId;
779 toolPtr->rect = lpToolInfo->rect;
780 toolPtr->hinst = lpToolInfo->hinst;
781
782 if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0))
783 {
784// TRACE (tooltips, "add string id %x!\n", (int)lpToolInfo->lpszText);
785 toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
786 } else if (lpToolInfo->lpszText)
787 {
788 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKA)
789 {
790// TRACE (tooltips, "add CALLBACK!\n");
791 toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
792 } else
793 {
794 INT len = lstrlenA (lpToolInfo->lpszText);
795// TRACE (tooltips, "add text \"%s\"!\n", lpToolInfo->lpszText);
796 toolPtr->lpszText = (WCHAR*)COMCTL32_Alloc((len+1)*sizeof(WCHAR));
797 lstrcpyAtoW (toolPtr->lpszText, lpToolInfo->lpszText);
798 }
799 } else toolPtr->lpszText = NULL;
800
801 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
802 toolPtr->lParam = lpToolInfo->lParam;
803
804 /* install subclassing hook */
805 TOOLTIPS_Subclass(hwnd,toolPtr);
806
807 return TRUE;
808}
809
810
811static LRESULT
812TOOLTIPS_AddToolW (HWND hwnd, WPARAM wParam, LPARAM lParam)
813{
814 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
815 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
816 TTTOOL_INFO *toolPtr;
817
818 if (lpToolInfo == NULL)
819 return FALSE;
820 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
821 return FALSE;
822
823// TRACE (tooltips, "add tool (%x) %x %d%s!\n",
824// hwnd, lpToolInfo->hwnd, lpToolInfo->uId,
825// (lpToolInfo->uFlags & TTF_IDISHWND) ? " TTF_IDISHWND" : "");
826
827 if (infoPtr->uNumTools == 0)
828 {
829 infoPtr->tools = (TTTOOL_INFO*)COMCTL32_Alloc (sizeof(TTTOOL_INFO));
830 toolPtr = infoPtr->tools;
831 } else
832 {
833 TTTOOL_INFO *oldTools = infoPtr->tools;
834 INT x;
835
836 toolPtr = NULL;
837
838 //check if toolinfo already exists
839 for (x = 0;x < infoPtr->uNumTools;x++)
840 {
841 if (lpToolInfo->hwnd == infoPtr->tools[x].hwnd && lpToolInfo->uId == infoPtr->tools[x].uId)
842 {
843 //return toolPtr
844 toolPtr = &infoPtr->tools[x];
845 //free allocated memory
846 TOOLTIPS_Desubclass(toolPtr);
847 if ((toolPtr->hinst) && (toolPtr->lpszText))
848 {
849 if (toolPtr->lpszText != LPSTR_TEXTCALLBACKW) COMCTL32_Free(toolPtr->lpszText);
850 }
851
852 break;
853 }
854 }
855
856 if (toolPtr == NULL)
857 {
858 infoPtr->tools = (TTTOOL_INFO*)COMCTL32_Alloc(sizeof(TTTOOL_INFO)*(infoPtr->uNumTools+1));
859 memcpy (infoPtr->tools,oldTools,infoPtr->uNumTools*sizeof(TTTOOL_INFO));
860 COMCTL32_Free(oldTools);
861 toolPtr = &infoPtr->tools[infoPtr->uNumTools];
862 }
863 }
864
865 infoPtr->uNumTools++;
866
867 /* copy tool data */
868 toolPtr->uFlags = lpToolInfo->uFlags;
869 toolPtr->hwnd = lpToolInfo->hwnd;
870 toolPtr->uId = lpToolInfo->uId;
871 toolPtr->rect = lpToolInfo->rect;
872 toolPtr->hinst = lpToolInfo->hinst;
873
874 if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0)) {
875// TRACE (tooltips, "add string id %x!\n", (int)lpToolInfo->lpszText);
876 toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
877 }
878 else if (lpToolInfo->lpszText) {
879 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKW) {
880// TRACE (tooltips, "add CALLBACK!\n");
881 toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
882 }
883 else {
884 INT len = lstrlenW (lpToolInfo->lpszText);
885// TRACE (tooltips, "add text \"%s\"!\n",
886// debugstr_w(lpToolInfo->lpszText));
887 toolPtr->lpszText = (WCHAR*)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
888 lstrcpyW (toolPtr->lpszText, lpToolInfo->lpszText);
889 }
890 }
891
892 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
893 toolPtr->lParam = lpToolInfo->lParam;
894
895 /* install subclassing hook */
896 TOOLTIPS_Subclass(hwnd,toolPtr);
897
898 return TRUE;
899}
900
901
902static LRESULT
903TOOLTIPS_DelToolA (HWND hwnd, WPARAM wParam, LPARAM lParam)
904{
905 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
906 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
907 TTTOOL_INFO *toolPtr;
908 INT nTool;
909
910 if (lpToolInfo == NULL)
911 return 0;
912 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA)
913 return 0;
914 if (infoPtr->uNumTools == 0)
915 return 0;
916
917 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
918 if (nTool == -1) return 0;
919
920// TRACE (tooltips, "tool %d\n", nTool);
921
922 /* delete text string */
923 toolPtr = &infoPtr->tools[nTool];
924 if ((toolPtr->hinst) && (toolPtr->lpszText)) {
925 if ( (toolPtr->lpszText != LPSTR_TEXTCALLBACKW) &&
926 (HIWORD((INT)toolPtr->lpszText) != 0) )
927 COMCTL32_Free (toolPtr->lpszText);
928 }
929
930 /* remove subclassing */
931 TOOLTIPS_Desubclass(toolPtr);
932
933 /* delete tool from tool list */
934 if (infoPtr->uNumTools == 1) {
935 COMCTL32_Free (infoPtr->tools);
936 infoPtr->tools = NULL;
937 }
938 else {
939 TTTOOL_INFO *oldTools = infoPtr->tools;
940 infoPtr->tools =
941 (TTTOOL_INFO*)COMCTL32_Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1));
942
943 if (nTool > 0)
944 memcpy (&infoPtr->tools[0], &oldTools[0],
945 nTool * sizeof(TTTOOL_INFO));
946
947 if (nTool < infoPtr->uNumTools - 1)
948 memcpy (&infoPtr->tools[nTool], &oldTools[nTool + 1],
949 (infoPtr->uNumTools - nTool - 1) * sizeof(TTTOOL_INFO));
950
951 COMCTL32_Free (oldTools);
952 }
953
954 infoPtr->uNumTools--;
955
956 return 0;
957}
958
959
960static LRESULT
961TOOLTIPS_DelToolW (HWND hwnd, WPARAM wParam, LPARAM lParam)
962{
963 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
964 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
965 TTTOOL_INFO *toolPtr;
966 INT nTool;
967
968 if (lpToolInfo == NULL)
969 return 0;
970 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
971 return 0;
972 if (infoPtr->uNumTools == 0)
973 return 0;
974
975 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
976 if (nTool == -1) return 0;
977
978// TRACE (tooltips, "tool %d\n", nTool);
979
980 /* delete text string */
981 toolPtr = &infoPtr->tools[nTool];
982 if ((toolPtr->hinst) && (toolPtr->lpszText)) {
983 if ( (toolPtr->lpszText != LPSTR_TEXTCALLBACKW) &&
984 (HIWORD((INT)toolPtr->lpszText) != 0) )
985 COMCTL32_Free (toolPtr->lpszText);
986 }
987
988 /* remove subclassing */
989 TOOLTIPS_Desubclass(toolPtr);
990
991 /* delete tool from tool list */
992 if (infoPtr->uNumTools == 1) {
993 COMCTL32_Free (infoPtr->tools);
994 infoPtr->tools = NULL;
995 }
996 else {
997 TTTOOL_INFO *oldTools = infoPtr->tools;
998 infoPtr->tools =
999 (TTTOOL_INFO*)COMCTL32_Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1));
1000
1001 if (nTool > 0)
1002 memcpy (&infoPtr->tools[0], &oldTools[0],
1003 nTool * sizeof(TTTOOL_INFO));
1004
1005 if (nTool < infoPtr->uNumTools - 1)
1006 memcpy (&infoPtr->tools[nTool], &oldTools[nTool + 1],
1007 (infoPtr->uNumTools - nTool - 1) * sizeof(TTTOOL_INFO));
1008
1009 COMCTL32_Free (oldTools);
1010 }
1011
1012 infoPtr->uNumTools--;
1013
1014 return 0;
1015}
1016
1017
1018static LRESULT
1019TOOLTIPS_EnumToolsA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1020{
1021 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1022 UINT uIndex = (UINT)wParam;
1023 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
1024 TTTOOL_INFO *toolPtr;
1025
1026 if (lpToolInfo == NULL)
1027 return FALSE;
1028 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA)
1029 return FALSE;
1030 if (uIndex >= infoPtr->uNumTools)
1031 return FALSE;
1032
1033// TRACE (tooltips, "index=%u\n", uIndex);
1034
1035 toolPtr = &infoPtr->tools[uIndex];
1036
1037 /* copy tool data */
1038 lpToolInfo->uFlags = toolPtr->uFlags;
1039 lpToolInfo->hwnd = toolPtr->hwnd;
1040 lpToolInfo->uId = toolPtr->uId;
1041 lpToolInfo->rect = toolPtr->rect;
1042 lpToolInfo->hinst = toolPtr->hinst;
1043/* lpToolInfo->lpszText = toolPtr->lpszText; */
1044 lpToolInfo->lpszText = NULL; /* FIXME */
1045
1046 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
1047 lpToolInfo->lParam = toolPtr->lParam;
1048
1049 return TRUE;
1050}
1051
1052
1053static LRESULT
1054TOOLTIPS_EnumToolsW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1055{
1056 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1057 UINT uIndex = (UINT)wParam;
1058 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
1059 TTTOOL_INFO *toolPtr;
1060
1061 if (lpToolInfo == NULL)
1062 return FALSE;
1063 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
1064 return FALSE;
1065 if (uIndex >= infoPtr->uNumTools)
1066 return FALSE;
1067
1068// TRACE (tooltips, "index=%u\n", uIndex);
1069
1070 toolPtr = &infoPtr->tools[uIndex];
1071
1072 /* copy tool data */
1073 lpToolInfo->uFlags = toolPtr->uFlags;
1074 lpToolInfo->hwnd = toolPtr->hwnd;
1075 lpToolInfo->uId = toolPtr->uId;
1076 lpToolInfo->rect = toolPtr->rect;
1077 lpToolInfo->hinst = toolPtr->hinst;
1078/* lpToolInfo->lpszText = toolPtr->lpszText; */
1079 lpToolInfo->lpszText = NULL; /* FIXME */
1080
1081 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
1082 lpToolInfo->lParam = toolPtr->lParam;
1083
1084 return TRUE;
1085}
1086
1087
1088static LRESULT
1089TOOLTIPS_GetCurrentToolA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1090{
1091 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1092 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
1093 TTTOOL_INFO *toolPtr;
1094
1095 if (lpToolInfo == NULL)
1096 return FALSE;
1097 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA)
1098 return FALSE;
1099
1100 if (lpToolInfo) {
1101 if (infoPtr->nCurrentTool > -1) {
1102 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
1103
1104 /* copy tool data */
1105 lpToolInfo->uFlags = toolPtr->uFlags;
1106 lpToolInfo->rect = toolPtr->rect;
1107 lpToolInfo->hinst = toolPtr->hinst;
1108/* lpToolInfo->lpszText = toolPtr->lpszText; */
1109 lpToolInfo->lpszText = NULL; /* FIXME */
1110
1111 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
1112 lpToolInfo->lParam = toolPtr->lParam;
1113
1114 return TRUE;
1115 }
1116 else
1117 return FALSE;
1118 }
1119 else
1120 return (infoPtr->nCurrentTool != -1);
1121
1122 return FALSE;
1123}
1124
1125
1126static LRESULT
1127TOOLTIPS_GetCurrentToolW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1128{
1129 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1130 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
1131 TTTOOL_INFO *toolPtr;
1132
1133 if (lpToolInfo == NULL)
1134 return FALSE;
1135 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
1136 return FALSE;
1137
1138 if (lpToolInfo) {
1139 if (infoPtr->nCurrentTool > -1) {
1140 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
1141
1142 /* copy tool data */
1143 lpToolInfo->uFlags = toolPtr->uFlags;
1144 lpToolInfo->rect = toolPtr->rect;
1145 lpToolInfo->hinst = toolPtr->hinst;
1146/* lpToolInfo->lpszText = toolPtr->lpszText; */
1147 lpToolInfo->lpszText = NULL; /* FIXME */
1148
1149 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
1150 lpToolInfo->lParam = toolPtr->lParam;
1151
1152 return TRUE;
1153 }
1154 else
1155 return FALSE;
1156 }
1157 else
1158 return (infoPtr->nCurrentTool != -1);
1159
1160 return FALSE;
1161}
1162
1163
1164static LRESULT
1165TOOLTIPS_GetDelayTime (HWND hwnd, WPARAM wParam, LPARAM lParam)
1166{
1167 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1168
1169 switch (wParam) {
1170 case TTDT_AUTOMATIC:
1171 return infoPtr->nAutomaticTime;
1172
1173 case TTDT_RESHOW:
1174 return infoPtr->nReshowTime;
1175
1176 case TTDT_AUTOPOP:
1177 return infoPtr->nAutoPopTime;
1178
1179 case TTDT_INITIAL:
1180 return infoPtr->nInitialTime;
1181 }
1182
1183 return 0;
1184}
1185
1186
1187static LRESULT
1188TOOLTIPS_GetMargin (HWND hwnd, WPARAM wParam, LPARAM lParam)
1189{
1190 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1191 LPRECT lpRect = (LPRECT)lParam;
1192
1193 lpRect->left = infoPtr->rcMargin.left;
1194 lpRect->right = infoPtr->rcMargin.right;
1195 lpRect->bottom = infoPtr->rcMargin.bottom;
1196 lpRect->top = infoPtr->rcMargin.top;
1197
1198 return 0;
1199}
1200
1201
1202static LRESULT
1203TOOLTIPS_GetMaxTipWidth (HWND hwnd, WPARAM wParam, LPARAM lParam)
1204{
1205 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1206
1207 return infoPtr->nMaxTipWidth;
1208}
1209
1210
1211static LRESULT
1212TOOLTIPS_GetTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1213{
1214 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1215 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
1216 INT nTool;
1217
1218 if (lpToolInfo == NULL)
1219 return 0;
1220 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA)
1221 return 0;
1222
1223 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1224 if (nTool == -1) return 0;
1225
1226 TOOLTIPS_GetTipText(hwnd,infoPtr,nTool); //CB: get text
1227
1228 lstrcpyWtoA(lpToolInfo->lpszText,infoPtr->szTipText);
1229
1230 return 0;
1231}
1232
1233
1234static LRESULT
1235TOOLTIPS_GetTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1236{
1237 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1238 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
1239 INT nTool;
1240
1241 if (lpToolInfo == NULL)
1242 return 0;
1243 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
1244 return 0;
1245
1246 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
1247 if (nTool == -1) return 0;
1248
1249 TOOLTIPS_GetTipText(hwnd,infoPtr,nTool); //CB: get text
1250
1251 lstrcpyW(lpToolInfo->lpszText,infoPtr->szTipText);
1252
1253 return 0;
1254}
1255
1256
1257static LRESULT
1258TOOLTIPS_GetTipBkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
1259{
1260 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1261 return infoPtr->clrBk;
1262}
1263
1264
1265static LRESULT
1266TOOLTIPS_GetTipTextColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
1267{
1268 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1269 return infoPtr->clrText;
1270}
1271
1272
1273static LRESULT
1274TOOLTIPS_GetToolCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
1275{
1276 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1277 return infoPtr->uNumTools;
1278}
1279
1280
1281static LRESULT
1282TOOLTIPS_GetToolInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1283{
1284 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1285 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
1286 TTTOOL_INFO *toolPtr;
1287 INT nTool;
1288
1289 if (lpToolInfo == NULL)
1290 return FALSE;
1291 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA)
1292 return FALSE;
1293 if (infoPtr->uNumTools == 0)
1294 return FALSE;
1295
1296 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1297 if (nTool == -1)
1298 return FALSE;
1299
1300// TRACE (tooltips, "tool %d\n", nTool);
1301
1302 toolPtr = &infoPtr->tools[nTool];
1303
1304 /* copy tool data */
1305 lpToolInfo->uFlags = toolPtr->uFlags;
1306 lpToolInfo->rect = toolPtr->rect;
1307 lpToolInfo->hinst = toolPtr->hinst;
1308/* lpToolInfo->lpszText = toolPtr->lpszText; */
1309 lpToolInfo->lpszText = NULL; /* FIXME */
1310
1311 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
1312 lpToolInfo->lParam = toolPtr->lParam;
1313
1314 return TRUE;
1315}
1316
1317
1318static LRESULT
1319TOOLTIPS_GetToolInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1320{
1321 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1322 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
1323 TTTOOL_INFO *toolPtr;
1324 INT nTool;
1325
1326 if (lpToolInfo == NULL)
1327 return FALSE;
1328 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
1329 return FALSE;
1330 if (infoPtr->uNumTools == 0)
1331 return FALSE;
1332
1333 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
1334 if (nTool == -1)
1335 return FALSE;
1336
1337// TRACE (tooltips, "tool %d\n", nTool);
1338
1339 toolPtr = &infoPtr->tools[nTool];
1340
1341 /* copy tool data */
1342 lpToolInfo->uFlags = toolPtr->uFlags;
1343 lpToolInfo->rect = toolPtr->rect;
1344 lpToolInfo->hinst = toolPtr->hinst;
1345/* lpToolInfo->lpszText = toolPtr->lpszText; */
1346 lpToolInfo->lpszText = NULL; /* FIXME */
1347
1348 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
1349 lpToolInfo->lParam = toolPtr->lParam;
1350
1351 return TRUE;
1352}
1353
1354
1355static LRESULT
1356TOOLTIPS_HitTestA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1357{
1358 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1359 LPTTHITTESTINFOA lptthit = (LPTTHITTESTINFOA)lParam;
1360 TTTOOL_INFO *toolPtr;
1361 INT nTool;
1362
1363 if (lptthit == 0)
1364 return FALSE;
1365
1366 nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lptthit->hwnd, &lptthit->pt);
1367 if (nTool == -1)
1368 return FALSE;
1369
1370// TRACE (tooltips, "tool %d!\n", nTool);
1371
1372 /* copy tool data */
1373 if (lptthit->ti.cbSize >= sizeof(TTTOOLINFOA)) {
1374 toolPtr = &infoPtr->tools[nTool];
1375
1376 lptthit->ti.uFlags = toolPtr->uFlags;
1377 lptthit->ti.hwnd = toolPtr->hwnd;
1378 lptthit->ti.uId = toolPtr->uId;
1379 lptthit->ti.rect = toolPtr->rect;
1380 lptthit->ti.hinst = toolPtr->hinst;
1381/* lptthit->ti.lpszText = toolPtr->lpszText; */
1382 lptthit->ti.lpszText = NULL; /* FIXME */
1383 lptthit->ti.lParam = toolPtr->lParam;
1384 }
1385
1386 return TRUE;
1387}
1388
1389
1390static LRESULT
1391TOOLTIPS_HitTestW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1392{
1393 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1394 LPTTHITTESTINFOW lptthit = (LPTTHITTESTINFOW)lParam;
1395 TTTOOL_INFO *toolPtr;
1396 INT nTool;
1397
1398 if (lptthit == 0)
1399 return FALSE;
1400
1401 nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lptthit->hwnd, &lptthit->pt);
1402 if (nTool == -1)
1403 return FALSE;
1404
1405// TRACE (tooltips, "tool %d!\n", nTool);
1406
1407 /* copy tool data */
1408 if (lptthit->ti.cbSize >= sizeof(TTTOOLINFOW)) {
1409 toolPtr = &infoPtr->tools[nTool];
1410
1411 lptthit->ti.uFlags = toolPtr->uFlags;
1412 lptthit->ti.hwnd = toolPtr->hwnd;
1413 lptthit->ti.uId = toolPtr->uId;
1414 lptthit->ti.rect = toolPtr->rect;
1415 lptthit->ti.hinst = toolPtr->hinst;
1416/* lptthit->ti.lpszText = toolPtr->lpszText; */
1417 lptthit->ti.lpszText = NULL; /* FIXME */
1418 lptthit->ti.lParam = toolPtr->lParam;
1419 }
1420
1421 return TRUE;
1422}
1423
1424
1425static LRESULT
1426TOOLTIPS_NewToolRectA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1427{
1428 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1429 LPTTTOOLINFOA lpti = (LPTTTOOLINFOA)lParam;
1430 INT nTool;
1431
1432 if (lpti == NULL)
1433 return 0;
1434 if (lpti->cbSize < TTTOOLINFO_V1_SIZEA)
1435 return FALSE;
1436
1437 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpti);
1438 if (nTool == -1) return 0;
1439
1440 infoPtr->tools[nTool].rect = lpti->rect;
1441
1442 return 0;
1443}
1444
1445
1446static LRESULT
1447TOOLTIPS_NewToolRectW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1448{
1449 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1450 LPTTTOOLINFOW lpti = (LPTTTOOLINFOW)lParam;
1451 INT nTool;
1452
1453 if (lpti == NULL)
1454 return 0;
1455 if (lpti->cbSize < TTTOOLINFO_V1_SIZEW)
1456 return FALSE;
1457
1458 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpti);
1459 if (nTool == -1) return 0;
1460
1461 infoPtr->tools[nTool].rect = lpti->rect;
1462
1463 return 0;
1464}
1465
1466
1467static LRESULT
1468TOOLTIPS_Pop (HWND hwnd, WPARAM wParam, LPARAM lParam)
1469{
1470 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1471
1472 TOOLTIPS_Hide (hwnd, infoPtr);
1473
1474 return 0;
1475}
1476
1477
1478static LRESULT
1479TOOLTIPS_RelayEvent (HWND hwnd, WPARAM wParam, LPARAM lParam)
1480{
1481 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1482 LPMSG lpMsg = (LPMSG)lParam;
1483 POINT pt;
1484
1485 if (lParam == 0)
1486 {
1487// ERR (tooltips, "lpMsg == NULL!\n");
1488 return 0;
1489 }
1490
1491 switch (lpMsg->message)
1492 {
1493 case WM_LBUTTONDOWN:
1494 case WM_LBUTTONUP:
1495 case WM_MBUTTONDOWN:
1496 case WM_MBUTTONUP:
1497 case WM_RBUTTONDOWN:
1498 case WM_RBUTTONUP:
1499 pt = lpMsg->pt;
1500 ScreenToClient(lpMsg->hwnd,&pt);
1501 infoPtr->nOldTool = infoPtr->nTool;
1502 infoPtr->nTool = TOOLTIPS_GetToolFromPoint(infoPtr,lpMsg->hwnd,&pt);
1503// TRACE (tooltips, "tool (%x) %d %d\n",
1504// hwnd, infoPtr->nOldTool, infoPtr->nTool);
1505 TOOLTIPS_Hide (hwnd, infoPtr);
1506 break;
1507
1508 case WM_MOUSEMOVE:
1509 pt = lpMsg->pt;
1510 ScreenToClient(lpMsg->hwnd,&pt);
1511 infoPtr->nOldTool = infoPtr->nTool;
1512 infoPtr->nTool = TOOLTIPS_GetToolFromPoint(infoPtr,lpMsg->hwnd,&pt);
1513// TRACE (tooltips, "tool (%x) %d %d\n",
1514// hwnd, infoPtr->nOldTool, infoPtr->nTool);
1515// TRACE (tooltips, "WM_MOUSEMOVE (%04x %ld %ld)\n",
1516// hwnd, pt.x, pt.y);
1517
1518 if (infoPtr->bActive && (infoPtr->nTool != infoPtr->nOldTool))
1519 {
1520 if (infoPtr->nOldTool == -1)
1521 {
1522 SetTimer(hwnd,ID_TIMERSHOW,infoPtr->nInitialTime,0);
1523// TRACE (tooltips, "timer 1 started!\n");
1524 } else
1525 {
1526 TOOLTIPS_Hide(hwnd,infoPtr);
1527 SetTimer (hwnd,ID_TIMERSHOW,infoPtr->nReshowTime,0);
1528// TRACE (tooltips, "timer 2 started!\n");
1529 }
1530 }
1531 if (infoPtr->nCurrentTool != -1)
1532 {
1533 SetTimer(hwnd,ID_TIMERLEAVE,100,0);
1534// TRACE (tooltips, "timer 3 started!\n");
1535 }
1536 break;
1537 }
1538
1539 return 0;
1540}
1541
1542
1543static LRESULT
1544TOOLTIPS_SetDelayTime (HWND hwnd, WPARAM wParam, LPARAM lParam)
1545{
1546 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1547 INT nTime = (INT)LOWORD(lParam);
1548
1549 switch (wParam) {
1550 case TTDT_AUTOMATIC:
1551 if (nTime == 0) {
1552 infoPtr->nAutomaticTime = 500;
1553 infoPtr->nReshowTime = 100;
1554 infoPtr->nAutoPopTime = 5000;
1555 infoPtr->nInitialTime = 500;
1556 }
1557 else {
1558 infoPtr->nAutomaticTime = nTime;
1559 infoPtr->nReshowTime = nTime / 5;
1560 infoPtr->nAutoPopTime = nTime * 10;
1561 infoPtr->nInitialTime = nTime;
1562 }
1563 break;
1564
1565 case TTDT_RESHOW:
1566 infoPtr->nReshowTime = nTime;
1567 break;
1568
1569 case TTDT_AUTOPOP:
1570 infoPtr->nAutoPopTime = nTime;
1571 break;
1572
1573 case TTDT_INITIAL:
1574 infoPtr->nInitialTime = nTime;
1575 break;
1576 }
1577
1578 return 0;
1579}
1580
1581
1582static LRESULT
1583TOOLTIPS_SetMargin (HWND hwnd, WPARAM wParam, LPARAM lParam)
1584{
1585 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1586 LPRECT lpRect = (LPRECT)lParam;
1587
1588 infoPtr->rcMargin.left = lpRect->left;
1589 infoPtr->rcMargin.right = lpRect->right;
1590 infoPtr->rcMargin.bottom = lpRect->bottom;
1591 infoPtr->rcMargin.top = lpRect->top;
1592
1593 return 0;
1594}
1595
1596
1597static LRESULT
1598TOOLTIPS_SetMaxTipWidth (HWND hwnd, WPARAM wParam, LPARAM lParam)
1599{
1600 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1601 INT nTemp = infoPtr->nMaxTipWidth;
1602
1603 infoPtr->nMaxTipWidth = (INT)lParam;
1604
1605 return nTemp;
1606}
1607
1608
1609static LRESULT
1610TOOLTIPS_SetTipBkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
1611{
1612 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1613
1614 infoPtr->clrBk = (COLORREF)wParam;
1615
1616 return 0;
1617}
1618
1619
1620static LRESULT
1621TOOLTIPS_SetTipTextColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
1622{
1623 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1624
1625 infoPtr->clrText = (COLORREF)wParam;
1626
1627 return 0;
1628}
1629
1630
1631static LRESULT
1632TOOLTIPS_SetToolInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1633{
1634 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1635 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
1636 TTTOOL_INFO *toolPtr;
1637 INT nTool;
1638
1639 if (lpToolInfo == NULL)
1640 return 0;
1641 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA)
1642 return 0;
1643
1644 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1645 if (nTool == -1) return 0;
1646
1647// TRACE (tooltips, "tool %d\n", nTool);
1648
1649 toolPtr = &infoPtr->tools[nTool];
1650
1651 /* copy tool data */
1652 toolPtr->uFlags = lpToolInfo->uFlags;
1653 toolPtr->hwnd = lpToolInfo->hwnd;
1654 toolPtr->uId = lpToolInfo->uId;
1655 toolPtr->rect = lpToolInfo->rect;
1656 toolPtr->hinst = lpToolInfo->hinst;
1657
1658 if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0)) {
1659// TRACE (tooltips, "set string id %x!\n", (INT)lpToolInfo->lpszText);
1660 toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
1661 }
1662 else if (lpToolInfo->lpszText) {
1663 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKA)
1664 toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
1665 else {
1666 if ( (toolPtr->lpszText) &&
1667 (HIWORD((INT)toolPtr->lpszText) != 0) ) {
1668 COMCTL32_Free (toolPtr->lpszText);
1669 toolPtr->lpszText = NULL;
1670 }
1671 if (lpToolInfo->lpszText) {
1672 INT len = lstrlenA (lpToolInfo->lpszText);
1673 toolPtr->lpszText = (WCHAR*)COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1674 lstrcpyAtoW (toolPtr->lpszText, lpToolInfo->lpszText);
1675 }
1676 }
1677 }
1678
1679 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
1680 toolPtr->lParam = lpToolInfo->lParam;
1681
1682 return 0;
1683}
1684
1685
1686static LRESULT
1687TOOLTIPS_SetToolInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1688{
1689 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1690 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
1691 TTTOOL_INFO *toolPtr;
1692 INT nTool;
1693
1694 if (lpToolInfo == NULL)
1695 return 0;
1696 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
1697 return 0;
1698
1699 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
1700 if (nTool == -1) return 0;
1701
1702// TRACE (tooltips, "tool %d\n", nTool);
1703
1704 toolPtr = &infoPtr->tools[nTool];
1705
1706 /* copy tool data */
1707 toolPtr->uFlags = lpToolInfo->uFlags;
1708 toolPtr->hwnd = lpToolInfo->hwnd;
1709 toolPtr->uId = lpToolInfo->uId;
1710 toolPtr->rect = lpToolInfo->rect;
1711 toolPtr->hinst = lpToolInfo->hinst;
1712
1713 if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0)) {
1714// TRACE (tooltips, "set string id %x!\n", (INT)lpToolInfo->lpszText);
1715 toolPtr->lpszText = lpToolInfo->lpszText;
1716 }
1717 else if (lpToolInfo->lpszText) {
1718 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKW)
1719 toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
1720 else {
1721 if ( (toolPtr->lpszText) &&
1722 (HIWORD((INT)toolPtr->lpszText) != 0) ) {
1723 COMCTL32_Free (toolPtr->lpszText);
1724 toolPtr->lpszText = NULL;
1725 }
1726 if (lpToolInfo->lpszText) {
1727 INT len = lstrlenW (lpToolInfo->lpszText);
1728 toolPtr->lpszText = (WCHAR*)COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1729 lstrcpyW (toolPtr->lpszText, lpToolInfo->lpszText);
1730 }
1731 }
1732 }
1733
1734 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
1735 toolPtr->lParam = lpToolInfo->lParam;
1736
1737 return 0;
1738}
1739
1740
1741static LRESULT
1742TOOLTIPS_TrackActivate (HWND hwnd, WPARAM wParam, LPARAM lParam)
1743{
1744 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1745 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
1746
1747 if (lpToolInfo == NULL) return 0;
1748 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA) return FALSE;
1749
1750 if ((BOOL)wParam)
1751 {
1752 /* activate */
1753 infoPtr->nTrackTool = TOOLTIPS_GetToolFromInfoA(infoPtr,lpToolInfo);
1754 if (infoPtr->nTrackTool != -1)
1755 {
1756 //TRACE (tooltips, "activated!\n");
1757 infoPtr->bTrackActive = TRUE;
1758 TOOLTIPS_TrackShow(hwnd,infoPtr);
1759 }
1760 } else
1761 {
1762 /* deactivate */
1763 TOOLTIPS_TrackHide(hwnd,infoPtr);
1764
1765 infoPtr->bTrackActive = FALSE;
1766 infoPtr->nTrackTool = -1;
1767
1768 //TRACE (tooltips, "deactivated!\n");
1769 }
1770
1771 return 0;
1772}
1773
1774
1775static LRESULT
1776TOOLTIPS_TrackPosition (HWND hwnd, WPARAM wParam, LPARAM lParam)
1777{
1778 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1779
1780 infoPtr->xTrackPos = (INT)LOWORD(lParam);
1781 infoPtr->yTrackPos = (INT)HIWORD(lParam);
1782
1783 if (infoPtr->bTrackActive)
1784 {
1785// TRACE (tooltips, "[%d %d]\n",
1786// infoPtr->xTrackPos, infoPtr->yTrackPos);
1787 TOOLTIPS_TrackShow(hwnd,infoPtr);
1788 }
1789
1790 return 0;
1791}
1792
1793
1794static LRESULT
1795TOOLTIPS_Update (HWND hwnd, WPARAM wParam, LPARAM lParam)
1796{
1797 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1798
1799 if (infoPtr->nCurrentTool != -1)
1800 UpdateWindow (hwnd);
1801
1802 return 0;
1803}
1804
1805
1806TOOLTIPS_UpdateTipTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1807{
1808 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1809 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
1810 TTTOOL_INFO *toolPtr;
1811 INT nTool;
1812
1813 if (lpToolInfo == NULL)
1814 return 0;
1815 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA)
1816 return FALSE;
1817
1818 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1819 if (nTool == -1) return 0;
1820
1821// TRACE("tool %d\n", nTool);
1822
1823 toolPtr = &infoPtr->tools[nTool];
1824
1825 /* copy tool text */
1826 toolPtr->hinst = lpToolInfo->hinst;
1827
1828 if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0)){
1829 toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
1830 }
1831 else if (lpToolInfo->lpszText) {
1832 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKA)
1833 toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
1834 else {
1835 if ( (toolPtr->lpszText) &&
1836 (HIWORD((INT)toolPtr->lpszText) != 0) ) {
1837 COMCTL32_Free (toolPtr->lpszText);
1838 toolPtr->lpszText = NULL;
1839 }
1840 if (lpToolInfo->lpszText) {
1841 INT len = lstrlenA (lpToolInfo->lpszText);
1842 toolPtr->lpszText = (WCHAR*)COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1843 lstrcpyAtoW (toolPtr->lpszText, lpToolInfo->lpszText);
1844 }
1845 }
1846 }
1847
1848 /* force repaint */
1849 if (infoPtr->bActive)
1850 TOOLTIPS_Show (hwnd, infoPtr);
1851 else if (infoPtr->bTrackActive)
1852 TOOLTIPS_TrackShow (hwnd, infoPtr);
1853
1854 return 0;
1855}
1856
1857
1858static LRESULT
1859TOOLTIPS_UpdateTipTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1860{
1861 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1862 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
1863 TTTOOL_INFO *toolPtr;
1864 INT nTool;
1865
1866 if (lpToolInfo == NULL)
1867 return 0;
1868 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
1869 return FALSE;
1870
1871 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
1872 if (nTool == -1)
1873 return 0;
1874
1875// TRACE("tool %d\n", nTool);
1876
1877 toolPtr = &infoPtr->tools[nTool];
1878
1879 /* copy tool text */
1880 toolPtr->hinst = lpToolInfo->hinst;
1881
1882 if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0)){
1883 toolPtr->lpszText = lpToolInfo->lpszText;
1884 }
1885 else if (lpToolInfo->lpszText) {
1886 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKW)
1887 toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
1888 else {
1889 if ( (toolPtr->lpszText) &&
1890 (HIWORD((INT)toolPtr->lpszText) != 0) ) {
1891 COMCTL32_Free (toolPtr->lpszText);
1892 toolPtr->lpszText = NULL;
1893 }
1894 if (lpToolInfo->lpszText) {
1895 INT len = lstrlenW (lpToolInfo->lpszText);
1896 toolPtr->lpszText = (WCHAR*)COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1897 lstrcpyW (toolPtr->lpszText, lpToolInfo->lpszText);
1898 }
1899 }
1900 }
1901
1902 /* force repaint */
1903 if (infoPtr->bActive)
1904 TOOLTIPS_Show (hwnd, infoPtr);
1905 else if (infoPtr->bTrackActive)
1906 TOOLTIPS_TrackShow (hwnd, infoPtr);
1907
1908 return 0;
1909}
1910
1911
1912static LRESULT
1913TOOLTIPS_WindowFromPoint (HWND hwnd, WPARAM wParam, LPARAM lParam)
1914{
1915 return WindowFromPoint (*((LPPOINT)lParam));
1916}
1917
1918
1919
1920static LRESULT
1921TOOLTIPS_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
1922{
1923 TOOLTIPS_INFO *infoPtr;
1924 NONCLIENTMETRICSA nclm;
1925 INT nResult;
1926
1927 /* allocate memory for info structure */
1928 infoPtr = (TOOLTIPS_INFO *)COMCTL32_Alloc(sizeof(TOOLTIPS_INFO));
1929 SetWindowLongA(hwnd,0,(DWORD)infoPtr);
1930
1931 /* initialize info structure */
1932 infoPtr->szTipText[0] = '\0';
1933 infoPtr->bActive = TRUE;
1934 infoPtr->bTrackActive = FALSE;
1935 infoPtr->clrBk = GetSysColor(COLOR_INFOBK);
1936 infoPtr->clrText = GetSysColor(COLOR_INFOTEXT);
1937 infoPtr->xTrackPos = 0;
1938 infoPtr->yTrackPos = 0;
1939
1940 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1941 SystemParametersInfoA(SPI_GETNONCLIENTMETRICS,0,&nclm,0);
1942 infoPtr->hFont = CreateFontIndirectA(&nclm.lfStatusFont);
1943
1944 infoPtr->nMaxTipWidth = -1;
1945 infoPtr->nTool = -1;
1946 infoPtr->nOldTool = -1;
1947 infoPtr->nCurrentTool = -1;
1948 infoPtr->nTrackTool = -1;
1949
1950 infoPtr->nAutomaticTime = 500;
1951 infoPtr->nReshowTime = 100;
1952 infoPtr->nAutoPopTime = 5000;
1953 infoPtr->nInitialTime = 500;
1954
1955 SetRectEmpty(&infoPtr->rcMargin);
1956
1957 nResult = (INT)SendMessageA(GetParent(hwnd),WM_NOTIFYFORMAT,(WPARAM)hwnd,(LPARAM)NF_QUERY);
1958// if (nResult == NFR_ANSI)
1959// TRACE (tooltips, " -- WM_NOTIFYFORMAT returns: NFR_ANSI\n");
1960// else if (nResult == NFR_UNICODE)
1961// FIXME (tooltips, " -- WM_NOTIFYFORMAT returns: NFR_UNICODE\n");
1962// else
1963// FIXME (tooltips, " -- WM_NOTIFYFORMAT returns: error!\n");
1964
1965 SetWindowPos(hwnd,HWND_TOP,0,0,0,0,SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOACTIVATE);
1966
1967 return 0;
1968}
1969
1970
1971static LRESULT
1972TOOLTIPS_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
1973{
1974 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(hwnd);
1975 TTTOOL_INFO *toolPtr;
1976 INT i;
1977
1978 /* free tools */
1979 if (infoPtr->tools) {
1980 for (i = 0; i < infoPtr->uNumTools; i++) {
1981 toolPtr = &infoPtr->tools[i];
1982 if ((toolPtr->hinst) && (toolPtr->lpszText)) {
1983 if ( (toolPtr->lpszText != LPSTR_TEXTCALLBACKW) &&
1984 (HIWORD((INT)toolPtr->lpszText) != 0) )
1985 {
1986 COMCTL32_Free (toolPtr->lpszText);
1987 toolPtr->lpszText = NULL;
1988 }
1989 }
1990
1991 /* remove subclassing */
1992 if (toolPtr->uFlags & TTF_SUBCLASS) {
1993 LPTT_SUBCLASS_INFO lpttsi;
1994
1995 if (toolPtr->uFlags & TTF_IDISHWND)
1996 lpttsi = (LPTT_SUBCLASS_INFO)GetPropA ((HWND)toolPtr->uId, COMCTL32_aSubclass);
1997 else
1998 lpttsi = (LPTT_SUBCLASS_INFO)GetPropA (toolPtr->hwnd, COMCTL32_aSubclass);
1999
2000 if (lpttsi) {
2001 SetWindowLongA ((HWND)toolPtr->uId, GWL_WNDPROC,
2002 (LONG)lpttsi->wpOrigProc);
2003 RemovePropA ((HWND)toolPtr->uId, COMCTL32_aSubclass);
2004 COMCTL32_Free (&lpttsi);
2005 }
2006 }
2007 }
2008 COMCTL32_Free (infoPtr->tools);
2009 }
2010
2011 /* delete font */
2012 DeleteObject (infoPtr->hFont);
2013
2014 /* free tool tips info data */
2015 COMCTL32_Free(infoPtr);
2016
2017 return 0;
2018}
2019
2020
2021static LRESULT
2022TOOLTIPS_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
2023{
2024 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2025 RECT rect;
2026 HBRUSH hBrush;
2027
2028 hBrush = CreateSolidBrush (infoPtr->clrBk);
2029 GetClientRect (hwnd, &rect);
2030 FillRect ((HDC)wParam, &rect, hBrush);
2031 DeleteObject (hBrush);
2032
2033 return FALSE;
2034}
2035
2036
2037static LRESULT
2038TOOLTIPS_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
2039{
2040 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2041
2042 return infoPtr->hFont;
2043}
2044
2045
2046static LRESULT
2047TOOLTIPS_MouseMessage (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2048{
2049 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2050
2051 TOOLTIPS_Hide (hwnd, infoPtr);
2052
2053 return 0;
2054}
2055
2056
2057static LRESULT
2058TOOLTIPS_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
2059{
2060 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
2061 DWORD dwExStyle = GetWindowLongA(hwnd,GWL_EXSTYLE);
2062
2063 dwStyle &= 0x0000FFFF;
2064 dwStyle |= (WS_POPUP | WS_BORDER | WS_CLIPSIBLINGS);
2065 SetWindowLongA(hwnd,GWL_STYLE,dwStyle);
2066
2067 SetWindowLongA(hwnd,GWL_EXSTYLE,dwExStyle | WS_EX_TOOLWINDOW);
2068
2069 return TRUE;
2070}
2071
2072
2073static LRESULT
2074TOOLTIPS_NCHitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
2075{
2076 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2077 INT nTool = (infoPtr->bTrackActive) ? infoPtr->nTrackTool : infoPtr->nTool;
2078
2079// TRACE (tooltips, " nTool=%d\n", nTool);
2080
2081 if ((nTool > -1) && (nTool < infoPtr->uNumTools)) {
2082 if (infoPtr->tools[nTool].uFlags & TTF_TRANSPARENT) {
2083// TRACE (tooltips, "-- in transparent mode!\n");
2084 return HTTRANSPARENT;
2085 }
2086 }
2087
2088 return DefWindowProcA (hwnd, WM_NCHITTEST, wParam, lParam);
2089}
2090
2091static LRESULT
2092TOOLTIPS_NotifyFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
2093{
2094// FIXME ("hwnd=%x wParam=%x lParam=%lx\n", hwnd, wParam, lParam);
2095
2096 return 0;
2097}
2098
2099static LRESULT
2100TOOLTIPS_Paint (HWND hwnd, WPARAM wParam, LPARAM lParam)
2101{
2102 HDC hdc;
2103 PAINTSTRUCT ps;
2104
2105 hdc = (wParam == 0) ? BeginPaint (hwnd, &ps) : (HDC)wParam;
2106 TOOLTIPS_Draw(hwnd, hdc);
2107 if (!wParam)
2108 EndPaint (hwnd, &ps);
2109 return 0;
2110}
2111
2112
2113static LRESULT
2114TOOLTIPS_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
2115{
2116 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2117
2118 infoPtr->hFont = (HFONT)wParam;
2119
2120 if ((LOWORD(lParam)) && (infoPtr->nCurrentTool != -1))
2121 {
2122 /* force repaint */
2123 if (infoPtr->bActive) TOOLTIPS_Show(hwnd,infoPtr);
2124 else if (infoPtr->bTrackActive) TOOLTIPS_TrackShow(hwnd,infoPtr);
2125 }
2126
2127 return 0;
2128}
2129/******************************************************************
2130 * TOOLTIPS_OnWMGetTextLength
2131 *
2132 * This function is called when the tooltip receive a
2133 * WM_GETTEXTLENGTH message.
2134 * wParam : not used
2135 * lParam : not used
2136 *
2137 * returns the length, in characters, of the tip text
2138 ******************************************************************/
2139
2140static LRESULT
2141TOOLTIPS_OnWMGetTextLength(HWND hwnd, WPARAM wParam, LPARAM lParam)
2142{
2143 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2144 return lstrlenW(infoPtr->szTipText);
2145}
2146/******************************************************************
2147 * TOOLTIPS_OnWMGetText
2148 *
2149 * This function is called when the tooltip receive a
2150 * WM_GETTEXT message.
2151 * wParam : specifies the maximum number of characters to be copied
2152 * lParam : is the pointer to the buffer that will receive
2153 * the tip text
2154 *
2155 * returns the number of characters copied
2156 ******************************************************************/
2157static LRESULT
2158TOOLTIPS_OnWMGetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
2159{
2160 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2161 INT length;
2162
2163 if(!infoPtr || !(infoPtr->szTipText))
2164 return 0;
2165
2166 length = lstrlenW(infoPtr->szTipText);
2167 /* When wParam is smaller than the lenght of the tip text
2168 copy wParam characters of the tip text and return wParam */
2169 if(wParam < length)
2170 {
2171 lstrcpynWtoA((LPSTR)lParam,infoPtr->szTipText,(UINT)wParam);//includes 0 terminator
2172 return wParam;
2173 }
2174 lstrcpyWtoA((LPSTR)lParam,infoPtr->szTipText);
2175 return length;
2176
2177}
2178
2179static LRESULT
2180TOOLTIPS_Timer (HWND hwnd, WPARAM wParam, LPARAM lParam)
2181{
2182 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2183
2184// TRACE (tooltips, "timer %d (%x) expired!\n", wParam, hwnd);
2185 switch (wParam)
2186 {
2187 case ID_TIMERSHOW:
2188 KillTimer(hwnd,ID_TIMERSHOW);
2189 if (TOOLTIPS_CheckTool(hwnd,TRUE) == infoPtr->nTool)
2190 TOOLTIPS_Show(hwnd,infoPtr);
2191 break;
2192
2193 case ID_TIMERPOP:
2194 TOOLTIPS_Hide (hwnd, infoPtr);
2195 break;
2196
2197 case ID_TIMERLEAVE:
2198 KillTimer (hwnd,ID_TIMERLEAVE);
2199 if (TOOLTIPS_CheckTool(hwnd,FALSE) == -1)
2200 {
2201 infoPtr->nTool = -1;
2202 infoPtr->nOldTool = -1;
2203 TOOLTIPS_Hide(hwnd,infoPtr);
2204 }
2205 break;
2206 }
2207
2208 return 0;
2209}
2210
2211
2212static LRESULT
2213TOOLTIPS_WinIniChange (HWND hwnd, WPARAM wParam, LPARAM lParam)
2214{
2215 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2216 NONCLIENTMETRICSA nclm;
2217
2218 infoPtr->clrBk = GetSysColor (COLOR_INFOBK);
2219 infoPtr->clrText = GetSysColor (COLOR_INFOTEXT);
2220
2221 DeleteObject (infoPtr->hFont);
2222 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
2223 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
2224 infoPtr->hFont = CreateFontIndirectA (&nclm.lfStatusFont);
2225
2226 return 0;
2227}
2228
2229
2230LRESULT CALLBACK
2231TOOLTIPS_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2232{
2233 LPTT_SUBCLASS_INFO lpttsi =
2234 (LPTT_SUBCLASS_INFO)GetPropA (hwnd, COMCTL32_aSubclass);
2235 TOOLTIPS_INFO *infoPtr;
2236 UINT nTool;
2237
2238 switch (uMsg) {
2239 case WM_LBUTTONDOWN:
2240 case WM_LBUTTONUP:
2241 case WM_MBUTTONDOWN:
2242 case WM_MBUTTONUP:
2243 case WM_RBUTTONDOWN:
2244 case WM_RBUTTONUP:
2245 infoPtr = TOOLTIPS_GetInfoPtr(lpttsi->hwndToolTip);
2246 nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd);
2247
2248// TRACE (tooltips, "subclassed mouse message %04x\n", uMsg);
2249 infoPtr->nOldTool = infoPtr->nTool;
2250 infoPtr->nTool = nTool;
2251 TOOLTIPS_Hide (lpttsi->hwndToolTip, infoPtr);
2252 break;
2253
2254 case WM_MOUSEMOVE:
2255 infoPtr = TOOLTIPS_GetInfoPtr (lpttsi->hwndToolTip);
2256 //@@@AH 2000/02/25 check if there is a valid instance data pointer
2257 if (!infoPtr)
2258 {
2259 dprintf(("Tooltips:SubclassProc:WM_MOUSEMOVE: infoPtr == NULL!\n"));
2260 break;
2261 }
2262 nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd);
2263
2264// TRACE (tooltips, "subclassed WM_MOUSEMOVE\n");
2265 infoPtr->nOldTool = infoPtr->nTool;
2266 infoPtr->nTool = nTool;
2267
2268 if ((infoPtr->bActive) &&
2269 (infoPtr->nTool != infoPtr->nOldTool)) {
2270 if (infoPtr->nOldTool == -1) {
2271 SetTimer (hwnd, ID_TIMERSHOW,
2272 infoPtr->nInitialTime, 0);
2273// TRACE (tooltips, "timer 1 started!\n");
2274 }
2275 else {
2276 TOOLTIPS_Hide (lpttsi->hwndToolTip, infoPtr);
2277 SetTimer (hwnd, ID_TIMERSHOW,
2278 infoPtr->nReshowTime, 0);
2279// TRACE (tooltips, "timer 2 started!\n");
2280 }
2281 }
2282 if (infoPtr->nCurrentTool != -1) {
2283 SetTimer (hwnd, ID_TIMERLEAVE, 100, 0);
2284// TRACE (tooltips, "timer 3 started!\n");
2285 }
2286 break;
2287 }
2288
2289 return CallWindowProcA (lpttsi->wpOrigProc, hwnd, uMsg, wParam, lParam);
2290}
2291
2292
2293static LRESULT CALLBACK
2294TOOLTIPS_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2295{
2296 switch (uMsg)
2297 {
2298 case TTM_ACTIVATE:
2299 return TOOLTIPS_Activate (hwnd, wParam, lParam);
2300
2301 case TTM_ADDTOOLA:
2302 return TOOLTIPS_AddToolA (hwnd, wParam, lParam);
2303
2304 case TTM_ADDTOOLW:
2305 return TOOLTIPS_AddToolW (hwnd, wParam, lParam);
2306
2307 case TTM_DELTOOLA:
2308 return TOOLTIPS_DelToolA (hwnd, wParam, lParam);
2309
2310 case TTM_DELTOOLW:
2311 return TOOLTIPS_DelToolW (hwnd, wParam, lParam);
2312
2313 case TTM_ENUMTOOLSA:
2314 return TOOLTIPS_EnumToolsA (hwnd, wParam, lParam);
2315
2316 case TTM_ENUMTOOLSW:
2317 return TOOLTIPS_EnumToolsW (hwnd, wParam, lParam);
2318
2319 case TTM_GETCURRENTTOOLA:
2320 return TOOLTIPS_GetCurrentToolA (hwnd, wParam, lParam);
2321
2322 case TTM_GETCURRENTTOOLW:
2323 return TOOLTIPS_GetCurrentToolW (hwnd, wParam, lParam);
2324
2325 case TTM_GETDELAYTIME:
2326 return TOOLTIPS_GetDelayTime (hwnd, wParam, lParam);
2327
2328 case TTM_GETMARGIN:
2329 return TOOLTIPS_GetMargin (hwnd, wParam, lParam);
2330
2331 case TTM_GETMAXTIPWIDTH:
2332 return TOOLTIPS_GetMaxTipWidth (hwnd, wParam, lParam);
2333
2334 case TTM_GETTEXTA:
2335 return TOOLTIPS_GetTextA (hwnd, wParam, lParam);
2336
2337 case TTM_GETTEXTW:
2338 return TOOLTIPS_GetTextW (hwnd, wParam, lParam);
2339
2340 case TTM_GETTIPBKCOLOR:
2341 return TOOLTIPS_GetTipBkColor (hwnd, wParam, lParam);
2342
2343 case TTM_GETTIPTEXTCOLOR:
2344 return TOOLTIPS_GetTipTextColor (hwnd, wParam, lParam);
2345
2346 case TTM_GETTOOLCOUNT:
2347 return TOOLTIPS_GetToolCount (hwnd, wParam, lParam);
2348
2349 case TTM_GETTOOLINFOA:
2350 return TOOLTIPS_GetToolInfoA (hwnd, wParam, lParam);
2351
2352 case TTM_GETTOOLINFOW:
2353 return TOOLTIPS_GetToolInfoW (hwnd, wParam, lParam);
2354
2355 case TTM_HITTESTA:
2356 return TOOLTIPS_HitTestA (hwnd, wParam, lParam);
2357
2358 case TTM_HITTESTW:
2359 return TOOLTIPS_HitTestW (hwnd, wParam, lParam);
2360
2361 case TTM_NEWTOOLRECTA:
2362 return TOOLTIPS_NewToolRectA (hwnd, wParam, lParam);
2363
2364 case TTM_NEWTOOLRECTW:
2365 return TOOLTIPS_NewToolRectW (hwnd, wParam, lParam);
2366
2367 case TTM_POP:
2368 return TOOLTIPS_Pop (hwnd, wParam, lParam);
2369
2370 case TTM_RELAYEVENT:
2371 return TOOLTIPS_RelayEvent (hwnd, wParam, lParam);
2372
2373 case TTM_SETDELAYTIME:
2374 return TOOLTIPS_SetDelayTime (hwnd, wParam, lParam);
2375
2376 case TTM_SETMARGIN:
2377 return TOOLTIPS_SetMargin (hwnd, wParam, lParam);
2378
2379 case TTM_SETMAXTIPWIDTH:
2380 return TOOLTIPS_SetMaxTipWidth (hwnd, wParam, lParam);
2381
2382 case TTM_SETTIPBKCOLOR:
2383 return TOOLTIPS_SetTipBkColor (hwnd, wParam, lParam);
2384
2385 case TTM_SETTIPTEXTCOLOR:
2386 return TOOLTIPS_SetTipTextColor (hwnd, wParam, lParam);
2387
2388 case TTM_SETTOOLINFOA:
2389 return TOOLTIPS_SetToolInfoA (hwnd, wParam, lParam);
2390
2391 case TTM_SETTOOLINFOW:
2392 return TOOLTIPS_SetToolInfoW (hwnd, wParam, lParam);
2393
2394 case TTM_TRACKACTIVATE:
2395 return TOOLTIPS_TrackActivate (hwnd, wParam, lParam);
2396
2397 case TTM_TRACKPOSITION:
2398 return TOOLTIPS_TrackPosition (hwnd, wParam, lParam);
2399
2400 case TTM_UPDATE:
2401 return TOOLTIPS_Update (hwnd, wParam, lParam);
2402
2403 case TTM_UPDATETIPTEXTA:
2404 return TOOLTIPS_UpdateTipTextA (hwnd, wParam, lParam);
2405
2406 case TTM_UPDATETIPTEXTW:
2407 return TOOLTIPS_UpdateTipTextW (hwnd, wParam, lParam);
2408
2409 case TTM_WINDOWFROMPOINT:
2410 return TOOLTIPS_WindowFromPoint (hwnd, wParam, lParam);
2411
2412
2413 case WM_CREATE:
2414 return TOOLTIPS_Create (hwnd, wParam, lParam);
2415
2416 case WM_DESTROY:
2417 return TOOLTIPS_Destroy (hwnd, wParam, lParam);
2418
2419 case WM_ERASEBKGND:
2420 return TOOLTIPS_EraseBackground (hwnd, wParam, lParam);
2421
2422 case WM_GETFONT:
2423 return TOOLTIPS_GetFont (hwnd, wParam, lParam);
2424
2425 case WM_GETTEXT:
2426 return TOOLTIPS_OnWMGetText (hwnd, wParam, lParam);
2427
2428 case WM_GETTEXTLENGTH:
2429 return TOOLTIPS_OnWMGetTextLength (hwnd, wParam, lParam);
2430
2431
2432 case WM_LBUTTONDOWN:
2433 case WM_LBUTTONUP:
2434 case WM_MBUTTONDOWN:
2435 case WM_MBUTTONUP:
2436 case WM_RBUTTONDOWN:
2437 case WM_RBUTTONUP:
2438 case WM_MOUSEMOVE:
2439 return TOOLTIPS_MouseMessage (hwnd, uMsg, wParam, lParam);
2440
2441 case WM_NCCREATE:
2442 return TOOLTIPS_NCCreate (hwnd, wParam, lParam);
2443
2444 case WM_NCHITTEST:
2445 return TOOLTIPS_NCHitTest (hwnd, wParam, lParam);
2446
2447 case WM_NOTIFYFORMAT:
2448 return TOOLTIPS_NotifyFormat (hwnd, wParam, lParam);
2449
2450 case WM_PAINT:
2451 return TOOLTIPS_Paint (hwnd, wParam, lParam);
2452
2453 case WM_SETFONT:
2454 return TOOLTIPS_SetFont (hwnd, wParam, lParam);
2455
2456 case WM_TIMER:
2457 return TOOLTIPS_Timer (hwnd, wParam, lParam);
2458
2459 case WM_WININICHANGE:
2460 return TOOLTIPS_WinIniChange (hwnd, wParam, lParam);
2461
2462 default:
2463// if (uMsg >= WM_USER)
2464// ERR (tooltips, "unknown msg %04x wp=%08x lp=%08lx\n",
2465// uMsg, wParam, lParam);
2466 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
2467 }
2468 return 0;
2469}
2470
2471
2472VOID
2473TOOLTIPS_Register (VOID)
2474{
2475 WNDCLASSA wndClass;
2476
2477 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
2478 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS;
2479 wndClass.lpfnWndProc = (WNDPROC)TOOLTIPS_WindowProc;
2480 wndClass.cbClsExtra = 0;
2481 wndClass.cbWndExtra = sizeof(TOOLTIPS_INFO *);
2482 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
2483 wndClass.hbrBackground = 0;
2484 wndClass.lpszClassName = TOOLTIPS_CLASSA;
2485
2486 RegisterClassA (&wndClass);
2487}
2488
2489
2490VOID
2491TOOLTIPS_Unregister (VOID)
2492{
2493 UnregisterClassA (TOOLTIPS_CLASSA, (HINSTANCE)NULL);
2494}
2495
Note: See TracBrowser for help on using the repository browser.