4 * Copyright 1998, 1999 Eric Kohl
7 * - Unicode support (started).
8 * - Custom draw support.
11 * - Run tests using Waite Group Windows95 API Bible Volume 2.
12 * The second cdrom (chapter 3) contains executables activate.exe,
13 * curtool.exe, deltool.exe, enumtools.exe, getinfo.exe, getiptxt.exe,
14 * hittest.exe, needtext.exe, newrect.exe, updtext.exe and winfrpt.exe.
22 #include "debugtools.h"
24 DEFAULT_DEBUG_CHANNEL(tooltips)
26 #define ID_TIMERSHOW 1 /* show delay timer */
27 #define ID_TIMERPOP 2 /* auto pop timer */
28 #define ID_TIMERLEAVE 3 /* tool leave timer */
31 extern LPSTR COMCTL32_aSubclass; /* global subclassing atom */
33 /* property name of tooltip window handle */
34 /*#define TT_SUBCLASS_PROP "CC32SubclassInfo" */
36 #define TOOLTIPS_GetInfoPtr(hWindow) ((TOOLTIPS_INFO *)GetWindowLongA (hWindow, 0))
40 TOOLTIPS_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
44 TOOLTIPS_Refresh (HWND hwnd, HDC hdc)
46 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(hwnd);
51 UINT uFlags = DT_EXTERNALLEADING;
53 if (infoPtr->nMaxTipWidth > -1)
54 uFlags |= DT_WORDBREAK;
55 if (GetWindowLongA (hwnd, GWL_STYLE) & TTS_NOPREFIX)
56 uFlags |= DT_NOPREFIX;
57 GetClientRect (hwnd, &rc);
59 /* fill the background */
60 hBrush = CreateSolidBrush (infoPtr->clrBk);
61 FillRect (hdc, &rc, hBrush);
62 DeleteObject (hBrush);
64 /* calculate text rectangle */
65 rc.left += (2 + infoPtr->rcMargin.left);
66 rc.top += (2 + infoPtr->rcMargin.top);
67 rc.right -= (2 + infoPtr->rcMargin.right);
68 rc.bottom -= (2 + infoPtr->rcMargin.bottom);
71 oldBkMode = SetBkMode (hdc, TRANSPARENT);
72 SetTextColor (hdc, infoPtr->clrText);
73 hOldFont = SelectObject (hdc, infoPtr->hFont);
74 DrawTextW (hdc, infoPtr->szTipText, -1, &rc, uFlags);
75 SelectObject (hdc, hOldFont);
76 if (oldBkMode != TRANSPARENT)
77 SetBkMode (hdc, oldBkMode);
82 TOOLTIPS_GetTipText (HWND hwnd, TOOLTIPS_INFO *infoPtr, INT nTool)
84 TTTOOL_INFO *toolPtr = &infoPtr->tools[nTool];
86 if ((toolPtr->hinst) && (HIWORD((UINT)toolPtr->lpszText) == 0)) {
88 TRACE("load res string %x %x\n",
89 toolPtr->hinst, (int)toolPtr->lpszText);
90 LoadStringW (toolPtr->hinst, (UINT)toolPtr->lpszText,
91 infoPtr->szTipText, INFOTIPSIZE);
93 else if (toolPtr->lpszText) {
94 if (toolPtr->lpszText == LPSTR_TEXTCALLBACKW) {
97 /* fill NMHDR struct */
98 ZeroMemory (&ttnmdi, sizeof(NMTTDISPINFOA));
99 ttnmdi.hdr.hwndFrom = hwnd;
100 ttnmdi.hdr.idFrom = toolPtr->uId;
101 ttnmdi.hdr.code = TTN_GETDISPINFOA;
102 ttnmdi.lpszText = (LPSTR)&ttnmdi.szText;
103 ttnmdi.uFlags = toolPtr->uFlags;
104 ttnmdi.lParam = toolPtr->lParam;
106 TRACE("hdr.idFrom = %x\n", ttnmdi.hdr.idFrom);
107 SendMessageA (toolPtr->hwnd, WM_NOTIFY,
108 (WPARAM)toolPtr->uId, (LPARAM)&ttnmdi);
110 if ((ttnmdi.hinst) && (HIWORD((UINT)ttnmdi.lpszText) == 0)) {
111 LoadStringW (ttnmdi.hinst, (UINT)ttnmdi.lpszText,
112 infoPtr->szTipText, INFOTIPSIZE);
113 if (ttnmdi.uFlags & TTF_DI_SETITEM) {
114 toolPtr->hinst = ttnmdi.hinst;
115 toolPtr->lpszText = (LPWSTR)ttnmdi.lpszText;
118 else if (ttnmdi.szText[0]) {
119 lstrcpynAtoW (infoPtr->szTipText, ttnmdi.szText, 80);
120 if (ttnmdi.uFlags & TTF_DI_SETITEM) {
121 INT len = lstrlenA (ttnmdi.szText);
123 toolPtr->lpszText = COMCTL32_Alloc ((len+1)* sizeof(WCHAR));
124 lstrcpyAtoW (toolPtr->lpszText, ttnmdi.szText);
127 else if (ttnmdi.lpszText == 0) {
128 /* no text available */
129 infoPtr->szTipText[0] = L'\0';
131 else if (ttnmdi.lpszText != LPSTR_TEXTCALLBACKA) {
132 lstrcpynAtoW (infoPtr->szTipText, ttnmdi.lpszText, INFOTIPSIZE);
133 if (ttnmdi.uFlags & TTF_DI_SETITEM) {
134 INT len = lstrlenA (ttnmdi.lpszText);
136 toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
137 lstrcpyAtoW (toolPtr->lpszText, ttnmdi.lpszText);
141 ERR("recursive text callback!\n");
142 infoPtr->szTipText[0] = '\0';
146 /* the item is a usual (unicode) text */
147 lstrcpynW (infoPtr->szTipText, toolPtr->lpszText, INFOTIPSIZE);
151 /* no text available */
152 infoPtr->szTipText[0] = L'\0';
155 TRACE("\"%s\"\n", debugstr_w(infoPtr->szTipText));
160 TOOLTIPS_CalcTipSize (HWND hwnd, TOOLTIPS_INFO *infoPtr, LPSIZE lpSize)
164 UINT uFlags = DT_EXTERNALLEADING | DT_CALCRECT;
165 RECT rc = {0, 0, 0, 0};
167 if (infoPtr->nMaxTipWidth > -1) {
168 rc.right = infoPtr->nMaxTipWidth;
169 uFlags |= DT_WORDBREAK;
171 if (GetWindowLongA (hwnd, GWL_STYLE) & TTS_NOPREFIX)
172 uFlags |= DT_NOPREFIX;
173 TRACE("\"%s\"\n", debugstr_w(infoPtr->szTipText));
176 hOldFont = SelectObject (hdc, infoPtr->hFont);
177 DrawTextW (hdc, infoPtr->szTipText, -1, &rc, uFlags);
178 SelectObject (hdc, hOldFont);
179 ReleaseDC (hwnd, hdc);
181 lpSize->cx = rc.right - rc.left + 4 +
182 infoPtr->rcMargin.left + infoPtr->rcMargin.right;
183 lpSize->cy = rc.bottom - rc.top + 4 +
184 infoPtr->rcMargin.bottom + infoPtr->rcMargin.top;
189 TOOLTIPS_Show (HWND hwnd, TOOLTIPS_INFO *infoPtr)
191 TTTOOL_INFO *toolPtr;
197 if (infoPtr->nTool == -1) {
198 TRACE("invalid tool (-1)!\n");
202 infoPtr->nCurrentTool = infoPtr->nTool;
204 TRACE("Show tooltip pre %d!\n", infoPtr->nTool);
206 TOOLTIPS_GetTipText (hwnd, infoPtr, infoPtr->nCurrentTool);
208 if (infoPtr->szTipText[0] == L'\0') {
209 infoPtr->nCurrentTool = -1;
213 TRACE("Show tooltip %d!\n", infoPtr->nCurrentTool);
214 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
217 hdr.idFrom = toolPtr->uId;
219 SendMessageA (toolPtr->hwnd, WM_NOTIFY,
220 (WPARAM)toolPtr->uId, (LPARAM)&hdr);
222 TRACE("\"%s\"\n", debugstr_w(infoPtr->szTipText));
224 TOOLTIPS_CalcTipSize (hwnd, infoPtr, &size);
225 TRACE("size %d - %d\n", size.cx, size.cy);
227 if (toolPtr->uFlags & TTF_CENTERTIP) {
230 if (toolPtr->uFlags & TTF_IDISHWND)
231 GetWindowRect ((HWND)toolPtr->uId, &rc);
234 MapWindowPoints (toolPtr->hwnd, (HWND)0, (LPPOINT)&rc, 2);
236 rect.left = (rc.left + rc.right - size.cx) / 2;
237 rect.top = rc.bottom + 2;
240 GetCursorPos ((LPPOINT)&rect);
244 /* 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 (HIWORD((INT)toolPtr->lpszText) != 0) )
790 COMCTL32_Free (toolPtr->lpszText);
793 /* remove subclassing */
794 if (toolPtr->uFlags & TTF_SUBCLASS) {
795 if (toolPtr->uFlags & TTF_IDISHWND) {
796 LPTT_SUBCLASS_INFO lpttsi =
797 (LPTT_SUBCLASS_INFO)GetPropA ((HWND)toolPtr->uId, COMCTL32_aSubclass);
799 SetWindowLongA ((HWND)toolPtr->uId, GWL_WNDPROC,
800 (LONG)lpttsi->wpOrigProc);
801 RemovePropA ((HWND)toolPtr->uId, COMCTL32_aSubclass);
802 COMCTL32_Free (&lpttsi);
805 ERR("Invalid data handle!\n");
808 LPTT_SUBCLASS_INFO lpttsi =
809 (LPTT_SUBCLASS_INFO)GetPropA (toolPtr->hwnd, COMCTL32_aSubclass);
811 if (lpttsi->uRefCount == 1) {
812 SetWindowLongA ((HWND)toolPtr->uId, GWL_WNDPROC,
813 (LONG)lpttsi->wpOrigProc);
814 RemovePropA ((HWND)toolPtr->uId, COMCTL32_aSubclass);
815 COMCTL32_Free (&lpttsi);
821 ERR("Invalid data handle!\n");
825 /* delete tool from tool list */
826 if (infoPtr->uNumTools == 1) {
827 COMCTL32_Free (infoPtr->tools);
828 infoPtr->tools = NULL;
831 TTTOOL_INFO *oldTools = infoPtr->tools;
833 COMCTL32_Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1));
836 memcpy (&infoPtr->tools[0], &oldTools[0],
837 nTool * sizeof(TTTOOL_INFO));
839 if (nTool < infoPtr->uNumTools - 1)
840 memcpy (&infoPtr->tools[nTool], &oldTools[nTool + 1],
841 (infoPtr->uNumTools - nTool - 1) * sizeof(TTTOOL_INFO));
843 COMCTL32_Free (oldTools);
846 infoPtr->uNumTools--;
853 TOOLTIPS_DelToolW (HWND hwnd, WPARAM wParam, LPARAM lParam)
855 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
856 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
857 TTTOOL_INFO *toolPtr;
860 if (lpToolInfo == NULL)
862 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
864 if (infoPtr->uNumTools == 0)
867 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
868 if (nTool == -1) return 0;
870 TRACE("tool %d\n", nTool);
872 /* delete text string */
873 toolPtr = &infoPtr->tools[nTool];
874 if ((toolPtr->hinst) && (toolPtr->lpszText)) {
875 if ( (toolPtr->lpszText != LPSTR_TEXTCALLBACKW) &&
876 (HIWORD((INT)toolPtr->lpszText) != 0) )
877 COMCTL32_Free (toolPtr->lpszText);
880 /* remove subclassing */
881 if (toolPtr->uFlags & TTF_SUBCLASS) {
882 if (toolPtr->uFlags & TTF_IDISHWND) {
883 LPTT_SUBCLASS_INFO lpttsi =
884 (LPTT_SUBCLASS_INFO)GetPropA ((HWND)toolPtr->uId, COMCTL32_aSubclass);
886 SetWindowLongA ((HWND)toolPtr->uId, GWL_WNDPROC,
887 (LONG)lpttsi->wpOrigProc);
888 RemovePropA ((HWND)toolPtr->uId, COMCTL32_aSubclass);
889 COMCTL32_Free (&lpttsi);
892 ERR("Invalid data handle!\n");
895 LPTT_SUBCLASS_INFO lpttsi =
896 (LPTT_SUBCLASS_INFO)GetPropA (toolPtr->hwnd, COMCTL32_aSubclass);
898 if (lpttsi->uRefCount == 1) {
899 SetWindowLongA ((HWND)toolPtr->uId, GWL_WNDPROC,
900 (LONG)lpttsi->wpOrigProc);
901 RemovePropA ((HWND)toolPtr->uId, COMCTL32_aSubclass);
902 COMCTL32_Free (&lpttsi);
908 ERR("Invalid data handle!\n");
912 /* delete tool from tool list */
913 if (infoPtr->uNumTools == 1) {
914 COMCTL32_Free (infoPtr->tools);
915 infoPtr->tools = NULL;
918 TTTOOL_INFO *oldTools = infoPtr->tools;
920 COMCTL32_Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1));
923 memcpy (&infoPtr->tools[0], &oldTools[0],
924 nTool * sizeof(TTTOOL_INFO));
926 if (nTool < infoPtr->uNumTools - 1)
927 memcpy (&infoPtr->tools[nTool], &oldTools[nTool + 1],
928 (infoPtr->uNumTools - nTool - 1) * sizeof(TTTOOL_INFO));
930 COMCTL32_Free (oldTools);
933 infoPtr->uNumTools--;
940 TOOLTIPS_EnumToolsA (HWND hwnd, WPARAM wParam, LPARAM lParam)
942 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
943 UINT uIndex = (UINT)wParam;
944 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
945 TTTOOL_INFO *toolPtr;
947 if (lpToolInfo == NULL)
949 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA)
951 if (uIndex >= infoPtr->uNumTools)
954 TRACE("index=%u\n", uIndex);
956 toolPtr = &infoPtr->tools[uIndex];
959 lpToolInfo->uFlags = toolPtr->uFlags;
960 lpToolInfo->hwnd = toolPtr->hwnd;
961 lpToolInfo->uId = toolPtr->uId;
962 lpToolInfo->rect = toolPtr->rect;
963 lpToolInfo->hinst = toolPtr->hinst;
964 /* lpToolInfo->lpszText = toolPtr->lpszText; */
965 lpToolInfo->lpszText = NULL; /* FIXME */
967 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
968 lpToolInfo->lParam = toolPtr->lParam;
975 TOOLTIPS_EnumToolsW (HWND hwnd, WPARAM wParam, LPARAM lParam)
977 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
978 UINT uIndex = (UINT)wParam;
979 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
980 TTTOOL_INFO *toolPtr;
982 if (lpToolInfo == NULL)
984 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
986 if (uIndex >= infoPtr->uNumTools)
989 TRACE("index=%u\n", uIndex);
991 toolPtr = &infoPtr->tools[uIndex];
994 lpToolInfo->uFlags = toolPtr->uFlags;
995 lpToolInfo->hwnd = toolPtr->hwnd;
996 lpToolInfo->uId = toolPtr->uId;
997 lpToolInfo->rect = toolPtr->rect;
998 lpToolInfo->hinst = toolPtr->hinst;
999 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1000 lpToolInfo->lpszText = NULL; /* FIXME */
1002 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
1003 lpToolInfo->lParam = toolPtr->lParam;
1010 TOOLTIPS_GetCurrentToolA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1012 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1013 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
1014 TTTOOL_INFO *toolPtr;
1016 if (lpToolInfo == NULL)
1018 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA)
1022 if (infoPtr->nCurrentTool > -1) {
1023 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
1025 /* copy tool data */
1026 lpToolInfo->uFlags = toolPtr->uFlags;
1027 lpToolInfo->rect = toolPtr->rect;
1028 lpToolInfo->hinst = toolPtr->hinst;
1029 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1030 lpToolInfo->lpszText = NULL; /* FIXME */
1032 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
1033 lpToolInfo->lParam = toolPtr->lParam;
1041 return (infoPtr->nCurrentTool != -1);
1048 TOOLTIPS_GetCurrentToolW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1050 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1051 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
1052 TTTOOL_INFO *toolPtr;
1054 if (lpToolInfo == NULL)
1056 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
1060 if (infoPtr->nCurrentTool > -1) {
1061 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
1063 /* copy tool data */
1064 lpToolInfo->uFlags = toolPtr->uFlags;
1065 lpToolInfo->rect = toolPtr->rect;
1066 lpToolInfo->hinst = toolPtr->hinst;
1067 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1068 lpToolInfo->lpszText = NULL; /* FIXME */
1070 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
1071 lpToolInfo->lParam = toolPtr->lParam;
1079 return (infoPtr->nCurrentTool != -1);
1086 TOOLTIPS_GetDelayTime (HWND hwnd, WPARAM wParam, LPARAM lParam)
1088 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1091 case TTDT_AUTOMATIC:
1092 return infoPtr->nAutomaticTime;
1095 return infoPtr->nReshowTime;
1098 return infoPtr->nAutoPopTime;
1101 return infoPtr->nInitialTime;
1109 TOOLTIPS_GetMargin (HWND hwnd, WPARAM wParam, LPARAM lParam)
1111 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1112 LPRECT lpRect = (LPRECT)lParam;
1114 lpRect->left = infoPtr->rcMargin.left;
1115 lpRect->right = infoPtr->rcMargin.right;
1116 lpRect->bottom = infoPtr->rcMargin.bottom;
1117 lpRect->top = infoPtr->rcMargin.top;
1123 inline static LRESULT
1124 TOOLTIPS_GetMaxTipWidth (HWND hwnd, WPARAM wParam, LPARAM lParam)
1126 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1128 return infoPtr->nMaxTipWidth;
1133 TOOLTIPS_GetTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1135 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1136 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
1139 if (lpToolInfo == NULL)
1141 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA)
1144 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1145 if (nTool == -1) return 0;
1147 lstrcpyWtoA (lpToolInfo->lpszText, infoPtr->tools[nTool].lpszText);
1154 TOOLTIPS_GetTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1156 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1157 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
1160 if (lpToolInfo == NULL)
1162 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
1165 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
1166 if (nTool == -1) return 0;
1168 lstrcpyW (lpToolInfo->lpszText, infoPtr->tools[nTool].lpszText);
1174 inline static LRESULT
1175 TOOLTIPS_GetTipBkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
1177 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1178 return infoPtr->clrBk;
1182 inline static LRESULT
1183 TOOLTIPS_GetTipTextColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
1185 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1186 return infoPtr->clrText;
1190 inline static LRESULT
1191 TOOLTIPS_GetToolCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
1193 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1194 return infoPtr->uNumTools;
1199 TOOLTIPS_GetToolInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1201 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1202 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
1203 TTTOOL_INFO *toolPtr;
1206 if (lpToolInfo == NULL)
1208 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA)
1210 if (infoPtr->uNumTools == 0)
1213 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1217 TRACE("tool %d\n", nTool);
1219 toolPtr = &infoPtr->tools[nTool];
1221 /* copy tool data */
1222 lpToolInfo->uFlags = toolPtr->uFlags;
1223 lpToolInfo->rect = toolPtr->rect;
1224 lpToolInfo->hinst = toolPtr->hinst;
1225 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1226 lpToolInfo->lpszText = NULL; /* FIXME */
1228 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
1229 lpToolInfo->lParam = toolPtr->lParam;
1236 TOOLTIPS_GetToolInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1238 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1239 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
1240 TTTOOL_INFO *toolPtr;
1243 if (lpToolInfo == NULL)
1245 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
1247 if (infoPtr->uNumTools == 0)
1250 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
1254 TRACE("tool %d\n", nTool);
1256 toolPtr = &infoPtr->tools[nTool];
1258 /* copy tool data */
1259 lpToolInfo->uFlags = toolPtr->uFlags;
1260 lpToolInfo->rect = toolPtr->rect;
1261 lpToolInfo->hinst = toolPtr->hinst;
1262 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1263 lpToolInfo->lpszText = NULL; /* FIXME */
1265 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
1266 lpToolInfo->lParam = toolPtr->lParam;
1273 TOOLTIPS_HitTestA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1275 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1276 LPTTHITTESTINFOA lptthit = (LPTTHITTESTINFOA)lParam;
1277 TTTOOL_INFO *toolPtr;
1283 nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lptthit->hwnd, &lptthit->pt);
1287 TRACE("tool %d!\n", nTool);
1289 /* copy tool data */
1290 if (lptthit->ti.cbSize >= sizeof(TTTOOLINFOA)) {
1291 toolPtr = &infoPtr->tools[nTool];
1293 lptthit->ti.uFlags = toolPtr->uFlags;
1294 lptthit->ti.hwnd = toolPtr->hwnd;
1295 lptthit->ti.uId = toolPtr->uId;
1296 lptthit->ti.rect = toolPtr->rect;
1297 lptthit->ti.hinst = toolPtr->hinst;
1298 /* lptthit->ti.lpszText = toolPtr->lpszText; */
1299 lptthit->ti.lpszText = NULL; /* FIXME */
1300 lptthit->ti.lParam = toolPtr->lParam;
1308 TOOLTIPS_HitTestW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1310 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1311 LPTTHITTESTINFOW lptthit = (LPTTHITTESTINFOW)lParam;
1312 TTTOOL_INFO *toolPtr;
1318 nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lptthit->hwnd, &lptthit->pt);
1322 TRACE("tool %d!\n", nTool);
1324 /* copy tool data */
1325 if (lptthit->ti.cbSize >= sizeof(TTTOOLINFOW)) {
1326 toolPtr = &infoPtr->tools[nTool];
1328 lptthit->ti.uFlags = toolPtr->uFlags;
1329 lptthit->ti.hwnd = toolPtr->hwnd;
1330 lptthit->ti.uId = toolPtr->uId;
1331 lptthit->ti.rect = toolPtr->rect;
1332 lptthit->ti.hinst = toolPtr->hinst;
1333 /* lptthit->ti.lpszText = toolPtr->lpszText; */
1334 lptthit->ti.lpszText = NULL; /* FIXME */
1335 lptthit->ti.lParam = toolPtr->lParam;
1343 TOOLTIPS_NewToolRectA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1345 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1346 LPTTTOOLINFOA lpti = (LPTTTOOLINFOA)lParam;
1351 if (lpti->cbSize < TTTOOLINFO_V1_SIZEA)
1354 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpti);
1355 if (nTool == -1) return 0;
1357 infoPtr->tools[nTool].rect = lpti->rect;
1364 TOOLTIPS_NewToolRectW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1366 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1367 LPTTTOOLINFOW lpti = (LPTTTOOLINFOW)lParam;
1372 if (lpti->cbSize < TTTOOLINFO_V1_SIZEW)
1375 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpti);
1376 if (nTool == -1) return 0;
1378 infoPtr->tools[nTool].rect = lpti->rect;
1384 inline static LRESULT
1385 TOOLTIPS_Pop (HWND hwnd, WPARAM wParam, LPARAM lParam)
1387 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1389 TOOLTIPS_Hide (hwnd, infoPtr);
1396 TOOLTIPS_RelayEvent (HWND hwnd, WPARAM wParam, LPARAM lParam)
1398 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1399 LPMSG lpMsg = (LPMSG)lParam;
1403 ERR("lpMsg == NULL!\n");
1407 switch (lpMsg->message) {
1408 case WM_LBUTTONDOWN:
1410 case WM_MBUTTONDOWN:
1412 case WM_RBUTTONDOWN:
1415 ScreenToClient (lpMsg->hwnd, &pt);
1416 infoPtr->nOldTool = infoPtr->nTool;
1417 infoPtr->nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lpMsg->hwnd, &pt);
1418 TRACE("tool (%x) %d %d\n",
1419 hwnd, infoPtr->nOldTool, infoPtr->nTool);
1420 TOOLTIPS_Hide (hwnd, infoPtr);
1425 ScreenToClient (lpMsg->hwnd, &pt);
1426 infoPtr->nOldTool = infoPtr->nTool;
1427 infoPtr->nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lpMsg->hwnd, &pt);
1428 TRACE("tool (%x) %d %d\n",
1429 hwnd, infoPtr->nOldTool, infoPtr->nTool);
1430 TRACE("WM_MOUSEMOVE (%04x %ld %ld)\n",
1432 if ((infoPtr->bActive) && (infoPtr->nTool != infoPtr->nOldTool)) {
1433 if (infoPtr->nOldTool == -1) {
1434 SetTimer (hwnd, ID_TIMERSHOW, infoPtr->nInitialTime, 0);
1435 TRACE("timer 1 started!\n");
1438 TOOLTIPS_Hide (hwnd, infoPtr);
1439 SetTimer (hwnd, ID_TIMERSHOW, infoPtr->nReshowTime, 0);
1440 TRACE("timer 2 started!\n");
1443 if (infoPtr->nCurrentTool != -1) {
1444 SetTimer (hwnd, ID_TIMERLEAVE, 100, 0);
1445 TRACE("timer 3 started!\n");
1455 TOOLTIPS_SetDelayTime (HWND hwnd, WPARAM wParam, LPARAM lParam)
1457 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1458 INT nTime = (INT)LOWORD(lParam);
1461 case TTDT_AUTOMATIC:
1463 infoPtr->nAutomaticTime = 500;
1464 infoPtr->nReshowTime = 100;
1465 infoPtr->nAutoPopTime = 5000;
1466 infoPtr->nInitialTime = 500;
1469 infoPtr->nAutomaticTime = nTime;
1470 infoPtr->nReshowTime = nTime / 5;
1471 infoPtr->nAutoPopTime = nTime * 10;
1472 infoPtr->nInitialTime = nTime;
1477 infoPtr->nReshowTime = nTime;
1481 infoPtr->nAutoPopTime = nTime;
1485 infoPtr->nInitialTime = nTime;
1494 TOOLTIPS_SetMargin (HWND hwnd, WPARAM wParam, LPARAM lParam)
1496 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1497 LPRECT lpRect = (LPRECT)lParam;
1499 infoPtr->rcMargin.left = lpRect->left;
1500 infoPtr->rcMargin.right = lpRect->right;
1501 infoPtr->rcMargin.bottom = lpRect->bottom;
1502 infoPtr->rcMargin.top = lpRect->top;
1508 inline static LRESULT
1509 TOOLTIPS_SetMaxTipWidth (HWND hwnd, WPARAM wParam, LPARAM lParam)
1511 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1512 INT nTemp = infoPtr->nMaxTipWidth;
1514 infoPtr->nMaxTipWidth = (INT)lParam;
1520 inline static LRESULT
1521 TOOLTIPS_SetTipBkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
1523 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1525 infoPtr->clrBk = (COLORREF)wParam;
1531 inline static LRESULT
1532 TOOLTIPS_SetTipTextColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
1534 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1536 infoPtr->clrText = (COLORREF)wParam;
1543 TOOLTIPS_SetToolInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1545 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1546 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
1547 TTTOOL_INFO *toolPtr;
1550 if (lpToolInfo == NULL)
1552 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA)
1555 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1556 if (nTool == -1) return 0;
1558 TRACE("tool %d\n", nTool);
1560 toolPtr = &infoPtr->tools[nTool];
1562 /* copy tool data */
1563 toolPtr->uFlags = lpToolInfo->uFlags;
1564 toolPtr->hwnd = lpToolInfo->hwnd;
1565 toolPtr->uId = lpToolInfo->uId;
1566 toolPtr->rect = lpToolInfo->rect;
1567 toolPtr->hinst = lpToolInfo->hinst;
1569 if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0)) {
1570 TRACE("set string id %x!\n", (INT)lpToolInfo->lpszText);
1571 toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
1573 else if (lpToolInfo->lpszText) {
1574 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKA)
1575 toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
1577 if ( (toolPtr->lpszText) &&
1578 (HIWORD((INT)toolPtr->lpszText) != 0) ) {
1579 COMCTL32_Free (toolPtr->lpszText);
1580 toolPtr->lpszText = NULL;
1582 if (lpToolInfo->lpszText) {
1583 INT len = lstrlenA (lpToolInfo->lpszText);
1584 toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1585 lstrcpyAtoW (toolPtr->lpszText, lpToolInfo->lpszText);
1590 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
1591 toolPtr->lParam = lpToolInfo->lParam;
1598 TOOLTIPS_SetToolInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1600 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1601 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
1602 TTTOOL_INFO *toolPtr;
1605 if (lpToolInfo == NULL)
1607 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
1610 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
1611 if (nTool == -1) return 0;
1613 TRACE("tool %d\n", nTool);
1615 toolPtr = &infoPtr->tools[nTool];
1617 /* copy tool data */
1618 toolPtr->uFlags = lpToolInfo->uFlags;
1619 toolPtr->hwnd = lpToolInfo->hwnd;
1620 toolPtr->uId = lpToolInfo->uId;
1621 toolPtr->rect = lpToolInfo->rect;
1622 toolPtr->hinst = lpToolInfo->hinst;
1624 if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0)) {
1625 TRACE("set string id %x!\n", (INT)lpToolInfo->lpszText);
1626 toolPtr->lpszText = lpToolInfo->lpszText;
1628 else if (lpToolInfo->lpszText) {
1629 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKW)
1630 toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
1632 if ( (toolPtr->lpszText) &&
1633 (HIWORD((INT)toolPtr->lpszText) != 0) ) {
1634 COMCTL32_Free (toolPtr->lpszText);
1635 toolPtr->lpszText = NULL;
1637 if (lpToolInfo->lpszText) {
1638 INT len = lstrlenW (lpToolInfo->lpszText);
1639 toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1640 lstrcpyW (toolPtr->lpszText, lpToolInfo->lpszText);
1645 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
1646 toolPtr->lParam = lpToolInfo->lParam;
1653 TOOLTIPS_TrackActivate (HWND hwnd, WPARAM wParam, LPARAM lParam)
1655 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1656 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
1658 if (lpToolInfo == NULL)
1660 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA)
1665 infoPtr->nTrackTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1666 if (infoPtr->nTrackTool != -1) {
1667 TRACE("activated!\n");
1668 infoPtr->bTrackActive = TRUE;
1669 TOOLTIPS_TrackShow (hwnd, infoPtr);
1674 TOOLTIPS_TrackHide (hwnd, infoPtr);
1676 infoPtr->bTrackActive = FALSE;
1677 infoPtr->nTrackTool = -1;
1679 TRACE("deactivated!\n");
1687 TOOLTIPS_TrackPosition (HWND hwnd, WPARAM wParam, LPARAM lParam)
1689 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1691 infoPtr->xTrackPos = (INT)LOWORD(lParam);
1692 infoPtr->yTrackPos = (INT)HIWORD(lParam);
1694 if (infoPtr->bTrackActive) {
1696 infoPtr->xTrackPos, infoPtr->yTrackPos);
1698 TOOLTIPS_TrackShow (hwnd, infoPtr);
1706 TOOLTIPS_Update (HWND hwnd, WPARAM wParam, LPARAM lParam)
1708 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1710 if (infoPtr->nCurrentTool != -1)
1711 UpdateWindow (hwnd);
1718 TOOLTIPS_UpdateTipTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1720 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1721 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
1722 TTTOOL_INFO *toolPtr;
1725 if (lpToolInfo == NULL)
1727 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA)
1730 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1731 if (nTool == -1) return 0;
1733 TRACE("tool %d\n", nTool);
1735 toolPtr = &infoPtr->tools[nTool];
1737 /* copy tool text */
1738 toolPtr->hinst = lpToolInfo->hinst;
1740 if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0)){
1741 toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
1743 else if (lpToolInfo->lpszText) {
1744 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKA)
1745 toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
1747 if ( (toolPtr->lpszText) &&
1748 (HIWORD((INT)toolPtr->lpszText) != 0) ) {
1749 COMCTL32_Free (toolPtr->lpszText);
1750 toolPtr->lpszText = NULL;
1752 if (lpToolInfo->lpszText) {
1753 INT len = lstrlenA (lpToolInfo->lpszText);
1754 toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1755 lstrcpyAtoW (toolPtr->lpszText, lpToolInfo->lpszText);
1761 if (infoPtr->bActive)
1762 TOOLTIPS_Show (hwnd, infoPtr);
1763 else if (infoPtr->bTrackActive)
1764 TOOLTIPS_TrackShow (hwnd, infoPtr);
1771 TOOLTIPS_UpdateTipTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1773 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1774 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
1775 TTTOOL_INFO *toolPtr;
1778 if (lpToolInfo == NULL)
1780 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
1783 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
1787 TRACE("tool %d\n", nTool);
1789 toolPtr = &infoPtr->tools[nTool];
1791 /* copy tool text */
1792 toolPtr->hinst = lpToolInfo->hinst;
1794 if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0)){
1795 toolPtr->lpszText = lpToolInfo->lpszText;
1797 else if (lpToolInfo->lpszText) {
1798 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKW)
1799 toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
1801 if ( (toolPtr->lpszText) &&
1802 (HIWORD((INT)toolPtr->lpszText) != 0) ) {
1803 COMCTL32_Free (toolPtr->lpszText);
1804 toolPtr->lpszText = NULL;
1806 if (lpToolInfo->lpszText) {
1807 INT len = lstrlenW (lpToolInfo->lpszText);
1808 toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1809 lstrcpyW (toolPtr->lpszText, lpToolInfo->lpszText);
1815 if (infoPtr->bActive)
1816 TOOLTIPS_Show (hwnd, infoPtr);
1817 else if (infoPtr->bTrackActive)
1818 TOOLTIPS_TrackShow (hwnd, infoPtr);
1825 TOOLTIPS_WindowFromPoint (HWND hwnd, WPARAM wParam, LPARAM lParam)
1827 return WindowFromPoint (*((LPPOINT)lParam));
1833 TOOLTIPS_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
1835 TOOLTIPS_INFO *infoPtr;
1836 NONCLIENTMETRICSA nclm;
1839 /* allocate memory for info structure */
1840 infoPtr = (TOOLTIPS_INFO *)COMCTL32_Alloc (sizeof(TOOLTIPS_INFO));
1841 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
1843 /* initialize info structure */
1844 infoPtr->bActive = TRUE;
1845 infoPtr->bTrackActive = FALSE;
1846 infoPtr->clrBk = GetSysColor (COLOR_INFOBK);
1847 infoPtr->clrText = GetSysColor (COLOR_INFOTEXT);
1849 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1850 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1851 infoPtr->hFont = CreateFontIndirectA (&nclm.lfStatusFont);
1853 infoPtr->nMaxTipWidth = -1;
1854 infoPtr->nTool = -1;
1855 infoPtr->nOldTool = -1;
1856 infoPtr->nCurrentTool = -1;
1857 infoPtr->nTrackTool = -1;
1859 infoPtr->nAutomaticTime = 500;
1860 infoPtr->nReshowTime = 100;
1861 infoPtr->nAutoPopTime = 5000;
1862 infoPtr->nInitialTime = 500;
1864 nResult = (INT) SendMessageA (GetParent (hwnd), WM_NOTIFYFORMAT,
1865 (WPARAM)hwnd, (LPARAM)NF_QUERY);
1866 if (nResult == NFR_ANSI) {
1867 infoPtr->bNotifyUnicode = FALSE;
1868 TRACE(" -- WM_NOTIFYFORMAT returns: NFR_ANSI\n");
1870 else if (nResult == NFR_UNICODE) {
1871 infoPtr->bNotifyUnicode = TRUE;
1872 TRACE(" -- WM_NOTIFYFORMAT returns: NFR_UNICODE\n");
1875 ERR (" -- WM_NOTIFYFORMAT returns: error!\n");
1878 SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOACTIVATE);
1885 TOOLTIPS_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
1887 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1888 TTTOOL_INFO *toolPtr;
1892 if (infoPtr->tools) {
1893 for (i = 0; i < infoPtr->uNumTools; i++) {
1894 toolPtr = &infoPtr->tools[i];
1895 if ((toolPtr->hinst) && (toolPtr->lpszText)) {
1896 if ( (toolPtr->lpszText != LPSTR_TEXTCALLBACKW) &&
1897 (HIWORD((INT)toolPtr->lpszText) != 0) )
1899 COMCTL32_Free (toolPtr->lpszText);
1900 toolPtr->lpszText = NULL;
1904 /* remove subclassing */
1905 if (toolPtr->uFlags & TTF_SUBCLASS) {
1906 LPTT_SUBCLASS_INFO lpttsi;
1908 if (toolPtr->uFlags & TTF_IDISHWND)
1909 lpttsi = (LPTT_SUBCLASS_INFO)GetPropA ((HWND)toolPtr->uId, COMCTL32_aSubclass);
1911 lpttsi = (LPTT_SUBCLASS_INFO)GetPropA (toolPtr->hwnd, COMCTL32_aSubclass);
1914 SetWindowLongA ((HWND)toolPtr->uId, GWL_WNDPROC,
1915 (LONG)lpttsi->wpOrigProc);
1916 RemovePropA ((HWND)toolPtr->uId, COMCTL32_aSubclass);
1917 COMCTL32_Free (&lpttsi);
1921 COMCTL32_Free (infoPtr->tools);
1925 DeleteObject (infoPtr->hFont);
1927 /* free tool tips info data */
1928 COMCTL32_Free (infoPtr);
1935 TOOLTIPS_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
1937 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1941 hBrush = CreateSolidBrush (infoPtr->clrBk);
1942 GetClientRect (hwnd, &rect);
1943 FillRect ((HDC)wParam, &rect, hBrush);
1944 DeleteObject (hBrush);
1951 TOOLTIPS_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
1953 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1955 return infoPtr->hFont;
1960 TOOLTIPS_MouseMessage (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1962 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1964 TOOLTIPS_Hide (hwnd, infoPtr);
1971 TOOLTIPS_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
1973 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1975 dwStyle &= 0x0000FFFF;
1976 dwStyle |= (WS_POPUP | WS_BORDER | WS_CLIPSIBLINGS);
1977 SetWindowLongA (hwnd, GWL_STYLE, dwStyle);
1984 TOOLTIPS_NCHitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
1986 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1987 INT nTool = (infoPtr->bTrackActive) ? infoPtr->nTrackTool : infoPtr->nTool;
1989 TRACE(" nTool=%d\n", nTool);
1991 if ((nTool > -1) && (nTool < infoPtr->uNumTools)) {
1992 if (infoPtr->tools[nTool].uFlags & TTF_TRANSPARENT) {
1993 TRACE("-- in transparent mode!\n");
1994 return HTTRANSPARENT;
1998 return DefWindowProcA (hwnd, WM_NCHITTEST, wParam, lParam);
2003 TOOLTIPS_NotifyFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
2005 FIXME ("hwnd=%x wParam=%x lParam=%lx\n", hwnd, wParam, lParam);
2012 TOOLTIPS_Paint (HWND hwnd, WPARAM wParam, LPARAM lParam)
2017 hdc = (wParam == 0) ? BeginPaint (hwnd, &ps) : (HDC)wParam;
2018 TOOLTIPS_Refresh (hwnd, hdc);
2020 EndPaint (hwnd, &ps);
2026 TOOLTIPS_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
2028 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2030 infoPtr->hFont = (HFONT)wParam;
2032 if ((LOWORD(lParam)) & (infoPtr->nCurrentTool != -1)) {
2033 FIXME("full redraw needed!\n");
2038 /******************************************************************
2039 * TOOLTIPS_OnWMGetTextLength
2041 * This function is called when the tooltip receive a
2042 * WM_GETTEXTLENGTH message.
2046 * returns the length, in characters, of the tip text
2047 ******************************************************************/
2049 TOOLTIPS_OnWMGetTextLength(HWND hwnd, WPARAM wParam, LPARAM lParam)
2051 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2052 return lstrlenW(infoPtr->szTipText);
2055 /******************************************************************
2056 * TOOLTIPS_OnWMGetText
2058 * This function is called when the tooltip receive a
2059 * WM_GETTEXT message.
2060 * wParam : specifies the maximum number of characters to be copied
2061 * lParam : is the pointer to the buffer that will receive
2064 * returns the number of characters copied
2065 ******************************************************************/
2067 TOOLTIPS_OnWMGetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
2069 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2072 if(!infoPtr || !(infoPtr->szTipText))
2075 length = lstrlenW(infoPtr->szTipText);
2076 /* When wParam is smaller than the lenght of the tip text
2077 copy wParam characters of the tip text and return wParam */
2080 lstrcpynWtoA((LPSTR)lParam, infoPtr->szTipText,(UINT)wParam);
2083 lstrcpyWtoA((LPSTR)lParam, infoPtr->szTipText);
2088 TOOLTIPS_Timer (HWND hwnd, WPARAM wParam, LPARAM lParam)
2090 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2092 TRACE("timer %d (%x) expired!\n", wParam, hwnd);
2097 KillTimer (hwnd, ID_TIMERSHOW);
2098 if (TOOLTIPS_CheckTool (hwnd, TRUE) == infoPtr->nTool)
2099 TOOLTIPS_Show (hwnd, infoPtr);
2103 TOOLTIPS_Hide (hwnd, infoPtr);
2107 KillTimer (hwnd, ID_TIMERLEAVE);
2108 if (TOOLTIPS_CheckTool (hwnd, FALSE) == -1) {
2109 infoPtr->nTool = -1;
2110 infoPtr->nOldTool = -1;
2111 TOOLTIPS_Hide (hwnd, infoPtr);
2120 TOOLTIPS_WinIniChange (HWND hwnd, WPARAM wParam, LPARAM lParam)
2122 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2123 NONCLIENTMETRICSA nclm;
2125 infoPtr->clrBk = GetSysColor (COLOR_INFOBK);
2126 infoPtr->clrText = GetSysColor (COLOR_INFOTEXT);
2128 DeleteObject (infoPtr->hFont);
2129 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
2130 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
2131 infoPtr->hFont = CreateFontIndirectA (&nclm.lfStatusFont);
2138 TOOLTIPS_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2140 LPTT_SUBCLASS_INFO lpttsi =
2141 (LPTT_SUBCLASS_INFO)GetPropA (hwnd, COMCTL32_aSubclass);
2142 TOOLTIPS_INFO *infoPtr;
2146 case WM_LBUTTONDOWN:
2148 case WM_MBUTTONDOWN:
2150 case WM_RBUTTONDOWN:
2152 infoPtr = TOOLTIPS_GetInfoPtr(lpttsi->hwndToolTip);
2153 nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd);
2155 TRACE("subclassed mouse message %04x\n", uMsg);
2156 infoPtr->nOldTool = infoPtr->nTool;
2157 infoPtr->nTool = nTool;
2158 TOOLTIPS_Hide (lpttsi->hwndToolTip, infoPtr);
2162 infoPtr = TOOLTIPS_GetInfoPtr (lpttsi->hwndToolTip);
2163 nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd);
2165 TRACE("subclassed WM_MOUSEMOVE\n");
2166 infoPtr->nOldTool = infoPtr->nTool;
2167 infoPtr->nTool = nTool;
2169 if ((infoPtr->bActive) &&
2170 (infoPtr->nTool != infoPtr->nOldTool)) {
2171 if (infoPtr->nOldTool == -1) {
2172 SetTimer (hwnd, ID_TIMERSHOW,
2173 infoPtr->nInitialTime, 0);
2174 TRACE("timer 1 started!\n");
2177 TOOLTIPS_Hide (lpttsi->hwndToolTip, infoPtr);
2178 SetTimer (hwnd, ID_TIMERSHOW,
2179 infoPtr->nReshowTime, 0);
2180 TRACE("timer 2 started!\n");
2183 if (infoPtr->nCurrentTool != -1) {
2184 SetTimer (hwnd, ID_TIMERLEAVE, 100, 0);
2185 TRACE("timer 3 started!\n");
2190 return CallWindowProcA (lpttsi->wpOrigProc, hwnd, uMsg, wParam, lParam);
2194 static LRESULT CALLBACK
2195 TOOLTIPS_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2200 return TOOLTIPS_Activate (hwnd, wParam, lParam);
2203 return TOOLTIPS_AddToolA (hwnd, wParam, lParam);
2206 return TOOLTIPS_AddToolW (hwnd, wParam, lParam);
2209 return TOOLTIPS_DelToolA (hwnd, wParam, lParam);
2212 return TOOLTIPS_DelToolW (hwnd, wParam, lParam);
2214 case TTM_ENUMTOOLSA:
2215 return TOOLTIPS_EnumToolsA (hwnd, wParam, lParam);
2217 case TTM_ENUMTOOLSW:
2218 return TOOLTIPS_EnumToolsW (hwnd, wParam, lParam);
2220 case TTM_GETCURRENTTOOLA:
2221 return TOOLTIPS_GetCurrentToolA (hwnd, wParam, lParam);
2223 case TTM_GETCURRENTTOOLW:
2224 return TOOLTIPS_GetCurrentToolW (hwnd, wParam, lParam);
2226 case TTM_GETDELAYTIME:
2227 return TOOLTIPS_GetDelayTime (hwnd, wParam, lParam);
2230 return TOOLTIPS_GetMargin (hwnd, wParam, lParam);
2232 case TTM_GETMAXTIPWIDTH:
2233 return TOOLTIPS_GetMaxTipWidth (hwnd, wParam, lParam);
2236 return TOOLTIPS_GetTextA (hwnd, wParam, lParam);
2239 return TOOLTIPS_GetTextW (hwnd, wParam, lParam);
2241 case TTM_GETTIPBKCOLOR:
2242 return TOOLTIPS_GetTipBkColor (hwnd, wParam, lParam);
2244 case TTM_GETTIPTEXTCOLOR:
2245 return TOOLTIPS_GetTipTextColor (hwnd, wParam, lParam);
2247 case TTM_GETTOOLCOUNT:
2248 return TOOLTIPS_GetToolCount (hwnd, wParam, lParam);
2250 case TTM_GETTOOLINFOA:
2251 return TOOLTIPS_GetToolInfoA (hwnd, wParam, lParam);
2253 case TTM_GETTOOLINFOW:
2254 return TOOLTIPS_GetToolInfoW (hwnd, wParam, lParam);
2257 return TOOLTIPS_HitTestA (hwnd, wParam, lParam);
2260 return TOOLTIPS_HitTestW (hwnd, wParam, lParam);
2262 case TTM_NEWTOOLRECTA:
2263 return TOOLTIPS_NewToolRectA (hwnd, wParam, lParam);
2265 case TTM_NEWTOOLRECTW:
2266 return TOOLTIPS_NewToolRectW (hwnd, wParam, lParam);
2269 return TOOLTIPS_Pop (hwnd, wParam, lParam);
2271 case TTM_RELAYEVENT:
2272 return TOOLTIPS_RelayEvent (hwnd, wParam, lParam);
2274 case TTM_SETDELAYTIME:
2275 return TOOLTIPS_SetDelayTime (hwnd, wParam, lParam);
2278 return TOOLTIPS_SetMargin (hwnd, wParam, lParam);
2280 case TTM_SETMAXTIPWIDTH:
2281 return TOOLTIPS_SetMaxTipWidth (hwnd, wParam, lParam);
2283 case TTM_SETTIPBKCOLOR:
2284 return TOOLTIPS_SetTipBkColor (hwnd, wParam, lParam);
2286 case TTM_SETTIPTEXTCOLOR:
2287 return TOOLTIPS_SetTipTextColor (hwnd, wParam, lParam);
2289 case TTM_SETTOOLINFOA:
2290 return TOOLTIPS_SetToolInfoA (hwnd, wParam, lParam);
2292 case TTM_SETTOOLINFOW:
2293 return TOOLTIPS_SetToolInfoW (hwnd, wParam, lParam);
2295 case TTM_TRACKACTIVATE:
2296 return TOOLTIPS_TrackActivate (hwnd, wParam, lParam);
2298 case TTM_TRACKPOSITION:
2299 return TOOLTIPS_TrackPosition (hwnd, wParam, lParam);
2302 return TOOLTIPS_Update (hwnd, wParam, lParam);
2304 case TTM_UPDATETIPTEXTA:
2305 return TOOLTIPS_UpdateTipTextA (hwnd, wParam, lParam);
2307 case TTM_UPDATETIPTEXTW:
2308 return TOOLTIPS_UpdateTipTextW (hwnd, wParam, lParam);
2310 case TTM_WINDOWFROMPOINT:
2311 return TOOLTIPS_WindowFromPoint (hwnd, wParam, lParam);
2315 return TOOLTIPS_Create (hwnd, wParam, lParam);
2318 return TOOLTIPS_Destroy (hwnd, wParam, lParam);
2321 return TOOLTIPS_EraseBackground (hwnd, wParam, lParam);
2324 return TOOLTIPS_GetFont (hwnd, wParam, lParam);
2327 return TOOLTIPS_OnWMGetText (hwnd, wParam, lParam);
2329 case WM_GETTEXTLENGTH:
2330 return TOOLTIPS_OnWMGetTextLength (hwnd, wParam, lParam);
2333 case WM_LBUTTONDOWN:
2335 case WM_MBUTTONDOWN:
2337 case WM_RBUTTONDOWN:
2340 return TOOLTIPS_MouseMessage (hwnd, uMsg, wParam, lParam);
2343 return TOOLTIPS_NCCreate (hwnd, wParam, lParam);
2346 return TOOLTIPS_NCHitTest (hwnd, wParam, lParam);
2348 case WM_NOTIFYFORMAT:
2349 return TOOLTIPS_NotifyFormat (hwnd, wParam, lParam);
2352 return TOOLTIPS_Paint (hwnd, wParam, lParam);
2355 return TOOLTIPS_SetFont (hwnd, wParam, lParam);
2358 return TOOLTIPS_Timer (hwnd, wParam, lParam);
2360 case WM_WININICHANGE:
2361 return TOOLTIPS_WinIniChange (hwnd, wParam, lParam);
2364 if (uMsg >= WM_USER)
2365 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
2366 uMsg, wParam, lParam);
2367 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
2374 TOOLTIPS_Register (void)
2378 if (GlobalFindAtomA (TOOLTIPS_CLASSA)) return;
2380 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
2381 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS;
2382 wndClass.lpfnWndProc = (WNDPROC)TOOLTIPS_WindowProc;
2383 wndClass.cbClsExtra = 0;
2384 wndClass.cbWndExtra = sizeof(TOOLTIPS_INFO *);
2385 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
2386 wndClass.hbrBackground = 0;
2387 wndClass.lpszClassName = TOOLTIPS_CLASSA;
2389 RegisterClassA (&wndClass);
2394 TOOLTIPS_Unregister (void)
2396 if (GlobalFindAtomA (TOOLTIPS_CLASSA))
2397 UnregisterClassA (TOOLTIPS_CLASSA, (HINSTANCE)NULL);