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

Last change on this file since 5120 was 3970, checked in by cbratschi, 25 years ago

Corel WINE 20000807 changes - part 1

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