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

Last change on this file since 3962 was 3962, checked in by sandervl, 25 years ago

PD: update to wine20000801 (toolbar+tooltips)

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