4 * Copyright 1998 Eric Kohl
7 * - Tracking tooltips (finished, except smart placement).
8 * - Transparent tooltips (under construction).
9 * - TTS_ALWAYSTIP (undefined).
11 * - Custom draw support.
12 * - The "lParam" variable from NMTTDISPINFO32A is not handled
13 * in TOOLTIPS_GetTipText.
16 * - Run tests using Waite Group Windows95 API Bible Volume 2.
17 * The second cdrom (chapter 3) contains executables activate.exe,
18 * curtool.exe, deltool.exe, enumtools.exe, getinfo.exe, getiptxt.exe,
19 * hittest.exe, needtext.exe, newrect.exe, updtext.exe and winfrpt.exe.
29 #define ID_TIMER1 1 /* show delay timer */
30 #define ID_TIMER2 2 /* auto pop timer */
31 #define ID_TIMER3 3 /* tool leave timer */
33 /* property name of tooltip window handle */
34 #define TT_SUBCLASS_PROP "CC32SubclassInfo"
36 #define TOOLTIPS_GetInfoPtr(wndPtr) ((TOOLTIPS_INFO *)wndPtr->wExtra[0])
40 TOOLTIPS_SubclassProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam);
44 TOOLTIPS_Refresh (WND *wndPtr, HDC32 hdc)
46 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
50 UINT32 uFlags = DT_EXTERNALLEADING;
52 if (infoPtr->nMaxTipWidth > -1)
53 uFlags |= DT_WORDBREAK;
54 if (wndPtr->dwStyle & TTS_NOPREFIX)
55 uFlags |= DT_NOPREFIX;
56 GetClientRect32 (wndPtr->hwndSelf, &rc);
57 rc.left += (2 + infoPtr->rcMargin.left);
58 rc.top += (2 + infoPtr->rcMargin.top);
59 rc.right -= (2 + infoPtr->rcMargin.right);
60 rc.bottom -= (2 + infoPtr->rcMargin.bottom);
61 oldBkMode = SetBkMode32 (hdc, TRANSPARENT);
62 SetTextColor32 (hdc, infoPtr->clrText);
63 hOldFont = SelectObject32 (hdc, infoPtr->hFont);
64 DrawText32A (hdc, infoPtr->szTipText, -1, &rc, uFlags);
65 SelectObject32 (hdc, hOldFont);
66 if (oldBkMode != TRANSPARENT)
67 SetBkMode32 (hdc, oldBkMode);
72 TOOLTIPS_GetTipText (WND *wndPtr, TOOLTIPS_INFO *infoPtr, INT32 nTool)
74 TTTOOL_INFO *toolPtr = &infoPtr->tools[nTool];
76 if ((toolPtr->hinst) && (HIWORD((UINT32)toolPtr->lpszText) == 0)) {
77 TRACE (tooltips, "get res string %x %x\n",
78 toolPtr->hinst, (int)toolPtr->lpszText);
79 LoadString32A (toolPtr->hinst, (UINT32)toolPtr->lpszText,
80 infoPtr->szTipText, INFOTIPSIZE);
82 else if (toolPtr->lpszText) {
83 if (toolPtr->lpszText == LPSTR_TEXTCALLBACK32A) {
84 NMTTDISPINFO32A ttnmdi;
86 /* fill NMHDR struct */
87 ZeroMemory (&ttnmdi, sizeof(NMTTDISPINFO32A));
88 ttnmdi.hdr.hwndFrom = wndPtr->hwndSelf;
89 ttnmdi.hdr.idFrom = toolPtr->uId;
90 ttnmdi.hdr.code = TTN_GETDISPINFO32A;
91 ttnmdi.uFlags = toolPtr->uFlags;
92 ttnmdi.lpszText = infoPtr->szTipText;
94 TRACE (tooltips, "hdr.idFrom = %x\n", ttnmdi.hdr.idFrom);
95 SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
96 (WPARAM32)toolPtr->uId, (LPARAM)&ttnmdi);
98 if ((ttnmdi.hinst) && (HIWORD((UINT32)ttnmdi.szText) == 0)) {
99 LoadString32A (ttnmdi.hinst, (UINT32)ttnmdi.szText,
100 infoPtr->szTipText, INFOTIPSIZE);
101 if (ttnmdi.uFlags & TTF_DI_SETITEM) {
102 toolPtr->hinst = ttnmdi.hinst;
103 toolPtr->lpszText = ttnmdi.szText;
106 else if (ttnmdi.szText[0]) {
107 lstrcpyn32A (infoPtr->szTipText, ttnmdi.szText, 80);
108 if (ttnmdi.uFlags & TTF_DI_SETITEM) {
109 INT32 len = lstrlen32A (ttnmdi.szText) + 1;
111 toolPtr->lpszText = COMCTL32_Alloc (len);
112 lstrcpy32A (toolPtr->lpszText, ttnmdi.szText);
115 else if (ttnmdi.lpszText == 0) {
116 /* no text available */
117 infoPtr->szTipText[0] = '\0';
119 else if (ttnmdi.lpszText != LPSTR_TEXTCALLBACK32A) {
120 if (ttnmdi.lpszText != infoPtr->szTipText)
121 lstrcpyn32A (infoPtr->szTipText, ttnmdi.lpszText,
123 if (ttnmdi.uFlags & TTF_DI_SETITEM) {
124 INT32 len = lstrlen32A (ttnmdi.lpszText) + 1;
126 toolPtr->lpszText = COMCTL32_Alloc (len);
127 lstrcpy32A (toolPtr->lpszText, ttnmdi.lpszText);
131 ERR (tooltips, "recursive text callback!\n");
132 infoPtr->szTipText[0] = '\0';
136 lstrcpyn32A (infoPtr->szTipText, toolPtr->lpszText, INFOTIPSIZE);
139 /* no text available */
140 infoPtr->szTipText[0] = '\0';
142 TRACE (tooltips, "\"%s\"\n", infoPtr->szTipText);
147 TOOLTIPS_CalcTipSize (WND *wndPtr, TOOLTIPS_INFO *infoPtr, LPSIZE32 lpSize)
151 UINT32 uFlags = DT_EXTERNALLEADING | DT_CALCRECT;
152 RECT32 rc = {0, 0, 0, 0};
154 if (infoPtr->nMaxTipWidth > -1) {
155 rc.right = infoPtr->nMaxTipWidth;
156 uFlags |= DT_WORDBREAK;
158 if (wndPtr->dwStyle & TTS_NOPREFIX)
159 uFlags |= DT_NOPREFIX;
160 TRACE (tooltips, "\"%s\"\n", infoPtr->szTipText);
162 hdc = GetDC32 (wndPtr->hwndSelf);
163 hOldFont = SelectObject32 (hdc, infoPtr->hFont);
164 DrawText32A (hdc, infoPtr->szTipText, -1, &rc, uFlags);
165 GetTextExtentPoint32A (hdc, infoPtr->szTipText, lstrlen32A(infoPtr->szTipText), lpSize);
166 SelectObject32 (hdc, hOldFont);
167 ReleaseDC32 (wndPtr->hwndSelf, hdc);
169 lpSize->cx = rc.right - rc.left + 4 +
170 infoPtr->rcMargin.left + infoPtr->rcMargin.right;
171 lpSize->cy = rc.bottom - rc.top + 4 +
172 infoPtr->rcMargin.bottom + infoPtr->rcMargin.top;
177 TOOLTIPS_Show (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
179 TTTOOL_INFO *toolPtr;
184 if (infoPtr->nTool == -1) {
185 TRACE (tooltips, "invalid tool (-1)!\n");
189 infoPtr->nCurrentTool = infoPtr->nTool;
191 TRACE (tooltips, "Show tooltip pre %d!\n", infoPtr->nTool);
193 TOOLTIPS_GetTipText (wndPtr, infoPtr, infoPtr->nCurrentTool);
195 if (infoPtr->szTipText[0] == '\0') {
196 infoPtr->nCurrentTool = -1;
200 TRACE (tooltips, "Show tooltip %d!\n", infoPtr->nCurrentTool);
201 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
203 hdr.hwndFrom = wndPtr->hwndSelf;
204 hdr.idFrom = toolPtr->uId;
206 SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
207 (WPARAM32)toolPtr->uId, (LPARAM)&hdr);
209 TRACE (tooltips, "\"%s\"\n", infoPtr->szTipText);
211 TOOLTIPS_CalcTipSize (wndPtr, infoPtr, &size);
212 TRACE (tooltips, "size %d - %d\n", size.cx, size.cy);
214 if (toolPtr->uFlags & TTF_CENTERTIP) {
217 if (toolPtr->uFlags & TTF_IDISHWND)
218 GetWindowRect32 ((HWND32)toolPtr->uId, &rc);
221 MapWindowPoints32 (toolPtr->hwnd, (HWND32)0, (LPPOINT32)&rc, 2);
223 rect.left = (rc.left + rc.right - size.cx) / 2;
224 rect.top = rc.bottom + 2;
227 GetCursorPos32 ((LPPOINT32)&rect);
231 TRACE (tooltips, "pos %d - %d\n", rect.left, rect.top);
233 rect.right = rect.left + size.cx;
234 rect.bottom = rect.top + size.cy;
236 AdjustWindowRectEx32 (&rect, wndPtr->dwStyle, FALSE, wndPtr->dwExStyle);
238 SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, rect.left, rect.top,
239 rect.right - rect.left, rect.bottom - rect.top,
242 SetTimer32 (wndPtr->hwndSelf, ID_TIMER2, infoPtr->nAutoPopTime, 0);
247 TOOLTIPS_Hide (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
249 TTTOOL_INFO *toolPtr;
252 if (infoPtr->nCurrentTool == -1)
255 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
256 TRACE (tooltips, "Hide tooltip %d!\n", infoPtr->nCurrentTool);
257 KillTimer32 (wndPtr->hwndSelf, ID_TIMER2);
259 hdr.hwndFrom = wndPtr->hwndSelf;
260 hdr.idFrom = toolPtr->uId;
262 SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
263 (WPARAM32)toolPtr->uId, (LPARAM)&hdr);
265 infoPtr->nCurrentTool = -1;
267 SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0,
268 SWP_NOZORDER | SWP_HIDEWINDOW);
273 TOOLTIPS_TrackShow (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
275 TTTOOL_INFO *toolPtr;
280 if (infoPtr->nTrackTool == -1) {
281 TRACE (tooltips, "invalid tracking tool (-1)!\n");
285 TRACE (tooltips, "show tracking tooltip pre %d!\n", infoPtr->nTrackTool);
287 TOOLTIPS_GetTipText (wndPtr, infoPtr, infoPtr->nTrackTool);
289 if (infoPtr->szTipText[0] == '\0') {
290 infoPtr->nTrackTool = -1;
294 TRACE (tooltips, "show tracking tooltip %d!\n", infoPtr->nTrackTool);
295 toolPtr = &infoPtr->tools[infoPtr->nTrackTool];
297 hdr.hwndFrom = wndPtr->hwndSelf;
298 hdr.idFrom = toolPtr->uId;
300 SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
301 (WPARAM32)toolPtr->uId, (LPARAM)&hdr);
303 TRACE (tooltips, "\"%s\"\n", infoPtr->szTipText);
305 TOOLTIPS_CalcTipSize (wndPtr, infoPtr, &size);
306 TRACE (tooltips, "size %d - %d\n", size.cx, size.cy);
308 if (toolPtr->uFlags & TTF_ABSOLUTE) {
309 rect.left = infoPtr->xTrackPos;
310 rect.top = infoPtr->yTrackPos;
312 if (toolPtr->uFlags & TTF_CENTERTIP) {
313 rect.left -= (size.cx / 2);
314 rect.top -= (size.cy / 2);
319 /* FIXME: do smart placement */
322 if (toolPtr->uFlags & TTF_IDISHWND)
323 GetWindowRect32 ((HWND32)toolPtr->uId, &rcTool);
325 rcTool = toolPtr->rect;
326 MapWindowPoints32 (toolPtr->hwnd, (HWND32)0, (LPPOINT32)&rcTool, 2);
329 GetCursorPos32 ((LPPOINT32)&rect);
332 /* smart placement */
333 if ((rect.left + size.cx > rcTool.left) && (rect.left < rcTool.right))
334 rect.left = rcTool.right;
336 if ((rect.top + size.cy > rcTool.top) &&
337 (rect.top < rcTool.bottom))
338 rect.top = rcTool.bottom;
341 if (toolPtr->uFlags & TTF_CENTERTIP) {
347 TRACE (tooltips, "pos %d - %d\n", rect.left, rect.top);
349 rect.right = rect.left + size.cx;
350 rect.bottom = rect.top + size.cy;
352 AdjustWindowRectEx32 (&rect, wndPtr->dwStyle, FALSE, wndPtr->dwExStyle);
354 SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, rect.left, rect.top,
355 rect.right - rect.left, rect.bottom - rect.top,
361 TOOLTIPS_TrackHide (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
363 TTTOOL_INFO *toolPtr;
366 if (infoPtr->nTrackTool == -1)
369 toolPtr = &infoPtr->tools[infoPtr->nTrackTool];
370 TRACE (tooltips, "hide tracking tooltip %d!\n", infoPtr->nTrackTool);
372 hdr.hwndFrom = wndPtr->hwndSelf;
373 hdr.idFrom = toolPtr->uId;
375 SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
376 (WPARAM32)toolPtr->uId, (LPARAM)&hdr);
378 SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0,
379 SWP_NOZORDER | SWP_HIDEWINDOW);
384 TOOLTIPS_GetToolFromInfoA (TOOLTIPS_INFO *infoPtr, LPTTTOOLINFO32A lpToolInfo)
386 TTTOOL_INFO *toolPtr;
389 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
390 toolPtr = &infoPtr->tools[nTool];
392 if (!(toolPtr->uFlags & TTF_IDISHWND) &&
393 (lpToolInfo->hwnd == toolPtr->hwnd) &&
394 (lpToolInfo->uId == toolPtr->uId))
398 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
399 toolPtr = &infoPtr->tools[nTool];
401 if ((toolPtr->uFlags & TTF_IDISHWND) &&
402 (lpToolInfo->uId == toolPtr->uId))
411 TOOLTIPS_GetToolFromPoint (TOOLTIPS_INFO *infoPtr, HWND32 hwnd, LPPOINT32 lpPt)
413 TTTOOL_INFO *toolPtr;
416 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
417 toolPtr = &infoPtr->tools[nTool];
419 if (!(toolPtr->uFlags & TTF_IDISHWND)) {
420 if (hwnd != toolPtr->hwnd)
422 if (!PtInRect32 (&toolPtr->rect, *lpPt))
428 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
429 toolPtr = &infoPtr->tools[nTool];
431 if (toolPtr->uFlags & TTF_IDISHWND) {
432 if ((HWND32)toolPtr->uId == hwnd)
442 TOOLTIPS_GetToolFromMessage (TOOLTIPS_INFO *infoPtr, HWND32 hwndTool)
447 dwPos = GetMessagePos ();
448 pt.x = (INT32)LOWORD(dwPos);
449 pt.y = (INT32)HIWORD(dwPos);
450 ScreenToClient32 (hwndTool, &pt);
452 return TOOLTIPS_GetToolFromPoint (infoPtr, hwndTool, &pt);
457 TOOLTIPS_CheckTool (WND *wndPtr, BOOL32 bShowTest)
459 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
464 GetCursorPos32 (&pt);
466 SendMessage32A (wndPtr->hwndSelf, TTM_WINDOWFROMPOINT, 0, (LPARAM)&pt);
470 ScreenToClient32 (hwndTool, &pt);
471 nTool = TOOLTIPS_GetToolFromPoint (infoPtr, hwndTool, &pt);
476 if (!(wndPtr->dwStyle & TTS_ALWAYSTIP) && bShowTest) {
477 if (!IsWindowEnabled32 (infoPtr->tools[infoPtr->nTool].hwnd))
482 TRACE (tooltips, "tool %d\n", nTool);
489 TOOLTIPS_Activate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
491 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
493 infoPtr->bActive = (BOOL32)wParam;
495 if (infoPtr->bActive)
496 TRACE (tooltips, "activate!\n");
498 if (!(infoPtr->bActive) && (infoPtr->nCurrentTool != -1))
499 TOOLTIPS_Hide (wndPtr, infoPtr);
506 TOOLTIPS_AddTool32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
508 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
509 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
510 TTTOOL_INFO *toolPtr;
512 if (lpToolInfo == NULL)
514 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
517 TRACE (tooltips, "add tool (%x) %x %d%s!\n",
518 wndPtr->hwndSelf, lpToolInfo->hwnd, lpToolInfo->uId,
519 (lpToolInfo->uFlags & TTF_IDISHWND) ? " TTF_IDISHWND" : "");
521 if (infoPtr->uNumTools == 0) {
522 infoPtr->tools = COMCTL32_Alloc (sizeof(TTTOOL_INFO));
523 toolPtr = infoPtr->tools;
526 TTTOOL_INFO *oldTools = infoPtr->tools;
528 COMCTL32_Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools + 1));
529 memcpy (infoPtr->tools, oldTools,
530 infoPtr->uNumTools * sizeof(TTTOOL_INFO));
531 COMCTL32_Free (oldTools);
532 toolPtr = &infoPtr->tools[infoPtr->uNumTools];
535 infoPtr->uNumTools++;
538 toolPtr->uFlags = lpToolInfo->uFlags;
539 toolPtr->hwnd = lpToolInfo->hwnd;
540 toolPtr->uId = lpToolInfo->uId;
541 toolPtr->rect = lpToolInfo->rect;
542 toolPtr->hinst = lpToolInfo->hinst;
544 if ((lpToolInfo->hinst) && (HIWORD((INT32)lpToolInfo->lpszText) == 0)) {
545 TRACE (tooltips, "add string id %x!\n", (int)lpToolInfo->lpszText);
546 toolPtr->lpszText = lpToolInfo->lpszText;
548 else if (lpToolInfo->lpszText) {
549 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACK32A) {
550 TRACE (tooltips, "add CALLBACK!\n");
551 toolPtr->lpszText = lpToolInfo->lpszText;
554 INT32 len = lstrlen32A (lpToolInfo->lpszText);
555 TRACE (tooltips, "add text \"%s\"!\n", lpToolInfo->lpszText);
556 toolPtr->lpszText = COMCTL32_Alloc (len + 1);
557 lstrcpy32A (toolPtr->lpszText, lpToolInfo->lpszText);
561 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A))
562 toolPtr->lParam = lpToolInfo->lParam;
564 /* install subclassing hook */
565 if (toolPtr->uFlags & TTF_SUBCLASS) {
566 if (toolPtr->uFlags & TTF_IDISHWND) {
567 LPTT_SUBCLASS_INFO lpttsi =
568 (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
569 if (lpttsi == NULL) {
571 (LPTT_SUBCLASS_INFO)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO));
573 (WNDPROC32)SetWindowLong32A ((HWND32)toolPtr->uId,
574 GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc);
575 lpttsi->hwndToolTip = wndPtr->hwndSelf;
577 SetProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP,
581 WARN (tooltips, "A window tool must only be listed once!\n");
584 LPTT_SUBCLASS_INFO lpttsi =
585 (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, TT_SUBCLASS_PROP);
586 if (lpttsi == NULL) {
588 (LPTT_SUBCLASS_INFO)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO));
590 (WNDPROC32)SetWindowLong32A (toolPtr->hwnd,
591 GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc);
592 lpttsi->hwndToolTip = wndPtr->hwndSelf;
594 SetProp32A (toolPtr->hwnd, TT_SUBCLASS_PROP, (HANDLE32)lpttsi);
599 TRACE (tooltips, "subclassing installed!\n");
606 // << TOOLTIPS_AddTool32W >>
610 TOOLTIPS_DelTool32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
612 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
613 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
614 TTTOOL_INFO *toolPtr;
617 if (lpToolInfo == NULL)
619 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
621 if (infoPtr->uNumTools == 0)
624 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
625 if (nTool == -1) return 0;
627 TRACE (tooltips, "tool %d\n", nTool);
629 /* delete text string */
630 toolPtr = &infoPtr->tools[nTool];
631 if ((toolPtr->hinst) && (toolPtr->lpszText)) {
632 if (toolPtr->lpszText != LPSTR_TEXTCALLBACK32A)
633 COMCTL32_Free (toolPtr->lpszText);
636 /* remove subclassing */
637 if (toolPtr->uFlags & TTF_SUBCLASS) {
638 if (toolPtr->uFlags & TTF_IDISHWND) {
639 LPTT_SUBCLASS_INFO lpttsi =
640 (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
642 SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
643 (LONG)lpttsi->wpOrigProc);
644 RemoveProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
645 COMCTL32_Free (&lpttsi);
648 ERR (tooltips, "Invalid data handle!\n");
651 LPTT_SUBCLASS_INFO lpttsi =
652 (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, TT_SUBCLASS_PROP);
654 if (lpttsi->uRefCount == 1) {
655 SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
656 (LONG)lpttsi->wpOrigProc);
657 RemoveProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
658 COMCTL32_Free (&lpttsi);
664 ERR (tooltips, "Invalid data handle!\n");
668 /* delete tool from tool list */
669 if (infoPtr->uNumTools == 1) {
670 COMCTL32_Free (infoPtr->tools);
671 infoPtr->tools = NULL;
674 TTTOOL_INFO *oldTools = infoPtr->tools;
676 COMCTL32_Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1));
679 memcpy (&infoPtr->tools[0], &oldTools[0],
680 nTool * sizeof(TTTOOL_INFO));
682 if (nTool < infoPtr->uNumTools - 1)
683 memcpy (&infoPtr->tools[nTool], &oldTools[nTool + 1],
684 (infoPtr->uNumTools - nTool - 1) * sizeof(TTTOOL_INFO));
686 COMCTL32_Free (oldTools);
689 infoPtr->uNumTools--;
695 // << TOOLTIPS_DelTool32W >>
699 TOOLTIPS_EnumTools32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
701 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
702 UINT32 uIndex = (UINT32)wParam;
703 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
704 TTTOOL_INFO *toolPtr;
706 if (lpToolInfo == NULL)
708 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
710 if (uIndex >= infoPtr->uNumTools)
713 TRACE (tooltips, "index=%u\n", uIndex);
715 toolPtr = &infoPtr->tools[uIndex];
718 lpToolInfo->uFlags = toolPtr->uFlags;
719 lpToolInfo->hwnd = toolPtr->hwnd;
720 lpToolInfo->uId = toolPtr->uId;
721 lpToolInfo->rect = toolPtr->rect;
722 lpToolInfo->hinst = toolPtr->hinst;
723 lpToolInfo->lpszText = toolPtr->lpszText;
725 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A))
726 lpToolInfo->lParam = toolPtr->lParam;
732 // << TOOLTIPS_EnumTools32W >>
736 TOOLTIPS_GetCurrentTool32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
738 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
739 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
740 TTTOOL_INFO *toolPtr;
742 if (lpToolInfo == NULL)
744 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
748 if (infoPtr->nCurrentTool > -1) {
749 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
752 lpToolInfo->uFlags = toolPtr->uFlags;
753 lpToolInfo->rect = toolPtr->rect;
754 lpToolInfo->hinst = toolPtr->hinst;
755 lpToolInfo->lpszText = toolPtr->lpszText;
757 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A))
758 lpToolInfo->lParam = toolPtr->lParam;
766 return (infoPtr->nCurrentTool != -1);
772 // << TOOLTIPS_GetCurrentTool32W >>
776 TOOLTIPS_GetDelayTime (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
778 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
782 return infoPtr->nAutomaticTime;
785 return infoPtr->nReshowTime;
788 return infoPtr->nAutoPopTime;
791 return infoPtr->nInitialTime;
799 TOOLTIPS_GetMargin (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
801 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
802 LPRECT32 lpRect = (LPRECT32)lParam;
804 lpRect->left = infoPtr->rcMargin.left;
805 lpRect->right = infoPtr->rcMargin.right;
806 lpRect->bottom = infoPtr->rcMargin.bottom;
807 lpRect->top = infoPtr->rcMargin.top;
813 __inline__ static LRESULT
814 TOOLTIPS_GetMaxTipWidth (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
816 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
818 return infoPtr->nMaxTipWidth;
823 TOOLTIPS_GetText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
825 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
826 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
829 if (lpToolInfo == NULL)
831 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
834 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
835 if (nTool == -1) return 0;
837 lstrcpy32A (lpToolInfo->lpszText, infoPtr->tools[nTool].lpszText);
843 // << TOOLTIPS_GetText32W >>
846 __inline__ static LRESULT
847 TOOLTIPS_GetTipBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
849 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
850 return infoPtr->clrBk;
854 __inline__ static LRESULT
855 TOOLTIPS_GetTipTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
857 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
858 return infoPtr->clrText;
862 __inline__ static LRESULT
863 TOOLTIPS_GetToolCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
865 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
866 return infoPtr->uNumTools;
871 TOOLTIPS_GetToolInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
873 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
874 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
875 TTTOOL_INFO *toolPtr;
878 if (lpToolInfo == NULL)
880 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
882 if (infoPtr->uNumTools == 0)
885 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
886 if (nTool == -1) return FALSE;
888 TRACE (tooltips, "tool %d\n", nTool);
890 toolPtr = &infoPtr->tools[nTool];
893 lpToolInfo->uFlags = toolPtr->uFlags;
894 lpToolInfo->rect = toolPtr->rect;
895 lpToolInfo->hinst = toolPtr->hinst;
896 lpToolInfo->lpszText = toolPtr->lpszText;
898 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A))
899 lpToolInfo->lParam = toolPtr->lParam;
905 // << TOOLTIPS_GetToolInfo32W >>
909 TOOLTIPS_HitTest32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
911 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
912 LPTTHITTESTINFO32A lptthit = (LPTTHITTESTINFO32A)lParam;
913 TTTOOL_INFO *toolPtr;
919 nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lptthit->hwnd, &lptthit->pt);
923 TRACE (tooltips, "tool %d!\n", nTool);
926 toolPtr = &infoPtr->tools[nTool];
927 lptthit->ti.cbSize = sizeof(TTTOOLINFO32A);
928 lptthit->ti.uFlags = toolPtr->uFlags;
929 lptthit->ti.hwnd = toolPtr->hwnd;
930 lptthit->ti.uId = toolPtr->uId;
931 lptthit->ti.rect = toolPtr->rect;
932 lptthit->ti.hinst = toolPtr->hinst;
933 lptthit->ti.lpszText = toolPtr->lpszText;
934 lptthit->ti.lParam = toolPtr->lParam;
940 // << TOOLTIPS_HitTest32W >>
944 TOOLTIPS_NewToolRect32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
946 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
947 LPTTTOOLINFO32A lpti = (LPTTTOOLINFO32A)lParam;
952 if (lpti->cbSize < TTTOOLINFO_V1_SIZE32A)
955 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpti);
956 if (nTool == -1) return 0;
958 infoPtr->tools[nTool].rect = lpti->rect;
964 // << TOOLTIPS_NewToolRect32W >>
967 __inline__ static LRESULT
968 TOOLTIPS_Pop (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
970 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
972 TOOLTIPS_Hide (wndPtr, infoPtr);
979 TOOLTIPS_RelayEvent (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
981 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
982 LPMSG32 lpMsg = (LPMSG32)lParam;
986 ERR (tooltips, "lpMsg == NULL!\n");
990 switch (lpMsg->message) {
998 ScreenToClient32 (lpMsg->hwnd, &pt);
999 infoPtr->nOldTool = infoPtr->nTool;
1000 infoPtr->nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lpMsg->hwnd, &pt);
1001 TRACE (tooltips, "tool (%x) %d %d\n",
1002 wndPtr->hwndSelf, infoPtr->nOldTool, infoPtr->nTool);
1003 TOOLTIPS_Hide (wndPtr, infoPtr);
1008 ScreenToClient32 (lpMsg->hwnd, &pt);
1009 infoPtr->nOldTool = infoPtr->nTool;
1010 infoPtr->nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lpMsg->hwnd, &pt);
1011 TRACE (tooltips, "tool (%x) %d %d\n",
1012 wndPtr->hwndSelf, infoPtr->nOldTool, infoPtr->nTool);
1013 TRACE (tooltips, "WM_MOUSEMOVE (%04x %d %d)\n",
1014 wndPtr->hwndSelf, pt.x, pt.y);
1015 if ((infoPtr->bActive) && (infoPtr->nTool != infoPtr->nOldTool)) {
1016 if (infoPtr->nOldTool == -1) {
1017 SetTimer32 (wndPtr->hwndSelf, ID_TIMER1,
1018 infoPtr->nInitialTime, 0);
1019 TRACE (tooltips, "timer 1 started!\n");
1022 TOOLTIPS_Hide (wndPtr, infoPtr);
1023 SetTimer32 (wndPtr->hwndSelf, ID_TIMER1,
1024 infoPtr->nReshowTime, 0);
1025 TRACE (tooltips, "timer 2 started!\n");
1028 if (infoPtr->nCurrentTool != -1) {
1029 SetTimer32 (wndPtr->hwndSelf, ID_TIMER3, 100, 0);
1030 TRACE (tooltips, "timer 3 started!\n");
1040 TOOLTIPS_SetDelayTime (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1042 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1043 INT32 nTime = (INT32)LOWORD(lParam);
1046 case TTDT_AUTOMATIC:
1048 infoPtr->nAutomaticTime = 500;
1049 infoPtr->nReshowTime = 100;
1050 infoPtr->nAutoPopTime = 5000;
1051 infoPtr->nInitialTime = 500;
1054 infoPtr->nAutomaticTime = nTime;
1055 infoPtr->nReshowTime = nTime / 5;
1056 infoPtr->nAutoPopTime = nTime * 10;
1057 infoPtr->nInitialTime = nTime;
1062 infoPtr->nReshowTime = nTime;
1066 infoPtr->nAutoPopTime = nTime;
1070 infoPtr->nInitialTime = nTime;
1079 TOOLTIPS_SetMargin (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1081 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1082 LPRECT32 lpRect = (LPRECT32)lParam;
1084 infoPtr->rcMargin.left = lpRect->left;
1085 infoPtr->rcMargin.right = lpRect->right;
1086 infoPtr->rcMargin.bottom = lpRect->bottom;
1087 infoPtr->rcMargin.top = lpRect->top;
1093 __inline__ static LRESULT
1094 TOOLTIPS_SetMaxTipWidth (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1096 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1097 INT32 nTemp = infoPtr->nMaxTipWidth;
1099 infoPtr->nMaxTipWidth = (INT32)lParam;
1105 __inline__ static LRESULT
1106 TOOLTIPS_SetTipBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1108 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1110 infoPtr->clrBk = (COLORREF)wParam;
1116 __inline__ static LRESULT
1117 TOOLTIPS_SetTipTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1119 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1121 infoPtr->clrText = (COLORREF)wParam;
1128 TOOLTIPS_SetToolInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1130 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1131 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
1132 TTTOOL_INFO *toolPtr;
1135 if (lpToolInfo == NULL)
1137 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
1140 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1141 if (nTool == -1) return 0;
1143 TRACE (tooltips, "tool %d\n", nTool);
1145 toolPtr = &infoPtr->tools[nTool];
1147 /* copy tool data */
1148 toolPtr->uFlags = lpToolInfo->uFlags;
1149 toolPtr->hwnd = lpToolInfo->hwnd;
1150 toolPtr->uId = lpToolInfo->uId;
1151 toolPtr->rect = lpToolInfo->rect;
1152 toolPtr->hinst = lpToolInfo->hinst;
1154 if ((lpToolInfo->hinst) && (HIWORD((INT32)lpToolInfo->lpszText) == 0)) {
1155 TRACE (tooltips, "set string id %x!\n", (INT32)lpToolInfo->lpszText);
1156 toolPtr->lpszText = lpToolInfo->lpszText;
1158 else if (lpToolInfo->lpszText) {
1159 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACK32A)
1160 toolPtr->lpszText = lpToolInfo->lpszText;
1162 INT32 len = lstrlen32A (lpToolInfo->lpszText);
1163 COMCTL32_Free (toolPtr->lpszText);
1164 toolPtr->lpszText = COMCTL32_Alloc (len + 1);
1165 lstrcpy32A (toolPtr->lpszText, lpToolInfo->lpszText);
1169 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A))
1170 toolPtr->lParam = lpToolInfo->lParam;
1176 // << TOOLTIPS_SetToolInfo32W >>
1180 TOOLTIPS_TrackActivate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1182 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1183 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
1185 if (lpToolInfo == NULL)
1187 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
1190 if ((BOOL32)wParam) {
1192 infoPtr->nTrackTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1193 if (infoPtr->nTrackTool != -1) {
1194 TRACE (tooltips, "activated!\n");
1195 infoPtr->bTrackActive = TRUE;
1196 TOOLTIPS_TrackShow (wndPtr, infoPtr);
1201 TOOLTIPS_TrackHide (wndPtr, infoPtr);
1203 infoPtr->bTrackActive = FALSE;
1204 infoPtr->nTrackTool = -1;
1206 TRACE (tooltips, "deactivated!\n");
1214 TOOLTIPS_TrackPosition (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1216 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1218 infoPtr->xTrackPos = (INT32)LOWORD(lParam);
1219 infoPtr->yTrackPos = (INT32)HIWORD(lParam);
1221 if (infoPtr->bTrackActive) {
1222 TRACE (tooltips, "[%d %d]\n",
1223 infoPtr->xTrackPos, infoPtr->yTrackPos);
1225 TOOLTIPS_TrackShow (wndPtr, infoPtr);
1233 TOOLTIPS_Update (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1235 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1237 if (infoPtr->nCurrentTool != -1)
1238 UpdateWindow32 (wndPtr->hwndSelf);
1245 TOOLTIPS_UpdateTipText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1247 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1248 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
1249 TTTOOL_INFO *toolPtr;
1252 if (lpToolInfo == NULL)
1254 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
1257 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1258 if (nTool == -1) return 0;
1260 TRACE (tooltips, "tool %d\n", nTool);
1262 toolPtr = &infoPtr->tools[nTool];
1264 /* copy tool text */
1265 toolPtr->hinst = lpToolInfo->hinst;
1267 if ((lpToolInfo->hinst) && (HIWORD((INT32)lpToolInfo->lpszText) == 0)){
1268 toolPtr->lpszText = lpToolInfo->lpszText;
1270 else if (lpToolInfo->lpszText) {
1271 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACK32A)
1272 toolPtr->lpszText = lpToolInfo->lpszText;
1274 INT32 len = lstrlen32A (lpToolInfo->lpszText);
1275 COMCTL32_Free (toolPtr->lpszText);
1276 toolPtr->lpszText = COMCTL32_Alloc (len + 1);
1277 lstrcpy32A (toolPtr->lpszText, lpToolInfo->lpszText);
1285 // << TOOLTIPS_UpdateTipText32W >>
1289 TOOLTIPS_WindowFromPoint (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1291 return WindowFromPoint32 (*((LPPOINT32)lParam));
1297 TOOLTIPS_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1299 TOOLTIPS_INFO *infoPtr;
1300 NONCLIENTMETRICS32A nclm;
1302 /* allocate memory for info structure */
1303 infoPtr = (TOOLTIPS_INFO *)COMCTL32_Alloc (sizeof(TOOLTIPS_INFO));
1304 wndPtr->wExtra[0] = (DWORD)infoPtr;
1306 if (infoPtr == NULL) {
1307 ERR (tooltips, "could not allocate info memory!\n");
1311 /* initialize info structure */
1312 infoPtr->bActive = TRUE;
1313 infoPtr->bTrackActive = FALSE;
1314 infoPtr->clrBk = GetSysColor32 (COLOR_INFOBK);
1315 infoPtr->clrText = GetSysColor32 (COLOR_INFOTEXT);
1317 nclm.cbSize = sizeof(NONCLIENTMETRICS32A);
1318 SystemParametersInfo32A (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1319 infoPtr->hFont = CreateFontIndirect32A (&nclm.lfStatusFont);
1321 infoPtr->nMaxTipWidth = -1;
1322 infoPtr->nTool = -1;
1323 infoPtr->nOldTool = -1;
1324 infoPtr->nCurrentTool = -1;
1325 infoPtr->nTrackTool = -1;
1327 infoPtr->nAutomaticTime = 500;
1328 infoPtr->nReshowTime = 100;
1329 infoPtr->nAutoPopTime = 5000;
1330 infoPtr->nInitialTime = 500;
1332 SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0,
1333 SWP_NOZORDER | SWP_HIDEWINDOW);
1340 TOOLTIPS_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1342 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1343 TTTOOL_INFO *toolPtr;
1347 if (infoPtr->tools) {
1348 for (i = 0; i < infoPtr->uNumTools; i++) {
1349 toolPtr = &infoPtr->tools[i];
1350 if ((toolPtr->hinst) && (toolPtr->lpszText)) {
1351 if (toolPtr->lpszText != LPSTR_TEXTCALLBACK32A)
1352 COMCTL32_Free (toolPtr->lpszText);
1355 /* remove subclassing */
1356 if (toolPtr->uFlags & TTF_SUBCLASS) {
1357 LPTT_SUBCLASS_INFO lpttsi;
1359 if (toolPtr->uFlags & TTF_IDISHWND)
1360 lpttsi = (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
1362 lpttsi = (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, TT_SUBCLASS_PROP);
1365 SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
1366 (LONG)lpttsi->wpOrigProc);
1367 RemoveProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
1368 COMCTL32_Free (&lpttsi);
1372 COMCTL32_Free (infoPtr->tools);
1376 DeleteObject32 (infoPtr->hFont);
1378 /* free tool tips info data */
1379 COMCTL32_Free (infoPtr);
1386 TOOLTIPS_EraseBackground (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1388 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1392 hBrush = CreateSolidBrush32 (infoPtr->clrBk);
1393 GetClientRect32 (wndPtr->hwndSelf, &rect);
1394 FillRect32 ((HDC32)wParam, &rect, hBrush);
1395 DeleteObject32 (hBrush);
1402 TOOLTIPS_GetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1404 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1406 return infoPtr->hFont;
1411 TOOLTIPS_MouseMessage (WND *wndPtr, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
1413 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1414 TTTOOL_INFO *toolPtr = &infoPtr->tools[infoPtr->nTool];
1416 if (toolPtr->uFlags & TTF_TRANSPARENT) {
1417 FIXME (tooltips, "transparent tooltips not implemented yet!\n");
1422 pt.x = (INT32)LOWORD(lParam);
1423 pt.y = (INT32)HIWORD(lParam);
1425 GetClientRect32 (toolPtr->hwnd, &rc);
1426 ScreenToClient32 (toolPtr->hwnd, &pt);
1427 if (PtInRect32 (&rc, pt))
1428 SendMessage32A (toolPtr->hwnd, uMsg, wParam, lParam);
1432 TOOLTIPS_Hide (wndPtr, infoPtr);
1439 TOOLTIPS_NcCreate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1441 wndPtr->dwStyle &= 0x0000FFFF;
1442 wndPtr->dwStyle |= (WS_POPUP | WS_BORDER | WS_CLIPSIBLINGS);
1449 TOOLTIPS_Paint (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1454 hdc = (wParam == 0) ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
1455 TOOLTIPS_Refresh (wndPtr, hdc);
1457 EndPaint32 (wndPtr->hwndSelf, &ps);
1463 TOOLTIPS_SetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1465 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1467 infoPtr->hFont = (HFONT32)wParam;
1469 if ((LOWORD(lParam)) & (infoPtr->nCurrentTool != -1)) {
1470 FIXME (tooltips, "full redraw needed!\n");
1478 TOOLTIPS_Timer (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1480 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1482 TRACE (tooltips, "timer %d (%x) expired!\n", wParam, wndPtr->hwndSelf);
1487 KillTimer32 (wndPtr->hwndSelf, ID_TIMER1);
1488 if (TOOLTIPS_CheckTool (wndPtr, TRUE) == infoPtr->nTool)
1489 TOOLTIPS_Show (wndPtr, infoPtr);
1493 TOOLTIPS_Hide (wndPtr, infoPtr);
1497 KillTimer32 (wndPtr->hwndSelf, ID_TIMER3);
1498 if (TOOLTIPS_CheckTool (wndPtr, FALSE) == -1) {
1499 infoPtr->nTool = -1;
1500 infoPtr->nOldTool = -1;
1501 TOOLTIPS_Hide (wndPtr, infoPtr);
1510 TOOLTIPS_WinIniChange (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1512 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1513 NONCLIENTMETRICS32A nclm;
1515 infoPtr->clrBk = GetSysColor32 (COLOR_INFOBK);
1516 infoPtr->clrText = GetSysColor32 (COLOR_INFOTEXT);
1518 DeleteObject32 (infoPtr->hFont);
1519 nclm.cbSize = sizeof(NONCLIENTMETRICS32A);
1520 SystemParametersInfo32A (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1521 infoPtr->hFont = CreateFontIndirect32A (&nclm.lfStatusFont);
1528 TOOLTIPS_SubclassProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
1530 LPTT_SUBCLASS_INFO lpttsi =
1531 (LPTT_SUBCLASS_INFO)GetProp32A (hwnd, TT_SUBCLASS_PROP);
1533 TOOLTIPS_INFO *infoPtr;
1537 case WM_LBUTTONDOWN:
1539 case WM_MBUTTONDOWN:
1541 case WM_RBUTTONDOWN:
1544 wndPtr = WIN_FindWndPtr(lpttsi->hwndToolTip);
1545 infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1546 nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd);
1548 TRACE (tooltips, "subclassed mouse message %04x\n", uMsg);
1549 infoPtr->nOldTool = infoPtr->nTool;
1550 infoPtr->nTool = nTool;
1551 TOOLTIPS_Hide (wndPtr, infoPtr);
1557 wndPtr = WIN_FindWndPtr(lpttsi->hwndToolTip);
1558 infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1559 nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd);
1561 TRACE (tooltips, "subclassed WM_MOUSEMOVE\n");
1562 infoPtr->nOldTool = infoPtr->nTool;
1563 infoPtr->nTool = nTool;
1565 if ((infoPtr->bActive) &&
1566 (infoPtr->nTool != infoPtr->nOldTool)) {
1567 if (infoPtr->nOldTool == -1) {
1568 SetTimer32 (wndPtr->hwndSelf, ID_TIMER1,
1569 infoPtr->nInitialTime, 0);
1570 TRACE (tooltips, "timer 1 started!\n");
1573 TOOLTIPS_Hide (wndPtr, infoPtr);
1574 SetTimer32 (wndPtr->hwndSelf, ID_TIMER1,
1575 infoPtr->nReshowTime, 0);
1576 TRACE (tooltips, "timer 2 started!\n");
1579 if (infoPtr->nCurrentTool != -1) {
1580 SetTimer32 (wndPtr->hwndSelf, ID_TIMER3, 100, 0);
1581 TRACE (tooltips, "timer 3 started!\n");
1587 return CallWindowProc32A (lpttsi->wpOrigProc, hwnd, uMsg, wParam, lParam);
1592 TOOLTIPS_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
1594 WND *wndPtr = WIN_FindWndPtr(hwnd);
1599 return TOOLTIPS_Activate (wndPtr, wParam, lParam);
1601 case TTM_ADDTOOL32A:
1602 return TOOLTIPS_AddTool32A (wndPtr, wParam, lParam);
1604 // case TTM_ADDTOOL32W:
1606 case TTM_DELTOOL32A:
1607 return TOOLTIPS_DelTool32A (wndPtr, wParam, lParam);
1609 // case TTM_DELTOOL32W:
1611 case TTM_ENUMTOOLS32A:
1612 return TOOLTIPS_EnumTools32A (wndPtr, wParam, lParam);
1614 // case TTM_ENUMTOOLS32W:
1616 case TTM_GETCURRENTTOOL32A:
1617 return TOOLTIPS_GetCurrentTool32A (wndPtr, wParam, lParam);
1619 // case TTM_GETCURRENTTOOL32W:
1621 case TTM_GETDELAYTIME:
1622 return TOOLTIPS_GetDelayTime (wndPtr, wParam, lParam);
1625 return TOOLTIPS_GetMargin (wndPtr, wParam, lParam);
1627 case TTM_GETMAXTIPWIDTH:
1628 return TOOLTIPS_GetMaxTipWidth (wndPtr, wParam, lParam);
1630 case TTM_GETTEXT32A:
1631 return TOOLTIPS_GetText32A (wndPtr, wParam, lParam);
1633 // case TTM_GETTEXT32W:
1635 case TTM_GETTIPBKCOLOR:
1636 return TOOLTIPS_GetTipBkColor (wndPtr, wParam, lParam);
1638 case TTM_GETTIPTEXTCOLOR:
1639 return TOOLTIPS_GetTipTextColor (wndPtr, wParam, lParam);
1641 case TTM_GETTOOLCOUNT:
1642 return TOOLTIPS_GetToolCount (wndPtr, wParam, lParam);
1644 case TTM_GETTOOLINFO32A:
1645 return TOOLTIPS_GetToolInfo32A (wndPtr, wParam, lParam);
1647 // case TTM_GETTOOLINFO32W:
1649 case TTM_HITTEST32A:
1650 return TOOLTIPS_HitTest32A (wndPtr, wParam, lParam);
1652 // case TTM_HITTEST32W:
1654 case TTM_NEWTOOLRECT32A:
1655 return TOOLTIPS_NewToolRect32A (wndPtr, wParam, lParam);
1657 // case TTM_NEWTOOLRECT32W:
1660 return TOOLTIPS_Pop (wndPtr, wParam, lParam);
1662 case TTM_RELAYEVENT:
1663 return TOOLTIPS_RelayEvent (wndPtr, wParam, lParam);
1665 case TTM_SETDELAYTIME:
1666 return TOOLTIPS_SetDelayTime (wndPtr, wParam, lParam);
1669 return TOOLTIPS_SetMargin (wndPtr, wParam, lParam);
1671 case TTM_SETMAXTIPWIDTH:
1672 return TOOLTIPS_SetMaxTipWidth (wndPtr, wParam, lParam);
1674 case TTM_SETTIPBKCOLOR:
1675 return TOOLTIPS_SetTipBkColor (wndPtr, wParam, lParam);
1677 case TTM_SETTIPTEXTCOLOR:
1678 return TOOLTIPS_SetTipTextColor (wndPtr, wParam, lParam);
1680 case TTM_SETTOOLINFO32A:
1681 return TOOLTIPS_SetToolInfo32A (wndPtr, wParam, lParam);
1683 // case TTM_SETTOOLINFO32W:
1685 case TTM_TRACKACTIVATE:
1686 return TOOLTIPS_TrackActivate (wndPtr, wParam, lParam);
1688 case TTM_TRACKPOSITION:
1689 return TOOLTIPS_TrackPosition (wndPtr, wParam, lParam);
1692 return TOOLTIPS_Update (wndPtr, wParam, lParam);
1694 case TTM_UPDATETIPTEXT32A:
1695 return TOOLTIPS_UpdateTipText32A (wndPtr, wParam, lParam);
1697 // case TTM_UPDATETIPTEXT32W:
1699 case TTM_WINDOWFROMPOINT:
1700 return TOOLTIPS_WindowFromPoint (wndPtr, wParam, lParam);
1704 return TOOLTIPS_Create (wndPtr, wParam, lParam);
1707 return TOOLTIPS_Destroy (wndPtr, wParam, lParam);
1710 return TOOLTIPS_EraseBackground (wndPtr, wParam, lParam);
1713 return TOOLTIPS_GetFont (wndPtr, wParam, lParam);
1716 // case WM_GETTEXTLENGTH:
1718 case WM_LBUTTONDOWN:
1720 case WM_MBUTTONDOWN:
1722 case WM_RBUTTONDOWN:
1725 return TOOLTIPS_MouseMessage (wndPtr, uMsg, wParam, lParam);
1728 return TOOLTIPS_NcCreate (wndPtr, wParam, lParam);
1730 // case WM_NCHITTEST:
1731 // case WM_NOTIFYFORMAT:
1734 return TOOLTIPS_Paint (wndPtr, wParam, lParam);
1736 // case WM_PRINTCLIENT:
1739 return TOOLTIPS_SetFont (wndPtr, wParam, lParam);
1741 // case WM_STYLECHANGED:
1744 return TOOLTIPS_Timer (wndPtr, wParam, lParam);
1746 case WM_WININICHANGE:
1747 return TOOLTIPS_WinIniChange (wndPtr, wParam, lParam);
1750 if (uMsg >= WM_USER)
1751 ERR (tooltips, "unknown msg %04x wp=%08x lp=%08lx\n",
1752 uMsg, wParam, lParam);
1753 return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
1760 TOOLTIPS_Register (VOID)
1762 WNDCLASS32A wndClass;
1764 if (GlobalFindAtom32A (TOOLTIPS_CLASS32A)) return;
1766 ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
1767 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS;
1768 wndClass.lpfnWndProc = (WNDPROC32)TOOLTIPS_WindowProc;
1769 wndClass.cbClsExtra = 0;
1770 wndClass.cbWndExtra = sizeof(TOOLTIPS_INFO *);
1771 wndClass.hCursor = LoadCursor32A (0, IDC_ARROW32A);
1772 wndClass.hbrBackground = 0;
1773 wndClass.lpszClassName = TOOLTIPS_CLASS32A;
1775 RegisterClass32A (&wndClass);
1780 TOOLTIPS_Unregister (VOID)
1782 if (GlobalFindAtom32A (TOOLTIPS_CLASS32A))
1783 UnregisterClass32A (TOOLTIPS_CLASS32A, (HINSTANCE32)NULL);