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

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

unicode and other changes

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