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

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

merge with latest Wine

File size: 71.3 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 dwStyle &= 0x0000FFFF;
2201 dwStyle |= (WS_POPUP | WS_BORDER | WS_CLIPSIBLINGS);
2202 SetWindowLongA(hwnd,GWL_STYLE,dwStyle);
2203
2204 SetWindowLongA(hwnd,GWL_EXSTYLE,dwExStyle | WS_EX_TOOLWINDOW);
2205
2206 return TRUE;
2207}
2208
2209
2210static LRESULT
2211TOOLTIPS_NCHitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
2212{
2213 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2214 INT nTool = (infoPtr->bTrackActive) ? infoPtr->nTrackTool : infoPtr->nTool;
2215
2216// TRACE (tooltips, " nTool=%d\n", nTool);
2217
2218 if ((nTool > -1) && (nTool < infoPtr->uNumTools)) {
2219 if (infoPtr->tools[nTool].uFlags & TTF_TRANSPARENT) {
2220// TRACE (tooltips, "-- in transparent mode!\n");
2221 return HTTRANSPARENT;
2222 }
2223 }
2224
2225 return DefWindowProcA (hwnd, WM_NCHITTEST, wParam, lParam);
2226}
2227
2228static LRESULT
2229TOOLTIPS_Paint (HWND hwnd, WPARAM wParam, LPARAM lParam)
2230{
2231 HDC hdc;
2232 PAINTSTRUCT ps;
2233
2234 hdc = (wParam == 0) ? BeginPaint (hwnd, &ps) : (HDC)wParam;
2235 TOOLTIPS_Draw(hwnd, hdc);
2236 if (!wParam)
2237 EndPaint (hwnd, &ps);
2238 return 0;
2239}
2240
2241
2242static LRESULT
2243TOOLTIPS_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
2244{
2245 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2246
2247 infoPtr->hFont = (HFONT)wParam;
2248
2249 if ((LOWORD(lParam)) && (infoPtr->nCurrentTool != -1))
2250 {
2251 /* force repaint */
2252 if (infoPtr->bActive) TOOLTIPS_Show(hwnd,infoPtr);
2253 else if (infoPtr->bTrackActive) TOOLTIPS_TrackShow(hwnd,infoPtr);
2254 }
2255
2256 return 0;
2257}
2258/******************************************************************
2259 * TOOLTIPS_OnWMGetTextLength
2260 *
2261 * This function is called when the tooltip receive a
2262 * WM_GETTEXTLENGTH message.
2263 * wParam : not used
2264 * lParam : not used
2265 *
2266 * returns the length, in characters, of the tip text
2267 ******************************************************************/
2268
2269static LRESULT
2270TOOLTIPS_OnWMGetTextLength(HWND hwnd, WPARAM wParam, LPARAM lParam)
2271{
2272 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2273 return lstrlenW(infoPtr->szTipText);
2274}
2275/******************************************************************
2276 * TOOLTIPS_OnWMGetText
2277 *
2278 * This function is called when the tooltip receive a
2279 * WM_GETTEXT message.
2280 * wParam : specifies the maximum number of characters to be copied
2281 * lParam : is the pointer to the buffer that will receive
2282 * the tip text
2283 *
2284 * returns the number of characters copied
2285 ******************************************************************/
2286static LRESULT
2287TOOLTIPS_OnWMGetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
2288{
2289 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2290 INT length;
2291
2292 if(!infoPtr || !(infoPtr->szTipText))
2293 return 0;
2294
2295 length = lstrlenW(infoPtr->szTipText);
2296 /* When wParam is smaller than the lenght of the tip text
2297 copy wParam characters of the tip text and return wParam */
2298 if(wParam < length)
2299 {
2300 lstrcpynWtoA((LPSTR)lParam,infoPtr->szTipText,(UINT)wParam);//includes 0 terminator
2301 return wParam;
2302 }
2303 lstrcpyWtoA((LPSTR)lParam,infoPtr->szTipText);
2304 return length;
2305
2306}
2307
2308static LRESULT
2309TOOLTIPS_Timer (HWND hwnd, WPARAM wParam, LPARAM lParam)
2310{
2311 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2312
2313// TRACE (tooltips, "timer %d (%x) expired!\n", wParam, hwnd);
2314 switch (wParam)
2315 {
2316 case ID_TIMERSHOW:
2317 KillTimer(hwnd,ID_TIMERSHOW);
2318 if (TOOLTIPS_CheckTool(hwnd,TRUE) == infoPtr->nTool)
2319 TOOLTIPS_Show(hwnd,infoPtr);
2320 break;
2321
2322 case ID_TIMERPOP:
2323 TOOLTIPS_Hide (hwnd, infoPtr);
2324 break;
2325
2326 case ID_TIMERLEAVE:
2327 KillTimer (hwnd,ID_TIMERLEAVE);
2328 if (TOOLTIPS_CheckTool(hwnd,FALSE) == -1)
2329 {
2330 infoPtr->nTool = -1;
2331 infoPtr->nOldTool = -1;
2332 TOOLTIPS_Hide(hwnd,infoPtr);
2333 }
2334 break;
2335 }
2336
2337 return 0;
2338}
2339
2340
2341static LRESULT
2342TOOLTIPS_WinIniChange (HWND hwnd, WPARAM wParam, LPARAM lParam)
2343{
2344 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2345 NONCLIENTMETRICSA nclm;
2346
2347 infoPtr->clrBk = GetSysColor (COLOR_INFOBK);
2348 infoPtr->clrText = GetSysColor (COLOR_INFOTEXT);
2349
2350#ifdef __WIN32OS2__
2351 //NEVER delete the font object received by WM_SETFONT!
2352 DeleteObject (infoPtr->hDefaultFont);
2353#else
2354 DeleteObject (infoPtr->hFont);
2355#endif
2356 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
2357 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
2358#ifdef __WIN32OS2__
2359 infoPtr->hFont = infoPtr->hDefaultFont = CreateFontIndirectA (&nclm.lfStatusFont);
2360#else
2361 infoPtr->hFont = CreateFontIndirectA (&nclm.lfStatusFont);
2362#endif
2363 return 0;
2364}
2365
2366LRESULT TOOLTIPS_MouseActivate(HWND hwnd,WPARAM wParam,LPARAM lParam)
2367{
2368 return MA_NOACTIVATE;
2369}
2370
2371LRESULT CALLBACK
2372TOOLTIPS_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2373{
2374 LPTT_SUBCLASS_INFO lpttsi =
2375 (LPTT_SUBCLASS_INFO)GetPropA (hwnd, COMCTL32_aSubclass);
2376 TOOLTIPS_INFO *infoPtr;
2377 UINT nTool;
2378
2379 switch (uMsg) {
2380 case WM_LBUTTONDOWN:
2381 case WM_LBUTTONUP:
2382 case WM_MBUTTONDOWN:
2383 case WM_MBUTTONUP:
2384 case WM_RBUTTONDOWN:
2385 case WM_RBUTTONUP:
2386 infoPtr = TOOLTIPS_GetInfoPtr(lpttsi->hwndToolTip);
2387 if (!infoPtr) break;
2388 nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd);
2389
2390 infoPtr->nOldTool = infoPtr->nTool;
2391 infoPtr->nTool = nTool;
2392 TOOLTIPS_Hide (lpttsi->hwndToolTip, infoPtr);
2393 break;
2394
2395 case WM_MOUSEMOVE:
2396 infoPtr = TOOLTIPS_GetInfoPtr (lpttsi->hwndToolTip);
2397 if (!infoPtr) break;
2398 nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd);
2399
2400 infoPtr->nOldTool = infoPtr->nTool;
2401 infoPtr->nTool = nTool;
2402
2403 if ((infoPtr->bActive) &&
2404 (infoPtr->nTool != infoPtr->nOldTool)) {
2405 if (infoPtr->nOldTool == -1) {
2406 SetTimer (hwnd, ID_TIMERSHOW,
2407 infoPtr->nInitialTime, 0);
2408 //TRACE (tooltips, "timer 1 started!\n");
2409 }
2410 else {
2411 TOOLTIPS_Hide (lpttsi->hwndToolTip, infoPtr);
2412 SetTimer (hwnd, ID_TIMERSHOW,
2413 infoPtr->nReshowTime, 0);
2414// TRACE (tooltips, "timer 2 started!\n");
2415 }
2416 }
2417 if (infoPtr->nCurrentTool != -1) {
2418 SetTimer (hwnd, ID_TIMERLEAVE, 100, 0);
2419// TRACE (tooltips, "timer 3 started!\n");
2420 }
2421 break;
2422 }
2423
2424 return CallWindowProcA (lpttsi->wpOrigProc, hwnd, uMsg, wParam, lParam);
2425}
2426
2427
2428static LRESULT CALLBACK
2429TOOLTIPS_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2430{
2431 switch (uMsg)
2432 {
2433 case TTM_ACTIVATE:
2434 return TOOLTIPS_Activate (hwnd, wParam, lParam);
2435
2436 case TTM_ADDTOOLA:
2437 return TOOLTIPS_AddToolA (hwnd, wParam, lParam);
2438
2439 case TTM_ADDTOOLW:
2440 return TOOLTIPS_AddToolW (hwnd, wParam, lParam);
2441
2442 case TTM_DELTOOLA:
2443 return TOOLTIPS_DelToolA (hwnd, wParam, lParam);
2444
2445 case TTM_DELTOOLW:
2446 return TOOLTIPS_DelToolW (hwnd, wParam, lParam);
2447
2448 case TTM_ENUMTOOLSA:
2449 return TOOLTIPS_EnumToolsA (hwnd, wParam, lParam);
2450
2451 case TTM_ENUMTOOLSW:
2452 return TOOLTIPS_EnumToolsW (hwnd, wParam, lParam);
2453
2454 case TTM_GETCURRENTTOOLA:
2455 return TOOLTIPS_GetCurrentToolA (hwnd, wParam, lParam);
2456
2457 case TTM_GETCURRENTTOOLW:
2458 return TOOLTIPS_GetCurrentToolW (hwnd, wParam, lParam);
2459
2460 case TTM_GETDELAYTIME:
2461 return TOOLTIPS_GetDelayTime (hwnd, wParam, lParam);
2462
2463 case TTM_GETMARGIN:
2464 return TOOLTIPS_GetMargin (hwnd, wParam, lParam);
2465
2466 case TTM_GETMAXTIPWIDTH:
2467 return TOOLTIPS_GetMaxTipWidth (hwnd, wParam, lParam);
2468
2469 case TTM_GETTEXTA:
2470 return TOOLTIPS_GetTextA (hwnd, wParam, lParam);
2471
2472 case TTM_GETTEXTW:
2473 return TOOLTIPS_GetTextW (hwnd, wParam, lParam);
2474
2475 case TTM_GETTIPBKCOLOR:
2476 return TOOLTIPS_GetTipBkColor (hwnd, wParam, lParam);
2477
2478 case TTM_GETTIPTEXTCOLOR:
2479 return TOOLTIPS_GetTipTextColor (hwnd, wParam, lParam);
2480
2481 case TTM_GETTOOLCOUNT:
2482 return TOOLTIPS_GetToolCount (hwnd, wParam, lParam);
2483
2484 case TTM_GETTOOLINFOA:
2485 return TOOLTIPS_GetToolInfoA (hwnd, wParam, lParam);
2486
2487 case TTM_GETTOOLINFOW:
2488 return TOOLTIPS_GetToolInfoW (hwnd, wParam, lParam);
2489
2490 case TTM_HITTESTA:
2491 return TOOLTIPS_HitTestA (hwnd, wParam, lParam);
2492
2493 case TTM_HITTESTW:
2494 return TOOLTIPS_HitTestW (hwnd, wParam, lParam);
2495
2496 case TTM_NEWTOOLRECTA:
2497 return TOOLTIPS_NewToolRectA (hwnd, wParam, lParam);
2498
2499 case TTM_NEWTOOLRECTW:
2500 return TOOLTIPS_NewToolRectW (hwnd, wParam, lParam);
2501
2502 case TTM_POP:
2503 return TOOLTIPS_Pop (hwnd, wParam, lParam);
2504
2505 case TTM_RELAYEVENT:
2506 return TOOLTIPS_RelayEvent (hwnd, wParam, lParam);
2507
2508 case TTM_SETDELAYTIME:
2509 return TOOLTIPS_SetDelayTime (hwnd, wParam, lParam);
2510
2511 case TTM_SETMARGIN:
2512 return TOOLTIPS_SetMargin (hwnd, wParam, lParam);
2513
2514 case TTM_SETMAXTIPWIDTH:
2515 return TOOLTIPS_SetMaxTipWidth (hwnd, wParam, lParam);
2516
2517 case TTM_SETTIPBKCOLOR:
2518 return TOOLTIPS_SetTipBkColor (hwnd, wParam, lParam);
2519
2520 case TTM_SETTIPTEXTCOLOR:
2521 return TOOLTIPS_SetTipTextColor (hwnd, wParam, lParam);
2522
2523 case TTM_SETTOOLINFOA:
2524 return TOOLTIPS_SetToolInfoA (hwnd, wParam, lParam);
2525
2526 case TTM_SETTOOLINFOW:
2527 return TOOLTIPS_SetToolInfoW (hwnd, wParam, lParam);
2528
2529 case TTM_TRACKACTIVATE:
2530 return TOOLTIPS_TrackActivate (hwnd, wParam, lParam);
2531
2532 case TTM_TRACKPOSITION:
2533 return TOOLTIPS_TrackPosition (hwnd, wParam, lParam);
2534
2535 case TTM_UPDATE:
2536 return TOOLTIPS_Update (hwnd, wParam, lParam);
2537
2538 case TTM_UPDATETIPTEXTA:
2539 return TOOLTIPS_UpdateTipTextA (hwnd, wParam, lParam);
2540
2541 case TTM_UPDATETIPTEXTW:
2542 return TOOLTIPS_UpdateTipTextW (hwnd, wParam, lParam);
2543
2544 case TTM_WINDOWFROMPOINT:
2545 return TOOLTIPS_WindowFromPoint (hwnd, wParam, lParam);
2546
2547
2548 case WM_CREATE:
2549 return TOOLTIPS_Create (hwnd, wParam, lParam);
2550
2551 case WM_DESTROY:
2552 return TOOLTIPS_Destroy (hwnd, wParam, lParam);
2553
2554 case WM_ERASEBKGND:
2555 return TOOLTIPS_EraseBackground (hwnd, wParam, lParam);
2556
2557 case WM_GETFONT:
2558 return TOOLTIPS_GetFont (hwnd, wParam, lParam);
2559
2560 case WM_GETTEXT:
2561 return TOOLTIPS_OnWMGetText (hwnd, wParam, lParam);
2562
2563 case WM_GETTEXTLENGTH:
2564 return TOOLTIPS_OnWMGetTextLength (hwnd, wParam, lParam);
2565
2566
2567 case WM_LBUTTONDOWN:
2568 case WM_LBUTTONUP:
2569 case WM_LBUTTONDBLCLK:
2570 case WM_MBUTTONDOWN:
2571 case WM_MBUTTONUP:
2572 case WM_MBUTTONDBLCLK:
2573 case WM_RBUTTONDOWN:
2574 case WM_RBUTTONUP:
2575 case WM_RBUTTONDBLCLK:
2576 case WM_MOUSEMOVE:
2577 return TOOLTIPS_MouseMessage (hwnd, uMsg, wParam, lParam);
2578
2579 case WM_MOUSEACTIVATE:
2580 return TOOLTIPS_MouseActivate(hwnd,wParam,lParam);
2581
2582 case WM_NCCREATE:
2583 return TOOLTIPS_NCCreate (hwnd, wParam, lParam);
2584
2585 case WM_NCHITTEST:
2586 return TOOLTIPS_NCHitTest (hwnd, wParam, lParam);
2587
2588 case WM_PAINT:
2589 return TOOLTIPS_Paint (hwnd, wParam, lParam);
2590
2591 case WM_SETFONT:
2592 return TOOLTIPS_SetFont (hwnd, wParam, lParam);
2593
2594 case WM_TIMER:
2595 return TOOLTIPS_Timer (hwnd, wParam, lParam);
2596
2597 case WM_WININICHANGE:
2598 return TOOLTIPS_WinIniChange (hwnd, wParam, lParam);
2599
2600 default:
2601// if (uMsg >= WM_USER)
2602// ERR (tooltips, "unknown msg %04x wp=%08x lp=%08lx\n",
2603// uMsg, wParam, lParam);
2604 return defComCtl32ProcA (hwnd, uMsg, wParam, lParam);
2605 }
2606 return 0;
2607}
2608
2609
2610VOID
2611TOOLTIPS_Register (VOID)
2612{
2613 WNDCLASSA wndClass;
2614
2615 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
2616 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS;
2617 wndClass.lpfnWndProc = (WNDPROC)TOOLTIPS_WindowProc;
2618 wndClass.cbClsExtra = 0;
2619 wndClass.cbWndExtra = sizeof(TOOLTIPS_INFO *);
2620 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
2621 wndClass.hbrBackground = 0;
2622 wndClass.lpszClassName = TOOLTIPS_CLASSA;
2623
2624 RegisterClassA (&wndClass);
2625}
2626
2627
2628VOID
2629TOOLTIPS_Unregister (VOID)
2630{
2631 UnregisterClassA (TOOLTIPS_CLASSA, (HINSTANCE)NULL);
2632}
2633
Note: See TracBrowser for help on using the repository browser.