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

Last change on this file since 2912 was 2893, checked in by achimha, 26 years ago

added infoPtr == NULL checks to prevent crashes

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