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

Last change on this file since 7612 was 7408, checked in by sandervl, 24 years ago

tooltips fixes (memory freed incorrectly)

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