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.
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 /* FIXME: check position */
246 TRACE("pos %d - %d\n", rect
.left
, rect
.top
);
248 rect
.right
= rect
.left
+ size
.cx
;
249 rect
.bottom
= rect
.top
+ size
.cy
;
251 AdjustWindowRectEx (&rect
, GetWindowLongA (hwnd
, GWL_STYLE
),
252 FALSE
, GetWindowLongA (hwnd
, GWL_EXSTYLE
));
254 SetWindowPos (hwnd
, HWND_TOP
, rect
.left
, rect
.top
,
255 rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
256 SWP_SHOWWINDOW
| SWP_NOACTIVATE
);
258 /* repaint the tooltip */
260 TOOLTIPS_Refresh (hwnd
, hdc
);
261 ReleaseDC (hwnd
, hdc
);
263 SetTimer (hwnd
, ID_TIMERPOP
, infoPtr
->nAutoPopTime
, 0);
268 TOOLTIPS_Hide (HWND hwnd
, TOOLTIPS_INFO
*infoPtr
)
270 TTTOOL_INFO
*toolPtr
;
273 if (infoPtr
->nCurrentTool
== -1)
276 toolPtr
= &infoPtr
->tools
[infoPtr
->nCurrentTool
];
277 TRACE("Hide tooltip %d!\n", infoPtr
->nCurrentTool
);
278 KillTimer (hwnd
, ID_TIMERPOP
);
281 hdr
.idFrom
= toolPtr
->uId
;
283 SendMessageA (toolPtr
->hwnd
, WM_NOTIFY
,
284 (WPARAM
)toolPtr
->uId
, (LPARAM
)&hdr
);
286 infoPtr
->nCurrentTool
= -1;
288 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0,
289 SWP_NOZORDER
| SWP_HIDEWINDOW
| SWP_NOACTIVATE
);
294 TOOLTIPS_TrackShow (HWND hwnd
, TOOLTIPS_INFO
*infoPtr
)
296 TTTOOL_INFO
*toolPtr
;
302 if (infoPtr
->nTrackTool
== -1) {
303 TRACE("invalid tracking tool (-1)!\n");
307 TRACE("show tracking tooltip pre %d!\n", infoPtr
->nTrackTool
);
309 TOOLTIPS_GetTipText (hwnd
, infoPtr
, infoPtr
->nTrackTool
);
311 if (infoPtr
->szTipText
[0] == L
'\0') {
312 infoPtr
->nTrackTool
= -1;
316 TRACE("show tracking tooltip %d!\n", infoPtr
->nTrackTool
);
317 toolPtr
= &infoPtr
->tools
[infoPtr
->nTrackTool
];
320 hdr
.idFrom
= toolPtr
->uId
;
322 SendMessageA (toolPtr
->hwnd
, WM_NOTIFY
,
323 (WPARAM
)toolPtr
->uId
, (LPARAM
)&hdr
);
325 TRACE("\"%s\"\n", debugstr_w(infoPtr
->szTipText
));
327 TOOLTIPS_CalcTipSize (hwnd
, infoPtr
, &size
);
328 TRACE("size %d - %d\n", size
.cx
, size
.cy
);
330 if (toolPtr
->uFlags
& TTF_ABSOLUTE
) {
331 rect
.left
= infoPtr
->xTrackPos
;
332 rect
.top
= infoPtr
->yTrackPos
;
334 if (toolPtr
->uFlags
& TTF_CENTERTIP
) {
335 rect
.left
-= (size
.cx
/ 2);
336 rect
.top
-= (size
.cy
/ 2);
342 if (toolPtr
->uFlags
& TTF_IDISHWND
)
343 GetWindowRect ((HWND
)toolPtr
->uId
, &rcTool
);
345 rcTool
= toolPtr
->rect
;
346 MapWindowPoints (toolPtr
->hwnd
, (HWND
)0, (LPPOINT
)&rcTool
, 2);
349 GetCursorPos ((LPPOINT
)&rect
);
352 if (toolPtr
->uFlags
& TTF_CENTERTIP
) {
353 rect
.left
-= (size
.cx
/ 2);
354 rect
.top
-= (size
.cy
/ 2);
357 /* smart placement */
358 if ((rect
.left
+ size
.cx
> rcTool
.left
) && (rect
.left
< rcTool
.right
) &&
359 (rect
.top
+ size
.cy
> rcTool
.top
) && (rect
.top
< rcTool
.bottom
))
360 rect
.left
= rcTool
.right
;
363 TRACE("pos %d - %d\n", rect
.left
, rect
.top
);
365 rect
.right
= rect
.left
+ size
.cx
;
366 rect
.bottom
= rect
.top
+ size
.cy
;
368 AdjustWindowRectEx (&rect
, GetWindowLongA (hwnd
, GWL_STYLE
),
369 FALSE
, GetWindowLongA (hwnd
, GWL_EXSTYLE
));
371 SetWindowPos (hwnd
, HWND_TOP
, rect
.left
, rect
.top
,
372 rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
373 SWP_SHOWWINDOW
| SWP_NOACTIVATE
);
376 TOOLTIPS_Refresh (hwnd
, hdc
);
377 ReleaseDC (hwnd
, hdc
);
382 TOOLTIPS_TrackHide (HWND hwnd
, TOOLTIPS_INFO
*infoPtr
)
384 TTTOOL_INFO
*toolPtr
;
387 if (infoPtr
->nTrackTool
== -1)
390 toolPtr
= &infoPtr
->tools
[infoPtr
->nTrackTool
];
391 TRACE("hide tracking tooltip %d!\n", infoPtr
->nTrackTool
);
394 hdr
.idFrom
= toolPtr
->uId
;
396 SendMessageA (toolPtr
->hwnd
, WM_NOTIFY
,
397 (WPARAM
)toolPtr
->uId
, (LPARAM
)&hdr
);
399 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0,
400 SWP_NOZORDER
| SWP_HIDEWINDOW
| SWP_NOACTIVATE
);
405 TOOLTIPS_GetToolFromInfoA (TOOLTIPS_INFO
*infoPtr
, LPTTTOOLINFOA lpToolInfo
)
407 TTTOOL_INFO
*toolPtr
;
410 for (nTool
= 0; nTool
< infoPtr
->uNumTools
; nTool
++) {
411 toolPtr
= &infoPtr
->tools
[nTool
];
413 if (!(toolPtr
->uFlags
& TTF_IDISHWND
) &&
414 (lpToolInfo
->hwnd
== toolPtr
->hwnd
) &&
415 (lpToolInfo
->uId
== toolPtr
->uId
))
419 for (nTool
= 0; nTool
< infoPtr
->uNumTools
; nTool
++) {
420 toolPtr
= &infoPtr
->tools
[nTool
];
422 if ((toolPtr
->uFlags
& TTF_IDISHWND
) &&
423 (lpToolInfo
->uId
== toolPtr
->uId
))
432 TOOLTIPS_GetToolFromInfoW (TOOLTIPS_INFO
*infoPtr
, LPTTTOOLINFOW lpToolInfo
)
434 TTTOOL_INFO
*toolPtr
;
437 for (nTool
= 0; nTool
< infoPtr
->uNumTools
; nTool
++) {
438 toolPtr
= &infoPtr
->tools
[nTool
];
440 if (!(toolPtr
->uFlags
& TTF_IDISHWND
) &&
441 (lpToolInfo
->hwnd
== toolPtr
->hwnd
) &&
442 (lpToolInfo
->uId
== toolPtr
->uId
))
446 for (nTool
= 0; nTool
< infoPtr
->uNumTools
; nTool
++) {
447 toolPtr
= &infoPtr
->tools
[nTool
];
449 if ((toolPtr
->uFlags
& TTF_IDISHWND
) &&
450 (lpToolInfo
->uId
== toolPtr
->uId
))
459 TOOLTIPS_GetToolFromPoint (TOOLTIPS_INFO
*infoPtr
, HWND hwnd
, LPPOINT lpPt
)
461 TTTOOL_INFO
*toolPtr
;
464 for (nTool
= 0; nTool
< infoPtr
->uNumTools
; nTool
++) {
465 toolPtr
= &infoPtr
->tools
[nTool
];
467 if (!(toolPtr
->uFlags
& TTF_IDISHWND
)) {
468 if (hwnd
!= toolPtr
->hwnd
)
470 if (!PtInRect (&toolPtr
->rect
, *lpPt
))
476 for (nTool
= 0; nTool
< infoPtr
->uNumTools
; nTool
++) {
477 toolPtr
= &infoPtr
->tools
[nTool
];
479 if (toolPtr
->uFlags
& TTF_IDISHWND
) {
480 if ((HWND
)toolPtr
->uId
== hwnd
)
490 TOOLTIPS_GetToolFromMessage (TOOLTIPS_INFO
*infoPtr
, HWND hwndTool
)
495 dwPos
= GetMessagePos ();
496 pt
.x
= (INT
)LOWORD(dwPos
);
497 pt
.y
= (INT
)HIWORD(dwPos
);
498 ScreenToClient (hwndTool
, &pt
);
500 return TOOLTIPS_GetToolFromPoint (infoPtr
, hwndTool
, &pt
);
505 TOOLTIPS_IsWindowActive (HWND hwnd
)
507 HWND hwndActive
= GetActiveWindow ();
510 if (hwndActive
== hwnd
)
512 return IsChild (hwndActive
, hwnd
);
517 TOOLTIPS_CheckTool (HWND hwnd
, BOOL bShowTest
)
519 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
525 hwndTool
= SendMessageA (hwnd
, TTM_WINDOWFROMPOINT
, 0, (LPARAM
)&pt
);
529 ScreenToClient (hwndTool
, &pt
);
530 nTool
= TOOLTIPS_GetToolFromPoint (infoPtr
, hwndTool
, &pt
);
534 if (!(GetWindowLongA (hwnd
, GWL_STYLE
) & TTS_ALWAYSTIP
) && bShowTest
) {
535 if (!TOOLTIPS_IsWindowActive (GetWindow (hwnd
, GW_OWNER
)))
539 TRACE("tool %d\n", nTool
);
546 TOOLTIPS_Activate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
548 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
550 infoPtr
->bActive
= (BOOL
)wParam
;
552 if (infoPtr
->bActive
)
553 TRACE("activate!\n");
555 if (!(infoPtr
->bActive
) && (infoPtr
->nCurrentTool
!= -1))
556 TOOLTIPS_Hide (hwnd
, infoPtr
);
563 TOOLTIPS_AddToolA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
565 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
566 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
567 TTTOOL_INFO
*toolPtr
;
569 if (lpToolInfo
== NULL
)
571 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
574 TRACE("add tool (%x) %x %d%s!\n",
575 hwnd
, lpToolInfo
->hwnd
, lpToolInfo
->uId
,
576 (lpToolInfo
->uFlags
& TTF_IDISHWND
) ? " TTF_IDISHWND" : "");
578 if (infoPtr
->uNumTools
== 0) {
579 infoPtr
->tools
= COMCTL32_Alloc (sizeof(TTTOOL_INFO
));
580 toolPtr
= infoPtr
->tools
;
583 TTTOOL_INFO
*oldTools
= infoPtr
->tools
;
585 COMCTL32_Alloc (sizeof(TTTOOL_INFO
) * (infoPtr
->uNumTools
+ 1));
586 memcpy (infoPtr
->tools
, oldTools
,
587 infoPtr
->uNumTools
* sizeof(TTTOOL_INFO
));
588 COMCTL32_Free (oldTools
);
589 toolPtr
= &infoPtr
->tools
[infoPtr
->uNumTools
];
592 infoPtr
->uNumTools
++;
595 toolPtr
->uFlags
= lpToolInfo
->uFlags
;
596 toolPtr
->hwnd
= lpToolInfo
->hwnd
;
597 toolPtr
->uId
= lpToolInfo
->uId
;
598 toolPtr
->rect
= lpToolInfo
->rect
;
599 toolPtr
->hinst
= lpToolInfo
->hinst
;
601 if ((lpToolInfo
->hinst
) && (HIWORD((INT
)lpToolInfo
->lpszText
) == 0)) {
602 TRACE("add string id %x!\n", (int)lpToolInfo
->lpszText
);
603 toolPtr
->lpszText
= (LPWSTR
)lpToolInfo
->lpszText
;
605 else if (lpToolInfo
->lpszText
) {
606 if (lpToolInfo
->lpszText
== LPSTR_TEXTCALLBACKA
) {
607 TRACE("add CALLBACK!\n");
608 toolPtr
->lpszText
= LPSTR_TEXTCALLBACKW
;
611 INT len
= lstrlenA (lpToolInfo
->lpszText
);
612 TRACE("add text \"%s\"!\n", lpToolInfo
->lpszText
);
613 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+ 1)*sizeof(WCHAR
));
614 lstrcpyAtoW (toolPtr
->lpszText
, lpToolInfo
->lpszText
);
618 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOA
))
619 toolPtr
->lParam
= lpToolInfo
->lParam
;
621 /* install subclassing hook */
622 if (toolPtr
->uFlags
& TTF_SUBCLASS
) {
623 if (toolPtr
->uFlags
& TTF_IDISHWND
) {
624 LPTT_SUBCLASS_INFO lpttsi
=
625 (LPTT_SUBCLASS_INFO
)GetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
626 if (lpttsi
== NULL
) {
628 (LPTT_SUBCLASS_INFO
)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO
));
630 (WNDPROC
)SetWindowLongA ((HWND
)toolPtr
->uId
,
631 GWL_WNDPROC
,(LONG
)TOOLTIPS_SubclassProc
);
632 lpttsi
->hwndToolTip
= hwnd
;
634 SetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
,
638 WARN("A window tool must only be listed once!\n");
641 LPTT_SUBCLASS_INFO lpttsi
=
642 (LPTT_SUBCLASS_INFO
)GetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
);
643 if (lpttsi
== NULL
) {
645 (LPTT_SUBCLASS_INFO
)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO
));
647 (WNDPROC
)SetWindowLongA (toolPtr
->hwnd
,
648 GWL_WNDPROC
,(LONG
)TOOLTIPS_SubclassProc
);
649 lpttsi
->hwndToolTip
= hwnd
;
651 SetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
, (HANDLE
)lpttsi
);
656 TRACE("subclassing installed!\n");
664 TOOLTIPS_AddToolW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
666 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
667 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
668 TTTOOL_INFO
*toolPtr
;
670 if (lpToolInfo
== NULL
)
672 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
675 TRACE("add tool (%x) %x %d%s!\n",
676 hwnd
, lpToolInfo
->hwnd
, lpToolInfo
->uId
,
677 (lpToolInfo
->uFlags
& TTF_IDISHWND
) ? " TTF_IDISHWND" : "");
679 if (infoPtr
->uNumTools
== 0) {
680 infoPtr
->tools
= COMCTL32_Alloc (sizeof(TTTOOL_INFO
));
681 toolPtr
= infoPtr
->tools
;
684 TTTOOL_INFO
*oldTools
= infoPtr
->tools
;
686 COMCTL32_Alloc (sizeof(TTTOOL_INFO
) * (infoPtr
->uNumTools
+ 1));
687 memcpy (infoPtr
->tools
, oldTools
,
688 infoPtr
->uNumTools
* sizeof(TTTOOL_INFO
));
689 COMCTL32_Free (oldTools
);
690 toolPtr
= &infoPtr
->tools
[infoPtr
->uNumTools
];
693 infoPtr
->uNumTools
++;
696 toolPtr
->uFlags
= lpToolInfo
->uFlags
;
697 toolPtr
->hwnd
= lpToolInfo
->hwnd
;
698 toolPtr
->uId
= lpToolInfo
->uId
;
699 toolPtr
->rect
= lpToolInfo
->rect
;
700 toolPtr
->hinst
= lpToolInfo
->hinst
;
702 if ((lpToolInfo
->hinst
) && (HIWORD((INT
)lpToolInfo
->lpszText
) == 0)) {
703 TRACE("add string id %x!\n", (int)lpToolInfo
->lpszText
);
704 toolPtr
->lpszText
= (LPWSTR
)lpToolInfo
->lpszText
;
706 else if (lpToolInfo
->lpszText
) {
707 if (lpToolInfo
->lpszText
== LPSTR_TEXTCALLBACKW
) {
708 TRACE("add CALLBACK!\n");
709 toolPtr
->lpszText
= LPSTR_TEXTCALLBACKW
;
712 INT len
= lstrlenW (lpToolInfo
->lpszText
);
713 TRACE("add text \"%s\"!\n",
714 debugstr_w(lpToolInfo
->lpszText
));
715 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+ 1)*sizeof(WCHAR
));
716 lstrcpyW (toolPtr
->lpszText
, lpToolInfo
->lpszText
);
720 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOW
))
721 toolPtr
->lParam
= lpToolInfo
->lParam
;
723 /* install subclassing hook */
724 if (toolPtr
->uFlags
& TTF_SUBCLASS
) {
725 if (toolPtr
->uFlags
& TTF_IDISHWND
) {
726 LPTT_SUBCLASS_INFO lpttsi
=
727 (LPTT_SUBCLASS_INFO
)GetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
728 if (lpttsi
== NULL
) {
730 (LPTT_SUBCLASS_INFO
)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO
));
732 (WNDPROC
)SetWindowLongA ((HWND
)toolPtr
->uId
,
733 GWL_WNDPROC
,(LONG
)TOOLTIPS_SubclassProc
);
734 lpttsi
->hwndToolTip
= hwnd
;
736 SetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
,
740 WARN("A window tool must only be listed once!\n");
743 LPTT_SUBCLASS_INFO lpttsi
=
744 (LPTT_SUBCLASS_INFO
)GetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
);
745 if (lpttsi
== NULL
) {
747 (LPTT_SUBCLASS_INFO
)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO
));
749 (WNDPROC
)SetWindowLongA (toolPtr
->hwnd
,
750 GWL_WNDPROC
,(LONG
)TOOLTIPS_SubclassProc
);
751 lpttsi
->hwndToolTip
= hwnd
;
753 SetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
, (HANDLE
)lpttsi
);
758 TRACE("subclassing installed!\n");
766 TOOLTIPS_DelToolA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
768 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
769 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
770 TTTOOL_INFO
*toolPtr
;
773 if (lpToolInfo
== NULL
)
775 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
777 if (infoPtr
->uNumTools
== 0)
780 nTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpToolInfo
);
781 if (nTool
== -1) return 0;
783 TRACE("tool %d\n", nTool
);
785 /* delete text string */
786 toolPtr
= &infoPtr
->tools
[nTool
];
787 if ((toolPtr
->hinst
) && (toolPtr
->lpszText
)) {
788 if (toolPtr
->lpszText
!= LPSTR_TEXTCALLBACKW
)
789 COMCTL32_Free (toolPtr
->lpszText
);
792 /* remove subclassing */
793 if (toolPtr
->uFlags
& TTF_SUBCLASS
) {
794 if (toolPtr
->uFlags
& TTF_IDISHWND
) {
795 LPTT_SUBCLASS_INFO lpttsi
=
796 (LPTT_SUBCLASS_INFO
)GetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
798 SetWindowLongA ((HWND
)toolPtr
->uId
, GWL_WNDPROC
,
799 (LONG
)lpttsi
->wpOrigProc
);
800 RemovePropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
801 COMCTL32_Free (&lpttsi
);
804 ERR("Invalid data handle!\n");
807 LPTT_SUBCLASS_INFO lpttsi
=
808 (LPTT_SUBCLASS_INFO
)GetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
);
810 if (lpttsi
->uRefCount
== 1) {
811 SetWindowLongA ((HWND
)toolPtr
->uId
, GWL_WNDPROC
,
812 (LONG
)lpttsi
->wpOrigProc
);
813 RemovePropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
814 COMCTL32_Free (&lpttsi
);
820 ERR("Invalid data handle!\n");
824 /* delete tool from tool list */
825 if (infoPtr
->uNumTools
== 1) {
826 COMCTL32_Free (infoPtr
->tools
);
827 infoPtr
->tools
= NULL
;
830 TTTOOL_INFO
*oldTools
= infoPtr
->tools
;
832 COMCTL32_Alloc (sizeof(TTTOOL_INFO
) * (infoPtr
->uNumTools
- 1));
835 memcpy (&infoPtr
->tools
[0], &oldTools
[0],
836 nTool
* sizeof(TTTOOL_INFO
));
838 if (nTool
< infoPtr
->uNumTools
- 1)
839 memcpy (&infoPtr
->tools
[nTool
], &oldTools
[nTool
+ 1],
840 (infoPtr
->uNumTools
- nTool
- 1) * sizeof(TTTOOL_INFO
));
842 COMCTL32_Free (oldTools
);
845 infoPtr
->uNumTools
--;
852 TOOLTIPS_DelToolW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
854 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
855 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
856 TTTOOL_INFO
*toolPtr
;
859 if (lpToolInfo
== NULL
)
861 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
863 if (infoPtr
->uNumTools
== 0)
866 nTool
= TOOLTIPS_GetToolFromInfoW (infoPtr
, lpToolInfo
);
867 if (nTool
== -1) return 0;
869 TRACE("tool %d\n", nTool
);
871 /* delete text string */
872 toolPtr
= &infoPtr
->tools
[nTool
];
873 if ((toolPtr
->hinst
) && (toolPtr
->lpszText
)) {
874 if (toolPtr
->lpszText
!= LPSTR_TEXTCALLBACKW
)
875 COMCTL32_Free (toolPtr
->lpszText
);
878 /* remove subclassing */
879 if (toolPtr
->uFlags
& TTF_SUBCLASS
) {
880 if (toolPtr
->uFlags
& TTF_IDISHWND
) {
881 LPTT_SUBCLASS_INFO lpttsi
=
882 (LPTT_SUBCLASS_INFO
)GetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
884 SetWindowLongA ((HWND
)toolPtr
->uId
, GWL_WNDPROC
,
885 (LONG
)lpttsi
->wpOrigProc
);
886 RemovePropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
887 COMCTL32_Free (&lpttsi
);
890 ERR("Invalid data handle!\n");
893 LPTT_SUBCLASS_INFO lpttsi
=
894 (LPTT_SUBCLASS_INFO
)GetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
);
896 if (lpttsi
->uRefCount
== 1) {
897 SetWindowLongA ((HWND
)toolPtr
->uId
, GWL_WNDPROC
,
898 (LONG
)lpttsi
->wpOrigProc
);
899 RemovePropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
900 COMCTL32_Free (&lpttsi
);
906 ERR("Invalid data handle!\n");
910 /* delete tool from tool list */
911 if (infoPtr
->uNumTools
== 1) {
912 COMCTL32_Free (infoPtr
->tools
);
913 infoPtr
->tools
= NULL
;
916 TTTOOL_INFO
*oldTools
= infoPtr
->tools
;
918 COMCTL32_Alloc (sizeof(TTTOOL_INFO
) * (infoPtr
->uNumTools
- 1));
921 memcpy (&infoPtr
->tools
[0], &oldTools
[0],
922 nTool
* sizeof(TTTOOL_INFO
));
924 if (nTool
< infoPtr
->uNumTools
- 1)
925 memcpy (&infoPtr
->tools
[nTool
], &oldTools
[nTool
+ 1],
926 (infoPtr
->uNumTools
- nTool
- 1) * sizeof(TTTOOL_INFO
));
928 COMCTL32_Free (oldTools
);
931 infoPtr
->uNumTools
--;
938 TOOLTIPS_EnumToolsA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
940 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
941 UINT uIndex
= (UINT
)wParam
;
942 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
943 TTTOOL_INFO
*toolPtr
;
945 if (lpToolInfo
== NULL
)
947 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
949 if (uIndex
>= infoPtr
->uNumTools
)
952 TRACE("index=%u\n", uIndex
);
954 toolPtr
= &infoPtr
->tools
[uIndex
];
957 lpToolInfo
->uFlags
= toolPtr
->uFlags
;
958 lpToolInfo
->hwnd
= toolPtr
->hwnd
;
959 lpToolInfo
->uId
= toolPtr
->uId
;
960 lpToolInfo
->rect
= toolPtr
->rect
;
961 lpToolInfo
->hinst
= toolPtr
->hinst
;
962 /* lpToolInfo->lpszText = toolPtr->lpszText; */
963 lpToolInfo
->lpszText
= NULL
; /* FIXME */
965 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOA
))
966 lpToolInfo
->lParam
= toolPtr
->lParam
;
973 TOOLTIPS_EnumToolsW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
975 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
976 UINT uIndex
= (UINT
)wParam
;
977 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
978 TTTOOL_INFO
*toolPtr
;
980 if (lpToolInfo
== NULL
)
982 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
984 if (uIndex
>= infoPtr
->uNumTools
)
987 TRACE("index=%u\n", uIndex
);
989 toolPtr
= &infoPtr
->tools
[uIndex
];
992 lpToolInfo
->uFlags
= toolPtr
->uFlags
;
993 lpToolInfo
->hwnd
= toolPtr
->hwnd
;
994 lpToolInfo
->uId
= toolPtr
->uId
;
995 lpToolInfo
->rect
= toolPtr
->rect
;
996 lpToolInfo
->hinst
= toolPtr
->hinst
;
997 /* lpToolInfo->lpszText = toolPtr->lpszText; */
998 lpToolInfo
->lpszText
= NULL
; /* FIXME */
1000 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOW
))
1001 lpToolInfo
->lParam
= toolPtr
->lParam
;
1008 TOOLTIPS_GetCurrentToolA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1010 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1011 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
1012 TTTOOL_INFO
*toolPtr
;
1014 if (lpToolInfo
== NULL
)
1016 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1020 if (infoPtr
->nCurrentTool
> -1) {
1021 toolPtr
= &infoPtr
->tools
[infoPtr
->nCurrentTool
];
1023 /* copy tool data */
1024 lpToolInfo
->uFlags
= toolPtr
->uFlags
;
1025 lpToolInfo
->rect
= toolPtr
->rect
;
1026 lpToolInfo
->hinst
= toolPtr
->hinst
;
1027 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1028 lpToolInfo
->lpszText
= NULL
; /* FIXME */
1030 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOA
))
1031 lpToolInfo
->lParam
= toolPtr
->lParam
;
1039 return (infoPtr
->nCurrentTool
!= -1);
1046 TOOLTIPS_GetCurrentToolW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1048 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1049 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
1050 TTTOOL_INFO
*toolPtr
;
1052 if (lpToolInfo
== NULL
)
1054 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
1058 if (infoPtr
->nCurrentTool
> -1) {
1059 toolPtr
= &infoPtr
->tools
[infoPtr
->nCurrentTool
];
1061 /* copy tool data */
1062 lpToolInfo
->uFlags
= toolPtr
->uFlags
;
1063 lpToolInfo
->rect
= toolPtr
->rect
;
1064 lpToolInfo
->hinst
= toolPtr
->hinst
;
1065 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1066 lpToolInfo
->lpszText
= NULL
; /* FIXME */
1068 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOW
))
1069 lpToolInfo
->lParam
= toolPtr
->lParam
;
1077 return (infoPtr
->nCurrentTool
!= -1);
1084 TOOLTIPS_GetDelayTime (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1086 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1089 case TTDT_AUTOMATIC
:
1090 return infoPtr
->nAutomaticTime
;
1093 return infoPtr
->nReshowTime
;
1096 return infoPtr
->nAutoPopTime
;
1099 return infoPtr
->nInitialTime
;
1107 TOOLTIPS_GetMargin (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1109 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1110 LPRECT lpRect
= (LPRECT
)lParam
;
1112 lpRect
->left
= infoPtr
->rcMargin
.left
;
1113 lpRect
->right
= infoPtr
->rcMargin
.right
;
1114 lpRect
->bottom
= infoPtr
->rcMargin
.bottom
;
1115 lpRect
->top
= infoPtr
->rcMargin
.top
;
1121 inline static LRESULT
1122 TOOLTIPS_GetMaxTipWidth (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1124 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1126 return infoPtr
->nMaxTipWidth
;
1131 TOOLTIPS_GetTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1133 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1134 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
1137 if (lpToolInfo
== NULL
)
1139 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1142 nTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpToolInfo
);
1143 if (nTool
== -1) return 0;
1145 lstrcpyWtoA (lpToolInfo
->lpszText
, infoPtr
->tools
[nTool
].lpszText
);
1152 TOOLTIPS_GetTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1154 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1155 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
1158 if (lpToolInfo
== NULL
)
1160 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
1163 nTool
= TOOLTIPS_GetToolFromInfoW (infoPtr
, lpToolInfo
);
1164 if (nTool
== -1) return 0;
1166 lstrcpyW (lpToolInfo
->lpszText
, infoPtr
->tools
[nTool
].lpszText
);
1172 inline static LRESULT
1173 TOOLTIPS_GetTipBkColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1175 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1176 return infoPtr
->clrBk
;
1180 inline static LRESULT
1181 TOOLTIPS_GetTipTextColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1183 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1184 return infoPtr
->clrText
;
1188 inline static LRESULT
1189 TOOLTIPS_GetToolCount (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1191 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1192 return infoPtr
->uNumTools
;
1197 TOOLTIPS_GetToolInfoA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1199 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1200 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
1201 TTTOOL_INFO
*toolPtr
;
1204 if (lpToolInfo
== NULL
)
1206 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1208 if (infoPtr
->uNumTools
== 0)
1211 nTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpToolInfo
);
1215 TRACE("tool %d\n", nTool
);
1217 toolPtr
= &infoPtr
->tools
[nTool
];
1219 /* copy tool data */
1220 lpToolInfo
->uFlags
= toolPtr
->uFlags
;
1221 lpToolInfo
->rect
= toolPtr
->rect
;
1222 lpToolInfo
->hinst
= toolPtr
->hinst
;
1223 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1224 lpToolInfo
->lpszText
= NULL
; /* FIXME */
1226 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOA
))
1227 lpToolInfo
->lParam
= toolPtr
->lParam
;
1234 TOOLTIPS_GetToolInfoW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1236 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1237 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
1238 TTTOOL_INFO
*toolPtr
;
1241 if (lpToolInfo
== NULL
)
1243 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
1245 if (infoPtr
->uNumTools
== 0)
1248 nTool
= TOOLTIPS_GetToolFromInfoW (infoPtr
, lpToolInfo
);
1252 TRACE("tool %d\n", nTool
);
1254 toolPtr
= &infoPtr
->tools
[nTool
];
1256 /* copy tool data */
1257 lpToolInfo
->uFlags
= toolPtr
->uFlags
;
1258 lpToolInfo
->rect
= toolPtr
->rect
;
1259 lpToolInfo
->hinst
= toolPtr
->hinst
;
1260 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1261 lpToolInfo
->lpszText
= NULL
; /* FIXME */
1263 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOW
))
1264 lpToolInfo
->lParam
= toolPtr
->lParam
;
1271 TOOLTIPS_HitTestA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1273 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1274 LPTTHITTESTINFOA lptthit
= (LPTTHITTESTINFOA
)lParam
;
1275 TTTOOL_INFO
*toolPtr
;
1281 nTool
= TOOLTIPS_GetToolFromPoint (infoPtr
, lptthit
->hwnd
, &lptthit
->pt
);
1285 TRACE("tool %d!\n", nTool
);
1287 /* copy tool data */
1288 if (lptthit
->ti
.cbSize
>= sizeof(TTTOOLINFOA
)) {
1289 toolPtr
= &infoPtr
->tools
[nTool
];
1291 lptthit
->ti
.uFlags
= toolPtr
->uFlags
;
1292 lptthit
->ti
.hwnd
= toolPtr
->hwnd
;
1293 lptthit
->ti
.uId
= toolPtr
->uId
;
1294 lptthit
->ti
.rect
= toolPtr
->rect
;
1295 lptthit
->ti
.hinst
= toolPtr
->hinst
;
1296 /* lptthit->ti.lpszText = toolPtr->lpszText; */
1297 lptthit
->ti
.lpszText
= NULL
; /* FIXME */
1298 lptthit
->ti
.lParam
= toolPtr
->lParam
;
1306 TOOLTIPS_HitTestW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1308 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1309 LPTTHITTESTINFOW lptthit
= (LPTTHITTESTINFOW
)lParam
;
1310 TTTOOL_INFO
*toolPtr
;
1316 nTool
= TOOLTIPS_GetToolFromPoint (infoPtr
, lptthit
->hwnd
, &lptthit
->pt
);
1320 TRACE("tool %d!\n", nTool
);
1322 /* copy tool data */
1323 if (lptthit
->ti
.cbSize
>= sizeof(TTTOOLINFOW
)) {
1324 toolPtr
= &infoPtr
->tools
[nTool
];
1326 lptthit
->ti
.uFlags
= toolPtr
->uFlags
;
1327 lptthit
->ti
.hwnd
= toolPtr
->hwnd
;
1328 lptthit
->ti
.uId
= toolPtr
->uId
;
1329 lptthit
->ti
.rect
= toolPtr
->rect
;
1330 lptthit
->ti
.hinst
= toolPtr
->hinst
;
1331 /* lptthit->ti.lpszText = toolPtr->lpszText; */
1332 lptthit
->ti
.lpszText
= NULL
; /* FIXME */
1333 lptthit
->ti
.lParam
= toolPtr
->lParam
;
1341 TOOLTIPS_NewToolRectA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1343 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1344 LPTTTOOLINFOA lpti
= (LPTTTOOLINFOA
)lParam
;
1349 if (lpti
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1352 nTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpti
);
1353 if (nTool
== -1) return 0;
1355 infoPtr
->tools
[nTool
].rect
= lpti
->rect
;
1362 TOOLTIPS_NewToolRectW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1364 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1365 LPTTTOOLINFOW lpti
= (LPTTTOOLINFOW
)lParam
;
1370 if (lpti
->cbSize
< TTTOOLINFO_V1_SIZEW
)
1373 nTool
= TOOLTIPS_GetToolFromInfoW (infoPtr
, lpti
);
1374 if (nTool
== -1) return 0;
1376 infoPtr
->tools
[nTool
].rect
= lpti
->rect
;
1382 inline static LRESULT
1383 TOOLTIPS_Pop (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1385 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1387 TOOLTIPS_Hide (hwnd
, infoPtr
);
1394 TOOLTIPS_RelayEvent (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1396 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1397 LPMSG lpMsg
= (LPMSG
)lParam
;
1401 ERR("lpMsg == NULL!\n");
1405 switch (lpMsg
->message
) {
1406 case WM_LBUTTONDOWN
:
1408 case WM_MBUTTONDOWN
:
1410 case WM_RBUTTONDOWN
:
1413 ScreenToClient (lpMsg
->hwnd
, &pt
);
1414 infoPtr
->nOldTool
= infoPtr
->nTool
;
1415 infoPtr
->nTool
= TOOLTIPS_GetToolFromPoint (infoPtr
, lpMsg
->hwnd
, &pt
);
1416 TRACE("tool (%x) %d %d\n",
1417 hwnd
, infoPtr
->nOldTool
, infoPtr
->nTool
);
1418 TOOLTIPS_Hide (hwnd
, infoPtr
);
1423 ScreenToClient (lpMsg
->hwnd
, &pt
);
1424 infoPtr
->nOldTool
= infoPtr
->nTool
;
1425 infoPtr
->nTool
= TOOLTIPS_GetToolFromPoint (infoPtr
, lpMsg
->hwnd
, &pt
);
1426 TRACE("tool (%x) %d %d\n",
1427 hwnd
, infoPtr
->nOldTool
, infoPtr
->nTool
);
1428 TRACE("WM_MOUSEMOVE (%04x %ld %ld)\n",
1430 if ((infoPtr
->bActive
) && (infoPtr
->nTool
!= infoPtr
->nOldTool
)) {
1431 if (infoPtr
->nOldTool
== -1) {
1432 SetTimer (hwnd
, ID_TIMERSHOW
, infoPtr
->nInitialTime
, 0);
1433 TRACE("timer 1 started!\n");
1436 TOOLTIPS_Hide (hwnd
, infoPtr
);
1437 SetTimer (hwnd
, ID_TIMERSHOW
, infoPtr
->nReshowTime
, 0);
1438 TRACE("timer 2 started!\n");
1441 if (infoPtr
->nCurrentTool
!= -1) {
1442 SetTimer (hwnd
, ID_TIMERLEAVE
, 100, 0);
1443 TRACE("timer 3 started!\n");
1453 TOOLTIPS_SetDelayTime (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1455 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1456 INT nTime
= (INT
)LOWORD(lParam
);
1459 case TTDT_AUTOMATIC
:
1461 infoPtr
->nAutomaticTime
= 500;
1462 infoPtr
->nReshowTime
= 100;
1463 infoPtr
->nAutoPopTime
= 5000;
1464 infoPtr
->nInitialTime
= 500;
1467 infoPtr
->nAutomaticTime
= nTime
;
1468 infoPtr
->nReshowTime
= nTime
/ 5;
1469 infoPtr
->nAutoPopTime
= nTime
* 10;
1470 infoPtr
->nInitialTime
= nTime
;
1475 infoPtr
->nReshowTime
= nTime
;
1479 infoPtr
->nAutoPopTime
= nTime
;
1483 infoPtr
->nInitialTime
= nTime
;
1492 TOOLTIPS_SetMargin (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1494 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1495 LPRECT lpRect
= (LPRECT
)lParam
;
1497 infoPtr
->rcMargin
.left
= lpRect
->left
;
1498 infoPtr
->rcMargin
.right
= lpRect
->right
;
1499 infoPtr
->rcMargin
.bottom
= lpRect
->bottom
;
1500 infoPtr
->rcMargin
.top
= lpRect
->top
;
1506 inline static LRESULT
1507 TOOLTIPS_SetMaxTipWidth (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1509 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1510 INT nTemp
= infoPtr
->nMaxTipWidth
;
1512 infoPtr
->nMaxTipWidth
= (INT
)lParam
;
1518 inline static LRESULT
1519 TOOLTIPS_SetTipBkColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1521 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1523 infoPtr
->clrBk
= (COLORREF
)wParam
;
1529 inline static LRESULT
1530 TOOLTIPS_SetTipTextColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1532 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1534 infoPtr
->clrText
= (COLORREF
)wParam
;
1541 TOOLTIPS_SetToolInfoA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1543 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1544 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
1545 TTTOOL_INFO
*toolPtr
;
1548 if (lpToolInfo
== NULL
)
1550 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1553 nTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpToolInfo
);
1554 if (nTool
== -1) return 0;
1556 TRACE("tool %d\n", nTool
);
1558 toolPtr
= &infoPtr
->tools
[nTool
];
1560 /* copy tool data */
1561 toolPtr
->uFlags
= lpToolInfo
->uFlags
;
1562 toolPtr
->hwnd
= lpToolInfo
->hwnd
;
1563 toolPtr
->uId
= lpToolInfo
->uId
;
1564 toolPtr
->rect
= lpToolInfo
->rect
;
1565 toolPtr
->hinst
= lpToolInfo
->hinst
;
1567 if ((lpToolInfo
->hinst
) && (HIWORD((INT
)lpToolInfo
->lpszText
) == 0)) {
1568 TRACE("set string id %x!\n", (INT
)lpToolInfo
->lpszText
);
1569 toolPtr
->lpszText
= (LPWSTR
)lpToolInfo
->lpszText
;
1571 else if (lpToolInfo
->lpszText
) {
1572 if (lpToolInfo
->lpszText
== LPSTR_TEXTCALLBACKA
)
1573 toolPtr
->lpszText
= LPSTR_TEXTCALLBACKW
;
1575 if (toolPtr
->lpszText
) {
1576 COMCTL32_Free (toolPtr
->lpszText
);
1577 toolPtr
->lpszText
= NULL
;
1579 if (lpToolInfo
->lpszText
) {
1580 INT len
= lstrlenA (lpToolInfo
->lpszText
);
1581 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1582 lstrcpyAtoW (toolPtr
->lpszText
, lpToolInfo
->lpszText
);
1587 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOA
))
1588 toolPtr
->lParam
= lpToolInfo
->lParam
;
1595 TOOLTIPS_SetToolInfoW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1597 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1598 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
1599 TTTOOL_INFO
*toolPtr
;
1602 if (lpToolInfo
== NULL
)
1604 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
1607 nTool
= TOOLTIPS_GetToolFromInfoW (infoPtr
, lpToolInfo
);
1608 if (nTool
== -1) return 0;
1610 TRACE("tool %d\n", nTool
);
1612 toolPtr
= &infoPtr
->tools
[nTool
];
1614 /* copy tool data */
1615 toolPtr
->uFlags
= lpToolInfo
->uFlags
;
1616 toolPtr
->hwnd
= lpToolInfo
->hwnd
;
1617 toolPtr
->uId
= lpToolInfo
->uId
;
1618 toolPtr
->rect
= lpToolInfo
->rect
;
1619 toolPtr
->hinst
= lpToolInfo
->hinst
;
1621 if ((lpToolInfo
->hinst
) && (HIWORD((INT
)lpToolInfo
->lpszText
) == 0)) {
1622 TRACE("set string id %x!\n", (INT
)lpToolInfo
->lpszText
);
1623 toolPtr
->lpszText
= lpToolInfo
->lpszText
;
1625 else if (lpToolInfo
->lpszText
) {
1626 if (lpToolInfo
->lpszText
== LPSTR_TEXTCALLBACKW
)
1627 toolPtr
->lpszText
= LPSTR_TEXTCALLBACKW
;
1629 if (toolPtr
->lpszText
) {
1630 COMCTL32_Free (toolPtr
->lpszText
);
1631 toolPtr
->lpszText
= NULL
;
1633 if (lpToolInfo
->lpszText
) {
1634 INT len
= lstrlenW (lpToolInfo
->lpszText
);
1635 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1636 lstrcpyW (toolPtr
->lpszText
, lpToolInfo
->lpszText
);
1641 if (lpToolInfo
->cbSize
>= sizeof(TTTOOLINFOW
))
1642 toolPtr
->lParam
= lpToolInfo
->lParam
;
1649 TOOLTIPS_TrackActivate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1651 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1652 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
1654 if (lpToolInfo
== NULL
)
1656 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1661 infoPtr
->nTrackTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpToolInfo
);
1662 if (infoPtr
->nTrackTool
!= -1) {
1663 TRACE("activated!\n");
1664 infoPtr
->bTrackActive
= TRUE
;
1665 TOOLTIPS_TrackShow (hwnd
, infoPtr
);
1670 TOOLTIPS_TrackHide (hwnd
, infoPtr
);
1672 infoPtr
->bTrackActive
= FALSE
;
1673 infoPtr
->nTrackTool
= -1;
1675 TRACE("deactivated!\n");
1683 TOOLTIPS_TrackPosition (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1685 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1687 infoPtr
->xTrackPos
= (INT
)LOWORD(lParam
);
1688 infoPtr
->yTrackPos
= (INT
)HIWORD(lParam
);
1690 if (infoPtr
->bTrackActive
) {
1692 infoPtr
->xTrackPos
, infoPtr
->yTrackPos
);
1694 TOOLTIPS_TrackShow (hwnd
, infoPtr
);
1702 TOOLTIPS_Update (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1704 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1706 if (infoPtr
->nCurrentTool
!= -1)
1707 UpdateWindow (hwnd
);
1714 TOOLTIPS_UpdateTipTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1716 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1717 LPTTTOOLINFOA lpToolInfo
= (LPTTTOOLINFOA
)lParam
;
1718 TTTOOL_INFO
*toolPtr
;
1721 if (lpToolInfo
== NULL
)
1723 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEA
)
1726 nTool
= TOOLTIPS_GetToolFromInfoA (infoPtr
, lpToolInfo
);
1727 if (nTool
== -1) return 0;
1729 TRACE("tool %d\n", nTool
);
1731 toolPtr
= &infoPtr
->tools
[nTool
];
1733 /* copy tool text */
1734 toolPtr
->hinst
= lpToolInfo
->hinst
;
1736 if ((lpToolInfo
->hinst
) && (HIWORD((INT
)lpToolInfo
->lpszText
) == 0)){
1737 toolPtr
->lpszText
= (LPWSTR
)lpToolInfo
->lpszText
;
1739 else if (lpToolInfo
->lpszText
) {
1740 if (lpToolInfo
->lpszText
== LPSTR_TEXTCALLBACKA
)
1741 toolPtr
->lpszText
= LPSTR_TEXTCALLBACKW
;
1743 if (toolPtr
->lpszText
) {
1744 COMCTL32_Free (toolPtr
->lpszText
);
1745 toolPtr
->lpszText
= NULL
;
1747 if (lpToolInfo
->lpszText
) {
1748 INT len
= lstrlenA (lpToolInfo
->lpszText
);
1749 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1750 lstrcpyAtoW (toolPtr
->lpszText
, lpToolInfo
->lpszText
);
1756 if (infoPtr
->bActive
)
1757 TOOLTIPS_Show (hwnd
, infoPtr
);
1758 else if (infoPtr
->bTrackActive
)
1759 TOOLTIPS_TrackShow (hwnd
, infoPtr
);
1766 TOOLTIPS_UpdateTipTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1768 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1769 LPTTTOOLINFOW lpToolInfo
= (LPTTTOOLINFOW
)lParam
;
1770 TTTOOL_INFO
*toolPtr
;
1773 if (lpToolInfo
== NULL
)
1775 if (lpToolInfo
->cbSize
< TTTOOLINFO_V1_SIZEW
)
1778 nTool
= TOOLTIPS_GetToolFromInfoW (infoPtr
, lpToolInfo
);
1782 TRACE("tool %d\n", nTool
);
1784 toolPtr
= &infoPtr
->tools
[nTool
];
1786 /* copy tool text */
1787 toolPtr
->hinst
= lpToolInfo
->hinst
;
1789 if ((lpToolInfo
->hinst
) && (HIWORD((INT
)lpToolInfo
->lpszText
) == 0)){
1790 toolPtr
->lpszText
= lpToolInfo
->lpszText
;
1792 else if (lpToolInfo
->lpszText
) {
1793 if (lpToolInfo
->lpszText
== LPSTR_TEXTCALLBACKW
)
1794 toolPtr
->lpszText
= LPSTR_TEXTCALLBACKW
;
1796 if (toolPtr
->lpszText
) {
1797 COMCTL32_Free (toolPtr
->lpszText
);
1798 toolPtr
->lpszText
= NULL
;
1800 if (lpToolInfo
->lpszText
) {
1801 INT len
= lstrlenW (lpToolInfo
->lpszText
);
1802 toolPtr
->lpszText
= COMCTL32_Alloc ((len
+1)*sizeof(WCHAR
));
1803 lstrcpyW (toolPtr
->lpszText
, lpToolInfo
->lpszText
);
1809 if (infoPtr
->bActive
)
1810 TOOLTIPS_Show (hwnd
, infoPtr
);
1811 else if (infoPtr
->bTrackActive
)
1812 TOOLTIPS_TrackShow (hwnd
, infoPtr
);
1819 TOOLTIPS_WindowFromPoint (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1821 return WindowFromPoint (*((LPPOINT
)lParam
));
1827 TOOLTIPS_Create (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1829 TOOLTIPS_INFO
*infoPtr
;
1830 NONCLIENTMETRICSA nclm
;
1833 /* allocate memory for info structure */
1834 infoPtr
= (TOOLTIPS_INFO
*)COMCTL32_Alloc (sizeof(TOOLTIPS_INFO
));
1835 SetWindowLongA (hwnd
, 0, (DWORD
)infoPtr
);
1837 /* initialize info structure */
1838 infoPtr
->bActive
= TRUE
;
1839 infoPtr
->bTrackActive
= FALSE
;
1840 infoPtr
->clrBk
= GetSysColor (COLOR_INFOBK
);
1841 infoPtr
->clrText
= GetSysColor (COLOR_INFOTEXT
);
1843 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
1844 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
1845 infoPtr
->hFont
= CreateFontIndirectA (&nclm
.lfStatusFont
);
1847 infoPtr
->nMaxTipWidth
= -1;
1848 infoPtr
->nTool
= -1;
1849 infoPtr
->nOldTool
= -1;
1850 infoPtr
->nCurrentTool
= -1;
1851 infoPtr
->nTrackTool
= -1;
1853 infoPtr
->nAutomaticTime
= 500;
1854 infoPtr
->nReshowTime
= 100;
1855 infoPtr
->nAutoPopTime
= 5000;
1856 infoPtr
->nInitialTime
= 500;
1858 nResult
= (INT
) SendMessageA (GetParent (hwnd
), WM_NOTIFYFORMAT
,
1859 (WPARAM
)hwnd
, (LPARAM
)NF_QUERY
);
1860 if (nResult
== NFR_ANSI
)
1861 TRACE(" -- WM_NOTIFYFORMAT returns: NFR_ANSI\n");
1862 else if (nResult
== NFR_UNICODE
)
1863 FIXME(" -- WM_NOTIFYFORMAT returns: NFR_UNICODE\n");
1865 FIXME(" -- WM_NOTIFYFORMAT returns: error!\n");
1867 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOZORDER
| SWP_HIDEWINDOW
| SWP_NOACTIVATE
);
1874 TOOLTIPS_Destroy (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1876 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1877 TTTOOL_INFO
*toolPtr
;
1881 if (infoPtr
->tools
) {
1882 for (i
= 0; i
< infoPtr
->uNumTools
; i
++) {
1883 toolPtr
= &infoPtr
->tools
[i
];
1884 if ((toolPtr
->hinst
) && (toolPtr
->lpszText
)) {
1885 if (toolPtr
->lpszText
!= LPSTR_TEXTCALLBACKW
)
1886 COMCTL32_Free (toolPtr
->lpszText
);
1889 /* remove subclassing */
1890 if (toolPtr
->uFlags
& TTF_SUBCLASS
) {
1891 LPTT_SUBCLASS_INFO lpttsi
;
1893 if (toolPtr
->uFlags
& TTF_IDISHWND
)
1894 lpttsi
= (LPTT_SUBCLASS_INFO
)GetPropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
1896 lpttsi
= (LPTT_SUBCLASS_INFO
)GetPropA (toolPtr
->hwnd
, COMCTL32_aSubclass
);
1899 SetWindowLongA ((HWND
)toolPtr
->uId
, GWL_WNDPROC
,
1900 (LONG
)lpttsi
->wpOrigProc
);
1901 RemovePropA ((HWND
)toolPtr
->uId
, COMCTL32_aSubclass
);
1902 COMCTL32_Free (&lpttsi
);
1906 COMCTL32_Free (infoPtr
->tools
);
1910 DeleteObject (infoPtr
->hFont
);
1912 /* free tool tips info data */
1913 COMCTL32_Free (infoPtr
);
1920 TOOLTIPS_EraseBackground (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1922 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1926 hBrush
= CreateSolidBrush (infoPtr
->clrBk
);
1927 GetClientRect (hwnd
, &rect
);
1928 FillRect ((HDC
)wParam
, &rect
, hBrush
);
1929 DeleteObject (hBrush
);
1936 TOOLTIPS_GetFont (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1938 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1940 return infoPtr
->hFont
;
1945 TOOLTIPS_MouseMessage (HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1947 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1949 TOOLTIPS_Hide (hwnd
, infoPtr
);
1956 TOOLTIPS_NCCreate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1958 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1960 dwStyle
&= 0x0000FFFF;
1961 dwStyle
|= (WS_POPUP
| WS_BORDER
| WS_CLIPSIBLINGS
);
1962 SetWindowLongA (hwnd
, GWL_STYLE
, dwStyle
);
1969 TOOLTIPS_NCHitTest (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1971 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
1972 INT nTool
= (infoPtr
->bTrackActive
) ? infoPtr
->nTrackTool
: infoPtr
->nTool
;
1974 TRACE(" nTool=%d\n", nTool
);
1976 if ((nTool
> -1) && (nTool
< infoPtr
->uNumTools
)) {
1977 if (infoPtr
->tools
[nTool
].uFlags
& TTF_TRANSPARENT
) {
1978 TRACE("-- in transparent mode!\n");
1979 return HTTRANSPARENT
;
1983 return DefWindowProcA (hwnd
, WM_NCHITTEST
, wParam
, lParam
);
1988 TOOLTIPS_Paint (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1993 hdc
= (wParam
== 0) ? BeginPaint (hwnd
, &ps
) : (HDC
)wParam
;
1994 TOOLTIPS_Refresh (hwnd
, hdc
);
1996 EndPaint (hwnd
, &ps
);
2002 TOOLTIPS_SetFont (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2004 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
2006 infoPtr
->hFont
= (HFONT
)wParam
;
2008 if ((LOWORD(lParam
)) & (infoPtr
->nCurrentTool
!= -1)) {
2009 FIXME("full redraw needed!\n");
2014 /******************************************************************
2015 * TOOLTIPS_OnWMGetTextLength
2017 * This function is called when the tooltip receive a
2018 * WM_GETTEXTLENGTH message.
2022 * returns the length, in characters, of the tip text
2023 ******************************************************************/
2025 TOOLTIPS_OnWMGetTextLength(HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2027 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
2028 return lstrlenW(infoPtr
->szTipText
);
2030 /******************************************************************
2031 * TOOLTIPS_OnWMGetText
2033 * This function is called when the tooltip receive a
2034 * WM_GETTEXT message.
2035 * wParam : specifies the maximum number of characters to be copied
2036 * lParam : is the pointer to the buffer that will receive
2039 * returns the number of characters copied
2040 ******************************************************************/
2042 TOOLTIPS_OnWMGetText (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2044 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
2047 if(!infoPtr
|| !(infoPtr
->szTipText
))
2050 length
= lstrlenW(infoPtr
->szTipText
);
2051 /* When wParam is smaller than the lenght of the tip text
2052 copy wParam characters of the tip text and return wParam */
2055 lstrcpynWtoA((LPSTR
)lParam
, infoPtr
->szTipText
,(UINT
)wParam
);
2058 lstrcpyWtoA((LPSTR
)lParam
, infoPtr
->szTipText
);
2064 TOOLTIPS_Timer (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2066 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
2068 TRACE("timer %d (%x) expired!\n", wParam
, hwnd
);
2073 KillTimer (hwnd
, ID_TIMERSHOW
);
2074 if (TOOLTIPS_CheckTool (hwnd
, TRUE
) == infoPtr
->nTool
)
2075 TOOLTIPS_Show (hwnd
, infoPtr
);
2079 TOOLTIPS_Hide (hwnd
, infoPtr
);
2083 KillTimer (hwnd
, ID_TIMERLEAVE
);
2084 if (TOOLTIPS_CheckTool (hwnd
, FALSE
) == -1) {
2085 infoPtr
->nTool
= -1;
2086 infoPtr
->nOldTool
= -1;
2087 TOOLTIPS_Hide (hwnd
, infoPtr
);
2096 TOOLTIPS_WinIniChange (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2098 TOOLTIPS_INFO
*infoPtr
= TOOLTIPS_GetInfoPtr (hwnd
);
2099 NONCLIENTMETRICSA nclm
;
2101 infoPtr
->clrBk
= GetSysColor (COLOR_INFOBK
);
2102 infoPtr
->clrText
= GetSysColor (COLOR_INFOTEXT
);
2104 DeleteObject (infoPtr
->hFont
);
2105 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
2106 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
2107 infoPtr
->hFont
= CreateFontIndirectA (&nclm
.lfStatusFont
);
2114 TOOLTIPS_SubclassProc (HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
2116 LPTT_SUBCLASS_INFO lpttsi
=
2117 (LPTT_SUBCLASS_INFO
)GetPropA (hwnd
, COMCTL32_aSubclass
);
2118 TOOLTIPS_INFO
*infoPtr
;
2122 case WM_LBUTTONDOWN
:
2124 case WM_MBUTTONDOWN
:
2126 case WM_RBUTTONDOWN
:
2128 infoPtr
= TOOLTIPS_GetInfoPtr(lpttsi
->hwndToolTip
);
2129 nTool
= TOOLTIPS_GetToolFromMessage (infoPtr
, hwnd
);
2131 TRACE("subclassed mouse message %04x\n", uMsg
);
2132 infoPtr
->nOldTool
= infoPtr
->nTool
;
2133 infoPtr
->nTool
= nTool
;
2134 TOOLTIPS_Hide (lpttsi
->hwndToolTip
, infoPtr
);
2138 infoPtr
= TOOLTIPS_GetInfoPtr (lpttsi
->hwndToolTip
);
2139 nTool
= TOOLTIPS_GetToolFromMessage (infoPtr
, hwnd
);
2141 TRACE("subclassed WM_MOUSEMOVE\n");
2142 infoPtr
->nOldTool
= infoPtr
->nTool
;
2143 infoPtr
->nTool
= nTool
;
2145 if ((infoPtr
->bActive
) &&
2146 (infoPtr
->nTool
!= infoPtr
->nOldTool
)) {
2147 if (infoPtr
->nOldTool
== -1) {
2148 SetTimer (hwnd
, ID_TIMERSHOW
,
2149 infoPtr
->nInitialTime
, 0);
2150 TRACE("timer 1 started!\n");
2153 TOOLTIPS_Hide (lpttsi
->hwndToolTip
, infoPtr
);
2154 SetTimer (hwnd
, ID_TIMERSHOW
,
2155 infoPtr
->nReshowTime
, 0);
2156 TRACE("timer 2 started!\n");
2159 if (infoPtr
->nCurrentTool
!= -1) {
2160 SetTimer (hwnd
, ID_TIMERLEAVE
, 100, 0);
2161 TRACE("timer 3 started!\n");
2166 return CallWindowProcA (lpttsi
->wpOrigProc
, hwnd
, uMsg
, wParam
, lParam
);
2171 TOOLTIPS_WindowProc (HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
2176 return TOOLTIPS_Activate (hwnd
, wParam
, lParam
);
2179 return TOOLTIPS_AddToolA (hwnd
, wParam
, lParam
);
2182 return TOOLTIPS_AddToolW (hwnd
, wParam
, lParam
);
2185 return TOOLTIPS_DelToolA (hwnd
, wParam
, lParam
);
2188 return TOOLTIPS_DelToolW (hwnd
, wParam
, lParam
);
2190 case TTM_ENUMTOOLSA
:
2191 return TOOLTIPS_EnumToolsA (hwnd
, wParam
, lParam
);
2193 case TTM_ENUMTOOLSW
:
2194 return TOOLTIPS_EnumToolsW (hwnd
, wParam
, lParam
);
2196 case TTM_GETCURRENTTOOLA
:
2197 return TOOLTIPS_GetCurrentToolA (hwnd
, wParam
, lParam
);
2199 case TTM_GETCURRENTTOOLW
:
2200 return TOOLTIPS_GetCurrentToolW (hwnd
, wParam
, lParam
);
2202 case TTM_GETDELAYTIME
:
2203 return TOOLTIPS_GetDelayTime (hwnd
, wParam
, lParam
);
2206 return TOOLTIPS_GetMargin (hwnd
, wParam
, lParam
);
2208 case TTM_GETMAXTIPWIDTH
:
2209 return TOOLTIPS_GetMaxTipWidth (hwnd
, wParam
, lParam
);
2212 return TOOLTIPS_GetTextA (hwnd
, wParam
, lParam
);
2215 return TOOLTIPS_GetTextW (hwnd
, wParam
, lParam
);
2217 case TTM_GETTIPBKCOLOR
:
2218 return TOOLTIPS_GetTipBkColor (hwnd
, wParam
, lParam
);
2220 case TTM_GETTIPTEXTCOLOR
:
2221 return TOOLTIPS_GetTipTextColor (hwnd
, wParam
, lParam
);
2223 case TTM_GETTOOLCOUNT
:
2224 return TOOLTIPS_GetToolCount (hwnd
, wParam
, lParam
);
2226 case TTM_GETTOOLINFOA
:
2227 return TOOLTIPS_GetToolInfoA (hwnd
, wParam
, lParam
);
2229 case TTM_GETTOOLINFOW
:
2230 return TOOLTIPS_GetToolInfoW (hwnd
, wParam
, lParam
);
2233 return TOOLTIPS_HitTestA (hwnd
, wParam
, lParam
);
2236 return TOOLTIPS_HitTestW (hwnd
, wParam
, lParam
);
2238 case TTM_NEWTOOLRECTA
:
2239 return TOOLTIPS_NewToolRectA (hwnd
, wParam
, lParam
);
2241 case TTM_NEWTOOLRECTW
:
2242 return TOOLTIPS_NewToolRectW (hwnd
, wParam
, lParam
);
2245 return TOOLTIPS_Pop (hwnd
, wParam
, lParam
);
2247 case TTM_RELAYEVENT
:
2248 return TOOLTIPS_RelayEvent (hwnd
, wParam
, lParam
);
2250 case TTM_SETDELAYTIME
:
2251 return TOOLTIPS_SetDelayTime (hwnd
, wParam
, lParam
);
2254 return TOOLTIPS_SetMargin (hwnd
, wParam
, lParam
);
2256 case TTM_SETMAXTIPWIDTH
:
2257 return TOOLTIPS_SetMaxTipWidth (hwnd
, wParam
, lParam
);
2259 case TTM_SETTIPBKCOLOR
:
2260 return TOOLTIPS_SetTipBkColor (hwnd
, wParam
, lParam
);
2262 case TTM_SETTIPTEXTCOLOR
:
2263 return TOOLTIPS_SetTipTextColor (hwnd
, wParam
, lParam
);
2265 case TTM_SETTOOLINFOA
:
2266 return TOOLTIPS_SetToolInfoA (hwnd
, wParam
, lParam
);
2268 case TTM_SETTOOLINFOW
:
2269 return TOOLTIPS_SetToolInfoW (hwnd
, wParam
, lParam
);
2271 case TTM_TRACKACTIVATE
:
2272 return TOOLTIPS_TrackActivate (hwnd
, wParam
, lParam
);
2274 case TTM_TRACKPOSITION
:
2275 return TOOLTIPS_TrackPosition (hwnd
, wParam
, lParam
);
2278 return TOOLTIPS_Update (hwnd
, wParam
, lParam
);
2280 case TTM_UPDATETIPTEXTA
:
2281 return TOOLTIPS_UpdateTipTextA (hwnd
, wParam
, lParam
);
2283 case TTM_UPDATETIPTEXTW
:
2284 return TOOLTIPS_UpdateTipTextW (hwnd
, wParam
, lParam
);
2286 case TTM_WINDOWFROMPOINT
:
2287 return TOOLTIPS_WindowFromPoint (hwnd
, wParam
, lParam
);
2291 return TOOLTIPS_Create (hwnd
, wParam
, lParam
);
2294 return TOOLTIPS_Destroy (hwnd
, wParam
, lParam
);
2297 return TOOLTIPS_EraseBackground (hwnd
, wParam
, lParam
);
2300 return TOOLTIPS_GetFont (hwnd
, wParam
, lParam
);
2303 return TOOLTIPS_OnWMGetText (hwnd
, wParam
, lParam
);
2305 case WM_GETTEXTLENGTH
:
2306 return TOOLTIPS_OnWMGetTextLength (hwnd
, wParam
, lParam
);
2309 case WM_LBUTTONDOWN
:
2311 case WM_MBUTTONDOWN
:
2313 case WM_RBUTTONDOWN
:
2316 return TOOLTIPS_MouseMessage (hwnd
, uMsg
, wParam
, lParam
);
2319 return TOOLTIPS_NCCreate (hwnd
, wParam
, lParam
);
2322 return TOOLTIPS_NCHitTest (hwnd
, wParam
, lParam
);
2324 /* case WM_NOTIFYFORMAT: */
2325 /* return TOOLTIPS_NotifyFormat (hwnd, wParam, lParam); */
2328 return TOOLTIPS_Paint (hwnd
, wParam
, lParam
);
2331 return TOOLTIPS_SetFont (hwnd
, wParam
, lParam
);
2334 return TOOLTIPS_Timer (hwnd
, wParam
, lParam
);
2336 case WM_WININICHANGE
:
2337 return TOOLTIPS_WinIniChange (hwnd
, wParam
, lParam
);
2340 if (uMsg
>= WM_USER
)
2341 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
2342 uMsg
, wParam
, lParam
);
2343 return DefWindowProcA (hwnd
, uMsg
, wParam
, lParam
);
2350 TOOLTIPS_Register (void)
2354 if (GlobalFindAtomA (TOOLTIPS_CLASSA
)) return;
2356 ZeroMemory (&wndClass
, sizeof(WNDCLASSA
));
2357 wndClass
.style
= CS_GLOBALCLASS
| CS_DBLCLKS
| CS_SAVEBITS
;
2358 wndClass
.lpfnWndProc
= (WNDPROC
)TOOLTIPS_WindowProc
;
2359 wndClass
.cbClsExtra
= 0;
2360 wndClass
.cbWndExtra
= sizeof(TOOLTIPS_INFO
*);
2361 wndClass
.hCursor
= LoadCursorA (0, IDC_ARROWA
);
2362 wndClass
.hbrBackground
= 0;
2363 wndClass
.lpszClassName
= TOOLTIPS_CLASSA
;
2365 RegisterClassA (&wndClass
);
2370 TOOLTIPS_Unregister (void)
2372 if (GlobalFindAtomA (TOOLTIPS_CLASSA
))
2373 UnregisterClassA (TOOLTIPS_CLASSA
, (HINSTANCE
)NULL
);