source: trunk/src/comctl32/tooltips.c@ 236

Last change on this file since 236 was 236, checked in by cbratschi, 26 years ago

bug fixes (unicode) and improvements

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