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