4 * Copyright 1998 Eric Kohl
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.
24 #define ID_TIMERSHOW 1 /* show delay timer */
25 #define ID_TIMERPOP 2 /* auto pop timer */
26 #define ID_TIMERLEAVE 3 /* tool leave timer */
29 extern LPSTR COMCTL32_aSubclass
; /* global subclassing atom */
31 /* property name of tooltip window handle */
32 /*#define TT_SUBCLASS_PROP "CC32SubclassInfo" */
34 #define TOOLTIPS_GetInfoPtr(hWindow) ((TOOLTIPS_INFO *)GetWindowLongA (hWindow, 0))
38 TOOLTIPS_SubclassProc (HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
42 TOOLTIPS_Refresh (HWND hwnd
, HDC hdc
)
44 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr(hwnd
);
49 UINT uFlags
= DT_EXTERNALLEADING
;
51 if (infoPtr
->nMaxTipWidth
> -1)
52 uFlags
|= DT_WORDBREAK
;
53 if (GetWindowLongA (hwnd
, GWL_STYLE
) & TTS_NOPREFIX
)
54 uFlags
|= DT_NOPREFIX
;
55 GetClientRect (hwnd
, &rc
);
57 /* fill the background */
58 hBrush
= CreateSolidBrush (infoPtr
->clrBk
);
59 FillRect (hdc
, &rc
, hBrush
);
60 DeleteObject (hBrush
);
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
);
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
)
75 SetBkMode (hdc
, oldBkMode
);
80 TOOLTIPS_GetTipText (HWND hwnd
, TOOLTIPS_INFO
*infoPtr
, INT nTool
)
82 TTTOOL_INFO
*toolPtr
= &infoPtr
->tools
[nTool
];
84 if ((toolPtr
->hinst
) && (HIWORD((UINT
)toolPtr
->lpszText
) == 0)) {
86 TRACE (tooltips
, "load res string %x %x\n",
87 toolPtr
->hinst
, (int)toolPtr
->lpszText
);
88 LoadStringW (toolPtr
->hinst
, (UINT
)toolPtr
->lpszText
,
89 infoPtr
->szTipText
, INFOTIPSIZE
);
91 else if (toolPtr
->lpszText
) {
92 if (toolPtr
->lpszText
== LPSTR_TEXTCALLBACKW
) {
95 /* fill NMHDR struct */
96 ZeroMemory (&ttnmdi
, sizeof(NMTTDISPINFOA
));
97 ttnmdi
.hdr
.hwndFrom
= hwnd
;
98 ttnmdi
.hdr
.idFrom
= toolPtr
->uId
;
99 ttnmdi
.hdr
.code
= TTN_GETDISPINFOA
;
100 ttnmdi
.lpszText
= (LPSTR
)&ttnmdi
.szText
;
101 ttnmdi
.uFlags
= toolPtr
->uFlags
;
102 ttnmdi
.lParam
= toolPtr
->lParam
;
104 TRACE (tooltips
, "hdr.idFrom = %x\n", ttnmdi
.hdr
.idFrom
);
105 SendMessageA (toolPtr
->hwnd
, WM_NOTIFY
,
106 (WPARAM
)toolPtr
->uId
, (LPARAM
)&ttnmdi
);
108 if ((ttnmdi
.hinst
) && (HIWORD((UINT
)ttnmdi
.szText
) == 0)) {
109 LoadStringW (ttnmdi
.hinst
, (UINT
)ttnmdi
.szText
,
110 infoPtr
->szTipText
, INFOTIPSIZE
);
111 if (ttnmdi
.uFlags
& TTF_DI_SETITEM
) {
112 toolPtr
->hinst
= ttnmdi
.hinst
;
113 toolPtr
->lpszText
= (LPWSTR
)ttnmdi
.szText
;
116 else if (ttnmdi
.szText
[0]) {
117 lstrcpynAtoW (infoPtr
->szTipText
, ttnmdi
.szText
, 80);
118 if (ttnmdi
.uFlags
& TTF_DI_SETITEM
) {
119 INT len
= lstrlenA (ttnmdi
.szText
);
121 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+1)* sizeof(WCHAR
));
122 lstrcpyAtoW (toolPtr
->lpszText
, ttnmdi
.szText
);
125 else if (ttnmdi
.lpszText
== 0) {
126 /* no text available */
127 infoPtr
->szTipText
[0] = L
'\0';
129 else if (ttnmdi
.lpszText
!= LPSTR_TEXTCALLBACKA
) {
130 lstrcpynAtoW (infoPtr
->szTipText
, ttnmdi
.lpszText
, INFOTIPSIZE
);
131 if (ttnmdi
.uFlags
& TTF_DI_SETITEM
) {
132 INT len
= lstrlenA (ttnmdi
.lpszText
);
134 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
135 lstrcpyAtoW (toolPtr
->lpszText
, ttnmdi
.lpszText
);
139 ERR (tooltips
, "recursive text callback!\n");
140 infoPtr
->szTipText
[0] = '\0';
144 /* the item is a usual (unicode) text */
145 lstrcpynW (infoPtr
->szTipText
, toolPtr
->lpszText
, INFOTIPSIZE
);
149 /* no text available */
150 infoPtr
->szTipText
[0] = L
'\0';
153 TRACE (tooltips
, "\"%s\"\n", debugstr_w(infoPtr
->szTipText
));
158 TOOLTIPS_CalcTipSize (HWND hwnd
, TOOLTIPS_INFO
*infoPtr
, LPSIZE lpSize
)
162 UINT uFlags
= DT_EXTERNALLEADING
| DT_CALCRECT
;
163 RECT rc
= {0, 0, 0, 0};
165 if (infoPtr
->nMaxTipWidth
> -1) {
166 rc
.right
= infoPtr
->nMaxTipWidth
;
167 uFlags
|= DT_WORDBREAK
;
169 if (GetWindowLongA (hwnd
, GWL_STYLE
) & TTS_NOPREFIX
)
170 uFlags
|= DT_NOPREFIX
;
171 TRACE (tooltips
, "\"%s\"\n", debugstr_w(infoPtr
->szTipText
));
174 hOldFont
= SelectObject (hdc
, infoPtr
->hFont
);
175 DrawTextW (hdc
, infoPtr
->szTipText
, -1, &rc
, uFlags
);
176 SelectObject (hdc
, hOldFont
);
177 ReleaseDC (hwnd
, hdc
);
179 lpSize
->cx
= rc
.right
- rc
.left
+ 4 +
180 infoPtr
->rcMargin
.left
+ infoPtr
->rcMargin
.right
;
181 lpSize
->cy
= rc
.bottom
- rc
.top
+ 4 +
182 infoPtr
->rcMargin
.bottom
+ infoPtr
->rcMargin
.top
;
187 TOOLTIPS_Show (HWND hwnd
, TOOLTIPS_INFO
*infoPtr
)
189 TTTOOL_INFO
*toolPtr
;
195 if (infoPtr
->nTool
== -1) {
196 TRACE (tooltips
, "invalid tool (-1)!\n");
200 infoPtr
->nCurrentTool
= infoPtr
->nTool
;
202 TRACE (tooltips
, "Show tooltip pre %d!\n", infoPtr
->nTool
);
204 TOOLTIPS_GetTipText (hwnd
, infoPtr
, infoPtr
->nCurrentTool
);
206 if (infoPtr
->szTipText
[0] == L
'\0') {
207 infoPtr
->nCurrentTool
= -1;
211 TRACE (tooltips
, "Show tooltip %d!\n", infoPtr
->nCurrentTool
);
212 toolPtr
= &infoPtr
->tools
[infoPtr
->nCurrentTool
];
215 hdr
.idFrom
= toolPtr
->uId
;
217 SendMessageA (toolPtr
->hwnd
, WM_NOTIFY
,
218 (WPARAM
)toolPtr
->uId
, (LPARAM
)&hdr
);
220 TRACE (tooltips
, "\"%s\"\n", debugstr_w(infoPtr
->szTipText
));
222 TOOLTIPS_CalcTipSize (hwnd
, infoPtr
, &size
);
223 TRACE (tooltips
, "size %d - %d\n", size
.cx
, size
.cy
);
225 if (toolPtr
->uFlags
& TTF_CENTERTIP
) {
228 if (toolPtr
->uFlags
& TTF_IDISHWND
)
229 GetWindowRect ((HWND
)toolPtr
->uId
, &rc
);
232 MapWindowPoints (toolPtr
->hwnd
, (HWND
)0, (LPPOINT
)&rc
, 2);
234 rect
.left
= (rc
.left
+ rc
.right
- size
.cx
) / 2;
235 rect
.top
= rc
.bottom
+ 2;
238 GetCursorPos ((LPPOINT
)&rect
);
242 /* FIXME: check position */
244 TRACE (tooltips
, "pos %d - %d\n", rect
.left
, rect
.top
);
246 rect
.right
= rect
.left
+ size
.cx
;
247 rect
.bottom
= rect
.top
+ size
.cy
;
249 AdjustWindowRectEx (&rect
, GetWindowLongA (hwnd
, GWL_STYLE
),
250 FALSE
, GetWindowLongA (hwnd
, GWL_EXSTYLE
));
252 SetWindowPos (hwnd
, HWND_TOP
, rect
.left
, rect
.top
,
253 rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
256 /* repaint the tooltip */
258 TOOLTIPS_Refresh (hwnd
, hdc
);
259 ReleaseDC (hwnd
, hdc
);
261 SetTimer (hwnd
, ID_TIMERPOP
, infoPtr
->nAutoPopTime
, 0);
266 TOOLTIPS_Hide (HWND hwnd
, TOOLTIPS_INFO
*infoPtr
)
268 TTTOOL_INFO
*toolPtr
;
271 if (infoPtr
->nCurrentTool
== -1)
274 toolPtr
= &infoPtr
->tools
[infoPtr
->nCurrentTool
];
275 TRACE (tooltips
, "Hide tooltip %d!\n", infoPtr
->nCurrentTool
);
276 KillTimer (hwnd
, ID_TIMERPOP
);
279 hdr
.idFrom
= toolPtr
->uId
;
281 SendMessageA (toolPtr
->hwnd
, WM_NOTIFY
,
282 (WPARAM
)toolPtr
->uId
, (LPARAM
)&hdr
);
284 infoPtr
->nCurrentTool
= -1;
286 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0,
287 SWP_NOZORDER
| SWP_HIDEWINDOW
);
292 TOOLTIPS_TrackShow (HWND hwnd
, TOOLTIPS_INFO
*infoPtr
)
294 TTTOOL_INFO
*toolPtr
;
300 if (infoPtr
->nTrackTool
== -1) {
301 TRACE (tooltips
, "invalid tracking tool (-1)!\n");
305 TRACE (tooltips
, "show tracking tooltip pre %d!\n", infoPtr
->nTrackTool
);
307 TOOLTIPS_GetTipText (hwnd
, infoPtr
, infoPtr
->nTrackTool
);
309 if (infoPtr
->szTipText
[0] == L
'\0') {
310 infoPtr
->nTrackTool
= -1;
314 TRACE (tooltips
, "show tracking tooltip %d!\n", infoPtr
->nTrackTool
);
315 toolPtr
= &infoPtr
->tools
[infoPtr
->nTrackTool
];
318 hdr
.idFrom
= toolPtr
->uId
;
320 SendMessageA (toolPtr
->hwnd
, WM_NOTIFY
,
321 (WPARAM
)toolPtr
->uId
, (LPARAM
)&hdr
);
323 TRACE (tooltips
, "\"%s\"\n", debugstr_w(infoPtr
->szTipText
));
325 TOOLTIPS_CalcTipSize (hwnd
, infoPtr
, &size
);
326 TRACE (tooltips
, "size %d - %d\n", size
.cx
, size
.cy
);
328 if (toolPtr
->uFlags
& TTF_ABSOLUTE
) {
329 rect
.left
= infoPtr
->xTrackPos
;
330 rect
.top
= infoPtr
->yTrackPos
;
332 if (toolPtr
->uFlags
& TTF_CENTERTIP
) {
333 rect
.left
-= (size
.cx
/ 2);
334 rect
.top
-= (size
.cy
/ 2);
340 if (toolPtr
->uFlags
& TTF_IDISHWND
)
341 GetWindowRect ((HWND
)toolPtr
->uId
, &rcTool
);
343 rcTool
= toolPtr
->rect
;
344 MapWindowPoints (toolPtr
->hwnd
, (HWND
)0, (LPPOINT
)&rcTool
, 2);
347 GetCursorPos ((LPPOINT
)&rect
);
350 if (toolPtr
->uFlags
& TTF_CENTERTIP
) {
351 rect
.left
-= (size
.cx
/ 2);
352 rect
.top
-= (size
.cy
/ 2);
355 /* smart placement */
356 if ((rect
.left
+ size
.cx
> rcTool
.left
) && (rect
.left
< rcTool
.right
) &&
357 (rect
.top
+ size
.cy
> rcTool
.top
) && (rect
.top
< rcTool
.bottom
))
358 rect
.left
= rcTool
.right
;
361 TRACE (tooltips
, "pos %d - %d\n", rect
.left
, rect
.top
);
363 rect
.right
= rect
.left
+ size
.cx
;
364 rect
.bottom
= rect
.top
+ size
.cy
;
366 AdjustWindowRectEx (&rect
, GetWindowLongA (hwnd
, GWL_STYLE
),
367 FALSE
, GetWindowLongA (hwnd
, GWL_EXSTYLE
));
369 SetWindowPos (hwnd
, HWND_TOP
, rect
.left
, rect
.top
,
370 rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
374 TOOLTIPS_Refresh (hwnd
, hdc
);
375 ReleaseDC (hwnd
, hdc
);
380 TOOLTIPS_TrackHide (HWND hwnd
, TOOLTIPS_INFO
*infoPtr
)
382 TTTOOL_INFO
*toolPtr
;
385 if (infoPtr
->nTrackTool
== -1)
388 toolPtr
= &infoPtr
->tools
[infoPtr
->nTrackTool
];
389 TRACE (tooltips
, "hide tracking tooltip %d!\n", infoPtr
->nTrackTool
);
392 hdr
.idFrom
= toolPtr
->uId
;
394 SendMessageA (toolPtr
->hwnd
, WM_NOTIFY
,
395 (WPARAM
)toolPtr
->uId
, (LPARAM
)&hdr
);
397 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0,
398 SWP_NOZORDER
| SWP_HIDEWINDOW
);
403 TOOLTIPS_GetToolFromInfoA (TOOLTIPS_INFO
*infoPtr
, LPTTTOOLINFOA lpToolInfo
)
405 TTTOOL_INFO
*toolPtr
;
408 for (nTool
= 0; nTool
< infoPtr
->uNumTools
; nTool
++) {
409 toolPtr
= &infoPtr
->tools
[nTool
];
411 if (!(toolPtr
->uFlags
& TTF_IDISHWND
) &&
412 (lpToolInfo
->hwnd
== toolPtr
->hwnd
) &&
413 (lpToolInfo
->uId
== toolPtr
->uId
))
417 for (nTool
= 0; nTool
< infoPtr
->uNumTools
; nTool
++) {
418 toolPtr
= &infoPtr
->tools
[nTool
];
420 if ((toolPtr
->uFlags
& TTF_IDISHWND
) &&
421 (lpToolInfo
->uId
== toolPtr
->uId
))
430 TOOLTIPS_GetToolFromInfoW (TOOLTIPS_INFO
*infoPtr
, LPTTTOOLINFOW lpToolInfo
)
432 TTTOOL_INFO
*toolPtr
;
435 for (nTool
= 0; nTool
< infoPtr
->uNumTools
; nTool
++) {
436 toolPtr
= &infoPtr
->tools
[nTool
];
438 if (!(toolPtr
->uFlags
& TTF_IDISHWND
) &&
439 (lpToolInfo
->hwnd
== toolPtr
->hwnd
) &&
440 (lpToolInfo
->uId
== toolPtr
->uId
))
444 for (nTool
= 0; nTool
< infoPtr
->uNumTools
; nTool
++) {
445 toolPtr
= &infoPtr
->tools
[nTool
];
447 if ((toolPtr
->uFlags
& TTF_IDISHWND
) &&
448 (lpToolInfo
->uId
== toolPtr
->uId
))
457 TOOLTIPS_GetToolFromPoint (TOOLTIPS_INFO
*infoPtr
, HWND hwnd
, LPPOINT lpPt
)
459 TTTOOL_INFO
*toolPtr
;
462 for (nTool
= 0; nTool
< infoPtr
->uNumTools
; nTool
++) {
463 toolPtr
= &infoPtr
->tools
[nTool
];
465 if (!(toolPtr
->uFlags
& TTF_IDISHWND
)) {
466 if (hwnd
!= toolPtr
->hwnd
)
468 if (!PtInRect (&toolPtr
->rect
, *lpPt
))
474 for (nTool
= 0; nTool
< infoPtr
->uNumTools
; nTool
++) {
475 toolPtr
= &infoPtr
->tools
[nTool
];
477 if (toolPtr
->uFlags
& TTF_IDISHWND
) {
478 if ((HWND
)toolPtr
->uId
== hwnd
)
488 TOOLTIPS_GetToolFromMessage (TOOLTIPS_INFO
*infoPtr
, HWND hwndTool
)
493 dwPos
= GetMessagePos ();
494 pt
.x
= (INT
)LOWORD(dwPos
);
495 pt
.y
= (INT
)HIWORD(dwPos
);
496 ScreenToClient (hwndTool
, &pt
);
498 return TOOLTIPS_GetToolFromPoint (infoPtr
, hwndTool
, &pt
);
503 TOOLTIPS_IsWindowActive (HWND hwnd
)
505 HWND hwndActive
= GetActiveWindow ();
508 if (hwndActive
== hwnd
)
510 return IsChild (hwndActive
, hwnd
);
515 TOOLTIPS_CheckTool (HWND hwnd
, BOOL bShowTest
)
517 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
523 hwndTool
= SendMessageA (hwnd
, TTM_WINDOWFROMPOINT
, 0, (LPARAM
)&pt
);
527 ScreenToClient (hwndTool
, &pt
);
528 nTool
= TOOLTIPS_GetToolFromPoint (infoPtr
, hwndTool
, &pt
);
532 if (!(GetWindowLongA (hwnd
, GWL_STYLE
) & TTS_ALWAYSTIP
) && bShowTest
) {
533 if (!TOOLTIPS_IsWindowActive (GetWindow (hwnd
, GW_OWNER
)))
537 TRACE (tooltips
, "tool %d\n", nTool
);
544 TOOLTIPS_Activate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
546 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
548 infoPtr
->bActive
= (BOOL
)wParam
;
550 if (infoPtr
->bActive
)
551 TRACE (tooltips
, "activate!\n");
553 if (!(infoPtr
->bActive
) && (infoPtr
->nCurrentTool
!= -1))
554 TOOLTIPS_Hide (hwnd
, infoPtr
);
561 TOOLTIPS_AddToolA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
563 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
564 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
565 TTTOOL_INFO
*toolPtr
;
567 if (lpToolInfo
== NULL
)
569 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
572 TRACE (tooltips
, "add tool (%x) %x %d%s!\n",
573 hwnd
, lpToolInfo
->hwnd
, lpToolInfo
->uId
,
574 (lpToolInfo
->uFlags
& TTF_IDISHWND
) ? " TTF_IDISHWND" : "");
576 if (infoPtr
->uNumTools
== 0) {
577 infoPtr
->tools
= COMCTL32_Alloc (sizeof(TTTOOL_INFO
));
578 toolPtr
= infoPtr
->tools
;
581 TTTOOL_INFO
*oldTools
= infoPtr
->tools
;
583 COMCTL32_Alloc (sizeof(TTTOOL_INFO
) * (infoPtr
->uNumTools
+ 1));
584 memcpy (infoPtr
->tools
, oldTools
,
585 infoPtr
->uNumTools
* sizeof(TTTOOL_INFO
));
586 COMCTL32_Free (oldTools
);
587 toolPtr
= &infoPtr
->tools
[infoPtr
->uNumTools
];
590 infoPtr
->uNumTools
++;
593 toolPtr
->uFlags
= lpToolInfo
->uFlags
;
594 toolPtr
->hwnd
= lpToolInfo
->hwnd
;
595 toolPtr
->uId
= lpToolInfo
->uId
;
596 toolPtr
->rect
= lpToolInfo
->rect
;
597 toolPtr
->hinst
= lpToolInfo
->hinst
;
599 if ((lpToolInfo
->hinst
) && (HIWORD((INT
)lpToolInfo
->lpszText
) == 0)) {
600 TRACE (tooltips
, "add string id %x!\n", (int)lpToolInfo
->lpszText
);
601 toolPtr
->lpszText
= (LPWSTR
)lpToolInfo
->lpszText
;
603 else if (lpToolInfo
->lpszText
) {
604 if (lpToolInfo
->lpszText
== LPSTR_TEXTCALLBACKA
) {
605 TRACE (tooltips
, "add CALLBACK!\n");
606 toolPtr
->lpszText
= LPSTR_TEXTCALLBACKW
;
609 INT len
= lstrlenA (lpToolInfo
->lpszText
);
610 TRACE (tooltips
, "add text \"%s\"!\n", lpToolInfo
->lpszText
);
611 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+ 1)*sizeof(WCHAR
));
612 lstrcpyAtoW (toolPtr
->lpszText
, lpToolInfo
->lpszText
);
616 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOA
))
617 toolPtr
->lParam
= lpToolInfo
->lParam
;
619 /* install subclassing hook */
620 if (toolPtr
->uFlags
& TTF_SUBCLASS
) {
621 if (toolPtr
->uFlags
& TTF_IDISHWND
) {
622 LPTT_SUBCLASS_INFO lpttsi
=
623 (LPTT_SUBCLASS_INFO
)GetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
624 if (lpttsi
== NULL
) {
626 (LPTT_SUBCLASS_INFO
)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO
));
628 (WNDPROC
)SetWindowLongA ((HWND
)toolPtr
->uId
,
629 GWL_WNDPROC
,(LONG
)TOOLTIPS_SubclassProc
);
630 lpttsi
->hwndToolTip
= hwnd
;
632 SetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
,
636 WARN (tooltips
, "A window tool must only be listed once!\n");
639 LPTT_SUBCLASS_INFO lpttsi
=
640 (LPTT_SUBCLASS_INFO
)GetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
);
641 if (lpttsi
== NULL
) {
643 (LPTT_SUBCLASS_INFO
)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO
));
645 (WNDPROC
)SetWindowLongA (toolPtr
->hwnd
,
646 GWL_WNDPROC
,(LONG
)TOOLTIPS_SubclassProc
);
647 lpttsi
->hwndToolTip
= hwnd
;
649 SetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
, (HANDLE
)lpttsi
);
654 TRACE (tooltips
, "subclassing installed!\n");
662 TOOLTIPS_AddToolW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
664 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
665 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
666 TTTOOL_INFO
*toolPtr
;
668 if (lpToolInfo
== NULL
)
670 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
673 TRACE (tooltips
, "add tool (%x) %x %d%s!\n",
674 hwnd
, lpToolInfo
->hwnd
, lpToolInfo
->uId
,
675 (lpToolInfo
->uFlags
& TTF_IDISHWND
) ? " TTF_IDISHWND" : "");
677 if (infoPtr
->uNumTools
== 0) {
678 infoPtr
->tools
= COMCTL32_Alloc (sizeof(TTTOOL_INFO
));
679 toolPtr
= infoPtr
->tools
;
682 TTTOOL_INFO
*oldTools
= infoPtr
->tools
;
684 COMCTL32_Alloc (sizeof(TTTOOL_INFO
) * (infoPtr
->uNumTools
+ 1));
685 memcpy (infoPtr
->tools
, oldTools
,
686 infoPtr
->uNumTools
* sizeof(TTTOOL_INFO
));
687 COMCTL32_Free (oldTools
);
688 toolPtr
= &infoPtr
->tools
[infoPtr
->uNumTools
];
691 infoPtr
->uNumTools
++;
694 toolPtr
->uFlags
= lpToolInfo
->uFlags
;
695 toolPtr
->hwnd
= lpToolInfo
->hwnd
;
696 toolPtr
->uId
= lpToolInfo
->uId
;
697 toolPtr
->rect
= lpToolInfo
->rect
;
698 toolPtr
->hinst
= lpToolInfo
->hinst
;
700 if ((lpToolInfo
->hinst
) && (HIWORD((INT
)lpToolInfo
->lpszText
) == 0)) {
701 TRACE (tooltips
, "add string id %x!\n", (int)lpToolInfo
->lpszText
);
702 toolPtr
->lpszText
= (LPWSTR
)lpToolInfo
->lpszText
;
704 else if (lpToolInfo
->lpszText
) {
705 if (lpToolInfo
->lpszText
== LPSTR_TEXTCALLBACKW
) {
706 TRACE (tooltips
, "add CALLBACK!\n");
707 toolPtr
->lpszText
= LPSTR_TEXTCALLBACKW
;
710 INT len
= lstrlenW (lpToolInfo
->lpszText
);
711 TRACE (tooltips
, "add text \"%s\"!\n",
712 debugstr_w(lpToolInfo
->lpszText
));
713 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+ 1)*sizeof(WCHAR
));
714 lstrcpyW (toolPtr
->lpszText
, lpToolInfo
->lpszText
);
718 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOW
))
719 toolPtr
->lParam
= lpToolInfo
->lParam
;
721 /* install subclassing hook */
722 if (toolPtr
->uFlags
& TTF_SUBCLASS
) {
723 if (toolPtr
->uFlags
& TTF_IDISHWND
) {
724 LPTT_SUBCLASS_INFO lpttsi
=
725 (LPTT_SUBCLASS_INFO
)GetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
726 if (lpttsi
== NULL
) {
728 (LPTT_SUBCLASS_INFO
)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO
));
730 (WNDPROC
)SetWindowLongA ((HWND
)toolPtr
->uId
,
731 GWL_WNDPROC
,(LONG
)TOOLTIPS_SubclassProc
);
732 lpttsi
->hwndToolTip
= hwnd
;
734 SetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
,
738 WARN (tooltips
, "A window tool must only be listed once!\n");
741 LPTT_SUBCLASS_INFO lpttsi
=
742 (LPTT_SUBCLASS_INFO
)GetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
);
743 if (lpttsi
== NULL
) {
745 (LPTT_SUBCLASS_INFO
)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO
));
747 (WNDPROC
)SetWindowLongA (toolPtr
->hwnd
,
748 GWL_WNDPROC
,(LONG
)TOOLTIPS_SubclassProc
);
749 lpttsi
->hwndToolTip
= hwnd
;
751 SetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
, (HANDLE
)lpttsi
);
756 TRACE (tooltips
, "subclassing installed!\n");
764 TOOLTIPS_DelToolA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
766 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
767 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
768 TTTOOL_INFO
*toolPtr
;
771 if (lpToolInfo
== NULL
)
773 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
775 if (infoPtr
->uNumTools
== 0)
778 nTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpToolInfo
);
779 if (nTool
== -1) return 0;
781 TRACE (tooltips
, "tool %d\n", nTool
);
783 /* delete text string */
784 toolPtr
= &infoPtr
->tools
[nTool
];
785 if ((toolPtr
->hinst
) && (toolPtr
->lpszText
)) {
786 if (toolPtr
->lpszText
!= LPSTR_TEXTCALLBACKW
)
787 COMCTL32_Free (toolPtr
->lpszText
);
790 /* remove subclassing */
791 if (toolPtr
->uFlags
& TTF_SUBCLASS
) {
792 if (toolPtr
->uFlags
& TTF_IDISHWND
) {
793 LPTT_SUBCLASS_INFO lpttsi
=
794 (LPTT_SUBCLASS_INFO
)GetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
796 SetWindowLongA ((HWND
)toolPtr
->uId
, GWL_WNDPROC
,
797 (LONG
)lpttsi
->wpOrigProc
);
798 RemovePropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
799 COMCTL32_Free (&lpttsi
);
802 ERR (tooltips
, "Invalid data handle!\n");
805 LPTT_SUBCLASS_INFO lpttsi
=
806 (LPTT_SUBCLASS_INFO
)GetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
);
808 if (lpttsi
->uRefCount
== 1) {
809 SetWindowLongA ((HWND
)toolPtr
->uId
, GWL_WNDPROC
,
810 (LONG
)lpttsi
->wpOrigProc
);
811 RemovePropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
812 COMCTL32_Free (&lpttsi
);
818 ERR (tooltips
, "Invalid data handle!\n");
822 /* delete tool from tool list */
823 if (infoPtr
->uNumTools
== 1) {
824 COMCTL32_Free (infoPtr
->tools
);
825 infoPtr
->tools
= NULL
;
828 TTTOOL_INFO
*oldTools
= infoPtr
->tools
;
830 COMCTL32_Alloc (sizeof(TTTOOL_INFO
) * (infoPtr
->uNumTools
- 1));
833 memcpy (&infoPtr
->tools
[0], &oldTools
[0],
834 nTool
* sizeof(TTTOOL_INFO
));
836 if (nTool
< infoPtr
->uNumTools
- 1)
837 memcpy (&infoPtr
->tools
[nTool
], &oldTools
[nTool
+ 1],
838 (infoPtr
->uNumTools
- nTool
- 1) * sizeof(TTTOOL_INFO
));
840 COMCTL32_Free (oldTools
);
843 infoPtr
->uNumTools
--;
850 TOOLTIPS_DelToolW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
852 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
853 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
854 TTTOOL_INFO
*toolPtr
;
857 if (lpToolInfo
== NULL
)
859 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
861 if (infoPtr
->uNumTools
== 0)
864 nTool
= TOOLTIPS_GetToolFromInfoW (infoPtr
, lpToolInfo
);
865 if (nTool
== -1) return 0;
867 TRACE (tooltips
, "tool %d\n", nTool
);
869 /* delete text string */
870 toolPtr
= &infoPtr
->tools
[nTool
];
871 if ((toolPtr
->hinst
) && (toolPtr
->lpszText
)) {
872 if (toolPtr
->lpszText
!= LPSTR_TEXTCALLBACKW
)
873 COMCTL32_Free (toolPtr
->lpszText
);
876 /* remove subclassing */
877 if (toolPtr
->uFlags
& TTF_SUBCLASS
) {
878 if (toolPtr
->uFlags
& TTF_IDISHWND
) {
879 LPTT_SUBCLASS_INFO lpttsi
=
880 (LPTT_SUBCLASS_INFO
)GetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
882 SetWindowLongA ((HWND
)toolPtr
->uId
, GWL_WNDPROC
,
883 (LONG
)lpttsi
->wpOrigProc
);
884 RemovePropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
885 COMCTL32_Free (&lpttsi
);
888 ERR (tooltips
, "Invalid data handle!\n");
891 LPTT_SUBCLASS_INFO lpttsi
=
892 (LPTT_SUBCLASS_INFO
)GetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
);
894 if (lpttsi
->uRefCount
== 1) {
895 SetWindowLongA ((HWND
)toolPtr
->uId
, GWL_WNDPROC
,
896 (LONG
)lpttsi
->wpOrigProc
);
897 RemovePropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
898 COMCTL32_Free (&lpttsi
);
904 ERR (tooltips
, "Invalid data handle!\n");
908 /* delete tool from tool list */
909 if (infoPtr
->uNumTools
== 1) {
910 COMCTL32_Free (infoPtr
->tools
);
911 infoPtr
->tools
= NULL
;
914 TTTOOL_INFO
*oldTools
= infoPtr
->tools
;
916 COMCTL32_Alloc (sizeof(TTTOOL_INFO
) * (infoPtr
->uNumTools
- 1));
919 memcpy (&infoPtr
->tools
[0], &oldTools
[0],
920 nTool
* sizeof(TTTOOL_INFO
));
922 if (nTool
< infoPtr
->uNumTools
- 1)
923 memcpy (&infoPtr
->tools
[nTool
], &oldTools
[nTool
+ 1],
924 (infoPtr
->uNumTools
- nTool
- 1) * sizeof(TTTOOL_INFO
));
926 COMCTL32_Free (oldTools
);
929 infoPtr
->uNumTools
--;
936 TOOLTIPS_EnumToolsA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
938 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
939 UINT uIndex
= (UINT
)wParam
;
940 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
941 TTTOOL_INFO
*toolPtr
;
943 if (lpToolInfo
== NULL
)
945 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
947 if (uIndex
>= infoPtr
->uNumTools
)
950 TRACE (tooltips
, "index=%u\n", uIndex
);
952 toolPtr
= &infoPtr
->tools
[uIndex
];
955 lpToolInfo
->uFlags
= toolPtr
->uFlags
;
956 lpToolInfo
->hwnd
= toolPtr
->hwnd
;
957 lpToolInfo
->uId
= toolPtr
->uId
;
958 lpToolInfo
->rect
= toolPtr
->rect
;
959 lpToolInfo
->hinst
= toolPtr
->hinst
;
960 /* lpToolInfo->lpszText = toolPtr->lpszText; */
961 lpToolInfo
->lpszText
= NULL
; /* FIXME */
963 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOA
))
964 lpToolInfo
->lParam
= toolPtr
->lParam
;
971 TOOLTIPS_EnumToolsW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
973 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
974 UINT uIndex
= (UINT
)wParam
;
975 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
976 TTTOOL_INFO
*toolPtr
;
978 if (lpToolInfo
== NULL
)
980 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
982 if (uIndex
>= infoPtr
->uNumTools
)
985 TRACE (tooltips
, "index=%u\n", uIndex
);
987 toolPtr
= &infoPtr
->tools
[uIndex
];
990 lpToolInfo
->uFlags
= toolPtr
->uFlags
;
991 lpToolInfo
->hwnd
= toolPtr
->hwnd
;
992 lpToolInfo
->uId
= toolPtr
->uId
;
993 lpToolInfo
->rect
= toolPtr
->rect
;
994 lpToolInfo
->hinst
= toolPtr
->hinst
;
995 /* lpToolInfo->lpszText = toolPtr->lpszText; */
996 lpToolInfo
->lpszText
= NULL
; /* FIXME */
998 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOW
))
999 lpToolInfo
->lParam
= toolPtr
->lParam
;
1006 TOOLTIPS_GetCurrentToolA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1008 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1009 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
1010 TTTOOL_INFO
*toolPtr
;
1012 if (lpToolInfo
== NULL
)
1014 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1018 if (infoPtr
->nCurrentTool
> -1) {
1019 toolPtr
= &infoPtr
->tools
[infoPtr
->nCurrentTool
];
1021 /* copy tool data */
1022 lpToolInfo
->uFlags
= toolPtr
->uFlags
;
1023 lpToolInfo
->rect
= toolPtr
->rect
;
1024 lpToolInfo
->hinst
= toolPtr
->hinst
;
1025 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1026 lpToolInfo
->lpszText
= NULL
; /* FIXME */
1028 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOA
))
1029 lpToolInfo
->lParam
= toolPtr
->lParam
;
1037 return (infoPtr
->nCurrentTool
!= -1);
1044 TOOLTIPS_GetCurrentToolW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1046 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1047 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
1048 TTTOOL_INFO
*toolPtr
;
1050 if (lpToolInfo
== NULL
)
1052 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
1056 if (infoPtr
->nCurrentTool
> -1) {
1057 toolPtr
= &infoPtr
->tools
[infoPtr
->nCurrentTool
];
1059 /* copy tool data */
1060 lpToolInfo
->uFlags
= toolPtr
->uFlags
;
1061 lpToolInfo
->rect
= toolPtr
->rect
;
1062 lpToolInfo
->hinst
= toolPtr
->hinst
;
1063 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1064 lpToolInfo
->lpszText
= NULL
; /* FIXME */
1066 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOW
))
1067 lpToolInfo
->lParam
= toolPtr
->lParam
;
1075 return (infoPtr
->nCurrentTool
!= -1);
1082 TOOLTIPS_GetDelayTime (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1084 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1087 case TTDT_AUTOMATIC
:
1088 return infoPtr
->nAutomaticTime
;
1091 return infoPtr
->nReshowTime
;
1094 return infoPtr
->nAutoPopTime
;
1097 return infoPtr
->nInitialTime
;
1105 TOOLTIPS_GetMargin (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1107 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1108 LPRECT lpRect
= (LPRECT
)lParam
;
1110 lpRect
->left
= infoPtr
->rcMargin
.left
;
1111 lpRect
->right
= infoPtr
->rcMargin
.right
;
1112 lpRect
->bottom
= infoPtr
->rcMargin
.bottom
;
1113 lpRect
->top
= infoPtr
->rcMargin
.top
;
1119 __inline__
static LRESULT
1120 TOOLTIPS_GetMaxTipWidth (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1122 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1124 return infoPtr
->nMaxTipWidth
;
1129 TOOLTIPS_GetTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1131 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1132 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
1135 if (lpToolInfo
== NULL
)
1137 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1140 nTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpToolInfo
);
1141 if (nTool
== -1) return 0;
1143 lstrcpyWtoA (lpToolInfo
->lpszText
, infoPtr
->tools
[nTool
].lpszText
);
1150 TOOLTIPS_GetTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1152 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1153 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
1156 if (lpToolInfo
== NULL
)
1158 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
1161 nTool
= TOOLTIPS_GetToolFromInfoW (infoPtr
, lpToolInfo
);
1162 if (nTool
== -1) return 0;
1164 lstrcpyW (lpToolInfo
->lpszText
, infoPtr
->tools
[nTool
].lpszText
);
1170 __inline__
static LRESULT
1171 TOOLTIPS_GetTipBkColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1173 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1174 return infoPtr
->clrBk
;
1178 __inline__
static LRESULT
1179 TOOLTIPS_GetTipTextColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1181 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1182 return infoPtr
->clrText
;
1186 __inline__
static LRESULT
1187 TOOLTIPS_GetToolCount (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1189 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1190 return infoPtr
->uNumTools
;
1195 TOOLTIPS_GetToolInfoA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1197 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1198 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
1199 TTTOOL_INFO
*toolPtr
;
1202 if (lpToolInfo
== NULL
)
1204 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1206 if (infoPtr
->uNumTools
== 0)
1209 nTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpToolInfo
);
1213 TRACE (tooltips
, "tool %d\n", nTool
);
1215 toolPtr
= &infoPtr
->tools
[nTool
];
1217 /* copy tool data */
1218 lpToolInfo
->uFlags
= toolPtr
->uFlags
;
1219 lpToolInfo
->rect
= toolPtr
->rect
;
1220 lpToolInfo
->hinst
= toolPtr
->hinst
;
1221 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1222 lpToolInfo
->lpszText
= NULL
; /* FIXME */
1224 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOA
))
1225 lpToolInfo
->lParam
= toolPtr
->lParam
;
1232 TOOLTIPS_GetToolInfoW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1234 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1235 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
1236 TTTOOL_INFO
*toolPtr
;
1239 if (lpToolInfo
== NULL
)
1241 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
1243 if (infoPtr
->uNumTools
== 0)
1246 nTool
= TOOLTIPS_GetToolFromInfoW (infoPtr
, lpToolInfo
);
1250 TRACE (tooltips
, "tool %d\n", nTool
);
1252 toolPtr
= &infoPtr
->tools
[nTool
];
1254 /* copy tool data */
1255 lpToolInfo
->uFlags
= toolPtr
->uFlags
;
1256 lpToolInfo
->rect
= toolPtr
->rect
;
1257 lpToolInfo
->hinst
= toolPtr
->hinst
;
1258 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1259 lpToolInfo
->lpszText
= NULL
; /* FIXME */
1261 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOW
))
1262 lpToolInfo
->lParam
= toolPtr
->lParam
;
1269 TOOLTIPS_HitTestA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1271 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1272 LPTTHITTESTINFOA lptthit
= (LPTTHITTESTINFOA
)lParam
;
1273 TTTOOL_INFO
*toolPtr
;
1279 nTool
= TOOLTIPS_GetToolFromPoint (infoPtr
, lptthit
->hwnd
, &lptthit
->pt
);
1283 TRACE (tooltips
, "tool %d!\n", nTool
);
1285 /* copy tool data */
1286 if (lptthit
->ti
.cbSize
>= sizeof(TTTOOLINFOA
)) {
1287 toolPtr
= &infoPtr
->tools
[nTool
];
1289 lptthit
->ti
.uFlags
= toolPtr
->uFlags
;
1290 lptthit
->ti
.hwnd
= toolPtr
->hwnd
;
1291 lptthit
->ti
.uId
= toolPtr
->uId
;
1292 lptthit
->ti
.rect
= toolPtr
->rect
;
1293 lptthit
->ti
.hinst
= toolPtr
->hinst
;
1294 /* lptthit->ti.lpszText = toolPtr->lpszText; */
1295 lptthit
->ti
.lpszText
= NULL
; /* FIXME */
1296 lptthit
->ti
.lParam
= toolPtr
->lParam
;
1304 TOOLTIPS_HitTestW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1306 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1307 LPTTHITTESTINFOW lptthit
= (LPTTHITTESTINFOW
)lParam
;
1308 TTTOOL_INFO
*toolPtr
;
1314 nTool
= TOOLTIPS_GetToolFromPoint (infoPtr
, lptthit
->hwnd
, &lptthit
->pt
);
1318 TRACE (tooltips
, "tool %d!\n", nTool
);
1320 /* copy tool data */
1321 if (lptthit
->ti
.cbSize
>= sizeof(TTTOOLINFOW
)) {
1322 toolPtr
= &infoPtr
->tools
[nTool
];
1324 lptthit
->ti
.uFlags
= toolPtr
->uFlags
;
1325 lptthit
->ti
.hwnd
= toolPtr
->hwnd
;
1326 lptthit
->ti
.uId
= toolPtr
->uId
;
1327 lptthit
->ti
.rect
= toolPtr
->rect
;
1328 lptthit
->ti
.hinst
= toolPtr
->hinst
;
1329 /* lptthit->ti.lpszText = toolPtr->lpszText; */
1330 lptthit
->ti
.lpszText
= NULL
; /* FIXME */
1331 lptthit
->ti
.lParam
= toolPtr
->lParam
;
1339 TOOLTIPS_NewToolRectA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1341 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1342 LPTTTOOLINFOA lpti
= (LPTTTOOLINFOA
)lParam
;
1347 if (lpti
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1350 nTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpti
);
1351 if (nTool
== -1) return 0;
1353 infoPtr
->tools
[nTool
].rect
= lpti
->rect
;
1360 TOOLTIPS_NewToolRectW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1362 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1363 LPTTTOOLINFOW lpti
= (LPTTTOOLINFOW
)lParam
;
1368 if (lpti
->cbSize
< TTTOOLINFO_V1_SIZEW
)
1371 nTool
= TOOLTIPS_GetToolFromInfoW (infoPtr
, lpti
);
1372 if (nTool
== -1) return 0;
1374 infoPtr
->tools
[nTool
].rect
= lpti
->rect
;
1380 __inline__
static LRESULT
1381 TOOLTIPS_Pop (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1383 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1385 TOOLTIPS_Hide (hwnd
, infoPtr
);
1392 TOOLTIPS_RelayEvent (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1394 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1395 LPMSG lpMsg
= (LPMSG
)lParam
;
1399 ERR (tooltips
, "lpMsg == NULL!\n");
1403 switch (lpMsg
->message
) {
1404 case WM_LBUTTONDOWN
:
1406 case WM_MBUTTONDOWN
:
1408 case WM_RBUTTONDOWN
:
1411 ScreenToClient (lpMsg
->hwnd
, &pt
);
1412 infoPtr
->nOldTool
= infoPtr
->nTool
;
1413 infoPtr
->nTool
= TOOLTIPS_GetToolFromPoint (infoPtr
, lpMsg
->hwnd
, &pt
);
1414 TRACE (tooltips
, "tool (%x) %d %d\n",
1415 hwnd
, infoPtr
->nOldTool
, infoPtr
->nTool
);
1416 TOOLTIPS_Hide (hwnd
, infoPtr
);
1421 ScreenToClient (lpMsg
->hwnd
, &pt
);
1422 infoPtr
->nOldTool
= infoPtr
->nTool
;
1423 infoPtr
->nTool
= TOOLTIPS_GetToolFromPoint (infoPtr
, lpMsg
->hwnd
, &pt
);
1424 TRACE (tooltips
, "tool (%x) %d %d\n",
1425 hwnd
, infoPtr
->nOldTool
, infoPtr
->nTool
);
1426 TRACE (tooltips
, "WM_MOUSEMOVE (%04x %ld %ld)\n",
1428 if ((infoPtr
->bActive
) && (infoPtr
->nTool
!= infoPtr
->nOldTool
)) {
1429 if (infoPtr
->nOldTool
== -1) {
1430 SetTimer (hwnd
, ID_TIMERSHOW
, infoPtr
->nInitialTime
, 0);
1431 TRACE (tooltips
, "timer 1 started!\n");
1434 TOOLTIPS_Hide (hwnd
, infoPtr
);
1435 SetTimer (hwnd
, ID_TIMERSHOW
, infoPtr
->nReshowTime
, 0);
1436 TRACE (tooltips
, "timer 2 started!\n");
1439 if (infoPtr
->nCurrentTool
!= -1) {
1440 SetTimer (hwnd
, ID_TIMERLEAVE
, 100, 0);
1441 TRACE (tooltips
, "timer 3 started!\n");
1451 TOOLTIPS_SetDelayTime (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1453 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1454 INT nTime
= (INT
)LOWORD(lParam
);
1457 case TTDT_AUTOMATIC
:
1459 infoPtr
->nAutomaticTime
= 500;
1460 infoPtr
->nReshowTime
= 100;
1461 infoPtr
->nAutoPopTime
= 5000;
1462 infoPtr
->nInitialTime
= 500;
1465 infoPtr
->nAutomaticTime
= nTime
;
1466 infoPtr
->nReshowTime
= nTime
/ 5;
1467 infoPtr
->nAutoPopTime
= nTime
* 10;
1468 infoPtr
->nInitialTime
= nTime
;
1473 infoPtr
->nReshowTime
= nTime
;
1477 infoPtr
->nAutoPopTime
= nTime
;
1481 infoPtr
->nInitialTime
= nTime
;
1490 TOOLTIPS_SetMargin (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1492 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1493 LPRECT lpRect
= (LPRECT
)lParam
;
1495 infoPtr
->rcMargin
.left
= lpRect
->left
;
1496 infoPtr
->rcMargin
.right
= lpRect
->right
;
1497 infoPtr
->rcMargin
.bottom
= lpRect
->bottom
;
1498 infoPtr
->rcMargin
.top
= lpRect
->top
;
1504 __inline__
static LRESULT
1505 TOOLTIPS_SetMaxTipWidth (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1507 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1508 INT nTemp
= infoPtr
->nMaxTipWidth
;
1510 infoPtr
->nMaxTipWidth
= (INT
)lParam
;
1516 __inline__
static LRESULT
1517 TOOLTIPS_SetTipBkColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1519 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1521 infoPtr
->clrBk
= (COLORREF
)wParam
;
1527 __inline__
static LRESULT
1528 TOOLTIPS_SetTipTextColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1530 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1532 infoPtr
->clrText
= (COLORREF
)wParam
;
1539 TOOLTIPS_SetToolInfoA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1541 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1542 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
1543 TTTOOL_INFO
*toolPtr
;
1546 if (lpToolInfo
== NULL
)
1548 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1551 nTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpToolInfo
);
1552 if (nTool
== -1) return 0;
1554 TRACE (tooltips
, "tool %d\n", nTool
);
1556 toolPtr
= &infoPtr
->tools
[nTool
];
1558 /* copy tool data */
1559 toolPtr
->uFlags
= lpToolInfo
->uFlags
;
1560 toolPtr
->hwnd
= lpToolInfo
->hwnd
;
1561 toolPtr
->uId
= lpToolInfo
->uId
;
1562 toolPtr
->rect
= lpToolInfo
->rect
;
1563 toolPtr
->hinst
= lpToolInfo
->hinst
;
1565 if ((lpToolInfo
->hinst
) && (HIWORD((INT
)lpToolInfo
->lpszText
) == 0)) {
1566 TRACE (tooltips
, "set string id %x!\n", (INT
)lpToolInfo
->lpszText
);
1567 toolPtr
->lpszText
= (LPWSTR
)lpToolInfo
->lpszText
;
1569 else if (lpToolInfo
->lpszText
) {
1570 if (lpToolInfo
->lpszText
== LPSTR_TEXTCALLBACKA
)
1571 toolPtr
->lpszText
= LPSTR_TEXTCALLBACKW
;
1573 if (toolPtr
->lpszText
) {
1574 COMCTL32_Free (toolPtr
->lpszText
);
1575 toolPtr
->lpszText
= NULL
;
1577 if (lpToolInfo
->lpszText
) {
1578 INT len
= lstrlenA (lpToolInfo
->lpszText
);
1579 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1580 lstrcpyAtoW (toolPtr
->lpszText
, lpToolInfo
->lpszText
);
1585 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOA
))
1586 toolPtr
->lParam
= lpToolInfo
->lParam
;
1593 TOOLTIPS_SetToolInfoW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1595 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1596 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
1597 TTTOOL_INFO
*toolPtr
;
1600 if (lpToolInfo
== NULL
)
1602 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
1605 nTool
= TOOLTIPS_GetToolFromInfoW (infoPtr
, lpToolInfo
);
1606 if (nTool
== -1) return 0;
1608 TRACE (tooltips
, "tool %d\n", nTool
);
1610 toolPtr
= &infoPtr
->tools
[nTool
];
1612 /* copy tool data */
1613 toolPtr
->uFlags
= lpToolInfo
->uFlags
;
1614 toolPtr
->hwnd
= lpToolInfo
->hwnd
;
1615 toolPtr
->uId
= lpToolInfo
->uId
;
1616 toolPtr
->rect
= lpToolInfo
->rect
;
1617 toolPtr
->hinst
= lpToolInfo
->hinst
;
1619 if ((lpToolInfo
->hinst
) && (HIWORD((INT
)lpToolInfo
->lpszText
) == 0)) {
1620 TRACE (tooltips
, "set string id %x!\n", (INT
)lpToolInfo
->lpszText
);
1621 toolPtr
->lpszText
= lpToolInfo
->lpszText
;
1623 else if (lpToolInfo
->lpszText
) {
1624 if (lpToolInfo
->lpszText
== LPSTR_TEXTCALLBACKW
)
1625 toolPtr
->lpszText
= LPSTR_TEXTCALLBACKW
;
1627 if (toolPtr
->lpszText
) {
1628 COMCTL32_Free (toolPtr
->lpszText
);
1629 toolPtr
->lpszText
= NULL
;
1631 if (lpToolInfo
->lpszText
) {
1632 INT len
= lstrlenW (lpToolInfo
->lpszText
);
1633 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1634 lstrcpyW (toolPtr
->lpszText
, lpToolInfo
->lpszText
);
1639 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOW
))
1640 toolPtr
->lParam
= lpToolInfo
->lParam
;
1647 TOOLTIPS_TrackActivate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1649 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1650 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
1652 if (lpToolInfo
== NULL
)
1654 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1659 infoPtr
->nTrackTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpToolInfo
);
1660 if (infoPtr
->nTrackTool
!= -1) {
1661 TRACE (tooltips
, "activated!\n");
1662 infoPtr
->bTrackActive
= TRUE
;
1663 TOOLTIPS_TrackShow (hwnd
, infoPtr
);
1668 TOOLTIPS_TrackHide (hwnd
, infoPtr
);
1670 infoPtr
->bTrackActive
= FALSE
;
1671 infoPtr
->nTrackTool
= -1;
1673 TRACE (tooltips
, "deactivated!\n");
1681 TOOLTIPS_TrackPosition (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1683 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1685 infoPtr
->xTrackPos
= (INT
)LOWORD(lParam
);
1686 infoPtr
->yTrackPos
= (INT
)HIWORD(lParam
);
1688 if (infoPtr
->bTrackActive
) {
1689 TRACE (tooltips
, "[%d %d]\n",
1690 infoPtr
->xTrackPos
, infoPtr
->yTrackPos
);
1692 TOOLTIPS_TrackShow (hwnd
, infoPtr
);
1700 TOOLTIPS_Update (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1702 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1704 if (infoPtr
->nCurrentTool
!= -1)
1705 UpdateWindow (hwnd
);
1712 TOOLTIPS_UpdateTipTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1714 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1715 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
1716 TTTOOL_INFO
*toolPtr
;
1719 if (lpToolInfo
== NULL
)
1721 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1724 nTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpToolInfo
);
1725 if (nTool
== -1) return 0;
1727 TRACE (tooltips
, "tool %d\n", nTool
);
1729 toolPtr
= &infoPtr
->tools
[nTool
];
1731 /* copy tool text */
1732 toolPtr
->hinst
= lpToolInfo
->hinst
;
1734 if ((lpToolInfo
->hinst
) && (HIWORD((INT
)lpToolInfo
->lpszText
) == 0)){
1735 toolPtr
->lpszText
= (LPWSTR
)lpToolInfo
->lpszText
;
1737 else if (lpToolInfo
->lpszText
) {
1738 if (lpToolInfo
->lpszText
== LPSTR_TEXTCALLBACKA
)
1739 toolPtr
->lpszText
= LPSTR_TEXTCALLBACKW
;
1741 if (toolPtr
->lpszText
) {
1742 COMCTL32_Free (toolPtr
->lpszText
);
1743 toolPtr
->lpszText
= NULL
;
1745 if (lpToolInfo
->lpszText
) {
1746 INT len
= lstrlenA (lpToolInfo
->lpszText
);
1747 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1748 lstrcpyAtoW (toolPtr
->lpszText
, lpToolInfo
->lpszText
);
1754 if (infoPtr
->bActive
)
1755 TOOLTIPS_Show (hwnd
, infoPtr
);
1756 else if (infoPtr
->bTrackActive
)
1757 TOOLTIPS_TrackShow (hwnd
, infoPtr
);
1764 TOOLTIPS_UpdateTipTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1766 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1767 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
1768 TTTOOL_INFO
*toolPtr
;
1771 if (lpToolInfo
== NULL
)
1773 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
1776 nTool
= TOOLTIPS_GetToolFromInfoW (infoPtr
, lpToolInfo
);
1780 TRACE (tooltips
, "tool %d\n", nTool
);
1782 toolPtr
= &infoPtr
->tools
[nTool
];
1784 /* copy tool text */
1785 toolPtr
->hinst
= lpToolInfo
->hinst
;
1787 if ((lpToolInfo
->hinst
) && (HIWORD((INT
)lpToolInfo
->lpszText
) == 0)){
1788 toolPtr
->lpszText
= lpToolInfo
->lpszText
;
1790 else if (lpToolInfo
->lpszText
) {
1791 if (lpToolInfo
->lpszText
== LPSTR_TEXTCALLBACKW
)
1792 toolPtr
->lpszText
= LPSTR_TEXTCALLBACKW
;
1794 if (toolPtr
->lpszText
) {
1795 COMCTL32_Free (toolPtr
->lpszText
);
1796 toolPtr
->lpszText
= NULL
;
1798 if (lpToolInfo
->lpszText
) {
1799 INT len
= lstrlenW (lpToolInfo
->lpszText
);
1800 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1801 lstrcpyW (toolPtr
->lpszText
, lpToolInfo
->lpszText
);
1807 if (infoPtr
->bActive
)
1808 TOOLTIPS_Show (hwnd
, infoPtr
);
1809 else if (infoPtr
->bTrackActive
)
1810 TOOLTIPS_TrackShow (hwnd
, infoPtr
);
1817 TOOLTIPS_WindowFromPoint (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1819 return WindowFromPoint (*((LPPOINT
)lParam
));
1825 TOOLTIPS_Create (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1827 TOOLTIPS_INFO
*infoPtr
;
1828 NONCLIENTMETRICSA nclm
;
1831 /* allocate memory for info structure */
1832 infoPtr
= (TOOLTIPS_INFO
*)COMCTL32_Alloc (sizeof(TOOLTIPS_INFO
));
1833 SetWindowLongA (hwnd
, 0, (DWORD
)infoPtr
);
1835 /* initialize info structure */
1836 infoPtr
->bActive
= TRUE
;
1837 infoPtr
->bTrackActive
= FALSE
;
1838 infoPtr
->clrBk
= GetSysColor (COLOR_INFOBK
);
1839 infoPtr
->clrText
= GetSysColor (COLOR_INFOTEXT
);
1841 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
1842 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
1843 infoPtr
->hFont
= CreateFontIndirectA (&nclm
.lfStatusFont
);
1845 infoPtr
->nMaxTipWidth
= -1;
1846 infoPtr
->nTool
= -1;
1847 infoPtr
->nOldTool
= -1;
1848 infoPtr
->nCurrentTool
= -1;
1849 infoPtr
->nTrackTool
= -1;
1851 infoPtr
->nAutomaticTime
= 500;
1852 infoPtr
->nReshowTime
= 100;
1853 infoPtr
->nAutoPopTime
= 5000;
1854 infoPtr
->nInitialTime
= 500;
1856 nResult
= (INT
) SendMessageA (GetParent (hwnd
), WM_NOTIFYFORMAT
,
1857 (WPARAM
)hwnd
, (LPARAM
)NF_QUERY
);
1858 if (nResult
== NFR_ANSI
)
1859 FIXME (tooltips
, " -- WM_NOTIFYFORMAT returns: NFR_ANSI\n");
1860 else if (nResult
== NFR_UNICODE
)
1861 FIXME (tooltips
, " -- WM_NOTIFYFORMAT returns: NFR_UNICODE\n");
1863 FIXME (tooltips
, " -- WM_NOTIFYFORMAT returns: error!\n");
1865 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOZORDER
| SWP_HIDEWINDOW
);
1872 TOOLTIPS_Destroy (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1874 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1875 TTTOOL_INFO
*toolPtr
;
1879 if (infoPtr
->tools
) {
1880 for (i
= 0; i
< infoPtr
->uNumTools
; i
++) {
1881 toolPtr
= &infoPtr
->tools
[i
];
1882 if ((toolPtr
->hinst
) && (toolPtr
->lpszText
)) {
1883 if (toolPtr
->lpszText
!= LPSTR_TEXTCALLBACKW
)
1884 COMCTL32_Free (toolPtr
->lpszText
);
1887 /* remove subclassing */
1888 if (toolPtr
->uFlags
& TTF_SUBCLASS
) {
1889 LPTT_SUBCLASS_INFO lpttsi
;
1891 if (toolPtr
->uFlags
& TTF_IDISHWND
)
1892 lpttsi
= (LPTT_SUBCLASS_INFO
)GetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
1894 lpttsi
= (LPTT_SUBCLASS_INFO
)GetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
);
1897 SetWindowLongA ((HWND
)toolPtr
->uId
, GWL_WNDPROC
,
1898 (LONG
)lpttsi
->wpOrigProc
);
1899 RemovePropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
1900 COMCTL32_Free (&lpttsi
);
1904 COMCTL32_Free (infoPtr
->tools
);
1908 DeleteObject (infoPtr
->hFont
);
1910 /* free tool tips info data */
1911 COMCTL32_Free (infoPtr
);
1918 TOOLTIPS_EraseBackground (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1920 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1924 hBrush
= CreateSolidBrush (infoPtr
->clrBk
);
1925 GetClientRect (hwnd
, &rect
);
1926 FillRect ((HDC
)wParam
, &rect
, hBrush
);
1927 DeleteObject (hBrush
);
1934 TOOLTIPS_GetFont (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1936 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1938 return infoPtr
->hFont
;
1943 TOOLTIPS_MouseMessage (HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1945 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1947 TOOLTIPS_Hide (hwnd
, infoPtr
);
1954 TOOLTIPS_NCCreate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1956 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1958 dwStyle
&= 0x0000FFFF;
1959 dwStyle
|= (WS_POPUP
| WS_BORDER
| WS_CLIPSIBLINGS
);
1960 SetWindowLongA (hwnd
, GWL_STYLE
, dwStyle
);
1967 TOOLTIPS_NCHitTest (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1969 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1970 INT nTool
= (infoPtr
->bTrackActive
) ? infoPtr
->nTrackTool
: infoPtr
->nTool
;
1972 TRACE (tooltips
, " nTool=%d\n", nTool
);
1974 if ((nTool
> -1) && (nTool
< infoPtr
->uNumTools
)) {
1975 if (infoPtr
->tools
[nTool
].uFlags
& TTF_TRANSPARENT
) {
1976 TRACE (tooltips
, "-- in transparent mode!\n");
1977 return HTTRANSPARENT
;
1981 return DefWindowProcA (hwnd
, WM_NCHITTEST
, wParam
, lParam
);
1986 TOOLTIPS_Paint (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1991 hdc
= (wParam
== 0) ? BeginPaint (hwnd
, &ps
) : (HDC
)wParam
;
1992 TOOLTIPS_Refresh (hwnd
, hdc
);
1994 EndPaint (hwnd
, &ps
);
2000 TOOLTIPS_SetFont (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2002 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
2004 infoPtr
->hFont
= (HFONT
)wParam
;
2006 if ((LOWORD(lParam
)) & (infoPtr
->nCurrentTool
!= -1)) {
2007 FIXME (tooltips
, "full redraw needed!\n");
2015 TOOLTIPS_Timer (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2017 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
2019 TRACE (tooltips
, "timer %d (%x) expired!\n", wParam
, hwnd
);
2024 KillTimer (hwnd
, ID_TIMERSHOW
);
2025 if (TOOLTIPS_CheckTool (hwnd
, TRUE
) == infoPtr
->nTool
)
2026 TOOLTIPS_Show (hwnd
, infoPtr
);
2030 TOOLTIPS_Hide (hwnd
, infoPtr
);
2034 KillTimer (hwnd
, ID_TIMERLEAVE
);
2035 if (TOOLTIPS_CheckTool (hwnd
, FALSE
) == -1) {
2036 infoPtr
->nTool
= -1;
2037 infoPtr
->nOldTool
= -1;
2038 TOOLTIPS_Hide (hwnd
, infoPtr
);
2047 TOOLTIPS_WinIniChange (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2049 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
2050 NONCLIENTMETRICSA nclm
;
2052 infoPtr
->clrBk
= GetSysColor (COLOR_INFOBK
);
2053 infoPtr
->clrText
= GetSysColor (COLOR_INFOTEXT
);
2055 DeleteObject (infoPtr
->hFont
);
2056 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
2057 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
2058 infoPtr
->hFont
= CreateFontIndirectA (&nclm
.lfStatusFont
);
2065 TOOLTIPS_SubclassProc (HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
2067 LPTT_SUBCLASS_INFO lpttsi
=
2068 (LPTT_SUBCLASS_INFO
)GetPropA (hwnd
, COMCTL32_aSubclass
);
2069 TOOLTIPS_INFO
*infoPtr
;
2073 case WM_LBUTTONDOWN
:
2075 case WM_MBUTTONDOWN
:
2077 case WM_RBUTTONDOWN
:
2079 infoPtr
= TOOLTIPS_GetInfoPtr(lpttsi
->hwndToolTip
);
2080 nTool
= TOOLTIPS_GetToolFromMessage (infoPtr
, hwnd
);
2082 TRACE (tooltips
, "subclassed mouse message %04x\n", uMsg
);
2083 infoPtr
->nOldTool
= infoPtr
->nTool
;
2084 infoPtr
->nTool
= nTool
;
2085 TOOLTIPS_Hide (lpttsi
->hwndToolTip
, infoPtr
);
2089 infoPtr
= TOOLTIPS_GetInfoPtr (lpttsi
->hwndToolTip
);
2090 nTool
= TOOLTIPS_GetToolFromMessage (infoPtr
, hwnd
);
2092 TRACE (tooltips
, "subclassed WM_MOUSEMOVE\n");
2093 infoPtr
->nOldTool
= infoPtr
->nTool
;
2094 infoPtr
->nTool
= nTool
;
2096 if ((infoPtr
->bActive
) &&
2097 (infoPtr
->nTool
!= infoPtr
->nOldTool
)) {
2098 if (infoPtr
->nOldTool
== -1) {
2099 SetTimer (hwnd
, ID_TIMERSHOW
,
2100 infoPtr
->nInitialTime
, 0);
2101 TRACE (tooltips
, "timer 1 started!\n");
2104 TOOLTIPS_Hide (lpttsi
->hwndToolTip
, infoPtr
);
2105 SetTimer (hwnd
, ID_TIMERSHOW
,
2106 infoPtr
->nReshowTime
, 0);
2107 TRACE (tooltips
, "timer 2 started!\n");
2110 if (infoPtr
->nCurrentTool
!= -1) {
2111 SetTimer (hwnd
, ID_TIMERLEAVE
, 100, 0);
2112 TRACE (tooltips
, "timer 3 started!\n");
2117 return CallWindowProcA (lpttsi
->wpOrigProc
, hwnd
, uMsg
, wParam
, lParam
);
2122 TOOLTIPS_WindowProc (HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
2127 return TOOLTIPS_Activate (hwnd
, wParam
, lParam
);
2130 return TOOLTIPS_AddToolA (hwnd
, wParam
, lParam
);
2133 return TOOLTIPS_AddToolW (hwnd
, wParam
, lParam
);
2136 return TOOLTIPS_DelToolA (hwnd
, wParam
, lParam
);
2139 return TOOLTIPS_DelToolW (hwnd
, wParam
, lParam
);
2141 case TTM_ENUMTOOLSA
:
2142 return TOOLTIPS_EnumToolsA (hwnd
, wParam
, lParam
);
2144 case TTM_ENUMTOOLSW
:
2145 return TOOLTIPS_EnumToolsW (hwnd
, wParam
, lParam
);
2147 case TTM_GETCURRENTTOOLA
:
2148 return TOOLTIPS_GetCurrentToolA (hwnd
, wParam
, lParam
);
2150 case TTM_GETCURRENTTOOLW
:
2151 return TOOLTIPS_GetCurrentToolW (hwnd
, wParam
, lParam
);
2153 case TTM_GETDELAYTIME
:
2154 return TOOLTIPS_GetDelayTime (hwnd
, wParam
, lParam
);
2157 return TOOLTIPS_GetMargin (hwnd
, wParam
, lParam
);
2159 case TTM_GETMAXTIPWIDTH
:
2160 return TOOLTIPS_GetMaxTipWidth (hwnd
, wParam
, lParam
);
2163 return TOOLTIPS_GetTextA (hwnd
, wParam
, lParam
);
2166 return TOOLTIPS_GetTextW (hwnd
, wParam
, lParam
);
2168 case TTM_GETTIPBKCOLOR
:
2169 return TOOLTIPS_GetTipBkColor (hwnd
, wParam
, lParam
);
2171 case TTM_GETTIPTEXTCOLOR
:
2172 return TOOLTIPS_GetTipTextColor (hwnd
, wParam
, lParam
);
2174 case TTM_GETTOOLCOUNT
:
2175 return TOOLTIPS_GetToolCount (hwnd
, wParam
, lParam
);
2177 case TTM_GETTOOLINFOA
:
2178 return TOOLTIPS_GetToolInfoA (hwnd
, wParam
, lParam
);
2180 case TTM_GETTOOLINFOW
:
2181 return TOOLTIPS_GetToolInfoW (hwnd
, wParam
, lParam
);
2184 return TOOLTIPS_HitTestA (hwnd
, wParam
, lParam
);
2187 return TOOLTIPS_HitTestW (hwnd
, wParam
, lParam
);
2189 case TTM_NEWTOOLRECTA
:
2190 return TOOLTIPS_NewToolRectA (hwnd
, wParam
, lParam
);
2192 case TTM_NEWTOOLRECTW
:
2193 return TOOLTIPS_NewToolRectW (hwnd
, wParam
, lParam
);
2196 return TOOLTIPS_Pop (hwnd
, wParam
, lParam
);
2198 case TTM_RELAYEVENT
:
2199 return TOOLTIPS_RelayEvent (hwnd
, wParam
, lParam
);
2201 case TTM_SETDELAYTIME
:
2202 return TOOLTIPS_SetDelayTime (hwnd
, wParam
, lParam
);
2205 return TOOLTIPS_SetMargin (hwnd
, wParam
, lParam
);
2207 case TTM_SETMAXTIPWIDTH
:
2208 return TOOLTIPS_SetMaxTipWidth (hwnd
, wParam
, lParam
);
2210 case TTM_SETTIPBKCOLOR
:
2211 return TOOLTIPS_SetTipBkColor (hwnd
, wParam
, lParam
);
2213 case TTM_SETTIPTEXTCOLOR
:
2214 return TOOLTIPS_SetTipTextColor (hwnd
, wParam
, lParam
);
2216 case TTM_SETTOOLINFOA
:
2217 return TOOLTIPS_SetToolInfoA (hwnd
, wParam
, lParam
);
2219 case TTM_SETTOOLINFOW
:
2220 return TOOLTIPS_SetToolInfoW (hwnd
, wParam
, lParam
);
2222 case TTM_TRACKACTIVATE
:
2223 return TOOLTIPS_TrackActivate (hwnd
, wParam
, lParam
);
2225 case TTM_TRACKPOSITION
:
2226 return TOOLTIPS_TrackPosition (hwnd
, wParam
, lParam
);
2229 return TOOLTIPS_Update (hwnd
, wParam
, lParam
);
2231 case TTM_UPDATETIPTEXTA
:
2232 return TOOLTIPS_UpdateTipTextA (hwnd
, wParam
, lParam
);
2234 case TTM_UPDATETIPTEXTW
:
2235 return TOOLTIPS_UpdateTipTextW (hwnd
, wParam
, lParam
);
2237 case TTM_WINDOWFROMPOINT
:
2238 return TOOLTIPS_WindowFromPoint (hwnd
, wParam
, lParam
);
2242 return TOOLTIPS_Create (hwnd
, wParam
, lParam
);
2245 return TOOLTIPS_Destroy (hwnd
, wParam
, lParam
);
2248 return TOOLTIPS_EraseBackground (hwnd
, wParam
, lParam
);
2251 return TOOLTIPS_GetFont (hwnd
, wParam
, lParam
);
2253 case WM_LBUTTONDOWN
:
2255 case WM_MBUTTONDOWN
:
2257 case WM_RBUTTONDOWN
:
2260 return TOOLTIPS_MouseMessage (hwnd
, uMsg
, wParam
, lParam
);
2263 return TOOLTIPS_NCCreate (hwnd
, wParam
, lParam
);
2266 return TOOLTIPS_NCHitTest (hwnd
, wParam
, lParam
);
2268 /* case WM_NOTIFYFORMAT: */
2269 /* return TOOLTIPS_NotifyFormat (hwnd, wParam, lParam); */
2272 return TOOLTIPS_Paint (hwnd
, wParam
, lParam
);
2275 return TOOLTIPS_SetFont (hwnd
, wParam
, lParam
);
2278 return TOOLTIPS_Timer (hwnd
, wParam
, lParam
);
2280 case WM_WININICHANGE
:
2281 return TOOLTIPS_WinIniChange (hwnd
, wParam
, lParam
);
2284 if (uMsg
>= WM_USER
)
2285 ERR (tooltips
, "unknown msg %04x wp=%08x lp=%08lx\n",
2286 uMsg
, wParam
, lParam
);
2287 return DefWindowProcA (hwnd
, uMsg
, wParam
, lParam
);
2294 TOOLTIPS_Register (VOID
)
2298 if (GlobalFindAtomA (TOOLTIPS_CLASSA
)) return;
2300 ZeroMemory (&wndClass
, sizeof(WNDCLASSA
));
2301 wndClass
.style
= CS_GLOBALCLASS
| CS_DBLCLKS
| CS_SAVEBITS
;
2302 wndClass
.lpfnWndProc
= (WNDPROC
)TOOLTIPS_WindowProc
;
2303 wndClass
.cbClsExtra
= 0;
2304 wndClass
.cbWndExtra
= sizeof(TOOLTIPS_INFO
*);
2305 wndClass
.hCursor
= LoadCursorA (0, IDC_ARROWA
);
2306 wndClass
.hbrBackground
= 0;
2307 wndClass
.lpszClassName
= TOOLTIPS_CLASSA
;
2309 RegisterClassA (&wndClass
);
2314 TOOLTIPS_Unregister (VOID
)
2316 if (GlobalFindAtomA (TOOLTIPS_CLASSA
))
2317 UnregisterClassA (TOOLTIPS_CLASSA
, (HINSTANCE
)NULL
);