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

Last change on this file since 8266 was 7616, checked in by sandervl, 24 years ago

font delete bugs removed

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