source: trunk/src/comctl32/tooltips.cpp@ 8985

Last change on this file since 8985 was 8985, checked in by sandervl, 23 years ago

PF: ignore TTS_ALWAYSTIP style. Windows 2000 appears to do the same.

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