Moved everything out of windows.h.
[wine] / dlls / comctl32 / tooltips.c
1 /*
2  * Tool tip control
3  *
4  * Copyright 1998 Eric Kohl
5  *
6  * TODO:
7  *   - Unicode support.
8  *   - Custom draw support.
9  *
10  * Testing:
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.
15  */
16
17 #include "windows.h"
18 #include "commctrl.h"
19 #include "tooltips.h"
20 #include "win.h"
21 #include "debug.h"
22
23 #define ID_TIMERSHOW   1    /* show delay timer */
24 #define ID_TIMERPOP    2    /* auto pop timer */
25 #define ID_TIMERLEAVE  3    /* tool leave timer */
26
27
28 extern LPSTR COMCTL32_aSubclass; /* global subclassing atom */
29
30 /* property name of tooltip window handle */
31 /*#define TT_SUBCLASS_PROP "CC32SubclassInfo" */
32
33 #define TOOLTIPS_GetInfoPtr(wndPtr) ((TOOLTIPS_INFO *)wndPtr->wExtra[0])
34
35
36 LRESULT CALLBACK
37 TOOLTIPS_SubclassProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam);
38
39
40 static VOID
41 TOOLTIPS_Refresh (WND *wndPtr, HDC32 hdc)
42 {
43     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
44     RECT32 rc;
45     INT32 oldBkMode;
46     HFONT32 hOldFont;
47     HBRUSH32 hBrush;
48     UINT32 uFlags = DT_EXTERNALLEADING;
49
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
56     /* fill the background */
57     hBrush = CreateSolidBrush32 (infoPtr->clrBk);
58     FillRect32 (hdc, &rc, hBrush);
59     DeleteObject32 (hBrush);
60
61     /* calculate text rectangle */
62     rc.left   += (2 + infoPtr->rcMargin.left);
63     rc.top    += (2 + infoPtr->rcMargin.top);
64     rc.right  -= (2 + infoPtr->rcMargin.right);
65     rc.bottom -= (2 + infoPtr->rcMargin.bottom);
66
67     /* draw text */
68     oldBkMode = SetBkMode32 (hdc, TRANSPARENT);
69     SetTextColor32 (hdc, infoPtr->clrText);
70     hOldFont = SelectObject32 (hdc, infoPtr->hFont);
71     DrawText32W (hdc, infoPtr->szTipText, -1, &rc, uFlags);
72     SelectObject32 (hdc, hOldFont);
73     if (oldBkMode != TRANSPARENT)
74         SetBkMode32 (hdc, oldBkMode);
75 }
76
77
78 static VOID
79 TOOLTIPS_GetTipText (WND *wndPtr, TOOLTIPS_INFO *infoPtr, INT32 nTool)
80 {
81     TTTOOL_INFO *toolPtr = &infoPtr->tools[nTool];
82
83     if ((toolPtr->hinst) && (HIWORD((UINT32)toolPtr->lpszText) == 0)) {
84         /* load a resource */
85         TRACE (tooltips, "load res string %x %x\n",
86                toolPtr->hinst, (int)toolPtr->lpszText);
87         LoadString32W (toolPtr->hinst, (UINT32)toolPtr->lpszText,
88                        infoPtr->szTipText, INFOTIPSIZE);
89     }
90     else if (toolPtr->lpszText) {
91         if (toolPtr->lpszText == LPSTR_TEXTCALLBACK32W) {
92             NMTTDISPINFO32A ttnmdi;
93
94             /* fill NMHDR struct */
95             ZeroMemory (&ttnmdi, sizeof(NMTTDISPINFO32A));
96             ttnmdi.hdr.hwndFrom = wndPtr->hwndSelf;
97             ttnmdi.hdr.idFrom = toolPtr->uId;
98             ttnmdi.hdr.code = TTN_GETDISPINFO32A;
99             ttnmdi.lpszText = (LPSTR)&ttnmdi.szText;
100             ttnmdi.uFlags = toolPtr->uFlags;
101             ttnmdi.lParam = toolPtr->lParam;
102
103             TRACE (tooltips, "hdr.idFrom = %x\n", ttnmdi.hdr.idFrom);
104             SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
105                             (WPARAM32)toolPtr->uId, (LPARAM)&ttnmdi);
106
107             if ((ttnmdi.hinst) && (HIWORD((UINT32)ttnmdi.szText) == 0)) {
108                 LoadString32W (ttnmdi.hinst, (UINT32)ttnmdi.szText,
109                                infoPtr->szTipText, INFOTIPSIZE);
110                 if (ttnmdi.uFlags & TTF_DI_SETITEM) {
111                     toolPtr->hinst = ttnmdi.hinst;
112                     toolPtr->lpszText = (LPWSTR)ttnmdi.szText;
113                 }
114             }
115             else if (ttnmdi.szText[0]) {
116                 lstrcpynAtoW (infoPtr->szTipText, ttnmdi.szText, 80);
117                 if (ttnmdi.uFlags & TTF_DI_SETITEM) {
118                     INT32 len = lstrlen32A (ttnmdi.szText);
119                     toolPtr->hinst = 0;
120                     toolPtr->lpszText = COMCTL32_Alloc ((len+1)* sizeof(WCHAR));
121                     lstrcpyAtoW (toolPtr->lpszText, ttnmdi.szText);
122                 }
123             }
124             else if (ttnmdi.lpszText == 0) {
125                 /* no text available */
126                 infoPtr->szTipText[0] = L'\0';
127             }
128             else if (ttnmdi.lpszText != LPSTR_TEXTCALLBACK32A) {
129                 lstrcpynAtoW (infoPtr->szTipText, ttnmdi.lpszText, INFOTIPSIZE);
130                 if (ttnmdi.uFlags & TTF_DI_SETITEM) {
131                     INT32 len = lstrlen32A (ttnmdi.lpszText);
132                     toolPtr->hinst = 0;
133                     toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
134                     lstrcpyAtoW (toolPtr->lpszText, ttnmdi.lpszText);
135                 }
136             }
137             else {
138                 ERR (tooltips, "recursive text callback!\n");
139                 infoPtr->szTipText[0] = '\0';
140             }
141         }
142         else {
143             /* the item is a usual (unicode) text */
144             lstrcpyn32W (infoPtr->szTipText, toolPtr->lpszText, INFOTIPSIZE);
145         }
146     }
147     else {
148         /* no text available */
149         infoPtr->szTipText[0] = L'\0';
150     }
151
152     TRACE (tooltips, "\"%s\"\n", debugstr_w(infoPtr->szTipText));
153 }
154
155
156 static VOID
157 TOOLTIPS_CalcTipSize (WND *wndPtr, TOOLTIPS_INFO *infoPtr, LPSIZE32 lpSize)
158 {
159     HDC32 hdc;
160     HFONT32 hOldFont;
161     UINT32 uFlags = DT_EXTERNALLEADING | DT_CALCRECT;
162     RECT32 rc = {0, 0, 0, 0};
163
164     if (infoPtr->nMaxTipWidth > -1) {
165         rc.right = infoPtr->nMaxTipWidth;
166         uFlags |= DT_WORDBREAK;
167     }
168     if (wndPtr->dwStyle & TTS_NOPREFIX)
169         uFlags |= DT_NOPREFIX;
170     TRACE (tooltips, "\"%s\"\n", debugstr_w(infoPtr->szTipText));
171
172     hdc = GetDC32 (wndPtr->hwndSelf);
173     hOldFont = SelectObject32 (hdc, infoPtr->hFont);
174     DrawText32W (hdc, infoPtr->szTipText, -1, &rc, uFlags);
175     SelectObject32 (hdc, hOldFont);
176     ReleaseDC32 (wndPtr->hwndSelf, hdc);
177
178     lpSize->cx = rc.right - rc.left + 4 + 
179                  infoPtr->rcMargin.left + infoPtr->rcMargin.right;
180     lpSize->cy = rc.bottom - rc.top + 4 +
181                  infoPtr->rcMargin.bottom + infoPtr->rcMargin.top;
182 }
183
184
185 static VOID
186 TOOLTIPS_Show (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
187 {
188     TTTOOL_INFO *toolPtr;
189     RECT32 rect;
190     SIZE32 size;
191     HDC32  hdc;
192     NMHDR  hdr;
193
194     if (infoPtr->nTool == -1) {
195         TRACE (tooltips, "invalid tool (-1)!\n");
196         return;
197     }
198
199     infoPtr->nCurrentTool = infoPtr->nTool;
200
201     TRACE (tooltips, "Show tooltip pre %d!\n", infoPtr->nTool);
202
203     TOOLTIPS_GetTipText (wndPtr, infoPtr, infoPtr->nCurrentTool);
204
205     if (infoPtr->szTipText[0] == L'\0') {
206         infoPtr->nCurrentTool = -1;
207         return;
208     }
209
210     TRACE (tooltips, "Show tooltip %d!\n", infoPtr->nCurrentTool);
211     toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
212
213     hdr.hwndFrom = wndPtr->hwndSelf;
214     hdr.idFrom = toolPtr->uId;
215     hdr.code = TTN_SHOW;
216     SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
217                     (WPARAM32)toolPtr->uId, (LPARAM)&hdr);
218
219     TRACE (tooltips, "\"%s\"\n", debugstr_w(infoPtr->szTipText));
220
221     TOOLTIPS_CalcTipSize (wndPtr, infoPtr, &size);
222     TRACE (tooltips, "size %d - %d\n", size.cx, size.cy);
223
224     if (toolPtr->uFlags & TTF_CENTERTIP) {
225         RECT32 rc;
226
227         if (toolPtr->uFlags & TTF_IDISHWND)
228             GetWindowRect32 ((HWND32)toolPtr->uId, &rc);
229         else {
230             rc = toolPtr->rect;
231             MapWindowPoints32 (toolPtr->hwnd, (HWND32)0, (LPPOINT32)&rc, 2);
232         }
233         rect.left = (rc.left + rc.right - size.cx) / 2;
234         rect.top  = rc.bottom + 2;
235     }
236     else {
237         GetCursorPos32 ((LPPOINT32)&rect);
238         rect.top += 20;
239     }
240
241     /* FIXME: check position */
242
243     TRACE (tooltips, "pos %d - %d\n", rect.left, rect.top);
244
245     rect.right = rect.left + size.cx;
246     rect.bottom = rect.top + size.cy;
247
248     AdjustWindowRectEx32 (&rect, wndPtr->dwStyle, FALSE, wndPtr->dwExStyle);
249
250     SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, rect.left, rect.top,
251                     rect.right - rect.left, rect.bottom - rect.top,
252                     SWP_SHOWWINDOW);
253
254     /* repaint the tooltip */
255     hdc = GetDC32 (wndPtr->hwndSelf);
256     TOOLTIPS_Refresh (wndPtr, hdc);
257     ReleaseDC32 (wndPtr->hwndSelf, hdc);
258
259     SetTimer32 (wndPtr->hwndSelf, ID_TIMERPOP, infoPtr->nAutoPopTime, 0);
260 }
261
262
263 static VOID
264 TOOLTIPS_Hide (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
265 {
266     TTTOOL_INFO *toolPtr;
267     NMHDR hdr;
268
269     if (infoPtr->nCurrentTool == -1)
270         return;
271
272     toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
273     TRACE (tooltips, "Hide tooltip %d!\n", infoPtr->nCurrentTool);
274     KillTimer32 (wndPtr->hwndSelf, ID_TIMERPOP);
275
276     hdr.hwndFrom = wndPtr->hwndSelf;
277     hdr.idFrom = toolPtr->uId;
278     hdr.code = TTN_POP;
279     SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
280                     (WPARAM32)toolPtr->uId, (LPARAM)&hdr);
281
282     infoPtr->nCurrentTool = -1;
283
284     SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0,
285                     SWP_NOZORDER | SWP_HIDEWINDOW);
286 }
287
288
289 static VOID
290 TOOLTIPS_TrackShow (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
291 {
292     TTTOOL_INFO *toolPtr;
293     RECT32 rect;
294     SIZE32 size;
295     HDC32  hdc;
296     NMHDR hdr;
297
298     if (infoPtr->nTrackTool == -1) {
299         TRACE (tooltips, "invalid tracking tool (-1)!\n");
300         return;
301     }
302
303     TRACE (tooltips, "show tracking tooltip pre %d!\n", infoPtr->nTrackTool);
304
305     TOOLTIPS_GetTipText (wndPtr, infoPtr, infoPtr->nTrackTool);
306
307     if (infoPtr->szTipText[0] == L'\0') {
308         infoPtr->nTrackTool = -1;
309         return;
310     }
311
312     TRACE (tooltips, "show tracking tooltip %d!\n", infoPtr->nTrackTool);
313     toolPtr = &infoPtr->tools[infoPtr->nTrackTool];
314
315     hdr.hwndFrom = wndPtr->hwndSelf;
316     hdr.idFrom = toolPtr->uId;
317     hdr.code = TTN_SHOW;
318     SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
319                     (WPARAM32)toolPtr->uId, (LPARAM)&hdr);
320
321     TRACE (tooltips, "\"%s\"\n", debugstr_w(infoPtr->szTipText));
322
323     TOOLTIPS_CalcTipSize (wndPtr, infoPtr, &size);
324     TRACE (tooltips, "size %d - %d\n", size.cx, size.cy);
325
326     if (toolPtr->uFlags & TTF_ABSOLUTE) {
327         rect.left = infoPtr->xTrackPos;
328         rect.top  = infoPtr->yTrackPos;
329
330         if (toolPtr->uFlags & TTF_CENTERTIP) {
331             rect.left -= (size.cx / 2);
332             rect.top  -= (size.cy / 2);
333         }
334     }
335     else {
336         RECT32 rcTool;
337
338         if (toolPtr->uFlags & TTF_IDISHWND)
339             GetWindowRect32 ((HWND32)toolPtr->uId, &rcTool);
340         else {
341             rcTool = toolPtr->rect;
342             MapWindowPoints32 (toolPtr->hwnd, (HWND32)0, (LPPOINT32)&rcTool, 2);
343         }
344
345         GetCursorPos32 ((LPPOINT32)&rect);
346         rect.top += 20;
347
348         if (toolPtr->uFlags & TTF_CENTERTIP) {
349             rect.left -= (size.cx / 2);
350             rect.top  -= (size.cy / 2);
351         }
352
353         /* smart placement */
354         if ((rect.left + size.cx > rcTool.left) && (rect.left < rcTool.right) &&
355             (rect.top + size.cy > rcTool.top) && (rect.top < rcTool.bottom))
356             rect.left = rcTool.right;
357     }
358
359     TRACE (tooltips, "pos %d - %d\n", rect.left, rect.top);
360
361     rect.right = rect.left + size.cx;
362     rect.bottom = rect.top + size.cy;
363
364     AdjustWindowRectEx32 (&rect, wndPtr->dwStyle, FALSE, wndPtr->dwExStyle);
365
366     SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, rect.left, rect.top,
367                     rect.right - rect.left, rect.bottom - rect.top,
368                     SWP_SHOWWINDOW);
369
370     hdc = GetDC32 (wndPtr->hwndSelf);
371     TOOLTIPS_Refresh (wndPtr, hdc);
372     ReleaseDC32 (wndPtr->hwndSelf, hdc);
373 }
374
375
376 static VOID
377 TOOLTIPS_TrackHide (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
378 {
379     TTTOOL_INFO *toolPtr;
380     NMHDR hdr;
381
382     if (infoPtr->nTrackTool == -1)
383         return;
384
385     toolPtr = &infoPtr->tools[infoPtr->nTrackTool];
386     TRACE (tooltips, "hide tracking tooltip %d!\n", infoPtr->nTrackTool);
387
388     hdr.hwndFrom = wndPtr->hwndSelf;
389     hdr.idFrom = toolPtr->uId;
390     hdr.code = TTN_POP;
391     SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
392                     (WPARAM32)toolPtr->uId, (LPARAM)&hdr);
393
394     SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0,
395                     SWP_NOZORDER | SWP_HIDEWINDOW);
396 }
397
398
399 static INT32
400 TOOLTIPS_GetToolFromInfoA (TOOLTIPS_INFO *infoPtr, LPTTTOOLINFO32A lpToolInfo)
401 {
402     TTTOOL_INFO *toolPtr;
403     INT32 nTool;
404
405     for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
406         toolPtr = &infoPtr->tools[nTool];
407
408         if (!(toolPtr->uFlags & TTF_IDISHWND) && 
409             (lpToolInfo->hwnd == toolPtr->hwnd) &&
410             (lpToolInfo->uId == toolPtr->uId))
411             return nTool;
412     }
413
414     for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
415         toolPtr = &infoPtr->tools[nTool];
416
417         if ((toolPtr->uFlags & TTF_IDISHWND) &&
418             (lpToolInfo->uId == toolPtr->uId))
419             return nTool;
420     }
421
422     return -1;
423 }
424
425
426 static INT32
427 TOOLTIPS_GetToolFromInfoW (TOOLTIPS_INFO *infoPtr, LPTTTOOLINFO32W lpToolInfo)
428 {
429     TTTOOL_INFO *toolPtr;
430     INT32 nTool;
431
432     for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
433         toolPtr = &infoPtr->tools[nTool];
434
435         if (!(toolPtr->uFlags & TTF_IDISHWND) && 
436             (lpToolInfo->hwnd == toolPtr->hwnd) &&
437             (lpToolInfo->uId == toolPtr->uId))
438             return nTool;
439     }
440
441     for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
442         toolPtr = &infoPtr->tools[nTool];
443
444         if ((toolPtr->uFlags & TTF_IDISHWND) &&
445             (lpToolInfo->uId == toolPtr->uId))
446             return nTool;
447     }
448
449     return -1;
450 }
451
452
453 static INT32
454 TOOLTIPS_GetToolFromPoint (TOOLTIPS_INFO *infoPtr, HWND32 hwnd, LPPOINT32 lpPt)
455 {
456     TTTOOL_INFO *toolPtr;
457     INT32  nTool;
458
459     for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
460         toolPtr = &infoPtr->tools[nTool];
461
462         if (!(toolPtr->uFlags & TTF_IDISHWND)) {
463             if (hwnd != toolPtr->hwnd)
464                 continue;
465             if (!PtInRect32 (&toolPtr->rect, *lpPt))
466                 continue;
467             return nTool;
468         }
469     }
470
471     for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
472         toolPtr = &infoPtr->tools[nTool];
473
474         if (toolPtr->uFlags & TTF_IDISHWND) {
475             if ((HWND32)toolPtr->uId == hwnd)
476                 return nTool;
477         }
478     }
479
480     return -1;
481 }
482
483
484 static INT32
485 TOOLTIPS_GetToolFromMessage (TOOLTIPS_INFO *infoPtr, HWND32 hwndTool)
486 {
487     DWORD   dwPos;
488     POINT32 pt;
489
490     dwPos = GetMessagePos ();
491     pt.x = (INT32)LOWORD(dwPos);
492     pt.y = (INT32)HIWORD(dwPos);
493     ScreenToClient32 (hwndTool, &pt);
494
495     return TOOLTIPS_GetToolFromPoint (infoPtr, hwndTool, &pt);
496 }
497
498
499 static BOOL32
500 TOOLTIPS_IsWindowActive (HWND32 hwnd)
501 {
502     HWND32 hwndActive = GetActiveWindow32 ();
503     if (!hwndActive)
504         return FALSE;
505     if (hwndActive == hwnd)
506         return TRUE;
507     return IsChild32 (hwndActive, hwnd);
508 }
509
510
511 static INT32
512 TOOLTIPS_CheckTool (WND *wndPtr, BOOL32 bShowTest)
513 {
514     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
515     POINT32 pt;
516     HWND32 hwndTool;
517     INT32 nTool;
518
519     GetCursorPos32 (&pt);
520     hwndTool =
521         SendMessage32A (wndPtr->hwndSelf, TTM_WINDOWFROMPOINT, 0, (LPARAM)&pt);
522     if (hwndTool == 0)
523         return -1;
524
525     ScreenToClient32 (hwndTool, &pt);
526     nTool = TOOLTIPS_GetToolFromPoint (infoPtr, hwndTool, &pt);
527     if (nTool == -1)
528         return -1;
529
530     if (!(wndPtr->dwStyle & TTS_ALWAYSTIP) && bShowTest) {
531         if (!TOOLTIPS_IsWindowActive (wndPtr->owner->hwndSelf))
532             return -1;
533     }
534
535     TRACE (tooltips, "tool %d\n", nTool);
536
537     return nTool;
538 }
539
540
541 static LRESULT
542 TOOLTIPS_Activate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
543 {
544     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
545
546     infoPtr->bActive = (BOOL32)wParam;
547
548     if (infoPtr->bActive)
549         TRACE (tooltips, "activate!\n");
550
551     if (!(infoPtr->bActive) && (infoPtr->nCurrentTool != -1)) 
552         TOOLTIPS_Hide (wndPtr, infoPtr);
553
554     return 0;
555 }
556
557
558 static LRESULT
559 TOOLTIPS_AddTool32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
560 {
561     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
562     LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
563     TTTOOL_INFO *toolPtr;
564
565     if (lpToolInfo == NULL)
566         return FALSE;
567     if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
568         return FALSE;
569
570     TRACE (tooltips, "add tool (%x) %x %d%s!\n",
571            wndPtr->hwndSelf, lpToolInfo->hwnd, lpToolInfo->uId,
572            (lpToolInfo->uFlags & TTF_IDISHWND) ? " TTF_IDISHWND" : "");
573
574     if (infoPtr->uNumTools == 0) {
575         infoPtr->tools = COMCTL32_Alloc (sizeof(TTTOOL_INFO));
576         toolPtr = infoPtr->tools;
577     }
578     else {
579         TTTOOL_INFO *oldTools = infoPtr->tools;
580         infoPtr->tools =
581             COMCTL32_Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools + 1));
582         memcpy (infoPtr->tools, oldTools,
583                 infoPtr->uNumTools * sizeof(TTTOOL_INFO));
584         COMCTL32_Free (oldTools);
585         toolPtr = &infoPtr->tools[infoPtr->uNumTools];
586     }
587
588     infoPtr->uNumTools++;
589
590     /* copy tool data */
591     toolPtr->uFlags = lpToolInfo->uFlags;
592     toolPtr->hwnd   = lpToolInfo->hwnd;
593     toolPtr->uId    = lpToolInfo->uId;
594     toolPtr->rect   = lpToolInfo->rect;
595     toolPtr->hinst  = lpToolInfo->hinst;
596
597     if ((lpToolInfo->hinst) && (HIWORD((INT32)lpToolInfo->lpszText) == 0)) {
598         TRACE (tooltips, "add string id %x!\n", (int)lpToolInfo->lpszText);
599         toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
600     }
601     else if (lpToolInfo->lpszText) {
602         if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACK32A) {
603             TRACE (tooltips, "add CALLBACK!\n");
604             toolPtr->lpszText = LPSTR_TEXTCALLBACK32W;
605         }
606         else {
607             INT32 len = lstrlen32A (lpToolInfo->lpszText);
608             TRACE (tooltips, "add text \"%s\"!\n", lpToolInfo->lpszText);
609             toolPtr->lpszText = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
610             lstrcpyAtoW (toolPtr->lpszText, lpToolInfo->lpszText);
611         }
612     }
613
614     if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A))
615         toolPtr->lParam = lpToolInfo->lParam;
616
617     /* install subclassing hook */
618     if (toolPtr->uFlags & TTF_SUBCLASS) {
619         if (toolPtr->uFlags & TTF_IDISHWND) {
620             LPTT_SUBCLASS_INFO lpttsi =
621                 (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass);
622             if (lpttsi == NULL) {
623                 lpttsi =
624                     (LPTT_SUBCLASS_INFO)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO));
625                 lpttsi->wpOrigProc = 
626                     (WNDPROC32)SetWindowLong32A ((HWND32)toolPtr->uId,
627                     GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc);
628                 lpttsi->hwndToolTip = wndPtr->hwndSelf;
629                 lpttsi->uRefCount++;
630                 SetProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass,
631                             (HANDLE32)lpttsi);
632             }
633             else
634                 WARN (tooltips, "A window tool must only be listed once!\n");
635         }
636         else {
637             LPTT_SUBCLASS_INFO lpttsi =
638                 (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, COMCTL32_aSubclass);
639             if (lpttsi == NULL) {
640                 lpttsi =
641                     (LPTT_SUBCLASS_INFO)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO));
642                 lpttsi->wpOrigProc = 
643                     (WNDPROC32)SetWindowLong32A (toolPtr->hwnd,
644                     GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc);
645                 lpttsi->hwndToolTip = wndPtr->hwndSelf;
646                 lpttsi->uRefCount++;
647                 SetProp32A (toolPtr->hwnd, COMCTL32_aSubclass, (HANDLE32)lpttsi);
648             }
649             else
650                 lpttsi->uRefCount++;
651         }
652         TRACE (tooltips, "subclassing installed!\n");
653     }
654
655     return TRUE;
656 }
657
658
659 static LRESULT
660 TOOLTIPS_AddTool32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
661 {
662     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
663     LPTTTOOLINFO32W lpToolInfo = (LPTTTOOLINFO32W)lParam;
664     TTTOOL_INFO *toolPtr;
665
666     if (lpToolInfo == NULL)
667         return FALSE;
668     if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32W)
669         return FALSE;
670
671     TRACE (tooltips, "add tool (%x) %x %d%s!\n",
672            wndPtr->hwndSelf, lpToolInfo->hwnd, lpToolInfo->uId,
673            (lpToolInfo->uFlags & TTF_IDISHWND) ? " TTF_IDISHWND" : "");
674
675     if (infoPtr->uNumTools == 0) {
676         infoPtr->tools = COMCTL32_Alloc (sizeof(TTTOOL_INFO));
677         toolPtr = infoPtr->tools;
678     }
679     else {
680         TTTOOL_INFO *oldTools = infoPtr->tools;
681         infoPtr->tools =
682             COMCTL32_Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools + 1));
683         memcpy (infoPtr->tools, oldTools,
684                 infoPtr->uNumTools * sizeof(TTTOOL_INFO));
685         COMCTL32_Free (oldTools);
686         toolPtr = &infoPtr->tools[infoPtr->uNumTools];
687     }
688
689     infoPtr->uNumTools++;
690
691     /* copy tool data */
692     toolPtr->uFlags = lpToolInfo->uFlags;
693     toolPtr->hwnd   = lpToolInfo->hwnd;
694     toolPtr->uId    = lpToolInfo->uId;
695     toolPtr->rect   = lpToolInfo->rect;
696     toolPtr->hinst  = lpToolInfo->hinst;
697
698     if ((lpToolInfo->hinst) && (HIWORD((INT32)lpToolInfo->lpszText) == 0)) {
699         TRACE (tooltips, "add string id %x!\n", (int)lpToolInfo->lpszText);
700         toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
701     }
702     else if (lpToolInfo->lpszText) {
703         if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACK32W) {
704             TRACE (tooltips, "add CALLBACK!\n");
705             toolPtr->lpszText = LPSTR_TEXTCALLBACK32W;
706         }
707         else {
708             INT32 len = lstrlen32W (lpToolInfo->lpszText);
709             TRACE (tooltips, "add text \"%s\"!\n",
710                    debugstr_w(lpToolInfo->lpszText));
711             toolPtr->lpszText = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
712             lstrcpy32W (toolPtr->lpszText, lpToolInfo->lpszText);
713         }
714     }
715
716     if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32W))
717         toolPtr->lParam = lpToolInfo->lParam;
718
719     /* install subclassing hook */
720     if (toolPtr->uFlags & TTF_SUBCLASS) {
721         if (toolPtr->uFlags & TTF_IDISHWND) {
722             LPTT_SUBCLASS_INFO lpttsi =
723                 (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass);
724             if (lpttsi == NULL) {
725                 lpttsi =
726                     (LPTT_SUBCLASS_INFO)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO));
727                 lpttsi->wpOrigProc = 
728                     (WNDPROC32)SetWindowLong32A ((HWND32)toolPtr->uId,
729                     GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc);
730                 lpttsi->hwndToolTip = wndPtr->hwndSelf;
731                 lpttsi->uRefCount++;
732                 SetProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass,
733                             (HANDLE32)lpttsi);
734             }
735             else
736                 WARN (tooltips, "A window tool must only be listed once!\n");
737         }
738         else {
739             LPTT_SUBCLASS_INFO lpttsi =
740                 (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, COMCTL32_aSubclass);
741             if (lpttsi == NULL) {
742                 lpttsi =
743                     (LPTT_SUBCLASS_INFO)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO));
744                 lpttsi->wpOrigProc = 
745                     (WNDPROC32)SetWindowLong32A (toolPtr->hwnd,
746                     GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc);
747                 lpttsi->hwndToolTip = wndPtr->hwndSelf;
748                 lpttsi->uRefCount++;
749                 SetProp32A (toolPtr->hwnd, COMCTL32_aSubclass, (HANDLE32)lpttsi);
750             }
751             else
752                 lpttsi->uRefCount++;
753         }
754         TRACE (tooltips, "subclassing installed!\n");
755     }
756
757     return TRUE;
758 }
759
760
761 static LRESULT
762 TOOLTIPS_DelTool32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
763 {
764     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
765     LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
766     TTTOOL_INFO *toolPtr;
767     INT32 nTool;
768
769     if (lpToolInfo == NULL)
770         return 0;
771     if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
772         return 0;
773     if (infoPtr->uNumTools == 0)
774         return 0;
775
776     nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
777     if (nTool == -1) return 0;
778
779     TRACE (tooltips, "tool %d\n", nTool);
780
781     /* delete text string */
782     toolPtr = &infoPtr->tools[nTool]; 
783     if ((toolPtr->hinst) && (toolPtr->lpszText)) {
784         if (toolPtr->lpszText != LPSTR_TEXTCALLBACK32W)
785             COMCTL32_Free (toolPtr->lpszText);
786     }
787
788     /* remove subclassing */
789     if (toolPtr->uFlags & TTF_SUBCLASS) {
790         if (toolPtr->uFlags & TTF_IDISHWND) {
791             LPTT_SUBCLASS_INFO lpttsi =
792                 (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass);
793             if (lpttsi) {
794                 SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
795                                   (LONG)lpttsi->wpOrigProc);
796                 RemoveProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass);
797                 COMCTL32_Free (&lpttsi);
798             }
799             else
800                 ERR (tooltips, "Invalid data handle!\n");
801         }
802         else {
803             LPTT_SUBCLASS_INFO lpttsi =
804                 (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, COMCTL32_aSubclass);
805             if (lpttsi) {
806                 if (lpttsi->uRefCount == 1) {
807                     SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
808                                       (LONG)lpttsi->wpOrigProc);
809                     RemoveProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass);
810                     COMCTL32_Free (&lpttsi);
811                 }
812                 else
813                     lpttsi->uRefCount--;
814             }
815             else
816                 ERR (tooltips, "Invalid data handle!\n");
817         }
818     }
819
820     /* delete tool from tool list */
821     if (infoPtr->uNumTools == 1) {
822         COMCTL32_Free (infoPtr->tools);
823         infoPtr->tools = NULL;
824     }
825     else {
826         TTTOOL_INFO *oldTools = infoPtr->tools;
827         infoPtr->tools =
828             COMCTL32_Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1));
829
830         if (nTool > 0)
831             memcpy (&infoPtr->tools[0], &oldTools[0],
832                     nTool * sizeof(TTTOOL_INFO));
833
834         if (nTool < infoPtr->uNumTools - 1)
835             memcpy (&infoPtr->tools[nTool], &oldTools[nTool + 1],
836                     (infoPtr->uNumTools - nTool - 1) * sizeof(TTTOOL_INFO));
837
838         COMCTL32_Free (oldTools);
839     }
840
841     infoPtr->uNumTools--;
842
843     return 0;
844 }
845
846
847 static LRESULT
848 TOOLTIPS_DelTool32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
849 {
850     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
851     LPTTTOOLINFO32W lpToolInfo = (LPTTTOOLINFO32W)lParam;
852     TTTOOL_INFO *toolPtr;
853     INT32 nTool;
854
855     if (lpToolInfo == NULL)
856         return 0;
857     if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32W)
858         return 0;
859     if (infoPtr->uNumTools == 0)
860         return 0;
861
862     nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
863     if (nTool == -1) return 0;
864
865     TRACE (tooltips, "tool %d\n", nTool);
866
867     /* delete text string */
868     toolPtr = &infoPtr->tools[nTool]; 
869     if ((toolPtr->hinst) && (toolPtr->lpszText)) {
870         if (toolPtr->lpszText != LPSTR_TEXTCALLBACK32W)
871             COMCTL32_Free (toolPtr->lpszText);
872     }
873
874     /* remove subclassing */
875     if (toolPtr->uFlags & TTF_SUBCLASS) {
876         if (toolPtr->uFlags & TTF_IDISHWND) {
877             LPTT_SUBCLASS_INFO lpttsi =
878                 (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass);
879             if (lpttsi) {
880                 SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
881                                   (LONG)lpttsi->wpOrigProc);
882                 RemoveProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass);
883                 COMCTL32_Free (&lpttsi);
884             }
885             else
886                 ERR (tooltips, "Invalid data handle!\n");
887         }
888         else {
889             LPTT_SUBCLASS_INFO lpttsi =
890                 (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, COMCTL32_aSubclass);
891             if (lpttsi) {
892                 if (lpttsi->uRefCount == 1) {
893                     SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
894                                       (LONG)lpttsi->wpOrigProc);
895                     RemoveProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass);
896                     COMCTL32_Free (&lpttsi);
897                 }
898                 else
899                     lpttsi->uRefCount--;
900             }
901             else
902                 ERR (tooltips, "Invalid data handle!\n");
903         }
904     }
905
906     /* delete tool from tool list */
907     if (infoPtr->uNumTools == 1) {
908         COMCTL32_Free (infoPtr->tools);
909         infoPtr->tools = NULL;
910     }
911     else {
912         TTTOOL_INFO *oldTools = infoPtr->tools;
913         infoPtr->tools =
914             COMCTL32_Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1));
915
916         if (nTool > 0)
917             memcpy (&infoPtr->tools[0], &oldTools[0],
918                     nTool * sizeof(TTTOOL_INFO));
919
920         if (nTool < infoPtr->uNumTools - 1)
921             memcpy (&infoPtr->tools[nTool], &oldTools[nTool + 1],
922                     (infoPtr->uNumTools - nTool - 1) * sizeof(TTTOOL_INFO));
923
924         COMCTL32_Free (oldTools);
925     }
926
927     infoPtr->uNumTools--;
928
929     return 0;
930 }
931
932
933 static LRESULT
934 TOOLTIPS_EnumTools32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
935 {
936     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
937     UINT32 uIndex = (UINT32)wParam;
938     LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
939     TTTOOL_INFO *toolPtr;
940
941     if (lpToolInfo == NULL)
942         return FALSE;
943     if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
944         return FALSE;
945     if (uIndex >= infoPtr->uNumTools)
946         return FALSE;
947
948     TRACE (tooltips, "index=%u\n", uIndex);
949
950     toolPtr = &infoPtr->tools[uIndex];
951
952     /* copy tool data */
953     lpToolInfo->uFlags   = toolPtr->uFlags;
954     lpToolInfo->hwnd     = toolPtr->hwnd;
955     lpToolInfo->uId      = toolPtr->uId;
956     lpToolInfo->rect     = toolPtr->rect;
957     lpToolInfo->hinst    = toolPtr->hinst;
958 /*    lpToolInfo->lpszText = toolPtr->lpszText; */
959     lpToolInfo->lpszText = NULL;  /* FIXME */
960
961     if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A))
962         lpToolInfo->lParam = toolPtr->lParam;
963
964     return TRUE;
965 }
966
967
968 static LRESULT
969 TOOLTIPS_EnumTools32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
970 {
971     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
972     UINT32 uIndex = (UINT32)wParam;
973     LPTTTOOLINFO32W lpToolInfo = (LPTTTOOLINFO32W)lParam;
974     TTTOOL_INFO *toolPtr;
975
976     if (lpToolInfo == NULL)
977         return FALSE;
978     if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32W)
979         return FALSE;
980     if (uIndex >= infoPtr->uNumTools)
981         return FALSE;
982
983     TRACE (tooltips, "index=%u\n", uIndex);
984
985     toolPtr = &infoPtr->tools[uIndex];
986
987     /* copy tool data */
988     lpToolInfo->uFlags   = toolPtr->uFlags;
989     lpToolInfo->hwnd     = toolPtr->hwnd;
990     lpToolInfo->uId      = toolPtr->uId;
991     lpToolInfo->rect     = toolPtr->rect;
992     lpToolInfo->hinst    = toolPtr->hinst;
993 /*    lpToolInfo->lpszText = toolPtr->lpszText; */
994     lpToolInfo->lpszText = NULL;  /* FIXME */
995
996     if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32W))
997         lpToolInfo->lParam = toolPtr->lParam;
998
999     return TRUE;
1000 }
1001
1002
1003 static LRESULT
1004 TOOLTIPS_GetCurrentTool32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1005 {
1006     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1007     LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
1008     TTTOOL_INFO *toolPtr;
1009
1010     if (lpToolInfo == NULL)
1011         return FALSE;
1012     if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
1013         return FALSE;
1014
1015     if (lpToolInfo) {
1016         if (infoPtr->nCurrentTool > -1) {
1017             toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
1018
1019             /* copy tool data */
1020             lpToolInfo->uFlags   = toolPtr->uFlags;
1021             lpToolInfo->rect     = toolPtr->rect;
1022             lpToolInfo->hinst    = toolPtr->hinst;
1023 /*          lpToolInfo->lpszText = toolPtr->lpszText; */
1024             lpToolInfo->lpszText = NULL;  /* FIXME */
1025
1026             if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A))
1027                 lpToolInfo->lParam = toolPtr->lParam;
1028
1029             return TRUE;
1030         }
1031         else
1032             return FALSE;
1033     }
1034     else
1035         return (infoPtr->nCurrentTool != -1);
1036
1037     return FALSE;
1038 }
1039
1040
1041 static LRESULT
1042 TOOLTIPS_GetCurrentTool32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1043 {
1044     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1045     LPTTTOOLINFO32W lpToolInfo = (LPTTTOOLINFO32W)lParam;
1046     TTTOOL_INFO *toolPtr;
1047
1048     if (lpToolInfo == NULL)
1049         return FALSE;
1050     if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32W)
1051         return FALSE;
1052
1053     if (lpToolInfo) {
1054         if (infoPtr->nCurrentTool > -1) {
1055             toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
1056
1057             /* copy tool data */
1058             lpToolInfo->uFlags   = toolPtr->uFlags;
1059             lpToolInfo->rect     = toolPtr->rect;
1060             lpToolInfo->hinst    = toolPtr->hinst;
1061 /*          lpToolInfo->lpszText = toolPtr->lpszText; */
1062             lpToolInfo->lpszText = NULL;  /* FIXME */
1063
1064             if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32W))
1065                 lpToolInfo->lParam = toolPtr->lParam;
1066
1067             return TRUE;
1068         }
1069         else
1070             return FALSE;
1071     }
1072     else
1073         return (infoPtr->nCurrentTool != -1);
1074
1075     return FALSE;
1076 }
1077
1078
1079 static LRESULT
1080 TOOLTIPS_GetDelayTime (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1081 {
1082     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1083
1084     switch (wParam) {
1085         case TTDT_AUTOMATIC:
1086             return infoPtr->nAutomaticTime;
1087
1088         case TTDT_RESHOW:
1089             return infoPtr->nReshowTime;
1090
1091         case TTDT_AUTOPOP:
1092             return infoPtr->nAutoPopTime;
1093
1094         case TTDT_INITIAL:
1095             return infoPtr->nInitialTime;
1096     }
1097
1098     return 0;
1099 }
1100
1101
1102 static LRESULT
1103 TOOLTIPS_GetMargin (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1104 {
1105     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1106     LPRECT32 lpRect = (LPRECT32)lParam;
1107
1108     lpRect->left   = infoPtr->rcMargin.left;
1109     lpRect->right  = infoPtr->rcMargin.right;
1110     lpRect->bottom = infoPtr->rcMargin.bottom;
1111     lpRect->top    = infoPtr->rcMargin.top;
1112
1113     return 0;
1114 }
1115
1116
1117 __inline__ static LRESULT
1118 TOOLTIPS_GetMaxTipWidth (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1119 {
1120     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1121
1122     return infoPtr->nMaxTipWidth;
1123 }
1124
1125
1126 static LRESULT
1127 TOOLTIPS_GetText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1128 {
1129     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1130     LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
1131     INT32 nTool;
1132
1133     if (lpToolInfo == NULL)
1134         return 0;
1135     if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
1136         return 0;
1137
1138     nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1139     if (nTool == -1) return 0;
1140
1141     lstrcpyWtoA (lpToolInfo->lpszText, infoPtr->tools[nTool].lpszText);
1142
1143     return 0;
1144 }
1145
1146
1147 static LRESULT
1148 TOOLTIPS_GetText32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1149 {
1150     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1151     LPTTTOOLINFO32W lpToolInfo = (LPTTTOOLINFO32W)lParam;
1152     INT32 nTool;
1153
1154     if (lpToolInfo == NULL)
1155         return 0;
1156     if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32W)
1157         return 0;
1158
1159     nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
1160     if (nTool == -1) return 0;
1161
1162     lstrcpy32W (lpToolInfo->lpszText, infoPtr->tools[nTool].lpszText);
1163
1164     return 0;
1165 }
1166
1167
1168 __inline__ static LRESULT
1169 TOOLTIPS_GetTipBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1170 {
1171     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1172     return infoPtr->clrBk;
1173 }
1174
1175
1176 __inline__ static LRESULT
1177 TOOLTIPS_GetTipTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1178 {
1179     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1180     return infoPtr->clrText;
1181 }
1182
1183
1184 __inline__ static LRESULT
1185 TOOLTIPS_GetToolCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1186 {
1187     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1188     return infoPtr->uNumTools;
1189 }
1190
1191
1192 static LRESULT
1193 TOOLTIPS_GetToolInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1194 {
1195     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1196     LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
1197     TTTOOL_INFO *toolPtr;
1198     INT32 nTool;
1199
1200     if (lpToolInfo == NULL)
1201         return FALSE;
1202     if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
1203         return FALSE;
1204     if (infoPtr->uNumTools == 0)
1205         return FALSE;
1206
1207     nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1208     if (nTool == -1)
1209         return FALSE;
1210
1211     TRACE (tooltips, "tool %d\n", nTool);
1212
1213     toolPtr = &infoPtr->tools[nTool];
1214
1215     /* copy tool data */
1216     lpToolInfo->uFlags   = toolPtr->uFlags;
1217     lpToolInfo->rect     = toolPtr->rect;
1218     lpToolInfo->hinst    = toolPtr->hinst;
1219 /*    lpToolInfo->lpszText = toolPtr->lpszText; */
1220     lpToolInfo->lpszText = NULL;  /* FIXME */
1221
1222     if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A))
1223         lpToolInfo->lParam = toolPtr->lParam;
1224
1225     return TRUE;
1226 }
1227
1228
1229 static LRESULT
1230 TOOLTIPS_GetToolInfo32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1231 {
1232     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1233     LPTTTOOLINFO32W lpToolInfo = (LPTTTOOLINFO32W)lParam;
1234     TTTOOL_INFO *toolPtr;
1235     INT32 nTool;
1236
1237     if (lpToolInfo == NULL)
1238         return FALSE;
1239     if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32W)
1240         return FALSE;
1241     if (infoPtr->uNumTools == 0)
1242         return FALSE;
1243
1244     nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
1245     if (nTool == -1)
1246         return FALSE;
1247
1248     TRACE (tooltips, "tool %d\n", nTool);
1249
1250     toolPtr = &infoPtr->tools[nTool];
1251
1252     /* copy tool data */
1253     lpToolInfo->uFlags   = toolPtr->uFlags;
1254     lpToolInfo->rect     = toolPtr->rect;
1255     lpToolInfo->hinst    = toolPtr->hinst;
1256 /*    lpToolInfo->lpszText = toolPtr->lpszText; */
1257     lpToolInfo->lpszText = NULL;  /* FIXME */
1258
1259     if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32W))
1260         lpToolInfo->lParam = toolPtr->lParam;
1261
1262     return TRUE;
1263 }
1264
1265
1266 static LRESULT
1267 TOOLTIPS_HitTest32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1268 {
1269     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1270     LPTTHITTESTINFO32A lptthit = (LPTTHITTESTINFO32A)lParam;
1271     TTTOOL_INFO *toolPtr;
1272     INT32 nTool;
1273
1274     if (lptthit == 0)
1275         return FALSE;
1276
1277     nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lptthit->hwnd, &lptthit->pt);
1278     if (nTool == -1)
1279         return FALSE;
1280
1281     TRACE (tooltips, "tool %d!\n", nTool);
1282
1283     /* copy tool data */
1284     if (lptthit->ti.cbSize >= sizeof(TTTOOLINFO32A)) {
1285         toolPtr = &infoPtr->tools[nTool];
1286
1287         lptthit->ti.uFlags   = toolPtr->uFlags;
1288         lptthit->ti.hwnd     = toolPtr->hwnd;
1289         lptthit->ti.uId      = toolPtr->uId;
1290         lptthit->ti.rect     = toolPtr->rect;
1291         lptthit->ti.hinst    = toolPtr->hinst;
1292 /*      lptthit->ti.lpszText = toolPtr->lpszText; */
1293         lptthit->ti.lpszText = NULL;  /* FIXME */
1294         lptthit->ti.lParam   = toolPtr->lParam;
1295     }
1296
1297     return TRUE;
1298 }
1299
1300
1301 static LRESULT
1302 TOOLTIPS_HitTest32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1303 {
1304     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1305     LPTTHITTESTINFO32W lptthit = (LPTTHITTESTINFO32W)lParam;
1306     TTTOOL_INFO *toolPtr;
1307     INT32 nTool;
1308
1309     if (lptthit == 0)
1310         return FALSE;
1311
1312     nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lptthit->hwnd, &lptthit->pt);
1313     if (nTool == -1)
1314         return FALSE;
1315
1316     TRACE (tooltips, "tool %d!\n", nTool);
1317
1318     /* copy tool data */
1319     if (lptthit->ti.cbSize >= sizeof(TTTOOLINFO32W)) {
1320         toolPtr = &infoPtr->tools[nTool];
1321
1322         lptthit->ti.uFlags   = toolPtr->uFlags;
1323         lptthit->ti.hwnd     = toolPtr->hwnd;
1324         lptthit->ti.uId      = toolPtr->uId;
1325         lptthit->ti.rect     = toolPtr->rect;
1326         lptthit->ti.hinst    = toolPtr->hinst;
1327 /*      lptthit->ti.lpszText = toolPtr->lpszText; */
1328         lptthit->ti.lpszText = NULL;  /* FIXME */
1329         lptthit->ti.lParam   = toolPtr->lParam;
1330     }
1331
1332     return TRUE;
1333 }
1334
1335
1336 static LRESULT
1337 TOOLTIPS_NewToolRect32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1338 {
1339     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1340     LPTTTOOLINFO32A lpti = (LPTTTOOLINFO32A)lParam;
1341     INT32 nTool;
1342
1343     if (lpti == NULL)
1344         return 0;
1345     if (lpti->cbSize < TTTOOLINFO_V1_SIZE32A)
1346         return FALSE;
1347
1348     nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpti);
1349     if (nTool == -1) return 0;
1350
1351     infoPtr->tools[nTool].rect = lpti->rect;
1352
1353     return 0;
1354 }
1355
1356
1357 static LRESULT
1358 TOOLTIPS_NewToolRect32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1359 {
1360     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1361     LPTTTOOLINFO32W lpti = (LPTTTOOLINFO32W)lParam;
1362     INT32 nTool;
1363
1364     if (lpti == NULL)
1365         return 0;
1366     if (lpti->cbSize < TTTOOLINFO_V1_SIZE32W)
1367         return FALSE;
1368
1369     nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpti);
1370     if (nTool == -1) return 0;
1371
1372     infoPtr->tools[nTool].rect = lpti->rect;
1373
1374     return 0;
1375 }
1376
1377
1378 __inline__ static LRESULT
1379 TOOLTIPS_Pop (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1380 {
1381     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1382
1383     TOOLTIPS_Hide (wndPtr, infoPtr);
1384
1385     return 0;
1386 }
1387
1388
1389 static LRESULT
1390 TOOLTIPS_RelayEvent (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1391 {
1392     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1393     LPMSG32 lpMsg = (LPMSG32)lParam;
1394     POINT32 pt;
1395
1396     if (lParam == 0) {
1397         ERR (tooltips, "lpMsg == NULL!\n");
1398         return 0;
1399     }
1400
1401     switch (lpMsg->message) {
1402         case WM_LBUTTONDOWN:
1403         case WM_LBUTTONUP:
1404         case WM_MBUTTONDOWN:
1405         case WM_MBUTTONUP:
1406         case WM_RBUTTONDOWN:
1407         case WM_RBUTTONUP:
1408             pt = lpMsg->pt;
1409             ScreenToClient32 (lpMsg->hwnd, &pt);
1410             infoPtr->nOldTool = infoPtr->nTool;
1411             infoPtr->nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lpMsg->hwnd, &pt);
1412             TRACE (tooltips, "tool (%x) %d %d\n",
1413                    wndPtr->hwndSelf, infoPtr->nOldTool, infoPtr->nTool);
1414             TOOLTIPS_Hide (wndPtr, infoPtr);
1415             break;
1416
1417         case WM_MOUSEMOVE:
1418             pt = lpMsg->pt;
1419             ScreenToClient32 (lpMsg->hwnd, &pt);
1420             infoPtr->nOldTool = infoPtr->nTool;
1421             infoPtr->nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lpMsg->hwnd, &pt);
1422             TRACE (tooltips, "tool (%x) %d %d\n",
1423                    wndPtr->hwndSelf, infoPtr->nOldTool, infoPtr->nTool);
1424             TRACE (tooltips, "WM_MOUSEMOVE (%04x %d %d)\n",
1425                    wndPtr->hwndSelf, pt.x, pt.y);
1426             if ((infoPtr->bActive) && (infoPtr->nTool != infoPtr->nOldTool)) {
1427                 if (infoPtr->nOldTool == -1) {
1428                     SetTimer32 (wndPtr->hwndSelf, ID_TIMERSHOW,
1429                                 infoPtr->nInitialTime, 0);
1430                     TRACE (tooltips, "timer 1 started!\n");
1431                 }
1432                 else {
1433                     TOOLTIPS_Hide (wndPtr, infoPtr);
1434                     SetTimer32 (wndPtr->hwndSelf, ID_TIMERSHOW,
1435                                 infoPtr->nReshowTime, 0);
1436                     TRACE (tooltips, "timer 2 started!\n");
1437                 }
1438             }
1439             if (infoPtr->nCurrentTool != -1) {
1440                 SetTimer32 (wndPtr->hwndSelf, ID_TIMERLEAVE, 100, 0);
1441                 TRACE (tooltips, "timer 3 started!\n");
1442             }
1443             break;
1444     }
1445
1446     return 0;
1447 }
1448
1449
1450 static LRESULT
1451 TOOLTIPS_SetDelayTime (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1452 {
1453     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1454     INT32 nTime = (INT32)LOWORD(lParam);
1455
1456     switch (wParam) {
1457         case TTDT_AUTOMATIC:
1458             if (nTime == 0) {
1459                 infoPtr->nAutomaticTime = 500;
1460                 infoPtr->nReshowTime    = 100;
1461                 infoPtr->nAutoPopTime   = 5000;
1462                 infoPtr->nInitialTime   = 500;
1463             }
1464             else {
1465                 infoPtr->nAutomaticTime = nTime;
1466                 infoPtr->nReshowTime    = nTime / 5;
1467                 infoPtr->nAutoPopTime   = nTime * 10;
1468                 infoPtr->nInitialTime   = nTime;
1469             }
1470             break;
1471
1472         case TTDT_RESHOW:
1473             infoPtr->nReshowTime = nTime;
1474             break;
1475
1476         case TTDT_AUTOPOP:
1477             infoPtr->nAutoPopTime = nTime;
1478             break;
1479
1480         case TTDT_INITIAL:
1481             infoPtr->nInitialTime = nTime;
1482             break;
1483     }
1484
1485     return 0;
1486 }
1487
1488
1489 static LRESULT
1490 TOOLTIPS_SetMargin (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1491 {
1492     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1493     LPRECT32 lpRect = (LPRECT32)lParam;
1494
1495     infoPtr->rcMargin.left   = lpRect->left;
1496     infoPtr->rcMargin.right  = lpRect->right;
1497     infoPtr->rcMargin.bottom = lpRect->bottom;
1498     infoPtr->rcMargin.top    = lpRect->top;
1499
1500     return 0;
1501 }
1502
1503
1504 __inline__ static LRESULT
1505 TOOLTIPS_SetMaxTipWidth (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1506 {
1507     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1508     INT32 nTemp = infoPtr->nMaxTipWidth;
1509
1510     infoPtr->nMaxTipWidth = (INT32)lParam;
1511
1512     return nTemp;
1513 }
1514
1515
1516 __inline__ static LRESULT
1517 TOOLTIPS_SetTipBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1518 {
1519     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1520
1521     infoPtr->clrBk = (COLORREF)wParam;
1522
1523     return 0;
1524 }
1525
1526
1527 __inline__ static LRESULT
1528 TOOLTIPS_SetTipTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1529 {
1530     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1531
1532     infoPtr->clrText = (COLORREF)wParam;
1533
1534     return 0;
1535 }
1536
1537
1538 static LRESULT
1539 TOOLTIPS_SetToolInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1540 {
1541     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1542     LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
1543     TTTOOL_INFO *toolPtr;
1544     INT32 nTool;
1545
1546     if (lpToolInfo == NULL)
1547         return 0;
1548     if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
1549         return 0;
1550
1551     nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1552     if (nTool == -1) return 0;
1553
1554     TRACE (tooltips, "tool %d\n", nTool);
1555
1556     toolPtr = &infoPtr->tools[nTool];
1557
1558     /* copy tool data */
1559     toolPtr->uFlags = lpToolInfo->uFlags;
1560     toolPtr->hwnd   = lpToolInfo->hwnd;
1561     toolPtr->uId    = lpToolInfo->uId;
1562     toolPtr->rect   = lpToolInfo->rect;
1563     toolPtr->hinst  = lpToolInfo->hinst;
1564
1565     if ((lpToolInfo->hinst) && (HIWORD((INT32)lpToolInfo->lpszText) == 0)) {
1566         TRACE (tooltips, "set string id %x!\n", (INT32)lpToolInfo->lpszText);
1567         toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
1568     }
1569     else if (lpToolInfo->lpszText) {
1570         if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACK32A)
1571             toolPtr->lpszText = LPSTR_TEXTCALLBACK32W;
1572         else {
1573             if (toolPtr->lpszText) {
1574                 COMCTL32_Free (toolPtr->lpszText);
1575                 toolPtr->lpszText = NULL;
1576             }
1577             if (lpToolInfo->lpszText) {
1578                 INT32 len = lstrlen32A (lpToolInfo->lpszText);
1579                 toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1580                 lstrcpyAtoW (toolPtr->lpszText, lpToolInfo->lpszText);
1581             }
1582         }
1583     }
1584
1585     if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A))
1586         toolPtr->lParam = lpToolInfo->lParam;
1587
1588     return 0;
1589 }
1590
1591
1592 static LRESULT
1593 TOOLTIPS_SetToolInfo32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1594 {
1595     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1596     LPTTTOOLINFO32W lpToolInfo = (LPTTTOOLINFO32W)lParam;
1597     TTTOOL_INFO *toolPtr;
1598     INT32 nTool;
1599
1600     if (lpToolInfo == NULL)
1601         return 0;
1602     if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32W)
1603         return 0;
1604
1605     nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
1606     if (nTool == -1) return 0;
1607
1608     TRACE (tooltips, "tool %d\n", nTool);
1609
1610     toolPtr = &infoPtr->tools[nTool];
1611
1612     /* copy tool data */
1613     toolPtr->uFlags = lpToolInfo->uFlags;
1614     toolPtr->hwnd   = lpToolInfo->hwnd;
1615     toolPtr->uId    = lpToolInfo->uId;
1616     toolPtr->rect   = lpToolInfo->rect;
1617     toolPtr->hinst  = lpToolInfo->hinst;
1618
1619     if ((lpToolInfo->hinst) && (HIWORD((INT32)lpToolInfo->lpszText) == 0)) {
1620         TRACE (tooltips, "set string id %x!\n", (INT32)lpToolInfo->lpszText);
1621         toolPtr->lpszText = lpToolInfo->lpszText;
1622     }
1623     else if (lpToolInfo->lpszText) {
1624         if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACK32W)
1625             toolPtr->lpszText = LPSTR_TEXTCALLBACK32W;
1626         else {
1627             if (toolPtr->lpszText) {
1628                 COMCTL32_Free (toolPtr->lpszText);
1629                 toolPtr->lpszText = NULL;
1630             }
1631             if (lpToolInfo->lpszText) {
1632                 INT32 len = lstrlen32W (lpToolInfo->lpszText);
1633                 toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1634                 lstrcpy32W (toolPtr->lpszText, lpToolInfo->lpszText);
1635             }
1636         }
1637     }
1638
1639     if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32W))
1640         toolPtr->lParam = lpToolInfo->lParam;
1641
1642     return 0;
1643 }
1644
1645
1646 static LRESULT
1647 TOOLTIPS_TrackActivate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1648 {
1649     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1650     LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
1651
1652     if (lpToolInfo == NULL)
1653         return 0;
1654     if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
1655         return FALSE;
1656
1657     if ((BOOL32)wParam) {
1658         /* activate */
1659         infoPtr->nTrackTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1660         if (infoPtr->nTrackTool != -1) {
1661             TRACE (tooltips, "activated!\n");
1662             infoPtr->bTrackActive = TRUE;
1663             TOOLTIPS_TrackShow (wndPtr, infoPtr);
1664         }
1665     }
1666     else {
1667         /* deactivate */
1668         TOOLTIPS_TrackHide (wndPtr, infoPtr);
1669
1670         infoPtr->bTrackActive = FALSE;
1671         infoPtr->nTrackTool = -1;
1672
1673         TRACE (tooltips, "deactivated!\n");
1674     }
1675
1676     return 0;
1677 }
1678
1679
1680 static LRESULT
1681 TOOLTIPS_TrackPosition (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1682 {
1683     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1684
1685     infoPtr->xTrackPos = (INT32)LOWORD(lParam);
1686     infoPtr->yTrackPos = (INT32)HIWORD(lParam);
1687
1688     if (infoPtr->bTrackActive) {
1689         TRACE (tooltips, "[%d %d]\n",
1690                infoPtr->xTrackPos, infoPtr->yTrackPos);
1691
1692         TOOLTIPS_TrackShow (wndPtr, infoPtr);
1693     }
1694
1695     return 0;
1696 }
1697
1698
1699 static LRESULT
1700 TOOLTIPS_Update (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1701 {
1702     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1703
1704     if (infoPtr->nCurrentTool != -1)
1705         UpdateWindow32 (wndPtr->hwndSelf);
1706
1707     return 0;
1708 }
1709
1710
1711 static LRESULT
1712 TOOLTIPS_UpdateTipText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1713 {
1714     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1715     LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
1716     TTTOOL_INFO *toolPtr;
1717     INT32 nTool;
1718
1719     if (lpToolInfo == NULL)
1720         return 0;
1721     if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
1722         return FALSE;
1723
1724     nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1725     if (nTool == -1) return 0;
1726
1727     TRACE (tooltips, "tool %d\n", nTool);
1728
1729     toolPtr = &infoPtr->tools[nTool];
1730
1731     /* copy tool text */
1732     toolPtr->hinst  = lpToolInfo->hinst;
1733
1734     if ((lpToolInfo->hinst) && (HIWORD((INT32)lpToolInfo->lpszText) == 0)){
1735         toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
1736     }
1737     else if (lpToolInfo->lpszText) {
1738         if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACK32A)
1739             toolPtr->lpszText = LPSTR_TEXTCALLBACK32W;
1740         else {
1741             if (toolPtr->lpszText) {
1742                 COMCTL32_Free (toolPtr->lpszText);
1743                 toolPtr->lpszText = NULL;
1744             }
1745             if (lpToolInfo->lpszText) {
1746                 INT32 len = lstrlen32A (lpToolInfo->lpszText);
1747                 toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1748                 lstrcpyAtoW (toolPtr->lpszText, lpToolInfo->lpszText);
1749             }
1750         }
1751     }
1752
1753     /* force repaint */
1754     if (infoPtr->bActive)
1755         TOOLTIPS_Show (wndPtr, infoPtr);
1756     else if (infoPtr->bTrackActive)
1757         TOOLTIPS_TrackShow (wndPtr, infoPtr);
1758
1759     return 0;
1760 }
1761
1762
1763 static LRESULT
1764 TOOLTIPS_UpdateTipText32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1765 {
1766     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1767     LPTTTOOLINFO32W lpToolInfo = (LPTTTOOLINFO32W)lParam;
1768     TTTOOL_INFO *toolPtr;
1769     INT32 nTool;
1770
1771     if (lpToolInfo == NULL)
1772         return 0;
1773     if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32W)
1774         return FALSE;
1775
1776     nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
1777     if (nTool == -1)
1778         return 0;
1779
1780     TRACE (tooltips, "tool %d\n", nTool);
1781
1782     toolPtr = &infoPtr->tools[nTool];
1783
1784     /* copy tool text */
1785     toolPtr->hinst  = lpToolInfo->hinst;
1786
1787     if ((lpToolInfo->hinst) && (HIWORD((INT32)lpToolInfo->lpszText) == 0)){
1788         toolPtr->lpszText = lpToolInfo->lpszText;
1789     }
1790     else if (lpToolInfo->lpszText) {
1791         if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACK32W)
1792             toolPtr->lpszText = LPSTR_TEXTCALLBACK32W;
1793         else {
1794             if (toolPtr->lpszText) {
1795                 COMCTL32_Free (toolPtr->lpszText);
1796                 toolPtr->lpszText = NULL;
1797             }
1798             if (lpToolInfo->lpszText) {
1799                 INT32 len = lstrlen32W (lpToolInfo->lpszText);
1800                 toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1801                 lstrcpy32W (toolPtr->lpszText, lpToolInfo->lpszText);
1802             }
1803         }
1804     }
1805
1806     /* force repaint */
1807     if (infoPtr->bActive)
1808         TOOLTIPS_Show (wndPtr, infoPtr);
1809     else if (infoPtr->bTrackActive)
1810         TOOLTIPS_TrackShow (wndPtr, infoPtr);
1811
1812     return 0;
1813 }
1814
1815
1816 static LRESULT
1817 TOOLTIPS_WindowFromPoint (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1818 {
1819     return WindowFromPoint32 (*((LPPOINT32)lParam));
1820 }
1821
1822
1823
1824 static LRESULT
1825 TOOLTIPS_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1826 {
1827     TOOLTIPS_INFO *infoPtr;
1828     NONCLIENTMETRICS32A nclm;
1829     INT32 nResult;
1830
1831     /* allocate memory for info structure */
1832     infoPtr = (TOOLTIPS_INFO *)COMCTL32_Alloc (sizeof(TOOLTIPS_INFO));
1833     wndPtr->wExtra[0] = (DWORD)infoPtr;
1834
1835     if (infoPtr == NULL) {
1836         ERR (tooltips, "could not allocate info memory!\n");
1837         return 0;
1838     }
1839
1840     /* initialize info structure */
1841     infoPtr->bActive = TRUE;
1842     infoPtr->bTrackActive = FALSE;
1843     infoPtr->clrBk   = GetSysColor32 (COLOR_INFOBK);
1844     infoPtr->clrText = GetSysColor32 (COLOR_INFOTEXT);
1845
1846     nclm.cbSize = sizeof(NONCLIENTMETRICS32A);
1847     SystemParametersInfo32A (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1848     infoPtr->hFont = CreateFontIndirect32A (&nclm.lfStatusFont);
1849
1850     infoPtr->nMaxTipWidth = -1;
1851     infoPtr->nTool = -1;
1852     infoPtr->nOldTool = -1;
1853     infoPtr->nCurrentTool = -1;
1854     infoPtr->nTrackTool = -1;
1855
1856     infoPtr->nAutomaticTime = 500;
1857     infoPtr->nReshowTime    = 100;
1858     infoPtr->nAutoPopTime   = 5000;
1859     infoPtr->nInitialTime   = 500;
1860
1861     nResult =
1862         (INT32) SendMessage32A (wndPtr->parent->hwndSelf, WM_NOTIFYFORMAT,
1863                                 (WPARAM32)wndPtr->hwndSelf, (LPARAM)NF_QUERY);
1864     if (nResult == NFR_ANSI)
1865         FIXME (tooltips, " -- WM_NOTIFYFORMAT returns: NFR_ANSI\n");
1866     else if (nResult == NFR_UNICODE)
1867         FIXME (tooltips, " -- WM_NOTIFYFORMAT returns: NFR_UNICODE\n");
1868     else
1869         FIXME (tooltips, " -- WM_NOTIFYFORMAT returns: error!\n");
1870
1871     SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0,
1872                     SWP_NOZORDER | SWP_HIDEWINDOW);
1873
1874     return 0;
1875 }
1876
1877
1878 static LRESULT
1879 TOOLTIPS_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1880 {
1881     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1882     TTTOOL_INFO *toolPtr;
1883     INT32 i;
1884
1885     /* free tools */
1886     if (infoPtr->tools) {
1887         for (i = 0; i < infoPtr->uNumTools; i++) {
1888             toolPtr = &infoPtr->tools[i];
1889             if ((toolPtr->hinst) && (toolPtr->lpszText)) {
1890                 if (toolPtr->lpszText != LPSTR_TEXTCALLBACK32W)
1891                     COMCTL32_Free (toolPtr->lpszText);
1892             }
1893
1894             /* remove subclassing */
1895             if (toolPtr->uFlags & TTF_SUBCLASS) {
1896                 LPTT_SUBCLASS_INFO lpttsi;
1897
1898                 if (toolPtr->uFlags & TTF_IDISHWND)
1899                     lpttsi = (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass);
1900                 else
1901                     lpttsi = (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, COMCTL32_aSubclass);
1902
1903                 if (lpttsi) {
1904                     SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
1905                                       (LONG)lpttsi->wpOrigProc);
1906                     RemoveProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass);
1907                     COMCTL32_Free (&lpttsi);
1908                 }
1909             }
1910         }
1911         COMCTL32_Free (infoPtr->tools);
1912     }
1913
1914     /* delete font */
1915     DeleteObject32 (infoPtr->hFont);
1916
1917     /* free tool tips info data */
1918     COMCTL32_Free (infoPtr);
1919
1920     return 0;
1921 }
1922
1923
1924 static LRESULT
1925 TOOLTIPS_EraseBackground (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1926 {
1927     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1928     RECT32 rect;
1929     HBRUSH32 hBrush;
1930
1931     hBrush = CreateSolidBrush32 (infoPtr->clrBk);
1932     GetClientRect32 (wndPtr->hwndSelf, &rect);
1933     FillRect32 ((HDC32)wParam, &rect, hBrush);
1934     DeleteObject32 (hBrush);
1935
1936     return FALSE;
1937 }
1938
1939
1940 static LRESULT
1941 TOOLTIPS_GetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1942 {
1943     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1944
1945     return infoPtr->hFont;
1946 }
1947
1948
1949 static LRESULT
1950 TOOLTIPS_MouseMessage (WND *wndPtr, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
1951 {
1952     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1953
1954     TOOLTIPS_Hide (wndPtr, infoPtr);
1955
1956     return 0;
1957 }
1958
1959
1960 static LRESULT
1961 TOOLTIPS_NCCreate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1962 {
1963     wndPtr->dwStyle &= 0x0000FFFF;
1964     wndPtr->dwStyle |= (WS_POPUP | WS_BORDER | WS_CLIPSIBLINGS);
1965
1966     return TRUE;
1967 }
1968
1969
1970 static LRESULT
1971 TOOLTIPS_NCHitTest (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1972 {
1973     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1974     INT32 nTool = (infoPtr->bTrackActive) ? infoPtr->nTrackTool : infoPtr->nTool;
1975
1976     TRACE (tooltips, " nTool=%d\n", nTool);
1977
1978     if ((nTool > -1) && (nTool < infoPtr->uNumTools)) {
1979         if (infoPtr->tools[nTool].uFlags & TTF_TRANSPARENT) {
1980             TRACE (tooltips, "-- in transparent mode!\n");
1981             return HTTRANSPARENT;
1982         }
1983     }
1984
1985     return DefWindowProc32A (wndPtr->hwndSelf, WM_NCHITTEST, wParam, lParam);
1986 }
1987
1988
1989 static LRESULT
1990 TOOLTIPS_Paint (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1991 {
1992     HDC32 hdc;
1993     PAINTSTRUCT32 ps;
1994
1995     hdc = (wParam == 0) ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
1996     TOOLTIPS_Refresh (wndPtr, hdc);
1997     if (!wParam)
1998         EndPaint32 (wndPtr->hwndSelf, &ps);
1999     return 0;
2000 }
2001
2002
2003 static LRESULT
2004 TOOLTIPS_SetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2005 {
2006     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
2007
2008     infoPtr->hFont = (HFONT32)wParam;
2009
2010     if ((LOWORD(lParam)) & (infoPtr->nCurrentTool != -1)) {
2011         FIXME (tooltips, "full redraw needed!\n");
2012     }
2013
2014     return 0;
2015 }
2016
2017
2018 static LRESULT
2019 TOOLTIPS_Timer (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2020 {
2021     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
2022
2023     TRACE (tooltips, "timer %d (%x) expired!\n", wParam, wndPtr->hwndSelf);
2024
2025     switch (wParam)
2026     {
2027         case ID_TIMERSHOW:
2028             KillTimer32 (wndPtr->hwndSelf, ID_TIMERSHOW);
2029             if (TOOLTIPS_CheckTool (wndPtr, TRUE) == infoPtr->nTool)
2030                 TOOLTIPS_Show (wndPtr, infoPtr);
2031             break;
2032
2033         case ID_TIMERPOP:
2034             TOOLTIPS_Hide (wndPtr, infoPtr);
2035             break;
2036
2037         case ID_TIMERLEAVE:
2038             KillTimer32 (wndPtr->hwndSelf, ID_TIMERLEAVE);
2039             if (TOOLTIPS_CheckTool (wndPtr, FALSE) == -1) {
2040                 infoPtr->nTool = -1;
2041                 infoPtr->nOldTool = -1;
2042                 TOOLTIPS_Hide (wndPtr, infoPtr);
2043             }
2044             break;
2045     }
2046     return 0;
2047 }
2048
2049
2050 static LRESULT
2051 TOOLTIPS_WinIniChange (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2052 {
2053     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
2054     NONCLIENTMETRICS32A nclm;
2055
2056     infoPtr->clrBk   = GetSysColor32 (COLOR_INFOBK);
2057     infoPtr->clrText = GetSysColor32 (COLOR_INFOTEXT);
2058
2059     DeleteObject32 (infoPtr->hFont);
2060     nclm.cbSize = sizeof(NONCLIENTMETRICS32A);
2061     SystemParametersInfo32A (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
2062     infoPtr->hFont = CreateFontIndirect32A (&nclm.lfStatusFont);
2063
2064     return 0;
2065 }
2066
2067
2068 LRESULT CALLBACK
2069 TOOLTIPS_SubclassProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
2070 {
2071     LPTT_SUBCLASS_INFO lpttsi =
2072         (LPTT_SUBCLASS_INFO)GetProp32A (hwnd, COMCTL32_aSubclass);
2073     WND *wndPtr;
2074     TOOLTIPS_INFO *infoPtr;
2075     UINT32 nTool;
2076
2077     switch (uMsg) {
2078         case WM_LBUTTONDOWN:
2079         case WM_LBUTTONUP:
2080         case WM_MBUTTONDOWN:
2081         case WM_MBUTTONUP:
2082         case WM_RBUTTONDOWN:
2083         case WM_RBUTTONUP:
2084             {
2085                 wndPtr = WIN_FindWndPtr(lpttsi->hwndToolTip);
2086                 infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
2087                 nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd);
2088
2089                 TRACE (tooltips, "subclassed mouse message %04x\n", uMsg);
2090                 infoPtr->nOldTool = infoPtr->nTool;
2091                 infoPtr->nTool = nTool;
2092                 TOOLTIPS_Hide (wndPtr, infoPtr);
2093             }
2094             break;
2095
2096         case WM_MOUSEMOVE:
2097             {
2098                 wndPtr = WIN_FindWndPtr(lpttsi->hwndToolTip);
2099                 infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
2100                 nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd);
2101
2102                 TRACE (tooltips, "subclassed WM_MOUSEMOVE\n");
2103                 infoPtr->nOldTool = infoPtr->nTool;
2104                 infoPtr->nTool = nTool;
2105
2106                 if ((infoPtr->bActive) &&
2107                     (infoPtr->nTool != infoPtr->nOldTool)) {
2108                     if (infoPtr->nOldTool == -1) {
2109                         SetTimer32 (wndPtr->hwndSelf, ID_TIMERSHOW,
2110                                     infoPtr->nInitialTime, 0);
2111                         TRACE (tooltips, "timer 1 started!\n");
2112                     }
2113                     else {
2114                         TOOLTIPS_Hide (wndPtr, infoPtr);
2115                         SetTimer32 (wndPtr->hwndSelf, ID_TIMERSHOW,
2116                                 infoPtr->nReshowTime, 0);
2117                         TRACE (tooltips, "timer 2 started!\n");
2118                     }
2119                 }
2120                 if (infoPtr->nCurrentTool != -1) {
2121                     SetTimer32 (wndPtr->hwndSelf, ID_TIMERLEAVE, 100, 0);
2122                     TRACE (tooltips, "timer 3 started!\n");
2123                 }
2124             }
2125             break;
2126     }
2127
2128     return CallWindowProc32A (lpttsi->wpOrigProc, hwnd, uMsg, wParam, lParam);
2129 }
2130
2131
2132 LRESULT CALLBACK
2133 TOOLTIPS_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
2134 {
2135     WND *wndPtr = WIN_FindWndPtr(hwnd);
2136
2137     switch (uMsg)
2138     {
2139         case TTM_ACTIVATE:
2140             return TOOLTIPS_Activate (wndPtr, wParam, lParam);
2141
2142         case TTM_ADDTOOL32A:
2143             return TOOLTIPS_AddTool32A (wndPtr, wParam, lParam);
2144
2145         case TTM_ADDTOOL32W:
2146             return TOOLTIPS_AddTool32W (wndPtr, wParam, lParam);
2147
2148         case TTM_DELTOOL32A:
2149             return TOOLTIPS_DelTool32A (wndPtr, wParam, lParam);
2150
2151         case TTM_DELTOOL32W:
2152             return TOOLTIPS_DelTool32W (wndPtr, wParam, lParam);
2153
2154         case TTM_ENUMTOOLS32A:
2155             return TOOLTIPS_EnumTools32A (wndPtr, wParam, lParam);
2156
2157         case TTM_ENUMTOOLS32W:
2158             return TOOLTIPS_EnumTools32W (wndPtr, wParam, lParam);
2159
2160         case TTM_GETCURRENTTOOL32A:
2161             return TOOLTIPS_GetCurrentTool32A (wndPtr, wParam, lParam);
2162
2163         case TTM_GETCURRENTTOOL32W:
2164             return TOOLTIPS_GetCurrentTool32W (wndPtr, wParam, lParam);
2165
2166         case TTM_GETDELAYTIME:
2167             return TOOLTIPS_GetDelayTime (wndPtr, wParam, lParam);
2168
2169         case TTM_GETMARGIN:
2170             return TOOLTIPS_GetMargin (wndPtr, wParam, lParam);
2171
2172         case TTM_GETMAXTIPWIDTH:
2173             return TOOLTIPS_GetMaxTipWidth (wndPtr, wParam, lParam);
2174
2175         case TTM_GETTEXT32A:
2176             return TOOLTIPS_GetText32A (wndPtr, wParam, lParam);
2177
2178         case TTM_GETTEXT32W:
2179             return TOOLTIPS_GetText32W (wndPtr, wParam, lParam);
2180
2181         case TTM_GETTIPBKCOLOR:
2182             return TOOLTIPS_GetTipBkColor (wndPtr, wParam, lParam);
2183
2184         case TTM_GETTIPTEXTCOLOR:
2185             return TOOLTIPS_GetTipTextColor (wndPtr, wParam, lParam);
2186
2187         case TTM_GETTOOLCOUNT:
2188             return TOOLTIPS_GetToolCount (wndPtr, wParam, lParam);
2189
2190         case TTM_GETTOOLINFO32A:
2191             return TOOLTIPS_GetToolInfo32A (wndPtr, wParam, lParam);
2192
2193         case TTM_GETTOOLINFO32W:
2194             return TOOLTIPS_GetToolInfo32W (wndPtr, wParam, lParam);
2195
2196         case TTM_HITTEST32A:
2197             return TOOLTIPS_HitTest32A (wndPtr, wParam, lParam);
2198
2199         case TTM_HITTEST32W:
2200             return TOOLTIPS_HitTest32W (wndPtr, wParam, lParam);
2201
2202         case TTM_NEWTOOLRECT32A:
2203             return TOOLTIPS_NewToolRect32A (wndPtr, wParam, lParam);
2204
2205         case TTM_NEWTOOLRECT32W:
2206             return TOOLTIPS_NewToolRect32W (wndPtr, wParam, lParam);
2207
2208         case TTM_POP:
2209             return TOOLTIPS_Pop (wndPtr, wParam, lParam);
2210
2211         case TTM_RELAYEVENT:
2212             return TOOLTIPS_RelayEvent (wndPtr, wParam, lParam);
2213
2214         case TTM_SETDELAYTIME:
2215             return TOOLTIPS_SetDelayTime (wndPtr, wParam, lParam);
2216
2217         case TTM_SETMARGIN:
2218             return TOOLTIPS_SetMargin (wndPtr, wParam, lParam);
2219
2220         case TTM_SETMAXTIPWIDTH:
2221             return TOOLTIPS_SetMaxTipWidth (wndPtr, wParam, lParam);
2222
2223         case TTM_SETTIPBKCOLOR:
2224             return TOOLTIPS_SetTipBkColor (wndPtr, wParam, lParam);
2225
2226         case TTM_SETTIPTEXTCOLOR:
2227             return TOOLTIPS_SetTipTextColor (wndPtr, wParam, lParam);
2228
2229         case TTM_SETTOOLINFO32A:
2230             return TOOLTIPS_SetToolInfo32A (wndPtr, wParam, lParam);
2231
2232         case TTM_SETTOOLINFO32W:
2233             return TOOLTIPS_SetToolInfo32W (wndPtr, wParam, lParam);
2234
2235         case TTM_TRACKACTIVATE:
2236             return TOOLTIPS_TrackActivate (wndPtr, wParam, lParam);
2237
2238         case TTM_TRACKPOSITION:
2239             return TOOLTIPS_TrackPosition (wndPtr, wParam, lParam);
2240
2241         case TTM_UPDATE:
2242             return TOOLTIPS_Update (wndPtr, wParam, lParam);
2243
2244         case TTM_UPDATETIPTEXT32A:
2245             return TOOLTIPS_UpdateTipText32A (wndPtr, wParam, lParam);
2246
2247         case TTM_UPDATETIPTEXT32W:
2248             return TOOLTIPS_UpdateTipText32W (wndPtr, wParam, lParam);
2249
2250         case TTM_WINDOWFROMPOINT:
2251             return TOOLTIPS_WindowFromPoint (wndPtr, wParam, lParam);
2252
2253
2254         case WM_CREATE:
2255             return TOOLTIPS_Create (wndPtr, wParam, lParam);
2256
2257         case WM_DESTROY:
2258             return TOOLTIPS_Destroy (wndPtr, wParam, lParam);
2259
2260         case WM_ERASEBKGND:
2261             return TOOLTIPS_EraseBackground (wndPtr, wParam, lParam);
2262
2263         case WM_GETFONT:
2264             return TOOLTIPS_GetFont (wndPtr, wParam, lParam);
2265
2266         case WM_LBUTTONDOWN:
2267         case WM_LBUTTONUP:
2268         case WM_MBUTTONDOWN:
2269         case WM_MBUTTONUP:
2270         case WM_RBUTTONDOWN:
2271         case WM_RBUTTONUP:
2272         case WM_MOUSEMOVE:
2273             return TOOLTIPS_MouseMessage (wndPtr, uMsg, wParam, lParam);
2274
2275         case WM_NCCREATE:
2276             return TOOLTIPS_NCCreate (wndPtr, wParam, lParam);
2277
2278         case WM_NCHITTEST:
2279             return TOOLTIPS_NCHitTest (wndPtr, wParam, lParam);
2280
2281 /*      case WM_NOTIFYFORMAT: */
2282 /*          return TOOLTIPS_NotifyFormat (wndPtr, wParam, lParam); */
2283
2284         case WM_PAINT:
2285             return TOOLTIPS_Paint (wndPtr, wParam, lParam);
2286
2287         case WM_SETFONT:
2288             return TOOLTIPS_SetFont (wndPtr, wParam, lParam);
2289
2290         case WM_TIMER:
2291             return TOOLTIPS_Timer (wndPtr, wParam, lParam);
2292
2293         case WM_WININICHANGE:
2294             return TOOLTIPS_WinIniChange (wndPtr, wParam, lParam);
2295
2296         default:
2297             if (uMsg >= WM_USER)
2298                 ERR (tooltips, "unknown msg %04x wp=%08x lp=%08lx\n",
2299                      uMsg, wParam, lParam);
2300             return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
2301     }
2302     return 0;
2303 }
2304
2305
2306 VOID
2307 TOOLTIPS_Register (VOID)
2308 {
2309     WNDCLASS32A wndClass;
2310
2311     if (GlobalFindAtom32A (TOOLTIPS_CLASS32A)) return;
2312
2313     ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
2314     wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS;
2315     wndClass.lpfnWndProc   = (WNDPROC32)TOOLTIPS_WindowProc;
2316     wndClass.cbClsExtra    = 0;
2317     wndClass.cbWndExtra    = sizeof(TOOLTIPS_INFO *);
2318     wndClass.hCursor       = LoadCursor32A (0, IDC_ARROW32A);
2319     wndClass.hbrBackground = 0;
2320     wndClass.lpszClassName = TOOLTIPS_CLASS32A;
2321  
2322     RegisterClass32A (&wndClass);
2323 }
2324
2325
2326 VOID
2327 TOOLTIPS_Unregister (VOID)
2328 {
2329     if (GlobalFindAtom32A (TOOLTIPS_CLASS32A))
2330         UnregisterClass32A (TOOLTIPS_CLASS32A, (HINSTANCE32)NULL);
2331 }
2332