4 * Copyright 1998, 1999 Eric Kohl
7 * - Unicode support (started).
8 * - Custom draw support.
11 * - Run tests using Waite Group Windows95 API Bible Volume 2.
12 * The second cdrom (chapter 3) contains executables activate.exe,
13 * curtool.exe, deltool.exe, enumtools.exe, getinfo.exe, getiptxt.exe,
14 * hittest.exe, needtext.exe, newrect.exe, updtext.exe and winfrpt.exe.
22 #include "debugtools.h"
24 DEFAULT_DEBUG_CHANNEL(tooltips
)
26 #define ID_TIMERSHOW 1 /* show delay timer */
27 #define ID_TIMERPOP 2 /* auto pop timer */
28 #define ID_TIMERLEAVE 3 /* tool leave timer */
31 extern LPSTR COMCTL32_aSubclass
; /* global subclassing atom */
33 /* property name of tooltip window handle */
34 /*#define TT_SUBCLASS_PROP "CC32SubclassInfo" */
36 #define TOOLTIPS_GetInfoPtr(hWindow) ((TOOLTIPS_INFO *)GetWindowLongA (hWindow, 0))
40 TOOLTIPS_SubclassProc (HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
44 TOOLTIPS_Refresh (HWND hwnd
, HDC hdc
)
46 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr(hwnd
);
51 UINT uFlags
= DT_EXTERNALLEADING
;
53 if (infoPtr
->nMaxTipWidth
> -1)
54 uFlags
|= DT_WORDBREAK
;
55 if (GetWindowLongA (hwnd
, GWL_STYLE
) & TTS_NOPREFIX
)
56 uFlags
|= DT_NOPREFIX
;
57 GetClientRect (hwnd
, &rc
);
59 /* fill the background */
60 hBrush
= CreateSolidBrush (infoPtr
->clrBk
);
61 FillRect (hdc
, &rc
, hBrush
);
62 DeleteObject (hBrush
);
64 /* calculate text rectangle */
65 rc
.left
+= (2 + infoPtr
->rcMargin
.left
);
66 rc
.top
+= (2 + infoPtr
->rcMargin
.top
);
67 rc
.right
-= (2 + infoPtr
->rcMargin
.right
);
68 rc
.bottom
-= (2 + infoPtr
->rcMargin
.bottom
);
71 oldBkMode
= SetBkMode (hdc
, TRANSPARENT
);
72 SetTextColor (hdc
, infoPtr
->clrText
);
73 hOldFont
= SelectObject (hdc
, infoPtr
->hFont
);
74 DrawTextW (hdc
, infoPtr
->szTipText
, -1, &rc
, uFlags
);
75 SelectObject (hdc
, hOldFont
);
76 if (oldBkMode
!= TRANSPARENT
)
77 SetBkMode (hdc
, oldBkMode
);
82 TOOLTIPS_GetTipText (HWND hwnd
, TOOLTIPS_INFO
*infoPtr
, INT nTool
)
84 TTTOOL_INFO
*toolPtr
= &infoPtr
->tools
[nTool
];
86 if ((toolPtr
->hinst
) && (HIWORD((UINT
)toolPtr
->lpszText
) == 0)) {
88 TRACE("load res string %x %x\n",
89 toolPtr
->hinst
, (int)toolPtr
->lpszText
);
90 LoadStringW (toolPtr
->hinst
, (UINT
)toolPtr
->lpszText
,
91 infoPtr
->szTipText
, INFOTIPSIZE
);
93 else if (toolPtr
->lpszText
) {
94 if (toolPtr
->lpszText
== LPSTR_TEXTCALLBACKW
) {
97 /* fill NMHDR struct */
98 ZeroMemory (&ttnmdi
, sizeof(NMTTDISPINFOA
));
99 ttnmdi
.hdr
.hwndFrom
= hwnd
;
100 ttnmdi
.hdr
.idFrom
= toolPtr
->uId
;
101 ttnmdi
.hdr
.code
= TTN_GETDISPINFOA
;
102 ttnmdi
.lpszText
= (LPSTR
)&ttnmdi
.szText
;
103 ttnmdi
.uFlags
= toolPtr
->uFlags
;
104 ttnmdi
.lParam
= toolPtr
->lParam
;
106 TRACE("hdr.idFrom = %x\n", ttnmdi
.hdr
.idFrom
);
107 SendMessageA (toolPtr
->hwnd
, WM_NOTIFY
,
108 (WPARAM
)toolPtr
->uId
, (LPARAM
)&ttnmdi
);
110 if ((ttnmdi
.hinst
) && (HIWORD((UINT
)ttnmdi
.lpszText
) == 0)) {
111 LoadStringW (ttnmdi
.hinst
, (UINT
)ttnmdi
.lpszText
,
112 infoPtr
->szTipText
, INFOTIPSIZE
);
113 if (ttnmdi
.uFlags
& TTF_DI_SETITEM
) {
114 toolPtr
->hinst
= ttnmdi
.hinst
;
115 toolPtr
->lpszText
= (LPWSTR
)ttnmdi
.lpszText
;
118 else if (ttnmdi
.szText
[0]) {
119 lstrcpynAtoW (infoPtr
->szTipText
, ttnmdi
.szText
, 80);
120 if (ttnmdi
.uFlags
& TTF_DI_SETITEM
) {
121 INT len
= lstrlenA (ttnmdi
.szText
);
123 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+1)* sizeof(WCHAR
));
124 lstrcpyAtoW (toolPtr
->lpszText
, ttnmdi
.szText
);
127 else if (ttnmdi
.lpszText
== 0) {
128 /* no text available */
129 infoPtr
->szTipText
[0] = L
'\0';
131 else if (ttnmdi
.lpszText
!= LPSTR_TEXTCALLBACKA
) {
132 lstrcpynAtoW (infoPtr
->szTipText
, ttnmdi
.lpszText
, INFOTIPSIZE
);
133 if (ttnmdi
.uFlags
& TTF_DI_SETITEM
) {
134 INT len
= lstrlenA (ttnmdi
.lpszText
);
136 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
137 lstrcpyAtoW (toolPtr
->lpszText
, ttnmdi
.lpszText
);
141 ERR("recursive text callback!\n");
142 infoPtr
->szTipText
[0] = '\0';
146 /* the item is a usual (unicode) text */
147 lstrcpynW (infoPtr
->szTipText
, toolPtr
->lpszText
, INFOTIPSIZE
);
151 /* no text available */
152 infoPtr
->szTipText
[0] = L
'\0';
155 TRACE("%s\n", debugstr_w(infoPtr
->szTipText
));
160 TOOLTIPS_CalcTipSize (HWND hwnd
, TOOLTIPS_INFO
*infoPtr
, LPSIZE lpSize
)
164 UINT uFlags
= DT_EXTERNALLEADING
| DT_CALCRECT
;
165 RECT rc
= {0, 0, 0, 0};
167 if (infoPtr
->nMaxTipWidth
> -1) {
168 rc
.right
= infoPtr
->nMaxTipWidth
;
169 uFlags
|= DT_WORDBREAK
;
171 if (GetWindowLongA (hwnd
, GWL_STYLE
) & TTS_NOPREFIX
)
172 uFlags
|= DT_NOPREFIX
;
173 TRACE("%s\n", debugstr_w(infoPtr
->szTipText
));
176 hOldFont
= SelectObject (hdc
, infoPtr
->hFont
);
177 DrawTextW (hdc
, infoPtr
->szTipText
, -1, &rc
, uFlags
);
178 SelectObject (hdc
, hOldFont
);
179 ReleaseDC (hwnd
, hdc
);
181 lpSize
->cx
= rc
.right
- rc
.left
+ 4 +
182 infoPtr
->rcMargin
.left
+ infoPtr
->rcMargin
.right
;
183 lpSize
->cy
= rc
.bottom
- rc
.top
+ 4 +
184 infoPtr
->rcMargin
.bottom
+ infoPtr
->rcMargin
.top
;
189 TOOLTIPS_Show (HWND hwnd
, TOOLTIPS_INFO
*infoPtr
)
191 TTTOOL_INFO
*toolPtr
;
197 if (infoPtr
->nTool
== -1) {
198 TRACE("invalid tool (-1)!\n");
202 infoPtr
->nCurrentTool
= infoPtr
->nTool
;
204 TRACE("Show tooltip pre %d!\n", infoPtr
->nTool
);
206 TOOLTIPS_GetTipText (hwnd
, infoPtr
, infoPtr
->nCurrentTool
);
208 if (infoPtr
->szTipText
[0] == L
'\0') {
209 infoPtr
->nCurrentTool
= -1;
213 TRACE("Show tooltip %d!\n", infoPtr
->nCurrentTool
);
214 toolPtr
= &infoPtr
->tools
[infoPtr
->nCurrentTool
];
217 hdr
.idFrom
= toolPtr
->uId
;
219 SendMessageA (toolPtr
->hwnd
, WM_NOTIFY
,
220 (WPARAM
)toolPtr
->uId
, (LPARAM
)&hdr
);
222 TRACE("%s\n", debugstr_w(infoPtr
->szTipText
));
224 TOOLTIPS_CalcTipSize (hwnd
, infoPtr
, &size
);
225 TRACE("size %d - %d\n", size
.cx
, size
.cy
);
227 if (toolPtr
->uFlags
& TTF_CENTERTIP
) {
230 if (toolPtr
->uFlags
& TTF_IDISHWND
)
231 GetWindowRect ((HWND
)toolPtr
->uId
, &rc
);
234 MapWindowPoints (toolPtr
->hwnd
, (HWND
)0, (LPPOINT
)&rc
, 2);
236 rect
.left
= (rc
.left
+ rc
.right
- size
.cx
) / 2;
237 rect
.top
= rc
.bottom
+ 2;
240 GetCursorPos ((LPPOINT
)&rect
);
244 TRACE("pos %d - %d\n", rect
.left
, rect
.top
);
246 rect
.right
= rect
.left
+ size
.cx
;
247 rect
.bottom
= rect
.top
+ size
.cy
;
250 wndrect
.right
= GetSystemMetrics( SM_CXSCREEN
);
251 if( rect
.right
> wndrect
.right
) {
252 rect
.left
-= rect
.right
- wndrect
.right
+ 2;
253 rect
.right
= wndrect
.right
- 2;
255 wndrect
.bottom
= GetSystemMetrics( SM_CYSCREEN
);
256 if( rect
.bottom
> wndrect
.bottom
) {
259 if (toolPtr
->uFlags
& TTF_IDISHWND
)
260 GetWindowRect ((HWND
)toolPtr
->uId
, &rc
);
263 MapWindowPoints (toolPtr
->hwnd
, (HWND
)0, (LPPOINT
)&rc
, 2);
265 rect
.bottom
= rc
.top
- 2;
266 rect
.top
= rect
.bottom
- size
.cy
;
269 AdjustWindowRectEx (&rect
, GetWindowLongA (hwnd
, GWL_STYLE
),
270 FALSE
, GetWindowLongA (hwnd
, GWL_EXSTYLE
));
272 SetWindowPos (hwnd
, HWND_TOP
, rect
.left
, rect
.top
,
273 rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
274 SWP_SHOWWINDOW
| SWP_NOACTIVATE
);
276 /* repaint the tooltip */
278 TOOLTIPS_Refresh (hwnd
, hdc
);
279 ReleaseDC (hwnd
, hdc
);
281 SetTimer (hwnd
, ID_TIMERPOP
, infoPtr
->nAutoPopTime
, 0);
286 TOOLTIPS_Hide (HWND hwnd
, TOOLTIPS_INFO
*infoPtr
)
288 TTTOOL_INFO
*toolPtr
;
291 if (infoPtr
->nCurrentTool
== -1)
294 toolPtr
= &infoPtr
->tools
[infoPtr
->nCurrentTool
];
295 TRACE("Hide tooltip %d!\n", infoPtr
->nCurrentTool
);
296 KillTimer (hwnd
, ID_TIMERPOP
);
299 hdr
.idFrom
= toolPtr
->uId
;
301 SendMessageA (toolPtr
->hwnd
, WM_NOTIFY
,
302 (WPARAM
)toolPtr
->uId
, (LPARAM
)&hdr
);
304 infoPtr
->nCurrentTool
= -1;
306 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0,
307 SWP_NOZORDER
| SWP_HIDEWINDOW
| SWP_NOACTIVATE
);
312 TOOLTIPS_TrackShow (HWND hwnd
, TOOLTIPS_INFO
*infoPtr
)
314 TTTOOL_INFO
*toolPtr
;
320 if (infoPtr
->nTrackTool
== -1) {
321 TRACE("invalid tracking tool (-1)!\n");
325 TRACE("show tracking tooltip pre %d!\n", infoPtr
->nTrackTool
);
327 TOOLTIPS_GetTipText (hwnd
, infoPtr
, infoPtr
->nTrackTool
);
329 if (infoPtr
->szTipText
[0] == L
'\0') {
330 infoPtr
->nTrackTool
= -1;
334 TRACE("show tracking tooltip %d!\n", infoPtr
->nTrackTool
);
335 toolPtr
= &infoPtr
->tools
[infoPtr
->nTrackTool
];
338 hdr
.idFrom
= toolPtr
->uId
;
340 SendMessageA (toolPtr
->hwnd
, WM_NOTIFY
,
341 (WPARAM
)toolPtr
->uId
, (LPARAM
)&hdr
);
343 TRACE("%s\n", debugstr_w(infoPtr
->szTipText
));
345 TOOLTIPS_CalcTipSize (hwnd
, infoPtr
, &size
);
346 TRACE("size %d - %d\n", size
.cx
, size
.cy
);
348 if (toolPtr
->uFlags
& TTF_ABSOLUTE
) {
349 rect
.left
= infoPtr
->xTrackPos
;
350 rect
.top
= infoPtr
->yTrackPos
;
352 if (toolPtr
->uFlags
& TTF_CENTERTIP
) {
353 rect
.left
-= (size
.cx
/ 2);
354 rect
.top
-= (size
.cy
/ 2);
360 if (toolPtr
->uFlags
& TTF_IDISHWND
)
361 GetWindowRect ((HWND
)toolPtr
->uId
, &rcTool
);
363 rcTool
= toolPtr
->rect
;
364 MapWindowPoints (toolPtr
->hwnd
, (HWND
)0, (LPPOINT
)&rcTool
, 2);
367 GetCursorPos ((LPPOINT
)&rect
);
370 if (toolPtr
->uFlags
& TTF_CENTERTIP
) {
371 rect
.left
-= (size
.cx
/ 2);
372 rect
.top
-= (size
.cy
/ 2);
375 /* smart placement */
376 if ((rect
.left
+ size
.cx
> rcTool
.left
) && (rect
.left
< rcTool
.right
) &&
377 (rect
.top
+ size
.cy
> rcTool
.top
) && (rect
.top
< rcTool
.bottom
))
378 rect
.left
= rcTool
.right
;
381 TRACE("pos %d - %d\n", rect
.left
, rect
.top
);
383 rect
.right
= rect
.left
+ size
.cx
;
384 rect
.bottom
= rect
.top
+ size
.cy
;
386 AdjustWindowRectEx (&rect
, GetWindowLongA (hwnd
, GWL_STYLE
),
387 FALSE
, GetWindowLongA (hwnd
, GWL_EXSTYLE
));
389 SetWindowPos (hwnd
, HWND_TOP
, rect
.left
, rect
.top
,
390 rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
391 SWP_SHOWWINDOW
| SWP_NOACTIVATE
);
394 TOOLTIPS_Refresh (hwnd
, hdc
);
395 ReleaseDC (hwnd
, hdc
);
400 TOOLTIPS_TrackHide (HWND hwnd
, TOOLTIPS_INFO
*infoPtr
)
402 TTTOOL_INFO
*toolPtr
;
405 if (infoPtr
->nTrackTool
== -1)
408 toolPtr
= &infoPtr
->tools
[infoPtr
->nTrackTool
];
409 TRACE("hide tracking tooltip %d!\n", infoPtr
->nTrackTool
);
412 hdr
.idFrom
= toolPtr
->uId
;
414 SendMessageA (toolPtr
->hwnd
, WM_NOTIFY
,
415 (WPARAM
)toolPtr
->uId
, (LPARAM
)&hdr
);
417 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0,
418 SWP_NOZORDER
| SWP_HIDEWINDOW
| SWP_NOACTIVATE
);
423 TOOLTIPS_GetToolFromInfoA (TOOLTIPS_INFO
*infoPtr
, LPTTTOOLINFOA lpToolInfo
)
425 TTTOOL_INFO
*toolPtr
;
428 for (nTool
= 0; nTool
< infoPtr
->uNumTools
; nTool
++) {
429 toolPtr
= &infoPtr
->tools
[nTool
];
431 if (!(toolPtr
->uFlags
& TTF_IDISHWND
) &&
432 (lpToolInfo
->hwnd
== toolPtr
->hwnd
) &&
433 (lpToolInfo
->uId
== toolPtr
->uId
))
437 for (nTool
= 0; nTool
< infoPtr
->uNumTools
; nTool
++) {
438 toolPtr
= &infoPtr
->tools
[nTool
];
440 if ((toolPtr
->uFlags
& TTF_IDISHWND
) &&
441 (lpToolInfo
->uId
== toolPtr
->uId
))
450 TOOLTIPS_GetToolFromInfoW (TOOLTIPS_INFO
*infoPtr
, LPTTTOOLINFOW lpToolInfo
)
452 TTTOOL_INFO
*toolPtr
;
455 for (nTool
= 0; nTool
< infoPtr
->uNumTools
; nTool
++) {
456 toolPtr
= &infoPtr
->tools
[nTool
];
458 if (!(toolPtr
->uFlags
& TTF_IDISHWND
) &&
459 (lpToolInfo
->hwnd
== toolPtr
->hwnd
) &&
460 (lpToolInfo
->uId
== toolPtr
->uId
))
464 for (nTool
= 0; nTool
< infoPtr
->uNumTools
; nTool
++) {
465 toolPtr
= &infoPtr
->tools
[nTool
];
467 if ((toolPtr
->uFlags
& TTF_IDISHWND
) &&
468 (lpToolInfo
->uId
== toolPtr
->uId
))
477 TOOLTIPS_GetToolFromPoint (TOOLTIPS_INFO
*infoPtr
, HWND hwnd
, LPPOINT lpPt
)
479 TTTOOL_INFO
*toolPtr
;
482 for (nTool
= 0; nTool
< infoPtr
->uNumTools
; nTool
++) {
483 toolPtr
= &infoPtr
->tools
[nTool
];
485 if (!(toolPtr
->uFlags
& TTF_IDISHWND
)) {
486 if (hwnd
!= toolPtr
->hwnd
)
488 if (!PtInRect (&toolPtr
->rect
, *lpPt
))
494 for (nTool
= 0; nTool
< infoPtr
->uNumTools
; nTool
++) {
495 toolPtr
= &infoPtr
->tools
[nTool
];
497 if (toolPtr
->uFlags
& TTF_IDISHWND
) {
498 if ((HWND
)toolPtr
->uId
== hwnd
)
508 TOOLTIPS_GetToolFromMessage (TOOLTIPS_INFO
*infoPtr
, HWND hwndTool
)
513 dwPos
= GetMessagePos ();
514 pt
.x
= (INT
)LOWORD(dwPos
);
515 pt
.y
= (INT
)HIWORD(dwPos
);
516 ScreenToClient (hwndTool
, &pt
);
518 return TOOLTIPS_GetToolFromPoint (infoPtr
, hwndTool
, &pt
);
523 TOOLTIPS_IsWindowActive (HWND hwnd
)
525 HWND hwndActive
= GetActiveWindow ();
528 if (hwndActive
== hwnd
)
530 return IsChild (hwndActive
, hwnd
);
535 TOOLTIPS_CheckTool (HWND hwnd
, BOOL bShowTest
)
537 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
543 hwndTool
= SendMessageA (hwnd
, TTM_WINDOWFROMPOINT
, 0, (LPARAM
)&pt
);
547 ScreenToClient (hwndTool
, &pt
);
548 nTool
= TOOLTIPS_GetToolFromPoint (infoPtr
, hwndTool
, &pt
);
552 if (!(GetWindowLongA (hwnd
, GWL_STYLE
) & TTS_ALWAYSTIP
) && bShowTest
) {
553 if (!TOOLTIPS_IsWindowActive (GetWindow (hwnd
, GW_OWNER
)))
557 TRACE("tool %d\n", nTool
);
564 TOOLTIPS_Activate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
566 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
568 infoPtr
->bActive
= (BOOL
)wParam
;
570 if (infoPtr
->bActive
)
571 TRACE("activate!\n");
573 if (!(infoPtr
->bActive
) && (infoPtr
->nCurrentTool
!= -1))
574 TOOLTIPS_Hide (hwnd
, infoPtr
);
581 TOOLTIPS_AddToolA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
583 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
584 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
585 TTTOOL_INFO
*toolPtr
;
587 if (lpToolInfo
== NULL
)
589 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
592 TRACE("add tool (%x) %x %d%s!\n",
593 hwnd
, lpToolInfo
->hwnd
, lpToolInfo
->uId
,
594 (lpToolInfo
->uFlags
& TTF_IDISHWND
) ? " TTF_IDISHWND" : "");
596 if (infoPtr
->uNumTools
== 0) {
597 infoPtr
->tools
= COMCTL32_Alloc (sizeof(TTTOOL_INFO
));
598 toolPtr
= infoPtr
->tools
;
601 TTTOOL_INFO
*oldTools
= infoPtr
->tools
;
603 COMCTL32_Alloc (sizeof(TTTOOL_INFO
) * (infoPtr
->uNumTools
+ 1));
604 memcpy (infoPtr
->tools
, oldTools
,
605 infoPtr
->uNumTools
* sizeof(TTTOOL_INFO
));
606 COMCTL32_Free (oldTools
);
607 toolPtr
= &infoPtr
->tools
[infoPtr
->uNumTools
];
610 infoPtr
->uNumTools
++;
613 toolPtr
->uFlags
= lpToolInfo
->uFlags
;
614 toolPtr
->hwnd
= lpToolInfo
->hwnd
;
615 toolPtr
->uId
= lpToolInfo
->uId
;
616 toolPtr
->rect
= lpToolInfo
->rect
;
617 toolPtr
->hinst
= lpToolInfo
->hinst
;
619 if ((lpToolInfo
->hinst
) && (HIWORD((INT
)lpToolInfo
->lpszText
) == 0)) {
620 TRACE("add string id %x!\n", (int)lpToolInfo
->lpszText
);
621 toolPtr
->lpszText
= (LPWSTR
)lpToolInfo
->lpszText
;
623 else if (lpToolInfo
->lpszText
) {
624 if (lpToolInfo
->lpszText
== LPSTR_TEXTCALLBACKA
) {
625 TRACE("add CALLBACK!\n");
626 toolPtr
->lpszText
= LPSTR_TEXTCALLBACKW
;
629 INT len
= lstrlenA (lpToolInfo
->lpszText
);
630 TRACE("add text \"%s\"!\n", lpToolInfo
->lpszText
);
631 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+ 1)*sizeof(WCHAR
));
632 lstrcpyAtoW (toolPtr
->lpszText
, lpToolInfo
->lpszText
);
636 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOA
))
637 toolPtr
->lParam
= lpToolInfo
->lParam
;
639 /* install subclassing hook */
640 if (toolPtr
->uFlags
& TTF_SUBCLASS
) {
641 if (toolPtr
->uFlags
& TTF_IDISHWND
) {
642 LPTT_SUBCLASS_INFO lpttsi
=
643 (LPTT_SUBCLASS_INFO
)GetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
644 if (lpttsi
== NULL
) {
646 (LPTT_SUBCLASS_INFO
)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO
));
648 (WNDPROC
)SetWindowLongA ((HWND
)toolPtr
->uId
,
649 GWL_WNDPROC
,(LONG
)TOOLTIPS_SubclassProc
);
650 lpttsi
->hwndToolTip
= hwnd
;
652 SetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
,
656 WARN("A window tool must only be listed once!\n");
659 LPTT_SUBCLASS_INFO lpttsi
=
660 (LPTT_SUBCLASS_INFO
)GetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
);
661 if (lpttsi
== NULL
) {
663 (LPTT_SUBCLASS_INFO
)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO
));
665 (WNDPROC
)SetWindowLongA (toolPtr
->hwnd
,
666 GWL_WNDPROC
,(LONG
)TOOLTIPS_SubclassProc
);
667 lpttsi
->hwndToolTip
= hwnd
;
669 SetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
, (HANDLE
)lpttsi
);
674 TRACE("subclassing installed!\n");
682 TOOLTIPS_AddToolW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
684 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
685 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
686 TTTOOL_INFO
*toolPtr
;
688 if (lpToolInfo
== NULL
)
690 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
693 TRACE("add tool (%x) %x %d%s!\n",
694 hwnd
, lpToolInfo
->hwnd
, lpToolInfo
->uId
,
695 (lpToolInfo
->uFlags
& TTF_IDISHWND
) ? " TTF_IDISHWND" : "");
697 if (infoPtr
->uNumTools
== 0) {
698 infoPtr
->tools
= COMCTL32_Alloc (sizeof(TTTOOL_INFO
));
699 toolPtr
= infoPtr
->tools
;
702 TTTOOL_INFO
*oldTools
= infoPtr
->tools
;
704 COMCTL32_Alloc (sizeof(TTTOOL_INFO
) * (infoPtr
->uNumTools
+ 1));
705 memcpy (infoPtr
->tools
, oldTools
,
706 infoPtr
->uNumTools
* sizeof(TTTOOL_INFO
));
707 COMCTL32_Free (oldTools
);
708 toolPtr
= &infoPtr
->tools
[infoPtr
->uNumTools
];
711 infoPtr
->uNumTools
++;
714 toolPtr
->uFlags
= lpToolInfo
->uFlags
;
715 toolPtr
->hwnd
= lpToolInfo
->hwnd
;
716 toolPtr
->uId
= lpToolInfo
->uId
;
717 toolPtr
->rect
= lpToolInfo
->rect
;
718 toolPtr
->hinst
= lpToolInfo
->hinst
;
720 if ((lpToolInfo
->hinst
) && (HIWORD((INT
)lpToolInfo
->lpszText
) == 0)) {
721 TRACE("add string id %x!\n", (int)lpToolInfo
->lpszText
);
722 toolPtr
->lpszText
= (LPWSTR
)lpToolInfo
->lpszText
;
724 else if (lpToolInfo
->lpszText
) {
725 if (lpToolInfo
->lpszText
== LPSTR_TEXTCALLBACKW
) {
726 TRACE("add CALLBACK!\n");
727 toolPtr
->lpszText
= LPSTR_TEXTCALLBACKW
;
730 INT len
= lstrlenW (lpToolInfo
->lpszText
);
731 TRACE("add text %s!\n",
732 debugstr_w(lpToolInfo
->lpszText
));
733 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+ 1)*sizeof(WCHAR
));
734 lstrcpyW (toolPtr
->lpszText
, lpToolInfo
->lpszText
);
738 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOW
))
739 toolPtr
->lParam
= lpToolInfo
->lParam
;
741 /* install subclassing hook */
742 if (toolPtr
->uFlags
& TTF_SUBCLASS
) {
743 if (toolPtr
->uFlags
& TTF_IDISHWND
) {
744 LPTT_SUBCLASS_INFO lpttsi
=
745 (LPTT_SUBCLASS_INFO
)GetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
746 if (lpttsi
== NULL
) {
748 (LPTT_SUBCLASS_INFO
)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO
));
750 (WNDPROC
)SetWindowLongA ((HWND
)toolPtr
->uId
,
751 GWL_WNDPROC
,(LONG
)TOOLTIPS_SubclassProc
);
752 lpttsi
->hwndToolTip
= hwnd
;
754 SetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
,
758 WARN("A window tool must only be listed once!\n");
761 LPTT_SUBCLASS_INFO lpttsi
=
762 (LPTT_SUBCLASS_INFO
)GetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
);
763 if (lpttsi
== NULL
) {
765 (LPTT_SUBCLASS_INFO
)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO
));
767 (WNDPROC
)SetWindowLongA (toolPtr
->hwnd
,
768 GWL_WNDPROC
,(LONG
)TOOLTIPS_SubclassProc
);
769 lpttsi
->hwndToolTip
= hwnd
;
771 SetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
, (HANDLE
)lpttsi
);
776 TRACE("subclassing installed!\n");
784 TOOLTIPS_DelToolA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
786 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
787 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
788 TTTOOL_INFO
*toolPtr
;
791 if (lpToolInfo
== NULL
)
793 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
795 if (infoPtr
->uNumTools
== 0)
798 nTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpToolInfo
);
799 if (nTool
== -1) return 0;
801 TRACE("tool %d\n", nTool
);
803 /* delete text string */
804 toolPtr
= &infoPtr
->tools
[nTool
];
805 if ((toolPtr
->hinst
) && (toolPtr
->lpszText
)) {
806 if ( (toolPtr
->lpszText
!= LPSTR_TEXTCALLBACKW
) &&
807 (HIWORD((INT
)toolPtr
->lpszText
) != 0) )
808 COMCTL32_Free (toolPtr
->lpszText
);
811 /* remove subclassing */
812 if (toolPtr
->uFlags
& TTF_SUBCLASS
) {
813 if (toolPtr
->uFlags
& TTF_IDISHWND
) {
814 LPTT_SUBCLASS_INFO lpttsi
=
815 (LPTT_SUBCLASS_INFO
)GetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
817 SetWindowLongA ((HWND
)toolPtr
->uId
, GWL_WNDPROC
,
818 (LONG
)lpttsi
->wpOrigProc
);
819 RemovePropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
820 COMCTL32_Free (&lpttsi
);
823 ERR("Invalid data handle!\n");
826 LPTT_SUBCLASS_INFO lpttsi
=
827 (LPTT_SUBCLASS_INFO
)GetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
);
829 if (lpttsi
->uRefCount
== 1) {
830 SetWindowLongA ((HWND
)toolPtr
->uId
, GWL_WNDPROC
,
831 (LONG
)lpttsi
->wpOrigProc
);
832 RemovePropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
833 COMCTL32_Free (&lpttsi
);
839 ERR("Invalid data handle!\n");
843 /* delete tool from tool list */
844 if (infoPtr
->uNumTools
== 1) {
845 COMCTL32_Free (infoPtr
->tools
);
846 infoPtr
->tools
= NULL
;
849 TTTOOL_INFO
*oldTools
= infoPtr
->tools
;
851 COMCTL32_Alloc (sizeof(TTTOOL_INFO
) * (infoPtr
->uNumTools
- 1));
854 memcpy (&infoPtr
->tools
[0], &oldTools
[0],
855 nTool
* sizeof(TTTOOL_INFO
));
857 if (nTool
< infoPtr
->uNumTools
- 1)
858 memcpy (&infoPtr
->tools
[nTool
], &oldTools
[nTool
+ 1],
859 (infoPtr
->uNumTools
- nTool
- 1) * sizeof(TTTOOL_INFO
));
861 COMCTL32_Free (oldTools
);
864 infoPtr
->uNumTools
--;
871 TOOLTIPS_DelToolW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
873 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
874 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
875 TTTOOL_INFO
*toolPtr
;
878 if (lpToolInfo
== NULL
)
880 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
882 if (infoPtr
->uNumTools
== 0)
885 nTool
= TOOLTIPS_GetToolFromInfoW (infoPtr
, lpToolInfo
);
886 if (nTool
== -1) return 0;
888 TRACE("tool %d\n", nTool
);
890 /* delete text string */
891 toolPtr
= &infoPtr
->tools
[nTool
];
892 if ((toolPtr
->hinst
) && (toolPtr
->lpszText
)) {
893 if ( (toolPtr
->lpszText
!= LPSTR_TEXTCALLBACKW
) &&
894 (HIWORD((INT
)toolPtr
->lpszText
) != 0) )
895 COMCTL32_Free (toolPtr
->lpszText
);
898 /* remove subclassing */
899 if (toolPtr
->uFlags
& TTF_SUBCLASS
) {
900 if (toolPtr
->uFlags
& TTF_IDISHWND
) {
901 LPTT_SUBCLASS_INFO lpttsi
=
902 (LPTT_SUBCLASS_INFO
)GetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
904 SetWindowLongA ((HWND
)toolPtr
->uId
, GWL_WNDPROC
,
905 (LONG
)lpttsi
->wpOrigProc
);
906 RemovePropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
907 COMCTL32_Free (&lpttsi
);
910 ERR("Invalid data handle!\n");
913 LPTT_SUBCLASS_INFO lpttsi
=
914 (LPTT_SUBCLASS_INFO
)GetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
);
916 if (lpttsi
->uRefCount
== 1) {
917 SetWindowLongA ((HWND
)toolPtr
->uId
, GWL_WNDPROC
,
918 (LONG
)lpttsi
->wpOrigProc
);
919 RemovePropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
920 COMCTL32_Free (&lpttsi
);
926 ERR("Invalid data handle!\n");
930 /* delete tool from tool list */
931 if (infoPtr
->uNumTools
== 1) {
932 COMCTL32_Free (infoPtr
->tools
);
933 infoPtr
->tools
= NULL
;
936 TTTOOL_INFO
*oldTools
= infoPtr
->tools
;
938 COMCTL32_Alloc (sizeof(TTTOOL_INFO
) * (infoPtr
->uNumTools
- 1));
941 memcpy (&infoPtr
->tools
[0], &oldTools
[0],
942 nTool
* sizeof(TTTOOL_INFO
));
944 if (nTool
< infoPtr
->uNumTools
- 1)
945 memcpy (&infoPtr
->tools
[nTool
], &oldTools
[nTool
+ 1],
946 (infoPtr
->uNumTools
- nTool
- 1) * sizeof(TTTOOL_INFO
));
948 COMCTL32_Free (oldTools
);
951 infoPtr
->uNumTools
--;
958 TOOLTIPS_EnumToolsA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
960 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
961 UINT uIndex
= (UINT
)wParam
;
962 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
963 TTTOOL_INFO
*toolPtr
;
965 if (lpToolInfo
== NULL
)
967 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
969 if (uIndex
>= infoPtr
->uNumTools
)
972 TRACE("index=%u\n", uIndex
);
974 toolPtr
= &infoPtr
->tools
[uIndex
];
977 lpToolInfo
->uFlags
= toolPtr
->uFlags
;
978 lpToolInfo
->hwnd
= toolPtr
->hwnd
;
979 lpToolInfo
->uId
= toolPtr
->uId
;
980 lpToolInfo
->rect
= toolPtr
->rect
;
981 lpToolInfo
->hinst
= toolPtr
->hinst
;
982 /* lpToolInfo->lpszText = toolPtr->lpszText; */
983 lpToolInfo
->lpszText
= NULL
; /* FIXME */
985 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOA
))
986 lpToolInfo
->lParam
= toolPtr
->lParam
;
993 TOOLTIPS_EnumToolsW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
995 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
996 UINT uIndex
= (UINT
)wParam
;
997 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
998 TTTOOL_INFO
*toolPtr
;
1000 if (lpToolInfo
== NULL
)
1002 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
1004 if (uIndex
>= infoPtr
->uNumTools
)
1007 TRACE("index=%u\n", uIndex
);
1009 toolPtr
= &infoPtr
->tools
[uIndex
];
1011 /* copy tool data */
1012 lpToolInfo
->uFlags
= toolPtr
->uFlags
;
1013 lpToolInfo
->hwnd
= toolPtr
->hwnd
;
1014 lpToolInfo
->uId
= toolPtr
->uId
;
1015 lpToolInfo
->rect
= toolPtr
->rect
;
1016 lpToolInfo
->hinst
= toolPtr
->hinst
;
1017 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1018 lpToolInfo
->lpszText
= NULL
; /* FIXME */
1020 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOW
))
1021 lpToolInfo
->lParam
= toolPtr
->lParam
;
1028 TOOLTIPS_GetCurrentToolA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1030 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1031 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
1032 TTTOOL_INFO
*toolPtr
;
1034 if (lpToolInfo
== NULL
)
1036 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1040 if (infoPtr
->nCurrentTool
> -1) {
1041 toolPtr
= &infoPtr
->tools
[infoPtr
->nCurrentTool
];
1043 /* copy tool data */
1044 lpToolInfo
->uFlags
= toolPtr
->uFlags
;
1045 lpToolInfo
->rect
= toolPtr
->rect
;
1046 lpToolInfo
->hinst
= toolPtr
->hinst
;
1047 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1048 lpToolInfo
->lpszText
= NULL
; /* FIXME */
1050 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOA
))
1051 lpToolInfo
->lParam
= toolPtr
->lParam
;
1059 return (infoPtr
->nCurrentTool
!= -1);
1066 TOOLTIPS_GetCurrentToolW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1068 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1069 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
1070 TTTOOL_INFO
*toolPtr
;
1072 if (lpToolInfo
== NULL
)
1074 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
1078 if (infoPtr
->nCurrentTool
> -1) {
1079 toolPtr
= &infoPtr
->tools
[infoPtr
->nCurrentTool
];
1081 /* copy tool data */
1082 lpToolInfo
->uFlags
= toolPtr
->uFlags
;
1083 lpToolInfo
->rect
= toolPtr
->rect
;
1084 lpToolInfo
->hinst
= toolPtr
->hinst
;
1085 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1086 lpToolInfo
->lpszText
= NULL
; /* FIXME */
1088 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOW
))
1089 lpToolInfo
->lParam
= toolPtr
->lParam
;
1097 return (infoPtr
->nCurrentTool
!= -1);
1104 TOOLTIPS_GetDelayTime (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1106 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1109 case TTDT_AUTOMATIC
:
1110 return infoPtr
->nAutomaticTime
;
1113 return infoPtr
->nReshowTime
;
1116 return infoPtr
->nAutoPopTime
;
1119 return infoPtr
->nInitialTime
;
1127 TOOLTIPS_GetMargin (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1129 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1130 LPRECT lpRect
= (LPRECT
)lParam
;
1132 lpRect
->left
= infoPtr
->rcMargin
.left
;
1133 lpRect
->right
= infoPtr
->rcMargin
.right
;
1134 lpRect
->bottom
= infoPtr
->rcMargin
.bottom
;
1135 lpRect
->top
= infoPtr
->rcMargin
.top
;
1141 inline static LRESULT
1142 TOOLTIPS_GetMaxTipWidth (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1144 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1146 return infoPtr
->nMaxTipWidth
;
1151 TOOLTIPS_GetTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1153 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1154 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
1157 if (lpToolInfo
== NULL
)
1159 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1162 nTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpToolInfo
);
1163 if (nTool
== -1) return 0;
1165 lstrcpyWtoA (lpToolInfo
->lpszText
, infoPtr
->tools
[nTool
].lpszText
);
1172 TOOLTIPS_GetTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1174 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1175 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
1178 if (lpToolInfo
== NULL
)
1180 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
1183 nTool
= TOOLTIPS_GetToolFromInfoW (infoPtr
, lpToolInfo
);
1184 if (nTool
== -1) return 0;
1186 lstrcpyW (lpToolInfo
->lpszText
, infoPtr
->tools
[nTool
].lpszText
);
1192 inline static LRESULT
1193 TOOLTIPS_GetTipBkColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1195 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1196 return infoPtr
->clrBk
;
1200 inline static LRESULT
1201 TOOLTIPS_GetTipTextColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1203 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1204 return infoPtr
->clrText
;
1208 inline static LRESULT
1209 TOOLTIPS_GetToolCount (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1211 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1212 return infoPtr
->uNumTools
;
1217 TOOLTIPS_GetToolInfoA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1219 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1220 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
1221 TTTOOL_INFO
*toolPtr
;
1224 if (lpToolInfo
== NULL
)
1226 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1228 if (infoPtr
->uNumTools
== 0)
1231 nTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpToolInfo
);
1235 TRACE("tool %d\n", nTool
);
1237 toolPtr
= &infoPtr
->tools
[nTool
];
1239 /* copy tool data */
1240 lpToolInfo
->uFlags
= toolPtr
->uFlags
;
1241 lpToolInfo
->rect
= toolPtr
->rect
;
1242 lpToolInfo
->hinst
= toolPtr
->hinst
;
1243 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1244 lpToolInfo
->lpszText
= NULL
; /* FIXME */
1246 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOA
))
1247 lpToolInfo
->lParam
= toolPtr
->lParam
;
1254 TOOLTIPS_GetToolInfoW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1256 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1257 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
1258 TTTOOL_INFO
*toolPtr
;
1261 if (lpToolInfo
== NULL
)
1263 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
1265 if (infoPtr
->uNumTools
== 0)
1268 nTool
= TOOLTIPS_GetToolFromInfoW (infoPtr
, lpToolInfo
);
1272 TRACE("tool %d\n", nTool
);
1274 toolPtr
= &infoPtr
->tools
[nTool
];
1276 /* copy tool data */
1277 lpToolInfo
->uFlags
= toolPtr
->uFlags
;
1278 lpToolInfo
->rect
= toolPtr
->rect
;
1279 lpToolInfo
->hinst
= toolPtr
->hinst
;
1280 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1281 lpToolInfo
->lpszText
= NULL
; /* FIXME */
1283 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOW
))
1284 lpToolInfo
->lParam
= toolPtr
->lParam
;
1291 TOOLTIPS_HitTestA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1293 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1294 LPTTHITTESTINFOA lptthit
= (LPTTHITTESTINFOA
)lParam
;
1295 TTTOOL_INFO
*toolPtr
;
1301 nTool
= TOOLTIPS_GetToolFromPoint (infoPtr
, lptthit
->hwnd
, &lptthit
->pt
);
1305 TRACE("tool %d!\n", nTool
);
1307 /* copy tool data */
1308 if (lptthit
->ti
.cbSize
>= sizeof(TTTOOLINFOA
)) {
1309 toolPtr
= &infoPtr
->tools
[nTool
];
1311 lptthit
->ti
.uFlags
= toolPtr
->uFlags
;
1312 lptthit
->ti
.hwnd
= toolPtr
->hwnd
;
1313 lptthit
->ti
.uId
= toolPtr
->uId
;
1314 lptthit
->ti
.rect
= toolPtr
->rect
;
1315 lptthit
->ti
.hinst
= toolPtr
->hinst
;
1316 /* lptthit->ti.lpszText = toolPtr->lpszText; */
1317 lptthit
->ti
.lpszText
= NULL
; /* FIXME */
1318 lptthit
->ti
.lParam
= toolPtr
->lParam
;
1326 TOOLTIPS_HitTestW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1328 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1329 LPTTHITTESTINFOW lptthit
= (LPTTHITTESTINFOW
)lParam
;
1330 TTTOOL_INFO
*toolPtr
;
1336 nTool
= TOOLTIPS_GetToolFromPoint (infoPtr
, lptthit
->hwnd
, &lptthit
->pt
);
1340 TRACE("tool %d!\n", nTool
);
1342 /* copy tool data */
1343 if (lptthit
->ti
.cbSize
>= sizeof(TTTOOLINFOW
)) {
1344 toolPtr
= &infoPtr
->tools
[nTool
];
1346 lptthit
->ti
.uFlags
= toolPtr
->uFlags
;
1347 lptthit
->ti
.hwnd
= toolPtr
->hwnd
;
1348 lptthit
->ti
.uId
= toolPtr
->uId
;
1349 lptthit
->ti
.rect
= toolPtr
->rect
;
1350 lptthit
->ti
.hinst
= toolPtr
->hinst
;
1351 /* lptthit->ti.lpszText = toolPtr->lpszText; */
1352 lptthit
->ti
.lpszText
= NULL
; /* FIXME */
1353 lptthit
->ti
.lParam
= toolPtr
->lParam
;
1361 TOOLTIPS_NewToolRectA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1363 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1364 LPTTTOOLINFOA lpti
= (LPTTTOOLINFOA
)lParam
;
1369 if (lpti
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1372 nTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpti
);
1373 if (nTool
== -1) return 0;
1375 infoPtr
->tools
[nTool
].rect
= lpti
->rect
;
1382 TOOLTIPS_NewToolRectW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1384 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1385 LPTTTOOLINFOW lpti
= (LPTTTOOLINFOW
)lParam
;
1390 if (lpti
->cbSize
< TTTOOLINFO_V1_SIZEW
)
1393 nTool
= TOOLTIPS_GetToolFromInfoW (infoPtr
, lpti
);
1394 if (nTool
== -1) return 0;
1396 infoPtr
->tools
[nTool
].rect
= lpti
->rect
;
1402 inline static LRESULT
1403 TOOLTIPS_Pop (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1405 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1407 TOOLTIPS_Hide (hwnd
, infoPtr
);
1414 TOOLTIPS_RelayEvent (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1416 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1417 LPMSG lpMsg
= (LPMSG
)lParam
;
1421 ERR("lpMsg == NULL!\n");
1425 switch (lpMsg
->message
) {
1426 case WM_LBUTTONDOWN
:
1428 case WM_MBUTTONDOWN
:
1430 case WM_RBUTTONDOWN
:
1433 ScreenToClient (lpMsg
->hwnd
, &pt
);
1434 infoPtr
->nOldTool
= infoPtr
->nTool
;
1435 infoPtr
->nTool
= TOOLTIPS_GetToolFromPoint (infoPtr
, lpMsg
->hwnd
, &pt
);
1436 TRACE("tool (%x) %d %d\n",
1437 hwnd
, infoPtr
->nOldTool
, infoPtr
->nTool
);
1438 TOOLTIPS_Hide (hwnd
, infoPtr
);
1443 ScreenToClient (lpMsg
->hwnd
, &pt
);
1444 infoPtr
->nOldTool
= infoPtr
->nTool
;
1445 infoPtr
->nTool
= TOOLTIPS_GetToolFromPoint (infoPtr
, lpMsg
->hwnd
, &pt
);
1446 TRACE("tool (%x) %d %d\n",
1447 hwnd
, infoPtr
->nOldTool
, infoPtr
->nTool
);
1448 TRACE("WM_MOUSEMOVE (%04x %ld %ld)\n",
1450 if ((infoPtr
->bActive
) && (infoPtr
->nTool
!= infoPtr
->nOldTool
)) {
1451 if (infoPtr
->nOldTool
== -1) {
1452 SetTimer (hwnd
, ID_TIMERSHOW
, infoPtr
->nInitialTime
, 0);
1453 TRACE("timer 1 started!\n");
1456 TOOLTIPS_Hide (hwnd
, infoPtr
);
1457 SetTimer (hwnd
, ID_TIMERSHOW
, infoPtr
->nReshowTime
, 0);
1458 TRACE("timer 2 started!\n");
1461 if (infoPtr
->nCurrentTool
!= -1) {
1462 SetTimer (hwnd
, ID_TIMERLEAVE
, 100, 0);
1463 TRACE("timer 3 started!\n");
1473 TOOLTIPS_SetDelayTime (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1475 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1476 INT nTime
= (INT
)LOWORD(lParam
);
1479 case TTDT_AUTOMATIC
:
1481 infoPtr
->nAutomaticTime
= 500;
1482 infoPtr
->nReshowTime
= 100;
1483 infoPtr
->nAutoPopTime
= 5000;
1484 infoPtr
->nInitialTime
= 500;
1487 infoPtr
->nAutomaticTime
= nTime
;
1488 infoPtr
->nReshowTime
= nTime
/ 5;
1489 infoPtr
->nAutoPopTime
= nTime
* 10;
1490 infoPtr
->nInitialTime
= nTime
;
1495 infoPtr
->nReshowTime
= nTime
;
1499 infoPtr
->nAutoPopTime
= nTime
;
1503 infoPtr
->nInitialTime
= nTime
;
1512 TOOLTIPS_SetMargin (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1514 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1515 LPRECT lpRect
= (LPRECT
)lParam
;
1517 infoPtr
->rcMargin
.left
= lpRect
->left
;
1518 infoPtr
->rcMargin
.right
= lpRect
->right
;
1519 infoPtr
->rcMargin
.bottom
= lpRect
->bottom
;
1520 infoPtr
->rcMargin
.top
= lpRect
->top
;
1526 inline static LRESULT
1527 TOOLTIPS_SetMaxTipWidth (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1529 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1530 INT nTemp
= infoPtr
->nMaxTipWidth
;
1532 infoPtr
->nMaxTipWidth
= (INT
)lParam
;
1538 inline static LRESULT
1539 TOOLTIPS_SetTipBkColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1541 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1543 infoPtr
->clrBk
= (COLORREF
)wParam
;
1549 inline static LRESULT
1550 TOOLTIPS_SetTipTextColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1552 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1554 infoPtr
->clrText
= (COLORREF
)wParam
;
1561 TOOLTIPS_SetToolInfoA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1563 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1564 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
1565 TTTOOL_INFO
*toolPtr
;
1568 if (lpToolInfo
== NULL
)
1570 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1573 nTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpToolInfo
);
1574 if (nTool
== -1) return 0;
1576 TRACE("tool %d\n", nTool
);
1578 toolPtr
= &infoPtr
->tools
[nTool
];
1580 /* copy tool data */
1581 toolPtr
->uFlags
= lpToolInfo
->uFlags
;
1582 toolPtr
->hwnd
= lpToolInfo
->hwnd
;
1583 toolPtr
->uId
= lpToolInfo
->uId
;
1584 toolPtr
->rect
= lpToolInfo
->rect
;
1585 toolPtr
->hinst
= lpToolInfo
->hinst
;
1587 if ((lpToolInfo
->hinst
) && (HIWORD((INT
)lpToolInfo
->lpszText
) == 0)) {
1588 TRACE("set string id %x!\n", (INT
)lpToolInfo
->lpszText
);
1589 toolPtr
->lpszText
= (LPWSTR
)lpToolInfo
->lpszText
;
1591 else if (lpToolInfo
->lpszText
) {
1592 if (lpToolInfo
->lpszText
== LPSTR_TEXTCALLBACKA
)
1593 toolPtr
->lpszText
= LPSTR_TEXTCALLBACKW
;
1595 if ( (toolPtr
->lpszText
) &&
1596 (HIWORD((INT
)toolPtr
->lpszText
) != 0) ) {
1597 COMCTL32_Free (toolPtr
->lpszText
);
1598 toolPtr
->lpszText
= NULL
;
1600 if (lpToolInfo
->lpszText
) {
1601 INT len
= lstrlenA (lpToolInfo
->lpszText
);
1602 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1603 lstrcpyAtoW (toolPtr
->lpszText
, lpToolInfo
->lpszText
);
1608 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOA
))
1609 toolPtr
->lParam
= lpToolInfo
->lParam
;
1616 TOOLTIPS_SetToolInfoW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1618 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1619 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
1620 TTTOOL_INFO
*toolPtr
;
1623 if (lpToolInfo
== NULL
)
1625 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
1628 nTool
= TOOLTIPS_GetToolFromInfoW (infoPtr
, lpToolInfo
);
1629 if (nTool
== -1) return 0;
1631 TRACE("tool %d\n", nTool
);
1633 toolPtr
= &infoPtr
->tools
[nTool
];
1635 /* copy tool data */
1636 toolPtr
->uFlags
= lpToolInfo
->uFlags
;
1637 toolPtr
->hwnd
= lpToolInfo
->hwnd
;
1638 toolPtr
->uId
= lpToolInfo
->uId
;
1639 toolPtr
->rect
= lpToolInfo
->rect
;
1640 toolPtr
->hinst
= lpToolInfo
->hinst
;
1642 if ((lpToolInfo
->hinst
) && (HIWORD((INT
)lpToolInfo
->lpszText
) == 0)) {
1643 TRACE("set string id %x!\n", (INT
)lpToolInfo
->lpszText
);
1644 toolPtr
->lpszText
= lpToolInfo
->lpszText
;
1646 else if (lpToolInfo
->lpszText
) {
1647 if (lpToolInfo
->lpszText
== LPSTR_TEXTCALLBACKW
)
1648 toolPtr
->lpszText
= LPSTR_TEXTCALLBACKW
;
1650 if ( (toolPtr
->lpszText
) &&
1651 (HIWORD((INT
)toolPtr
->lpszText
) != 0) ) {
1652 COMCTL32_Free (toolPtr
->lpszText
);
1653 toolPtr
->lpszText
= NULL
;
1655 if (lpToolInfo
->lpszText
) {
1656 INT len
= lstrlenW (lpToolInfo
->lpszText
);
1657 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1658 lstrcpyW (toolPtr
->lpszText
, lpToolInfo
->lpszText
);
1663 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOW
))
1664 toolPtr
->lParam
= lpToolInfo
->lParam
;
1671 TOOLTIPS_TrackActivate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1673 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1674 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
1676 if (lpToolInfo
== NULL
)
1678 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1683 infoPtr
->nTrackTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpToolInfo
);
1684 if (infoPtr
->nTrackTool
!= -1) {
1685 TRACE("activated!\n");
1686 infoPtr
->bTrackActive
= TRUE
;
1687 TOOLTIPS_TrackShow (hwnd
, infoPtr
);
1692 TOOLTIPS_TrackHide (hwnd
, infoPtr
);
1694 infoPtr
->bTrackActive
= FALSE
;
1695 infoPtr
->nTrackTool
= -1;
1697 TRACE("deactivated!\n");
1705 TOOLTIPS_TrackPosition (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1707 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1709 infoPtr
->xTrackPos
= (INT
)LOWORD(lParam
);
1710 infoPtr
->yTrackPos
= (INT
)HIWORD(lParam
);
1712 if (infoPtr
->bTrackActive
) {
1714 infoPtr
->xTrackPos
, infoPtr
->yTrackPos
);
1716 TOOLTIPS_TrackShow (hwnd
, infoPtr
);
1724 TOOLTIPS_Update (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1726 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1728 if (infoPtr
->nCurrentTool
!= -1)
1729 UpdateWindow (hwnd
);
1736 TOOLTIPS_UpdateTipTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1738 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1739 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
1740 TTTOOL_INFO
*toolPtr
;
1743 if (lpToolInfo
== NULL
)
1745 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1748 nTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpToolInfo
);
1749 if (nTool
== -1) return 0;
1751 TRACE("tool %d\n", nTool
);
1753 toolPtr
= &infoPtr
->tools
[nTool
];
1755 /* copy tool text */
1756 toolPtr
->hinst
= lpToolInfo
->hinst
;
1758 if ((lpToolInfo
->hinst
) && (HIWORD((INT
)lpToolInfo
->lpszText
) == 0)){
1759 toolPtr
->lpszText
= (LPWSTR
)lpToolInfo
->lpszText
;
1761 else if (lpToolInfo
->lpszText
) {
1762 if (lpToolInfo
->lpszText
== LPSTR_TEXTCALLBACKA
)
1763 toolPtr
->lpszText
= LPSTR_TEXTCALLBACKW
;
1765 if ( (toolPtr
->lpszText
) &&
1766 (HIWORD((INT
)toolPtr
->lpszText
) != 0) ) {
1767 COMCTL32_Free (toolPtr
->lpszText
);
1768 toolPtr
->lpszText
= NULL
;
1770 if (lpToolInfo
->lpszText
) {
1771 INT len
= lstrlenA (lpToolInfo
->lpszText
);
1772 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1773 lstrcpyAtoW (toolPtr
->lpszText
, lpToolInfo
->lpszText
);
1779 if (infoPtr
->bActive
)
1780 TOOLTIPS_Show (hwnd
, infoPtr
);
1781 else if (infoPtr
->bTrackActive
)
1782 TOOLTIPS_TrackShow (hwnd
, infoPtr
);
1789 TOOLTIPS_UpdateTipTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1791 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1792 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
1793 TTTOOL_INFO
*toolPtr
;
1796 if (lpToolInfo
== NULL
)
1798 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
1801 nTool
= TOOLTIPS_GetToolFromInfoW (infoPtr
, lpToolInfo
);
1805 TRACE("tool %d\n", nTool
);
1807 toolPtr
= &infoPtr
->tools
[nTool
];
1809 /* copy tool text */
1810 toolPtr
->hinst
= lpToolInfo
->hinst
;
1812 if ((lpToolInfo
->hinst
) && (HIWORD((INT
)lpToolInfo
->lpszText
) == 0)){
1813 toolPtr
->lpszText
= lpToolInfo
->lpszText
;
1815 else if (lpToolInfo
->lpszText
) {
1816 if (lpToolInfo
->lpszText
== LPSTR_TEXTCALLBACKW
)
1817 toolPtr
->lpszText
= LPSTR_TEXTCALLBACKW
;
1819 if ( (toolPtr
->lpszText
) &&
1820 (HIWORD((INT
)toolPtr
->lpszText
) != 0) ) {
1821 COMCTL32_Free (toolPtr
->lpszText
);
1822 toolPtr
->lpszText
= NULL
;
1824 if (lpToolInfo
->lpszText
) {
1825 INT len
= lstrlenW (lpToolInfo
->lpszText
);
1826 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1827 lstrcpyW (toolPtr
->lpszText
, lpToolInfo
->lpszText
);
1833 if (infoPtr
->bActive
)
1834 TOOLTIPS_Show (hwnd
, infoPtr
);
1835 else if (infoPtr
->bTrackActive
)
1836 TOOLTIPS_TrackShow (hwnd
, infoPtr
);
1843 TOOLTIPS_WindowFromPoint (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1845 return WindowFromPoint (*((LPPOINT
)lParam
));
1851 TOOLTIPS_Create (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1853 TOOLTIPS_INFO
*infoPtr
;
1854 NONCLIENTMETRICSA nclm
;
1857 /* allocate memory for info structure */
1858 infoPtr
= (TOOLTIPS_INFO
*)COMCTL32_Alloc (sizeof(TOOLTIPS_INFO
));
1859 SetWindowLongA (hwnd
, 0, (DWORD
)infoPtr
);
1861 /* initialize info structure */
1862 infoPtr
->bActive
= TRUE
;
1863 infoPtr
->bTrackActive
= FALSE
;
1864 infoPtr
->clrBk
= GetSysColor (COLOR_INFOBK
);
1865 infoPtr
->clrText
= GetSysColor (COLOR_INFOTEXT
);
1867 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
1868 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
1869 infoPtr
->hFont
= CreateFontIndirectA (&nclm
.lfStatusFont
);
1871 infoPtr
->nMaxTipWidth
= -1;
1872 infoPtr
->nTool
= -1;
1873 infoPtr
->nOldTool
= -1;
1874 infoPtr
->nCurrentTool
= -1;
1875 infoPtr
->nTrackTool
= -1;
1877 infoPtr
->nAutomaticTime
= 500;
1878 infoPtr
->nReshowTime
= 100;
1879 infoPtr
->nAutoPopTime
= 5000;
1880 infoPtr
->nInitialTime
= 500;
1882 nResult
= (INT
) SendMessageA (GetParent (hwnd
), WM_NOTIFYFORMAT
,
1883 (WPARAM
)hwnd
, (LPARAM
)NF_QUERY
);
1884 if (nResult
== NFR_ANSI
) {
1885 infoPtr
->bNotifyUnicode
= FALSE
;
1886 TRACE(" -- WM_NOTIFYFORMAT returns: NFR_ANSI\n");
1888 else if (nResult
== NFR_UNICODE
) {
1889 infoPtr
->bNotifyUnicode
= TRUE
;
1890 TRACE(" -- WM_NOTIFYFORMAT returns: NFR_UNICODE\n");
1893 ERR (" -- WM_NOTIFYFORMAT returns: error!\n");
1896 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOZORDER
| SWP_HIDEWINDOW
| SWP_NOACTIVATE
);
1903 TOOLTIPS_Destroy (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1905 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1906 TTTOOL_INFO
*toolPtr
;
1910 if (infoPtr
->tools
) {
1911 for (i
= 0; i
< infoPtr
->uNumTools
; i
++) {
1912 toolPtr
= &infoPtr
->tools
[i
];
1913 if ((toolPtr
->hinst
) && (toolPtr
->lpszText
)) {
1914 if ( (toolPtr
->lpszText
!= LPSTR_TEXTCALLBACKW
) &&
1915 (HIWORD((INT
)toolPtr
->lpszText
) != 0) )
1917 COMCTL32_Free (toolPtr
->lpszText
);
1918 toolPtr
->lpszText
= NULL
;
1922 /* remove subclassing */
1923 if (toolPtr
->uFlags
& TTF_SUBCLASS
) {
1924 LPTT_SUBCLASS_INFO lpttsi
;
1926 if (toolPtr
->uFlags
& TTF_IDISHWND
)
1927 lpttsi
= (LPTT_SUBCLASS_INFO
)GetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
1929 lpttsi
= (LPTT_SUBCLASS_INFO
)GetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
);
1932 SetWindowLongA ((HWND
)toolPtr
->uId
, GWL_WNDPROC
,
1933 (LONG
)lpttsi
->wpOrigProc
);
1934 RemovePropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
1935 COMCTL32_Free (&lpttsi
);
1939 COMCTL32_Free (infoPtr
->tools
);
1943 DeleteObject (infoPtr
->hFont
);
1945 /* free tool tips info data */
1946 COMCTL32_Free (infoPtr
);
1953 TOOLTIPS_EraseBackground (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1955 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1959 hBrush
= CreateSolidBrush (infoPtr
->clrBk
);
1960 GetClientRect (hwnd
, &rect
);
1961 FillRect ((HDC
)wParam
, &rect
, hBrush
);
1962 DeleteObject (hBrush
);
1969 TOOLTIPS_GetFont (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1971 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1973 return infoPtr
->hFont
;
1978 TOOLTIPS_MouseMessage (HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1980 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1982 TOOLTIPS_Hide (hwnd
, infoPtr
);
1989 TOOLTIPS_NCCreate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1991 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1993 dwStyle
&= 0x0000FFFF;
1994 dwStyle
|= (WS_POPUP
| WS_BORDER
| WS_CLIPSIBLINGS
);
1995 SetWindowLongA (hwnd
, GWL_STYLE
, dwStyle
);
2002 TOOLTIPS_NCHitTest (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2004 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
2005 INT nTool
= (infoPtr
->bTrackActive
) ? infoPtr
->nTrackTool
: infoPtr
->nTool
;
2007 TRACE(" nTool=%d\n", nTool
);
2009 if ((nTool
> -1) && (nTool
< infoPtr
->uNumTools
)) {
2010 if (infoPtr
->tools
[nTool
].uFlags
& TTF_TRANSPARENT
) {
2011 TRACE("-- in transparent mode!\n");
2012 return HTTRANSPARENT
;
2016 return DefWindowProcA (hwnd
, WM_NCHITTEST
, wParam
, lParam
);
2021 TOOLTIPS_NotifyFormat (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2023 FIXME ("hwnd=%x wParam=%x lParam=%lx\n", hwnd
, wParam
, lParam
);
2030 TOOLTIPS_Paint (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2035 hdc
= (wParam
== 0) ? BeginPaint (hwnd
, &ps
) : (HDC
)wParam
;
2036 TOOLTIPS_Refresh (hwnd
, hdc
);
2038 EndPaint (hwnd
, &ps
);
2044 TOOLTIPS_SetFont (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2046 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
2048 infoPtr
->hFont
= (HFONT
)wParam
;
2050 if ((LOWORD(lParam
)) & (infoPtr
->nCurrentTool
!= -1)) {
2051 FIXME("full redraw needed!\n");
2056 /******************************************************************
2057 * TOOLTIPS_OnWMGetTextLength
2059 * This function is called when the tooltip receive a
2060 * WM_GETTEXTLENGTH message.
2064 * returns the length, in characters, of the tip text
2065 ******************************************************************/
2067 TOOLTIPS_OnWMGetTextLength(HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2069 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
2070 return lstrlenW(infoPtr
->szTipText
);
2073 /******************************************************************
2074 * TOOLTIPS_OnWMGetText
2076 * This function is called when the tooltip receive a
2077 * WM_GETTEXT message.
2078 * wParam : specifies the maximum number of characters to be copied
2079 * lParam : is the pointer to the buffer that will receive
2082 * returns the number of characters copied
2083 ******************************************************************/
2085 TOOLTIPS_OnWMGetText (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2087 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
2090 if(!infoPtr
|| !(infoPtr
->szTipText
))
2093 length
= lstrlenW(infoPtr
->szTipText
);
2094 /* When wParam is smaller than the lenght of the tip text
2095 copy wParam characters of the tip text and return wParam */
2098 lstrcpynWtoA((LPSTR
)lParam
, infoPtr
->szTipText
,(UINT
)wParam
);
2101 lstrcpyWtoA((LPSTR
)lParam
, infoPtr
->szTipText
);
2106 TOOLTIPS_Timer (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2108 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
2110 TRACE("timer %d (%x) expired!\n", wParam
, hwnd
);
2115 KillTimer (hwnd
, ID_TIMERSHOW
);
2116 if (TOOLTIPS_CheckTool (hwnd
, TRUE
) == infoPtr
->nTool
)
2117 TOOLTIPS_Show (hwnd
, infoPtr
);
2121 TOOLTIPS_Hide (hwnd
, infoPtr
);
2125 KillTimer (hwnd
, ID_TIMERLEAVE
);
2126 if (TOOLTIPS_CheckTool (hwnd
, FALSE
) == -1) {
2127 infoPtr
->nTool
= -1;
2128 infoPtr
->nOldTool
= -1;
2129 TOOLTIPS_Hide (hwnd
, infoPtr
);
2138 TOOLTIPS_WinIniChange (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2140 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
2141 NONCLIENTMETRICSA nclm
;
2143 infoPtr
->clrBk
= GetSysColor (COLOR_INFOBK
);
2144 infoPtr
->clrText
= GetSysColor (COLOR_INFOTEXT
);
2146 DeleteObject (infoPtr
->hFont
);
2147 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
2148 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
2149 infoPtr
->hFont
= CreateFontIndirectA (&nclm
.lfStatusFont
);
2156 TOOLTIPS_SubclassProc (HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
2158 LPTT_SUBCLASS_INFO lpttsi
=
2159 (LPTT_SUBCLASS_INFO
)GetPropA (hwnd
, COMCTL32_aSubclass
);
2160 TOOLTIPS_INFO
*infoPtr
;
2164 case WM_LBUTTONDOWN
:
2166 case WM_MBUTTONDOWN
:
2168 case WM_RBUTTONDOWN
:
2170 infoPtr
= TOOLTIPS_GetInfoPtr(lpttsi
->hwndToolTip
);
2171 nTool
= TOOLTIPS_GetToolFromMessage (infoPtr
, hwnd
);
2173 TRACE("subclassed mouse message %04x\n", uMsg
);
2174 infoPtr
->nOldTool
= infoPtr
->nTool
;
2175 infoPtr
->nTool
= nTool
;
2176 TOOLTIPS_Hide (lpttsi
->hwndToolTip
, infoPtr
);
2180 infoPtr
= TOOLTIPS_GetInfoPtr (lpttsi
->hwndToolTip
);
2181 nTool
= TOOLTIPS_GetToolFromMessage (infoPtr
, hwnd
);
2183 TRACE("subclassed WM_MOUSEMOVE\n");
2184 infoPtr
->nOldTool
= infoPtr
->nTool
;
2185 infoPtr
->nTool
= nTool
;
2187 if ((infoPtr
->bActive
) &&
2188 (infoPtr
->nTool
!= infoPtr
->nOldTool
)) {
2189 if (infoPtr
->nOldTool
== -1) {
2190 SetTimer (hwnd
, ID_TIMERSHOW
,
2191 infoPtr
->nInitialTime
, 0);
2192 TRACE("timer 1 started!\n");
2195 TOOLTIPS_Hide (lpttsi
->hwndToolTip
, infoPtr
);
2196 SetTimer (hwnd
, ID_TIMERSHOW
,
2197 infoPtr
->nReshowTime
, 0);
2198 TRACE("timer 2 started!\n");
2201 if (infoPtr
->nCurrentTool
!= -1) {
2202 SetTimer (hwnd
, ID_TIMERLEAVE
, 100, 0);
2203 TRACE("timer 3 started!\n");
2208 return CallWindowProcA (lpttsi
->wpOrigProc
, hwnd
, uMsg
, wParam
, lParam
);
2212 static LRESULT CALLBACK
2213 TOOLTIPS_WindowProc (HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
2218 return TOOLTIPS_Activate (hwnd
, wParam
, lParam
);
2221 return TOOLTIPS_AddToolA (hwnd
, wParam
, lParam
);
2224 return TOOLTIPS_AddToolW (hwnd
, wParam
, lParam
);
2227 return TOOLTIPS_DelToolA (hwnd
, wParam
, lParam
);
2230 return TOOLTIPS_DelToolW (hwnd
, wParam
, lParam
);
2232 case TTM_ENUMTOOLSA
:
2233 return TOOLTIPS_EnumToolsA (hwnd
, wParam
, lParam
);
2235 case TTM_ENUMTOOLSW
:
2236 return TOOLTIPS_EnumToolsW (hwnd
, wParam
, lParam
);
2238 case TTM_GETCURRENTTOOLA
:
2239 return TOOLTIPS_GetCurrentToolA (hwnd
, wParam
, lParam
);
2241 case TTM_GETCURRENTTOOLW
:
2242 return TOOLTIPS_GetCurrentToolW (hwnd
, wParam
, lParam
);
2244 case TTM_GETDELAYTIME
:
2245 return TOOLTIPS_GetDelayTime (hwnd
, wParam
, lParam
);
2248 return TOOLTIPS_GetMargin (hwnd
, wParam
, lParam
);
2250 case TTM_GETMAXTIPWIDTH
:
2251 return TOOLTIPS_GetMaxTipWidth (hwnd
, wParam
, lParam
);
2254 return TOOLTIPS_GetTextA (hwnd
, wParam
, lParam
);
2257 return TOOLTIPS_GetTextW (hwnd
, wParam
, lParam
);
2259 case TTM_GETTIPBKCOLOR
:
2260 return TOOLTIPS_GetTipBkColor (hwnd
, wParam
, lParam
);
2262 case TTM_GETTIPTEXTCOLOR
:
2263 return TOOLTIPS_GetTipTextColor (hwnd
, wParam
, lParam
);
2265 case TTM_GETTOOLCOUNT
:
2266 return TOOLTIPS_GetToolCount (hwnd
, wParam
, lParam
);
2268 case TTM_GETTOOLINFOA
:
2269 return TOOLTIPS_GetToolInfoA (hwnd
, wParam
, lParam
);
2271 case TTM_GETTOOLINFOW
:
2272 return TOOLTIPS_GetToolInfoW (hwnd
, wParam
, lParam
);
2275 return TOOLTIPS_HitTestA (hwnd
, wParam
, lParam
);
2278 return TOOLTIPS_HitTestW (hwnd
, wParam
, lParam
);
2280 case TTM_NEWTOOLRECTA
:
2281 return TOOLTIPS_NewToolRectA (hwnd
, wParam
, lParam
);
2283 case TTM_NEWTOOLRECTW
:
2284 return TOOLTIPS_NewToolRectW (hwnd
, wParam
, lParam
);
2287 return TOOLTIPS_Pop (hwnd
, wParam
, lParam
);
2289 case TTM_RELAYEVENT
:
2290 return TOOLTIPS_RelayEvent (hwnd
, wParam
, lParam
);
2292 case TTM_SETDELAYTIME
:
2293 return TOOLTIPS_SetDelayTime (hwnd
, wParam
, lParam
);
2296 return TOOLTIPS_SetMargin (hwnd
, wParam
, lParam
);
2298 case TTM_SETMAXTIPWIDTH
:
2299 return TOOLTIPS_SetMaxTipWidth (hwnd
, wParam
, lParam
);
2301 case TTM_SETTIPBKCOLOR
:
2302 return TOOLTIPS_SetTipBkColor (hwnd
, wParam
, lParam
);
2304 case TTM_SETTIPTEXTCOLOR
:
2305 return TOOLTIPS_SetTipTextColor (hwnd
, wParam
, lParam
);
2307 case TTM_SETTOOLINFOA
:
2308 return TOOLTIPS_SetToolInfoA (hwnd
, wParam
, lParam
);
2310 case TTM_SETTOOLINFOW
:
2311 return TOOLTIPS_SetToolInfoW (hwnd
, wParam
, lParam
);
2313 case TTM_TRACKACTIVATE
:
2314 return TOOLTIPS_TrackActivate (hwnd
, wParam
, lParam
);
2316 case TTM_TRACKPOSITION
:
2317 return TOOLTIPS_TrackPosition (hwnd
, wParam
, lParam
);
2320 return TOOLTIPS_Update (hwnd
, wParam
, lParam
);
2322 case TTM_UPDATETIPTEXTA
:
2323 return TOOLTIPS_UpdateTipTextA (hwnd
, wParam
, lParam
);
2325 case TTM_UPDATETIPTEXTW
:
2326 return TOOLTIPS_UpdateTipTextW (hwnd
, wParam
, lParam
);
2328 case TTM_WINDOWFROMPOINT
:
2329 return TOOLTIPS_WindowFromPoint (hwnd
, wParam
, lParam
);
2333 return TOOLTIPS_Create (hwnd
, wParam
, lParam
);
2336 return TOOLTIPS_Destroy (hwnd
, wParam
, lParam
);
2339 return TOOLTIPS_EraseBackground (hwnd
, wParam
, lParam
);
2342 return TOOLTIPS_GetFont (hwnd
, wParam
, lParam
);
2345 return TOOLTIPS_OnWMGetText (hwnd
, wParam
, lParam
);
2347 case WM_GETTEXTLENGTH
:
2348 return TOOLTIPS_OnWMGetTextLength (hwnd
, wParam
, lParam
);
2351 case WM_LBUTTONDOWN
:
2353 case WM_MBUTTONDOWN
:
2355 case WM_RBUTTONDOWN
:
2358 return TOOLTIPS_MouseMessage (hwnd
, uMsg
, wParam
, lParam
);
2361 return TOOLTIPS_NCCreate (hwnd
, wParam
, lParam
);
2364 return TOOLTIPS_NCHitTest (hwnd
, wParam
, lParam
);
2366 case WM_NOTIFYFORMAT
:
2367 return TOOLTIPS_NotifyFormat (hwnd
, wParam
, lParam
);
2370 return TOOLTIPS_Paint (hwnd
, wParam
, lParam
);
2373 return TOOLTIPS_SetFont (hwnd
, wParam
, lParam
);
2376 return TOOLTIPS_Timer (hwnd
, wParam
, lParam
);
2378 case WM_WININICHANGE
:
2379 return TOOLTIPS_WinIniChange (hwnd
, wParam
, lParam
);
2382 if (uMsg
>= WM_USER
)
2383 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
2384 uMsg
, wParam
, lParam
);
2385 return DefWindowProcA (hwnd
, uMsg
, wParam
, lParam
);
2392 TOOLTIPS_Register (void)
2396 if (GlobalFindAtomA (TOOLTIPS_CLASSA
)) return;
2398 ZeroMemory (&wndClass
, sizeof(WNDCLASSA
));
2399 wndClass
.style
= CS_GLOBALCLASS
| CS_DBLCLKS
| CS_SAVEBITS
;
2400 wndClass
.lpfnWndProc
= (WNDPROC
)TOOLTIPS_WindowProc
;
2401 wndClass
.cbClsExtra
= 0;
2402 wndClass
.cbWndExtra
= sizeof(TOOLTIPS_INFO
*);
2403 wndClass
.hCursor
= LoadCursorA (0, IDC_ARROWA
);
2404 wndClass
.hbrBackground
= 0;
2405 wndClass
.lpszClassName
= TOOLTIPS_CLASSA
;
2407 RegisterClassA (&wndClass
);
2412 TOOLTIPS_Unregister (void)
2414 if (GlobalFindAtomA (TOOLTIPS_CLASSA
))
2415 UnregisterClassA (TOOLTIPS_CLASSA
, (HINSTANCE
)NULL
);