Release 980822
[wine/multimedia.git] / controls / tooltips.c
blobbaf6971d1d2ae72bc32b5a9e512c71f3d9731f1b
1 /*
2 * Tool tip control
4 * Copyright 1998 Eric Kohl
6 * TODO:
7 * - Tracking tooltips (under construction).
8 * - TTS_ALWAYSTIP (undefined).
9 * - Unicode support.
10 * - Custom draw support.
11 * - The "lParam" variable from NMTTDISPINFO32A is not handled
12 * in TOOLTIPS_GetTipText.
14 * Testing:
15 * - Run tests using Waite Group Windows95 API Bible Volume 2.
16 * The second cdrom (chapter 3) contains executables activate.exe,
17 * curtool.exe, deltool.exe, enumtools.exe, getinfo.exe, getiptxt.exe,
18 * hittest.exe, needtext.exe, newrect.exe, updtext.exe and winfrpt.exe.
21 #include "windows.h"
22 #include "commctrl.h"
23 #include "tooltips.h"
24 #include "heap.h"
25 #include "win.h"
26 #include "debug.h"
29 #define ID_TIMER1 1 /* show delay timer */
30 #define ID_TIMER2 2 /* auto pop timer */
31 #define ID_TIMER3 3 /* tool leave timer */
32 #define TT_SUBCLASS_PROP "CC32SubclassInfo" /* property name of tooltip window handle */
34 #define TOOLTIPS_GetInfoPtr(wndPtr) ((TOOLTIPS_INFO *)wndPtr->wExtra[0])
37 LRESULT CALLBACK
38 TOOLTIPS_SubclassProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam);
41 static VOID
42 TOOLTIPS_Refresh (WND *wndPtr, HDC32 hdc)
44 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
45 RECT32 rc;
46 INT32 oldBkMode;
47 HFONT32 hOldFont;
48 UINT32 uFlags = DT_EXTERNALLEADING;
50 if (infoPtr->nMaxTipWidth > -1)
51 uFlags |= DT_WORDBREAK;
52 if (wndPtr->dwStyle & TTS_NOPREFIX)
53 uFlags |= DT_NOPREFIX;
54 GetClientRect32 (wndPtr->hwndSelf, &rc);
55 rc.left += (2 + infoPtr->rcMargin.left);
56 rc.top += (2 + infoPtr->rcMargin.top);
57 rc.right -= (2 + infoPtr->rcMargin.right);
58 rc.bottom -= (2 + infoPtr->rcMargin.bottom);
59 oldBkMode = SetBkMode32 (hdc, TRANSPARENT);
60 SetTextColor32 (hdc, infoPtr->clrText);
61 hOldFont = SelectObject32 (hdc, infoPtr->hFont);
62 DrawText32A (hdc, infoPtr->szTipText, -1, &rc, uFlags);
63 SelectObject32 (hdc, hOldFont);
64 if (oldBkMode != TRANSPARENT)
65 SetBkMode32 (hdc, oldBkMode);
69 static VOID
70 TOOLTIPS_GetTipText (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
72 TTTOOL_INFO *toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
74 if (toolPtr->hinst) {
75 TRACE (tooltips, "get res string %x %x\n",
76 toolPtr->hinst, (int)toolPtr->lpszText);
77 LoadString32A (toolPtr->hinst, (UINT32)toolPtr->lpszText,
78 infoPtr->szTipText, INFOTIPSIZE);
80 else if (toolPtr->lpszText) {
81 if (toolPtr->lpszText == LPSTR_TEXTCALLBACK32A) {
82 NMTTDISPINFO32A ttnmdi;
84 /* fill NMHDR struct */
85 ZeroMemory (&ttnmdi, sizeof(NMTTDISPINFO32A));
86 ttnmdi.hdr.hwndFrom = wndPtr->hwndSelf;
87 ttnmdi.hdr.idFrom = toolPtr->uId;
88 ttnmdi.hdr.code = TTN_GETDISPINFO32A;
89 ttnmdi.uFlags = toolPtr->uFlags;
90 ttnmdi.lpszText = infoPtr->szTipText;
92 TRACE (tooltips, "hdr.idFrom = %x\n", ttnmdi.hdr.idFrom);
93 SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
94 (WPARAM32)toolPtr->uId, (LPARAM)&ttnmdi);
96 if (ttnmdi.hinst) {
97 LoadString32A (ttnmdi.hinst, (UINT32)ttnmdi.szText,
98 infoPtr->szTipText, INFOTIPSIZE);
99 if (ttnmdi.uFlags & TTF_DI_SETITEM) {
100 toolPtr->hinst = ttnmdi.hinst;
101 toolPtr->lpszText = ttnmdi.szText;
104 else if (ttnmdi.szText[0]) {
105 lstrcpyn32A (infoPtr->szTipText, ttnmdi.szText, 80);
106 if (ttnmdi.uFlags & TTF_DI_SETITEM) {
107 INT32 len = lstrlen32A (ttnmdi.szText) + 1;
108 toolPtr->hinst = 0;
109 toolPtr->lpszText =
110 HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len);
111 lstrcpy32A (toolPtr->lpszText, ttnmdi.szText);
114 else if (ttnmdi.lpszText == 0) {
115 /* no text available */
116 infoPtr->szTipText[0] = '\0';
118 else if (ttnmdi.lpszText != LPSTR_TEXTCALLBACK32A) {
119 if (ttnmdi.lpszText != infoPtr->szTipText)
120 lstrcpyn32A (infoPtr->szTipText, ttnmdi.lpszText,
121 INFOTIPSIZE);
122 if (ttnmdi.uFlags & TTF_DI_SETITEM) {
123 INT32 len = lstrlen32A (ttnmdi.lpszText) + 1;
124 toolPtr->hinst = 0;
125 toolPtr->lpszText =
126 HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len);
127 lstrcpy32A (toolPtr->lpszText, ttnmdi.lpszText);
130 else
131 ERR (tooltips, "recursive text callback!\n");
133 else
134 lstrcpyn32A (infoPtr->szTipText, toolPtr->lpszText, INFOTIPSIZE);
136 else
137 /* no text available */
138 infoPtr->szTipText[0] = '\0';
140 TRACE (tooltips, "\"%s\"\n", infoPtr->szTipText);
144 static VOID
145 TOOLTIPS_CalcTipSize (WND *wndPtr, TOOLTIPS_INFO *infoPtr, LPSIZE32 lpSize)
147 HDC32 hdc;
148 HFONT32 hOldFont;
149 UINT32 uFlags = DT_EXTERNALLEADING | DT_CALCRECT;
150 RECT32 rc = {0, 0, 0, 0};
152 if (infoPtr->nMaxTipWidth > -1) {
153 rc.right = infoPtr->nMaxTipWidth;
154 uFlags |= DT_WORDBREAK;
156 if (wndPtr->dwStyle & TTS_NOPREFIX)
157 uFlags |= DT_NOPREFIX;
158 TRACE (tooltips, "\"%s\"\n", infoPtr->szTipText);
160 hdc = GetDC32 (wndPtr->hwndSelf);
161 hOldFont = SelectObject32 (hdc, infoPtr->hFont);
162 DrawText32A (hdc, infoPtr->szTipText, -1, &rc, uFlags);
163 SelectObject32 (hdc, hOldFont);
164 ReleaseDC32 (wndPtr->hwndSelf, hdc);
166 lpSize->cx = rc.right - rc.left + 4 +
167 infoPtr->rcMargin.left + infoPtr->rcMargin.right;
168 lpSize->cy = rc.bottom - rc.top + 4 +
169 infoPtr->rcMargin.bottom + infoPtr->rcMargin.top;
173 static VOID
174 TOOLTIPS_Show (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
176 TTTOOL_INFO *toolPtr;
177 POINT32 pt;
178 SIZE32 size;
179 NMHDR hdr;
181 if (infoPtr->nTool == -1) {
182 TRACE (tooltips, "invalid tool (-1)!\n");
183 return;
186 infoPtr->nCurrentTool = infoPtr->nTool;
188 TRACE (tooltips, "Show tooltip pre %d!\n", infoPtr->nTool);
190 TOOLTIPS_GetTipText (wndPtr, infoPtr);
192 if (infoPtr->szTipText[0] == '\0') {
193 infoPtr->nCurrentTool = -1;
194 return;
197 TRACE (tooltips, "Show tooltip %d!\n", infoPtr->nCurrentTool);
198 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
200 hdr.hwndFrom = wndPtr->hwndSelf;
201 hdr.idFrom = toolPtr->uId;
202 hdr.code = TTN_SHOW;
203 SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
204 (WPARAM32)toolPtr->uId, (LPARAM)&hdr);
206 TRACE (tooltips, "\"%s\"\n", infoPtr->szTipText);
208 TOOLTIPS_CalcTipSize (wndPtr, infoPtr, &size);
209 TRACE (tooltips, "size %d - %d\n", size.cx, size.cy);
211 if ((toolPtr->uFlags & TTF_TRACK) && (toolPtr->uFlags & TTF_ABSOLUTE)) {
212 pt.x = infoPtr->xTrackPos;
213 pt.y = infoPtr->yTrackPos;
215 else if (toolPtr->uFlags & TTF_CENTERTIP) {
216 RECT32 rect;
218 if (toolPtr->uFlags & TTF_IDISHWND)
219 GetWindowRect32 ((HWND32)toolPtr->uId, &rect);
220 else {
221 rect = toolPtr->rect;
222 MapWindowPoints32 (toolPtr->hwnd, (HWND32)0, (LPPOINT32)&rect, 2);
224 pt.x = (rect.left + rect.right - size.cx) / 2;
225 pt.y = rect.bottom + 2;
227 else {
228 GetCursorPos32 (&pt);
229 pt.y += 20;
232 TRACE (tooltips, "pos %d - %d\n", pt.x, pt.y);
234 // SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 1, 1,
235 SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, pt.x, pt.y,
236 size.cx, size.cy, SWP_SHOWWINDOW);
238 SetTimer32 (wndPtr->hwndSelf, ID_TIMER2, infoPtr->nAutoPopTime, 0);
242 static VOID
243 TOOLTIPS_Hide (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
245 TTTOOL_INFO *toolPtr;
246 NMHDR hdr;
248 if (infoPtr->nCurrentTool == -1)
249 return;
251 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
252 TRACE (tooltips, "Hide tooltip %d!\n", infoPtr->nCurrentTool);
253 KillTimer32 (wndPtr->hwndSelf, ID_TIMER2);
255 hdr.hwndFrom = wndPtr->hwndSelf;
256 hdr.idFrom = toolPtr->uId;
257 hdr.code = TTN_POP;
258 SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
259 (WPARAM32)toolPtr->uId, (LPARAM)&hdr);
261 infoPtr->nCurrentTool = -1;
263 SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0, SWP_HIDEWINDOW);
267 static INT32
268 TOOLTIPS_GetToolFromInfoA (TOOLTIPS_INFO *infoPtr, LPTTTOOLINFO32A lpToolInfo)
270 TTTOOL_INFO *toolPtr;
271 INT32 nTool;
273 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
274 toolPtr = &infoPtr->tools[nTool];
276 if (!(toolPtr->uFlags & TTF_IDISHWND) &&
277 (lpToolInfo->hwnd == toolPtr->hwnd) &&
278 (lpToolInfo->uId == toolPtr->uId))
279 return nTool;
282 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
283 toolPtr = &infoPtr->tools[nTool];
285 if ((toolPtr->uFlags & TTF_IDISHWND) &&
286 (lpToolInfo->uId == toolPtr->uId))
287 return nTool;
290 return -1;
294 static INT32
295 TOOLTIPS_GetToolFromPoint (TOOLTIPS_INFO *infoPtr, HWND32 hwnd, LPPOINT32 lpPt)
297 TTTOOL_INFO *toolPtr;
298 INT32 nTool;
300 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
301 toolPtr = &infoPtr->tools[nTool];
303 if (!(toolPtr->uFlags & TTF_IDISHWND)) {
304 if (hwnd != toolPtr->hwnd)
305 continue;
306 if (!PtInRect32 (&toolPtr->rect, *lpPt))
307 continue;
308 return nTool;
312 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
313 toolPtr = &infoPtr->tools[nTool];
315 if (toolPtr->uFlags & TTF_IDISHWND) {
316 if ((HWND32)toolPtr->uId == hwnd)
317 return nTool;
321 return -1;
325 static INT32
326 TOOLTIPS_GetToolFromMessage (TOOLTIPS_INFO *infoPtr, HWND32 hwndTool)
328 DWORD dwPos;
329 POINT32 pt;
331 dwPos = GetMessagePos ();
332 pt.x = (INT32)LOWORD(dwPos);
333 pt.y = (INT32)HIWORD(dwPos);
334 ScreenToClient32 (hwndTool, &pt);
336 return TOOLTIPS_GetToolFromPoint (infoPtr, hwndTool, &pt);
340 static BOOL32
341 TOOLTIPS_CheckTool (WND *wndPtr)
343 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
344 POINT32 pt;
345 HWND32 hwndTool;
346 INT32 nTool;
348 GetCursorPos32 (&pt);
349 hwndTool =
350 SendMessage32A (wndPtr->hwndSelf, TTM_WINDOWFROMPOINT, 0, (LPARAM)&pt);
351 if (hwndTool == 0)
352 return FALSE;
354 ScreenToClient32 (hwndTool, &pt);
355 nTool = TOOLTIPS_GetToolFromPoint (infoPtr, hwndTool, &pt);
356 TRACE (tooltips, "tool %d\n", nTool);
358 return (nTool != -1);
362 static LRESULT
363 TOOLTIPS_Activate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
365 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
367 infoPtr->bActive = (BOOL32)wParam;
369 if (infoPtr->bActive)
370 TRACE (tooltips, "activate!\n");
372 if (!(infoPtr->bActive) && (infoPtr->nCurrentTool != -1))
373 TOOLTIPS_Hide (wndPtr, infoPtr);
375 return 0;
379 static LRESULT
380 TOOLTIPS_AddTool32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
382 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
383 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
384 TTTOOL_INFO *toolPtr;
386 if (lpToolInfo == NULL) return FALSE;
388 TRACE (tooltips, "add tool (%x) %x %d%s!\n",
389 wndPtr->hwndSelf, lpToolInfo->hwnd, lpToolInfo->uId,
390 (lpToolInfo->uFlags & TTF_IDISHWND) ? " TTF_IDISHWND" : "");
392 if (infoPtr->uNumTools == 0) {
393 infoPtr->tools =
394 HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
395 sizeof(TTTOOL_INFO));
396 toolPtr = infoPtr->tools;
398 else {
399 TTTOOL_INFO *oldTools = infoPtr->tools;
400 infoPtr->tools =
401 HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
402 sizeof(TTTOOL_INFO) * (infoPtr->uNumTools + 1));
403 memcpy (infoPtr->tools, oldTools,
404 infoPtr->uNumTools * sizeof(TTTOOL_INFO));
405 HeapFree (GetProcessHeap (), 0, oldTools);
406 toolPtr = &infoPtr->tools[infoPtr->uNumTools];
409 infoPtr->uNumTools++;
411 /* copy tool data */
412 toolPtr->uFlags = lpToolInfo->uFlags;
413 toolPtr->hwnd = lpToolInfo->hwnd;
414 toolPtr->uId = lpToolInfo->uId;
415 toolPtr->rect = lpToolInfo->rect;
416 toolPtr->hinst = lpToolInfo->hinst;
418 if (lpToolInfo->hinst) {
419 TRACE (tooltips, "add string id %x!\n", (int)lpToolInfo->lpszText);
420 toolPtr->lpszText = lpToolInfo->lpszText;
422 else if (lpToolInfo->lpszText) {
423 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACK32A) {
424 TRACE (tooltips, "add CALLBACK!\n");
425 toolPtr->lpszText = lpToolInfo->lpszText;
427 else {
428 INT32 len = lstrlen32A (lpToolInfo->lpszText);
429 TRACE (tooltips, "add text \"%s\"!\n", lpToolInfo->lpszText);
430 toolPtr->lpszText =
431 HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len + 1);
432 lstrcpy32A (toolPtr->lpszText, lpToolInfo->lpszText);
436 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A))
437 toolPtr->lParam = lpToolInfo->lParam;
439 /* install subclassing */
440 if (toolPtr->uFlags & TTF_SUBCLASS) {
441 if (toolPtr->uFlags & TTF_IDISHWND) {
442 LPTT_SUBCLASS_INFO lpttsi =
443 (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
444 if (lpttsi == NULL) {
445 lpttsi = (LPTT_SUBCLASS_INFO)HeapAlloc (GetProcessHeap(),
446 HEAP_ZERO_MEMORY, sizeof(TT_SUBCLASS_INFO));
447 lpttsi->wpOrigProc =
448 (WNDPROC32)SetWindowLong32A ((HWND32)toolPtr->uId,
449 GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc);
450 lpttsi->hwndToolTip = wndPtr->hwndSelf;
451 lpttsi->uRefCount++;
452 SetProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP,
453 (HANDLE32)lpttsi);
455 else
456 ERR (tooltips, "A window tool must only be listed once!\n");
458 else {
459 LPTT_SUBCLASS_INFO lpttsi =
460 (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, TT_SUBCLASS_PROP);
461 if (lpttsi == NULL) {
462 lpttsi = (LPTT_SUBCLASS_INFO)HeapAlloc (GetProcessHeap(),
463 HEAP_ZERO_MEMORY, sizeof(TT_SUBCLASS_INFO));
464 lpttsi->wpOrigProc =
465 (WNDPROC32)SetWindowLong32A (toolPtr->hwnd,
466 GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc);
467 lpttsi->hwndToolTip = wndPtr->hwndSelf;
468 lpttsi->uRefCount++;
469 SetProp32A (toolPtr->hwnd, TT_SUBCLASS_PROP, (HANDLE32)lpttsi);
471 else
472 lpttsi->uRefCount++;
474 TRACE (tooltips, "subclassing installed!\n");
477 return TRUE;
481 // << TOOLTIPS_AddTool32W >>
484 static LRESULT
485 TOOLTIPS_DelTool32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
487 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
488 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
489 TTTOOL_INFO *toolPtr;
490 INT32 nTool;
492 if (lpToolInfo == NULL) return 0;
493 if (infoPtr->uNumTools == 0) return 0;
495 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
496 if (nTool == -1) return 0;
498 TRACE (tooltips, "tool %d\n", nTool);
500 /* delete text string */
501 toolPtr = &infoPtr->tools[nTool];
502 if ((toolPtr->hinst) && (toolPtr->lpszText)) {
503 if (toolPtr->lpszText != LPSTR_TEXTCALLBACK32A)
504 HeapFree (GetProcessHeap (), 0, toolPtr->lpszText);
507 /* remove subclassing */
508 if (toolPtr->uFlags & TTF_SUBCLASS) {
509 if (toolPtr->uFlags & TTF_IDISHWND) {
510 LPTT_SUBCLASS_INFO lpttsi =
511 (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
512 if (lpttsi) {
513 SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
514 (LONG)lpttsi->wpOrigProc);
515 RemoveProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
516 HeapFree (GetProcessHeap(), 0, &lpttsi);
518 else
519 ERR (tooltips, "Invalid data handle!\n");
521 else {
522 LPTT_SUBCLASS_INFO lpttsi =
523 (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, TT_SUBCLASS_PROP);
524 if (lpttsi) {
525 if (lpttsi->uRefCount == 1) {
526 SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
527 (LONG)lpttsi->wpOrigProc);
528 RemoveProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
529 HeapFree (GetProcessHeap(), 0, &lpttsi);
531 else
532 lpttsi->uRefCount--;
534 else
535 ERR (tooltips, "Invalid data handle!\n");
539 /* delete tool from tool list */
540 if (infoPtr->uNumTools == 1) {
541 HeapFree (GetProcessHeap (), 0, infoPtr->tools);
542 infoPtr->tools = NULL;
544 else {
545 TTTOOL_INFO *oldTools = infoPtr->tools;
546 infoPtr->tools =
547 HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
548 sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1));
550 if (nTool > 0)
551 memcpy (&infoPtr->tools[0], &oldTools[0],
552 nTool * sizeof(TTTOOL_INFO));
554 if (nTool < infoPtr->uNumTools - 1)
555 memcpy (&infoPtr->tools[nTool], &oldTools[nTool + 1],
556 (infoPtr->uNumTools - nTool - 1) * sizeof(TTTOOL_INFO));
558 HeapFree (GetProcessHeap (), 0, oldTools);
561 infoPtr->uNumTools--;
563 return 0;
567 // << TOOLTIPS_DelTool32W >>
570 static LRESULT
571 TOOLTIPS_EnumTools32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
573 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
574 UINT32 uIndex = (UINT32)wParam;
575 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
576 TTTOOL_INFO *toolPtr;
578 if (uIndex >= infoPtr->uNumTools) return FALSE;
579 if (lpToolInfo == NULL) return FALSE;
581 TRACE (tooltips, "index=%u\n", uIndex);
583 toolPtr = &infoPtr->tools[uIndex];
585 /* copy tool data */
586 lpToolInfo->uFlags = toolPtr->uFlags;
587 lpToolInfo->hwnd = toolPtr->hwnd;
588 lpToolInfo->uId = toolPtr->uId;
589 lpToolInfo->rect = toolPtr->rect;
590 lpToolInfo->hinst = toolPtr->hinst;
591 lpToolInfo->lpszText = toolPtr->lpszText;
593 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A))
594 lpToolInfo->lParam = toolPtr->lParam;
596 return TRUE;
600 // << TOOLTIPS_EnumTools32W >>
603 static LRESULT
604 TOOLTIPS_GetCurrentTool32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
606 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
607 LPTTTOOLINFO32A lpti = (LPTTTOOLINFO32A)lParam;
608 TTTOOL_INFO *toolPtr;
610 if (lpti) {
611 if (infoPtr->nCurrentTool > -1) {
612 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
614 /* copy tool data */
615 lpti->uFlags = toolPtr->uFlags;
616 lpti->rect = toolPtr->rect;
617 lpti->hinst = toolPtr->hinst;
618 lpti->lpszText = toolPtr->lpszText;
620 if (lpti->cbSize >= sizeof(TTTOOLINFO32A))
621 lpti->lParam = toolPtr->lParam;
623 return TRUE;
625 else
626 return FALSE;
628 else
629 return (infoPtr->nCurrentTool != -1);
631 return FALSE;
635 // << TOOLTIPS_GetCurrentTool32W >>
638 static LRESULT
639 TOOLTIPS_GetDelayTime (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
641 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
643 switch (wParam) {
644 case TTDT_AUTOMATIC:
645 return infoPtr->nAutomaticTime;
647 case TTDT_RESHOW:
648 return infoPtr->nReshowTime;
650 case TTDT_AUTOPOP:
651 return infoPtr->nAutoPopTime;
653 case TTDT_INITIAL:
654 return infoPtr->nInitialTime;
657 return 0;
661 static LRESULT
662 TOOLTIPS_GetMargin (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
664 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
665 LPRECT32 lpRect = (LPRECT32)lParam;
667 lpRect->left = infoPtr->rcMargin.left;
668 lpRect->right = infoPtr->rcMargin.right;
669 lpRect->bottom = infoPtr->rcMargin.bottom;
670 lpRect->top = infoPtr->rcMargin.top;
672 return 0;
676 static LRESULT
677 TOOLTIPS_GetMaxTipWidth (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
679 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
681 return infoPtr->nMaxTipWidth;
685 static LRESULT
686 TOOLTIPS_GetText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
688 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
689 LPTTTOOLINFO32A lpti = (LPTTTOOLINFO32A)lParam;
690 INT32 nTool;
692 if (!(lpti)) return 0;
693 if (lpti->cbSize < sizeof(TTTOOLINFO32A)) return 0;
695 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpti);
696 if (nTool == -1) return 0;
698 lstrcpy32A (lpti->lpszText, infoPtr->tools[nTool].lpszText);
700 return 0;
704 // << TOOLTIPS_GetText32W >>
707 static LRESULT
708 TOOLTIPS_GetTipBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
710 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
711 return infoPtr->clrBk;
715 static LRESULT
716 TOOLTIPS_GetTipTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
718 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
719 return infoPtr->clrText;
723 static LRESULT
724 TOOLTIPS_GetToolCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
726 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
727 return infoPtr->uNumTools;
731 static LRESULT
732 TOOLTIPS_GetToolInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
734 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
735 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
736 TTTOOL_INFO *toolPtr;
737 INT32 nTool;
739 if (lpToolInfo == NULL) return FALSE;
740 if (infoPtr->uNumTools == 0) return FALSE;
742 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
743 if (nTool == -1) return FALSE;
745 TRACE (tooltips, "tool %d\n", nTool);
747 toolPtr = &infoPtr->tools[nTool];
749 /* copy tool data */
750 lpToolInfo->uFlags = toolPtr->uFlags;
751 lpToolInfo->rect = toolPtr->rect;
752 lpToolInfo->hinst = toolPtr->hinst;
753 lpToolInfo->lpszText = toolPtr->lpszText;
755 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A))
756 lpToolInfo->lParam = toolPtr->lParam;
758 return TRUE;
762 // << TOOLTIPS_GetToolInfo32W >>
765 static LRESULT
766 TOOLTIPS_HitTest32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
768 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
769 LPTTHITTESTINFO32A lptthit = (LPTTHITTESTINFO32A)lParam;
770 TTTOOL_INFO *toolPtr;
771 INT32 nTool;
773 if (lptthit == 0)
774 return FALSE;
776 nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lptthit->hwnd, &lptthit->pt);
777 if (nTool == -1)
778 return FALSE;
780 TRACE (tooltips, "tool %d!\n", nTool);
782 /* copy tool data */
783 toolPtr = &infoPtr->tools[nTool];
784 lptthit->ti.cbSize = sizeof(TTTOOLINFO32A);
785 lptthit->ti.uFlags = toolPtr->uFlags;
786 lptthit->ti.hwnd = toolPtr->hwnd;
787 lptthit->ti.uId = toolPtr->uId;
788 lptthit->ti.rect = toolPtr->rect;
789 lptthit->ti.hinst = toolPtr->hinst;
790 lptthit->ti.lpszText = toolPtr->lpszText;
791 lptthit->ti.lParam = toolPtr->lParam;
793 return TRUE;
797 // << TOOLTIPS_HitTest32W >>
800 static LRESULT
801 TOOLTIPS_NewToolRect32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
803 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
804 LPTTTOOLINFO32A lpti = (LPTTTOOLINFO32A)lParam;
805 INT32 nTool;
807 if (!(lpti)) return 0;
808 #if 0
809 if (lpti->cbSize < sizeof(TTTOOLINFO32A)) return 0;
810 #endif
812 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpti);
813 if (nTool == -1) return 0;
815 infoPtr->tools[nTool].rect = lpti->rect;
817 return 0;
821 // << TOOLTIPS_NewToolRect32W >>
824 static LRESULT
825 TOOLTIPS_Pop (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
827 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
829 TOOLTIPS_Hide (wndPtr, infoPtr);
831 return 0;
835 static LRESULT
836 TOOLTIPS_RelayEvent (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
838 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
839 LPMSG32 lpMsg = (LPMSG32)lParam;
840 POINT32 pt;
842 if (lParam == NULL) {
843 ERR (tooltips, "lpMsg == NULL!\n");
844 return 0;
847 switch (lpMsg->message) {
848 case WM_LBUTTONDOWN:
849 case WM_LBUTTONUP:
850 case WM_MBUTTONDOWN:
851 case WM_MBUTTONUP:
852 case WM_RBUTTONDOWN:
853 case WM_RBUTTONUP:
854 pt = lpMsg->pt;
855 ScreenToClient32 (lpMsg->hwnd, &pt);
856 infoPtr->nOldTool = infoPtr->nTool;
857 infoPtr->nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lpMsg->hwnd, &pt);
858 TRACE (tooltips, "tool (%x) %d %d\n",
859 wndPtr->hwndSelf, infoPtr->nOldTool, infoPtr->nTool);
860 TOOLTIPS_Hide (wndPtr, infoPtr);
861 break;
863 case WM_MOUSEMOVE:
864 pt = lpMsg->pt;
865 ScreenToClient32 (lpMsg->hwnd, &pt);
866 infoPtr->nOldTool = infoPtr->nTool;
867 infoPtr->nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lpMsg->hwnd, &pt);
868 TRACE (tooltips, "tool (%x) %d %d\n",
869 wndPtr->hwndSelf, infoPtr->nOldTool, infoPtr->nTool);
870 TRACE (tooltips, "WM_MOUSEMOVE (%04x %d %d)\n",
871 wndPtr->hwndSelf, pt.x, pt.y);
872 if ((infoPtr->bActive) && (infoPtr->nTool != infoPtr->nOldTool)) {
873 if (infoPtr->nOldTool == -1) {
874 SetTimer32 (wndPtr->hwndSelf, ID_TIMER1,
875 infoPtr->nInitialTime, 0);
876 TRACE (tooltips, "timer 1 started!\n");
878 else {
879 TOOLTIPS_Hide (wndPtr, infoPtr);
880 SetTimer32 (wndPtr->hwndSelf, ID_TIMER1,
881 infoPtr->nReshowTime, 0);
882 TRACE (tooltips, "timer 2 started!\n");
885 if (infoPtr->nCurrentTool != -1) {
886 SetTimer32 (wndPtr->hwndSelf, ID_TIMER3, 100, 0);
887 TRACE (tooltips, "timer 3 started!\n");
889 break;
892 return 0;
896 static LRESULT
897 TOOLTIPS_SetDelayTime (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
899 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
900 INT32 nTime = (INT32)LOWORD(lParam);
902 switch (wParam) {
903 case TTDT_AUTOMATIC:
904 if (nTime == 0) {
905 infoPtr->nAutomaticTime = 500;
906 infoPtr->nReshowTime = 100;
907 infoPtr->nAutoPopTime = 5000;
908 infoPtr->nInitialTime = 500;
910 else {
911 infoPtr->nAutomaticTime = nTime;
912 infoPtr->nReshowTime = nTime / 5;
913 infoPtr->nAutoPopTime = nTime * 10;
914 infoPtr->nInitialTime = nTime;
916 break;
918 case TTDT_RESHOW:
919 infoPtr->nReshowTime = nTime;
920 break;
922 case TTDT_AUTOPOP:
923 infoPtr->nAutoPopTime = nTime;
924 break;
926 case TTDT_INITIAL:
927 infoPtr->nInitialTime = nTime;
928 break;
931 return 0;
935 static LRESULT
936 TOOLTIPS_SetMargin (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
938 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
939 LPRECT32 lpRect = (LPRECT32)lParam;
941 infoPtr->rcMargin.left = lpRect->left;
942 infoPtr->rcMargin.right = lpRect->right;
943 infoPtr->rcMargin.bottom = lpRect->bottom;
944 infoPtr->rcMargin.top = lpRect->top;
946 return 0;
950 static LRESULT
951 TOOLTIPS_SetMaxTipWidth (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
953 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
954 INT32 nTemp = infoPtr->nMaxTipWidth;
956 infoPtr->nMaxTipWidth = (INT32)lParam;
958 return nTemp;
962 static LRESULT
963 TOOLTIPS_SetTipBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
965 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
967 infoPtr->clrBk = (COLORREF)wParam;
969 return 0;
973 static LRESULT
974 TOOLTIPS_SetTipTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
976 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
978 infoPtr->clrText = (COLORREF)wParam;
980 return 0;
984 static LRESULT
985 TOOLTIPS_SetToolInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
987 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
988 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
989 TTTOOL_INFO *toolPtr;
990 INT32 nTool;
992 if (lpToolInfo == NULL) return 0;
994 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
995 if (nTool == -1) return 0;
997 TRACE (tooltips, "tool %d\n", nTool);
999 toolPtr = &infoPtr->tools[nTool];
1001 /* copy tool data */
1002 toolPtr->uFlags = lpToolInfo->uFlags;
1003 toolPtr->hwnd = lpToolInfo->hwnd;
1004 toolPtr->uId = lpToolInfo->uId;
1005 toolPtr->rect = lpToolInfo->rect;
1006 toolPtr->hinst = lpToolInfo->hinst;
1008 if (lpToolInfo->hinst) {
1009 toolPtr->lpszText = lpToolInfo->lpszText;
1011 else if (lpToolInfo->lpszText) {
1012 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACK32A)
1013 toolPtr->lpszText = lpToolInfo->lpszText;
1014 else {
1015 INT32 len = lstrlen32A (lpToolInfo->lpszText);
1016 HeapFree (GetProcessHeap (), 0, toolPtr->lpszText);
1017 toolPtr->lpszText =
1018 HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len + 1);
1019 lstrcpy32A (toolPtr->lpszText, lpToolInfo->lpszText);
1023 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A))
1024 toolPtr->lParam = lpToolInfo->lParam;
1026 return 0;
1030 // << TOOLTIPS_SetToolInfo32W >>
1033 static LRESULT
1034 TOOLTIPS_TrackActivate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1036 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1037 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
1039 if ((BOOL32)wParam) {
1040 /* activate */
1041 infoPtr->nTrackTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1042 if (infoPtr->nTrackTool != -1) {
1043 infoPtr->bTrackActive = TRUE;
1045 /* FIXME : show tool tip */
1048 else {
1049 /* deactivate */
1050 /* FIXME : hide tool tip */
1052 infoPtr->bTrackActive = FALSE;
1053 infoPtr->nTrackTool = -1;
1056 return 0;
1060 static LRESULT
1061 TOOLTIPS_TrackPosition (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1063 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1065 infoPtr->xTrackPos = (INT32)LOWORD(lParam);
1066 infoPtr->yTrackPos = (INT32)HIWORD(lParam);
1068 if (infoPtr->bTrackActive) {
1070 FIXME (tooltips, "set position!\n");
1073 return 0;
1077 static LRESULT
1078 TOOLTIPS_Update (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1080 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1082 if (infoPtr->nCurrentTool != -1)
1083 UpdateWindow32 (wndPtr->hwndSelf);
1085 return 0;
1089 static LRESULT
1090 TOOLTIPS_UpdateTipText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1092 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1093 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
1094 TTTOOL_INFO *toolPtr;
1095 INT32 nTool;
1097 if (lpToolInfo == NULL) return 0;
1099 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1100 if (nTool == -1) return 0;
1102 TRACE (tooltips, "tool %d\n", nTool);
1104 toolPtr = &infoPtr->tools[nTool];
1106 /* copy tool text */
1107 toolPtr->hinst = lpToolInfo->hinst;
1109 if (lpToolInfo->hinst) {
1110 toolPtr->lpszText = lpToolInfo->lpszText;
1112 else if (lpToolInfo->lpszText) {
1113 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACK32A)
1114 toolPtr->lpszText = lpToolInfo->lpszText;
1115 else {
1116 INT32 len = lstrlen32A (lpToolInfo->lpszText);
1117 HeapFree (GetProcessHeap (), 0, toolPtr->lpszText);
1118 toolPtr->lpszText =
1119 HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len + 1);
1120 lstrcpy32A (toolPtr->lpszText, lpToolInfo->lpszText);
1124 return 0;
1128 // << TOOLTIPS_UpdateTipText32W >>
1131 static LRESULT
1132 TOOLTIPS_WindowFromPoint (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1134 return WindowFromPoint32 (*((LPPOINT32)lParam));
1139 static LRESULT
1140 TOOLTIPS_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1142 TOOLTIPS_INFO *infoPtr;
1143 LOGFONT32A logFont;
1145 /* allocate memory for info structure */
1146 infoPtr = (TOOLTIPS_INFO *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
1147 sizeof(TOOLTIPS_INFO));
1148 wndPtr->wExtra[0] = (DWORD)infoPtr;
1150 if (infoPtr == NULL) {
1151 ERR (tooltips, "could not allocate info memory!\n");
1152 return 0;
1155 /* initialize info structure */
1156 infoPtr->bActive = TRUE;
1157 infoPtr->bTrackActive = FALSE;
1158 infoPtr->clrBk = GetSysColor32 (COLOR_INFOBK);
1159 infoPtr->clrText = GetSysColor32 (COLOR_INFOTEXT);
1161 SystemParametersInfo32A( SPI_GETICONTITLELOGFONT, 0, &logFont, 0 );
1162 infoPtr->hFont = CreateFontIndirect32A( &logFont );
1164 infoPtr->nMaxTipWidth = -1;
1165 infoPtr->nTool = -1;
1166 infoPtr->nOldTool = -1;
1167 infoPtr->nCurrentTool = -1;
1168 infoPtr->nTrackTool = -1;
1170 infoPtr->nAutomaticTime = 500;
1171 infoPtr->nReshowTime = 100;
1172 infoPtr->nAutoPopTime = 5000;
1173 infoPtr->nInitialTime = 500;
1175 SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0, SWP_HIDEWINDOW);
1177 return 0;
1181 static LRESULT
1182 TOOLTIPS_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1184 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1185 TTTOOL_INFO *toolPtr;
1187 /* free tools */
1188 if (infoPtr->tools) {
1189 INT32 i;
1190 for (i = 0; i < infoPtr->uNumTools; i++) {
1191 toolPtr = &infoPtr->tools[i];
1192 if ((toolPtr->hinst) && (toolPtr->lpszText)) {
1193 if (toolPtr->lpszText != LPSTR_TEXTCALLBACK32A)
1194 HeapFree (GetProcessHeap (), 0, toolPtr->lpszText);
1197 /* remove subclassing */
1198 if (toolPtr->uFlags & TTF_SUBCLASS) {
1199 LPTT_SUBCLASS_INFO lpttsi;
1201 if (toolPtr->uFlags & TTF_IDISHWND)
1202 lpttsi = (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
1203 else
1204 lpttsi = (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, TT_SUBCLASS_PROP);
1206 if (lpttsi) {
1207 SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
1208 (LONG)lpttsi->wpOrigProc);
1209 RemoveProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP);
1210 HeapFree (GetProcessHeap(), 0, &lpttsi);
1214 HeapFree (GetProcessHeap (), 0, infoPtr->tools);
1217 /* delete font */
1218 DeleteObject32 (infoPtr->hFont);
1220 /* free tool tips info data */
1221 HeapFree (GetProcessHeap (), 0, infoPtr);
1223 return 0;
1227 static LRESULT
1228 TOOLTIPS_EraseBackground (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1230 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1231 RECT32 rect;
1232 HBRUSH32 hBrush;
1234 hBrush = CreateSolidBrush32 (infoPtr->clrBk);
1235 GetClientRect32 (wndPtr->hwndSelf, &rect);
1236 FillRect32 ((HDC32)wParam, &rect, hBrush);
1237 DeleteObject32 (hBrush);
1239 return FALSE;
1243 static LRESULT
1244 TOOLTIPS_GetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1246 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1248 return infoPtr->hFont;
1252 static LRESULT
1253 TOOLTIPS_MouseMove (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1255 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1257 TOOLTIPS_Hide (wndPtr, infoPtr);
1259 return 0;
1263 static LRESULT
1264 TOOLTIPS_NcCreate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1266 wndPtr->dwStyle &= 0x0000FFFF;
1267 wndPtr->dwStyle |= (WS_POPUP | WS_BORDER);
1269 return TRUE;
1273 static LRESULT
1274 TOOLTIPS_Paint (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1276 HDC32 hdc;
1277 PAINTSTRUCT32 ps;
1279 hdc = wParam==0 ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
1280 TOOLTIPS_Refresh (wndPtr, hdc);
1281 if (!wParam)
1282 EndPaint32 (wndPtr->hwndSelf, &ps);
1283 return 0;
1287 static LRESULT
1288 TOOLTIPS_SetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1290 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1292 infoPtr->hFont = (HFONT32)wParam;
1294 if ((LOWORD(lParam)) & (infoPtr->nCurrentTool != -1)) {
1295 FIXME (tooltips, "full redraw needed!\n");
1298 return 0;
1302 static LRESULT
1303 TOOLTIPS_Timer (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1305 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1307 TRACE (tooltips, "timer %d (%x) expired!\n", wParam, wndPtr->hwndSelf);
1309 switch (wParam)
1311 case ID_TIMER1:
1312 KillTimer32 (wndPtr->hwndSelf, ID_TIMER1);
1313 TOOLTIPS_Show (wndPtr, infoPtr);
1314 break;
1316 case ID_TIMER2:
1317 TOOLTIPS_Hide (wndPtr, infoPtr);
1318 break;
1320 case ID_TIMER3:
1321 KillTimer32 (wndPtr->hwndSelf, ID_TIMER3);
1322 if (TOOLTIPS_CheckTool (wndPtr) == FALSE) {
1323 infoPtr->nTool = -1;
1324 infoPtr->nOldTool = -1;
1325 TOOLTIPS_Hide (wndPtr, infoPtr);
1327 break;
1329 return 0;
1333 static LRESULT
1334 TOOLTIPS_WinIniChange (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1336 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1337 LOGFONT32A logFont;
1339 infoPtr->clrBk = GetSysColor32 (COLOR_INFOBK);
1340 infoPtr->clrText = GetSysColor32 (COLOR_INFOTEXT);
1342 DeleteObject32 (infoPtr->hFont);
1343 SystemParametersInfo32A( SPI_GETICONTITLELOGFONT, 0, &logFont, 0 );
1344 infoPtr->hFont = CreateFontIndirect32A( &logFont );
1346 return 0;
1350 LRESULT CALLBACK
1351 TOOLTIPS_SubclassProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
1353 LPTT_SUBCLASS_INFO lpttsi =
1354 (LPTT_SUBCLASS_INFO)GetProp32A (hwnd, TT_SUBCLASS_PROP);
1355 WND *wndPtr;
1356 TOOLTIPS_INFO *infoPtr;
1357 UINT32 nTool;
1359 switch (uMsg) {
1360 case WM_LBUTTONDOWN:
1361 case WM_LBUTTONUP:
1362 case WM_MBUTTONDOWN:
1363 case WM_MBUTTONUP:
1364 case WM_RBUTTONDOWN:
1365 case WM_RBUTTONUP:
1367 wndPtr = WIN_FindWndPtr(lpttsi->hwndToolTip);
1368 infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1369 nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd);
1371 TRACE (tooltips, "subclassed mouse message %04x\n", uMsg);
1372 infoPtr->nOldTool = infoPtr->nTool;
1373 infoPtr->nTool = nTool;
1374 TOOLTIPS_Hide (wndPtr, infoPtr);
1376 break;
1378 case WM_MOUSEMOVE:
1380 wndPtr = WIN_FindWndPtr(lpttsi->hwndToolTip);
1381 infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1382 nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd);
1384 TRACE (tooltips, "subclassed WM_MOUSEMOVE\n");
1385 infoPtr->nOldTool = infoPtr->nTool;
1386 infoPtr->nTool = nTool;
1388 if ((infoPtr->bActive) &&
1389 (infoPtr->nTool != infoPtr->nOldTool)) {
1390 if (infoPtr->nOldTool == -1) {
1391 SetTimer32 (wndPtr->hwndSelf, ID_TIMER1,
1392 infoPtr->nInitialTime, 0);
1393 TRACE (tooltips, "timer 1 started!\n");
1395 else {
1396 TOOLTIPS_Hide (wndPtr, infoPtr);
1397 SetTimer32 (wndPtr->hwndSelf, ID_TIMER1,
1398 infoPtr->nReshowTime, 0);
1399 TRACE (tooltips, "timer 2 started!\n");
1402 if (infoPtr->nCurrentTool != -1) {
1403 SetTimer32 (wndPtr->hwndSelf, ID_TIMER3, 100, 0);
1404 TRACE (tooltips, "timer 3 started!\n");
1407 break;
1410 return CallWindowProc32A (lpttsi->wpOrigProc, hwnd, uMsg, wParam, lParam);
1414 LRESULT CALLBACK
1415 TOOLTIPS_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
1417 WND *wndPtr = WIN_FindWndPtr(hwnd);
1419 switch (uMsg)
1421 case TTM_ACTIVATE:
1422 return TOOLTIPS_Activate (wndPtr, wParam, lParam);
1424 case TTM_ADDTOOL32A:
1425 return TOOLTIPS_AddTool32A (wndPtr, wParam, lParam);
1427 // case TTM_ADDTOOL32W:
1429 case TTM_DELTOOL32A:
1430 return TOOLTIPS_DelTool32A (wndPtr, wParam, lParam);
1432 // case TTM_DELTOOL32W:
1434 case TTM_ENUMTOOLS32A:
1435 return TOOLTIPS_EnumTools32A (wndPtr, wParam, lParam);
1437 // case TTM_ENUMTOOLS32W:
1439 case TTM_GETCURRENTTOOL32A:
1440 return TOOLTIPS_GetCurrentTool32A (wndPtr, wParam, lParam);
1442 // case TTM_GETCURRENTTOOL32W:
1444 case TTM_GETDELAYTIME:
1445 return TOOLTIPS_GetDelayTime (wndPtr, wParam, lParam);
1447 case TTM_GETMARGIN:
1448 return TOOLTIPS_GetMargin (wndPtr, wParam, lParam);
1450 case TTM_GETMAXTIPWIDTH:
1451 return TOOLTIPS_GetMaxTipWidth (wndPtr, wParam, lParam);
1453 case TTM_GETTEXT32A:
1454 return TOOLTIPS_GetText32A (wndPtr, wParam, lParam);
1456 // case TTM_GETTEXT32W:
1458 case TTM_GETTIPBKCOLOR:
1459 return TOOLTIPS_GetTipBkColor (wndPtr, wParam, lParam);
1461 case TTM_GETTIPTEXTCOLOR:
1462 return TOOLTIPS_GetTipTextColor (wndPtr, wParam, lParam);
1464 case TTM_GETTOOLCOUNT:
1465 return TOOLTIPS_GetToolCount (wndPtr, wParam, lParam);
1467 case TTM_GETTOOLINFO32A:
1468 return TOOLTIPS_GetToolInfo32A (wndPtr, wParam, lParam);
1470 // case TTM_GETTOOLINFO32W:
1472 case TTM_HITTEST32A:
1473 return TOOLTIPS_HitTest32A (wndPtr, wParam, lParam);
1475 // case TTM_HITTEST32W:
1477 case TTM_NEWTOOLRECT32A:
1478 return TOOLTIPS_NewToolRect32A (wndPtr, wParam, lParam);
1480 // case TTM_NEWTOOLRECT32W:
1482 case TTM_POP:
1483 return TOOLTIPS_Pop (wndPtr, wParam, lParam);
1485 case TTM_RELAYEVENT:
1486 return TOOLTIPS_RelayEvent (wndPtr, wParam, lParam);
1488 case TTM_SETDELAYTIME:
1489 return TOOLTIPS_SetDelayTime (wndPtr, wParam, lParam);
1491 case TTM_SETMARGIN:
1492 return TOOLTIPS_SetMargin (wndPtr, wParam, lParam);
1494 case TTM_SETMAXTIPWIDTH:
1495 return TOOLTIPS_SetMaxTipWidth (wndPtr, wParam, lParam);
1497 case TTM_SETTIPBKCOLOR:
1498 return TOOLTIPS_SetTipBkColor (wndPtr, wParam, lParam);
1500 case TTM_SETTIPTEXTCOLOR:
1501 return TOOLTIPS_SetTipTextColor (wndPtr, wParam, lParam);
1503 case TTM_SETTOOLINFO32A:
1504 return TOOLTIPS_SetToolInfo32A (wndPtr, wParam, lParam);
1506 // case TTM_SETTOOLINFO32W:
1508 case TTM_TRACKACTIVATE:
1509 return TOOLTIPS_TrackActivate (wndPtr, wParam, lParam);
1511 case TTM_TRACKPOSITION:
1512 return TOOLTIPS_TrackPosition (wndPtr, wParam, lParam);
1514 case TTM_UPDATE:
1515 return TOOLTIPS_Update (wndPtr, wParam, lParam);
1517 case TTM_UPDATETIPTEXT32A:
1518 return TOOLTIPS_UpdateTipText32A (wndPtr, wParam, lParam);
1520 // case TTM_UPDATETIPTEXT32W:
1522 case TTM_WINDOWFROMPOINT:
1523 return TOOLTIPS_WindowFromPoint (wndPtr, wParam, lParam);
1526 case WM_CREATE:
1527 return TOOLTIPS_Create (wndPtr, wParam, lParam);
1529 case WM_DESTROY:
1530 return TOOLTIPS_Destroy (wndPtr, wParam, lParam);
1532 case WM_ERASEBKGND:
1533 return TOOLTIPS_EraseBackground (wndPtr, wParam, lParam);
1535 case WM_GETFONT:
1536 return TOOLTIPS_GetFont (wndPtr, wParam, lParam);
1538 // case WM_GETTEXT:
1539 // case WM_GETTEXTLENGTH:
1540 // case WM_LBUTTONDOWN:
1541 // case WM_MBUTTONDOWN:
1543 case WM_MOUSEMOVE:
1544 return TOOLTIPS_MouseMove (wndPtr, wParam, lParam);
1546 case WM_NCCREATE:
1547 return TOOLTIPS_NcCreate (wndPtr, wParam, lParam);
1549 // case WM_NCHITTEST:
1550 // case WM_NOTIFYFORMAT:
1552 case WM_PAINT:
1553 return TOOLTIPS_Paint (wndPtr, wParam, lParam);
1555 // case WM_PRINTCLIENT:
1556 // case WM_RBUTTONDOWN:
1558 case WM_SETFONT:
1559 return TOOLTIPS_SetFont (wndPtr, wParam, lParam);
1561 // case WM_STYLECHANGED:
1563 case WM_TIMER:
1564 return TOOLTIPS_Timer (wndPtr, wParam, lParam);
1566 case WM_WININICHANGE:
1567 return TOOLTIPS_WinIniChange (wndPtr, wParam, lParam);
1569 default:
1570 if (uMsg >= WM_USER)
1571 ERR (tooltips, "unknown msg %04x wp=%08x lp=%08lx\n",
1572 uMsg, wParam, lParam);
1573 return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
1575 return 0;
1579 void
1580 TOOLTIPS_Register (void)
1582 WNDCLASS32A wndClass;
1584 if (GlobalFindAtom32A (TOOLTIPS_CLASS32A)) return;
1586 ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
1587 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS;
1588 wndClass.lpfnWndProc = (WNDPROC32)TOOLTIPS_WindowProc;
1589 wndClass.cbClsExtra = 0;
1590 wndClass.cbWndExtra = sizeof(TOOLTIPS_INFO *);
1591 wndClass.hCursor = LoadCursor32A (0, IDC_ARROW32A);
1592 wndClass.hbrBackground = 0;
1593 wndClass.lpszClassName = TOOLTIPS_CLASS32A;
1595 RegisterClass32A (&wndClass);