Added add_queue/remove_queue to server object operations.
[wine/testsucceed.git] / dlls / comctl32 / tooltips.c
blob32e0c2c104649a1b4248405f3ceadb3a19847300
1 /*
2 * Tool tip control
4 * Copyright 1998 Eric Kohl
6 * TODO:
7 * - Unicode support.
8 * - Custom draw support.
10 * Testing:
11 * - Run tests using Waite Group Windows95 API Bible Volume 2.
12 * The second cdrom (chapter 3) contains executables activate.exe,
13 * curtool.exe, deltool.exe, enumtools.exe, getinfo.exe, getiptxt.exe,
14 * hittest.exe, needtext.exe, newrect.exe, updtext.exe and winfrpt.exe.
17 #include "windows.h"
18 #include "commctrl.h"
19 #include "tooltips.h"
20 #include "win.h"
21 #include "debug.h"
23 #define ID_TIMERSHOW 1 /* show delay timer */
24 #define ID_TIMERPOP 2 /* auto pop timer */
25 #define ID_TIMERLEAVE 3 /* tool leave timer */
28 extern LPSTR COMCTL32_aSubclass; /* global subclassing atom */
30 /* property name of tooltip window handle */
31 /*#define TT_SUBCLASS_PROP "CC32SubclassInfo" */
33 #define TOOLTIPS_GetInfoPtr(wndPtr) ((TOOLTIPS_INFO *)wndPtr->wExtra[0])
36 LRESULT CALLBACK
37 TOOLTIPS_SubclassProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam);
40 static VOID
41 TOOLTIPS_Refresh (WND *wndPtr, HDC32 hdc)
43 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
44 RECT32 rc;
45 INT32 oldBkMode;
46 HFONT32 hOldFont;
47 UINT32 uFlags = DT_EXTERNALLEADING;
49 if (infoPtr->nMaxTipWidth > -1)
50 uFlags |= DT_WORDBREAK;
51 if (wndPtr->dwStyle & TTS_NOPREFIX)
52 uFlags |= DT_NOPREFIX;
53 GetClientRect32 (wndPtr->hwndSelf, &rc);
54 rc.left += (2 + infoPtr->rcMargin.left);
55 rc.top += (2 + infoPtr->rcMargin.top);
56 rc.right -= (2 + infoPtr->rcMargin.right);
57 rc.bottom -= (2 + infoPtr->rcMargin.bottom);
58 oldBkMode = SetBkMode32 (hdc, TRANSPARENT);
59 SetTextColor32 (hdc, infoPtr->clrText);
60 hOldFont = SelectObject32 (hdc, infoPtr->hFont);
61 DrawText32W (hdc, infoPtr->szTipText, -1, &rc, uFlags);
62 SelectObject32 (hdc, hOldFont);
63 if (oldBkMode != TRANSPARENT)
64 SetBkMode32 (hdc, oldBkMode);
68 static VOID
69 TOOLTIPS_GetTipText (WND *wndPtr, TOOLTIPS_INFO *infoPtr, INT32 nTool)
71 TTTOOL_INFO *toolPtr = &infoPtr->tools[nTool];
73 if ((toolPtr->hinst) && (HIWORD((UINT32)toolPtr->lpszText) == 0)) {
74 /* load a resource */
75 TRACE (tooltips, "load res string %x %x\n",
76 toolPtr->hinst, (int)toolPtr->lpszText);
77 LoadString32W (toolPtr->hinst, (UINT32)toolPtr->lpszText,
78 infoPtr->szTipText, INFOTIPSIZE);
80 else if (toolPtr->lpszText) {
81 if (toolPtr->lpszText == LPSTR_TEXTCALLBACK32W) {
82 NMTTDISPINFO32A ttnmdi;
84 /* fill NMHDR struct */
85 ZeroMemory (&ttnmdi, sizeof(NMTTDISPINFO32A));
86 ttnmdi.hdr.hwndFrom = wndPtr->hwndSelf;
87 ttnmdi.hdr.idFrom = toolPtr->uId;
88 ttnmdi.hdr.code = TTN_GETDISPINFO32A;
89 ttnmdi.lpszText = (LPSTR)&ttnmdi.szText;
90 ttnmdi.uFlags = toolPtr->uFlags;
91 ttnmdi.lParam = toolPtr->lParam;
93 TRACE (tooltips, "hdr.idFrom = %x\n", ttnmdi.hdr.idFrom);
94 SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
95 (WPARAM32)toolPtr->uId, (LPARAM)&ttnmdi);
97 if ((ttnmdi.hinst) && (HIWORD((UINT32)ttnmdi.szText) == 0)) {
98 LoadString32W (ttnmdi.hinst, (UINT32)ttnmdi.szText,
99 infoPtr->szTipText, INFOTIPSIZE);
100 if (ttnmdi.uFlags & TTF_DI_SETITEM) {
101 toolPtr->hinst = ttnmdi.hinst;
102 toolPtr->lpszText = (LPWSTR)ttnmdi.szText;
105 else if (ttnmdi.szText[0]) {
106 lstrcpynAtoW (infoPtr->szTipText, ttnmdi.szText, 80);
107 if (ttnmdi.uFlags & TTF_DI_SETITEM) {
108 INT32 len = lstrlen32A (ttnmdi.szText);
109 toolPtr->hinst = 0;
110 toolPtr->lpszText = COMCTL32_Alloc ((len+1)* sizeof(WCHAR));
111 lstrcpyAtoW (toolPtr->lpszText, ttnmdi.szText);
114 else if (ttnmdi.lpszText == 0) {
115 /* no text available */
116 infoPtr->szTipText[0] = L'\0';
118 else if (ttnmdi.lpszText != LPSTR_TEXTCALLBACK32A) {
119 lstrcpynAtoW (infoPtr->szTipText, ttnmdi.lpszText, INFOTIPSIZE);
120 if (ttnmdi.uFlags & TTF_DI_SETITEM) {
121 INT32 len = lstrlen32A (ttnmdi.lpszText);
122 toolPtr->hinst = 0;
123 toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
124 lstrcpyAtoW (toolPtr->lpszText, ttnmdi.lpszText);
127 else {
128 ERR (tooltips, "recursive text callback!\n");
129 infoPtr->szTipText[0] = '\0';
132 else {
133 /* the item is a usual (unicode) text */
134 lstrcpyn32W (infoPtr->szTipText, toolPtr->lpszText, INFOTIPSIZE);
137 else {
138 /* no text available */
139 infoPtr->szTipText[0] = L'\0';
142 TRACE (tooltips, "\"%s\"\n", debugstr_w(infoPtr->szTipText));
146 static VOID
147 TOOLTIPS_CalcTipSize (WND *wndPtr, TOOLTIPS_INFO *infoPtr, LPSIZE32 lpSize)
149 HDC32 hdc;
150 HFONT32 hOldFont;
151 UINT32 uFlags = DT_EXTERNALLEADING | DT_CALCRECT;
152 RECT32 rc = {0, 0, 0, 0};
154 if (infoPtr->nMaxTipWidth > -1) {
155 rc.right = infoPtr->nMaxTipWidth;
156 uFlags |= DT_WORDBREAK;
158 if (wndPtr->dwStyle & TTS_NOPREFIX)
159 uFlags |= DT_NOPREFIX;
160 TRACE (tooltips, "\"%s\"\n", debugstr_w(infoPtr->szTipText));
162 hdc = GetDC32 (wndPtr->hwndSelf);
163 hOldFont = SelectObject32 (hdc, infoPtr->hFont);
164 DrawText32W (hdc, infoPtr->szTipText, -1, &rc, uFlags);
165 SelectObject32 (hdc, hOldFont);
166 ReleaseDC32 (wndPtr->hwndSelf, hdc);
168 lpSize->cx = rc.right - rc.left + 4 +
169 infoPtr->rcMargin.left + infoPtr->rcMargin.right;
170 lpSize->cy = rc.bottom - rc.top + 4 +
171 infoPtr->rcMargin.bottom + infoPtr->rcMargin.top;
175 static VOID
176 TOOLTIPS_Show (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
178 TTTOOL_INFO *toolPtr;
179 RECT32 rect;
180 SIZE32 size;
181 NMHDR hdr;
183 if (infoPtr->nTool == -1) {
184 TRACE (tooltips, "invalid tool (-1)!\n");
185 return;
188 infoPtr->nCurrentTool = infoPtr->nTool;
190 TRACE (tooltips, "Show tooltip pre %d!\n", infoPtr->nTool);
192 TOOLTIPS_GetTipText (wndPtr, infoPtr, infoPtr->nCurrentTool);
194 if (infoPtr->szTipText[0] == L'\0') {
195 infoPtr->nCurrentTool = -1;
196 return;
199 TRACE (tooltips, "Show tooltip %d!\n", infoPtr->nCurrentTool);
200 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
202 hdr.hwndFrom = wndPtr->hwndSelf;
203 hdr.idFrom = toolPtr->uId;
204 hdr.code = TTN_SHOW;
205 SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
206 (WPARAM32)toolPtr->uId, (LPARAM)&hdr);
208 TRACE (tooltips, "\"%s\"\n", debugstr_w(infoPtr->szTipText));
210 TOOLTIPS_CalcTipSize (wndPtr, infoPtr, &size);
211 TRACE (tooltips, "size %d - %d\n", size.cx, size.cy);
213 if (toolPtr->uFlags & TTF_CENTERTIP) {
214 RECT32 rc;
216 if (toolPtr->uFlags & TTF_IDISHWND)
217 GetWindowRect32 ((HWND32)toolPtr->uId, &rc);
218 else {
219 rc = toolPtr->rect;
220 MapWindowPoints32 (toolPtr->hwnd, (HWND32)0, (LPPOINT32)&rc, 2);
222 rect.left = (rc.left + rc.right - size.cx) / 2;
223 rect.top = rc.bottom + 2;
225 else {
226 GetCursorPos32 ((LPPOINT32)&rect);
227 rect.top += 20;
230 /* FIXME: check position */
232 TRACE (tooltips, "pos %d - %d\n", rect.left, rect.top);
234 rect.right = rect.left + size.cx;
235 rect.bottom = rect.top + size.cy;
237 AdjustWindowRectEx32 (&rect, wndPtr->dwStyle, FALSE, wndPtr->dwExStyle);
239 SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, rect.left, rect.top,
240 rect.right - rect.left, rect.bottom - rect.top,
241 SWP_SHOWWINDOW);
243 SetTimer32 (wndPtr->hwndSelf, ID_TIMERPOP, infoPtr->nAutoPopTime, 0);
247 static VOID
248 TOOLTIPS_Hide (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
250 TTTOOL_INFO *toolPtr;
251 NMHDR hdr;
253 if (infoPtr->nCurrentTool == -1)
254 return;
256 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
257 TRACE (tooltips, "Hide tooltip %d!\n", infoPtr->nCurrentTool);
258 KillTimer32 (wndPtr->hwndSelf, ID_TIMERPOP);
260 hdr.hwndFrom = wndPtr->hwndSelf;
261 hdr.idFrom = toolPtr->uId;
262 hdr.code = TTN_POP;
263 SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
264 (WPARAM32)toolPtr->uId, (LPARAM)&hdr);
266 infoPtr->nCurrentTool = -1;
268 SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0,
269 SWP_NOZORDER | SWP_HIDEWINDOW);
273 static VOID
274 TOOLTIPS_TrackShow (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
276 TTTOOL_INFO *toolPtr;
277 RECT32 rect;
278 SIZE32 size;
279 NMHDR hdr;
281 if (infoPtr->nTrackTool == -1) {
282 TRACE (tooltips, "invalid tracking tool (-1)!\n");
283 return;
286 TRACE (tooltips, "show tracking tooltip pre %d!\n", infoPtr->nTrackTool);
288 TOOLTIPS_GetTipText (wndPtr, infoPtr, infoPtr->nTrackTool);
290 if (infoPtr->szTipText[0] == L'\0') {
291 infoPtr->nTrackTool = -1;
292 return;
295 TRACE (tooltips, "show tracking tooltip %d!\n", infoPtr->nTrackTool);
296 toolPtr = &infoPtr->tools[infoPtr->nTrackTool];
298 hdr.hwndFrom = wndPtr->hwndSelf;
299 hdr.idFrom = toolPtr->uId;
300 hdr.code = TTN_SHOW;
301 SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
302 (WPARAM32)toolPtr->uId, (LPARAM)&hdr);
304 TRACE (tooltips, "\"%s\"\n", debugstr_w(infoPtr->szTipText));
306 TOOLTIPS_CalcTipSize (wndPtr, infoPtr, &size);
307 TRACE (tooltips, "size %d - %d\n", size.cx, size.cy);
309 if (toolPtr->uFlags & TTF_ABSOLUTE) {
310 rect.left = infoPtr->xTrackPos;
311 rect.top = infoPtr->yTrackPos;
313 if (toolPtr->uFlags & TTF_CENTERTIP) {
314 rect.left -= (size.cx / 2);
315 rect.top -= (size.cy / 2);
318 else {
319 RECT32 rcTool;
321 if (toolPtr->uFlags & TTF_IDISHWND)
322 GetWindowRect32 ((HWND32)toolPtr->uId, &rcTool);
323 else {
324 rcTool = toolPtr->rect;
325 MapWindowPoints32 (toolPtr->hwnd, (HWND32)0, (LPPOINT32)&rcTool, 2);
328 GetCursorPos32 ((LPPOINT32)&rect);
329 rect.top += 20;
331 if (toolPtr->uFlags & TTF_CENTERTIP) {
332 rect.left -= (size.cx / 2);
333 rect.top -= (size.cy / 2);
336 /* smart placement */
337 if ((rect.left + size.cx > rcTool.left) && (rect.left < rcTool.right) &&
338 (rect.top + size.cy > rcTool.top) && (rect.top < rcTool.bottom))
339 rect.left = rcTool.right;
342 TRACE (tooltips, "pos %d - %d\n", rect.left, rect.top);
344 rect.right = rect.left + size.cx;
345 rect.bottom = rect.top + size.cy;
347 AdjustWindowRectEx32 (&rect, wndPtr->dwStyle, FALSE, wndPtr->dwExStyle);
349 SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, rect.left, rect.top,
350 rect.right - rect.left, rect.bottom - rect.top,
351 SWP_SHOWWINDOW);
355 static VOID
356 TOOLTIPS_TrackHide (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
358 TTTOOL_INFO *toolPtr;
359 NMHDR hdr;
361 if (infoPtr->nTrackTool == -1)
362 return;
364 toolPtr = &infoPtr->tools[infoPtr->nTrackTool];
365 TRACE (tooltips, "hide tracking tooltip %d!\n", infoPtr->nTrackTool);
367 hdr.hwndFrom = wndPtr->hwndSelf;
368 hdr.idFrom = toolPtr->uId;
369 hdr.code = TTN_POP;
370 SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
371 (WPARAM32)toolPtr->uId, (LPARAM)&hdr);
373 SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0,
374 SWP_NOZORDER | SWP_HIDEWINDOW);
378 static INT32
379 TOOLTIPS_GetToolFromInfoA (TOOLTIPS_INFO *infoPtr, LPTTTOOLINFO32A lpToolInfo)
381 TTTOOL_INFO *toolPtr;
382 INT32 nTool;
384 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
385 toolPtr = &infoPtr->tools[nTool];
387 if (!(toolPtr->uFlags & TTF_IDISHWND) &&
388 (lpToolInfo->hwnd == toolPtr->hwnd) &&
389 (lpToolInfo->uId == toolPtr->uId))
390 return nTool;
393 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
394 toolPtr = &infoPtr->tools[nTool];
396 if ((toolPtr->uFlags & TTF_IDISHWND) &&
397 (lpToolInfo->uId == toolPtr->uId))
398 return nTool;
401 return -1;
405 static INT32
406 TOOLTIPS_GetToolFromInfoW (TOOLTIPS_INFO *infoPtr, LPTTTOOLINFO32W lpToolInfo)
408 TTTOOL_INFO *toolPtr;
409 INT32 nTool;
411 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
412 toolPtr = &infoPtr->tools[nTool];
414 if (!(toolPtr->uFlags & TTF_IDISHWND) &&
415 (lpToolInfo->hwnd == toolPtr->hwnd) &&
416 (lpToolInfo->uId == toolPtr->uId))
417 return nTool;
420 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
421 toolPtr = &infoPtr->tools[nTool];
423 if ((toolPtr->uFlags & TTF_IDISHWND) &&
424 (lpToolInfo->uId == toolPtr->uId))
425 return nTool;
428 return -1;
432 static INT32
433 TOOLTIPS_GetToolFromPoint (TOOLTIPS_INFO *infoPtr, HWND32 hwnd, LPPOINT32 lpPt)
435 TTTOOL_INFO *toolPtr;
436 INT32 nTool;
438 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
439 toolPtr = &infoPtr->tools[nTool];
441 if (!(toolPtr->uFlags & TTF_IDISHWND)) {
442 if (hwnd != toolPtr->hwnd)
443 continue;
444 if (!PtInRect32 (&toolPtr->rect, *lpPt))
445 continue;
446 return nTool;
450 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
451 toolPtr = &infoPtr->tools[nTool];
453 if (toolPtr->uFlags & TTF_IDISHWND) {
454 if ((HWND32)toolPtr->uId == hwnd)
455 return nTool;
459 return -1;
463 static INT32
464 TOOLTIPS_GetToolFromMessage (TOOLTIPS_INFO *infoPtr, HWND32 hwndTool)
466 DWORD dwPos;
467 POINT32 pt;
469 dwPos = GetMessagePos ();
470 pt.x = (INT32)LOWORD(dwPos);
471 pt.y = (INT32)HIWORD(dwPos);
472 ScreenToClient32 (hwndTool, &pt);
474 return TOOLTIPS_GetToolFromPoint (infoPtr, hwndTool, &pt);
478 static BOOL32
479 TOOLTIPS_IsWindowActive (HWND32 hwnd)
481 HWND32 hwndActive = GetActiveWindow32 ();
482 if (!hwndActive)
483 return FALSE;
484 if (hwndActive == hwnd)
485 return TRUE;
486 return IsChild32 (hwndActive, hwnd);
490 static INT32
491 TOOLTIPS_CheckTool (WND *wndPtr, BOOL32 bShowTest)
493 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
494 POINT32 pt;
495 HWND32 hwndTool;
496 INT32 nTool;
498 GetCursorPos32 (&pt);
499 hwndTool =
500 SendMessage32A (wndPtr->hwndSelf, TTM_WINDOWFROMPOINT, 0, (LPARAM)&pt);
501 if (hwndTool == 0)
502 return -1;
504 ScreenToClient32 (hwndTool, &pt);
505 nTool = TOOLTIPS_GetToolFromPoint (infoPtr, hwndTool, &pt);
506 if (nTool == -1)
507 return -1;
509 if (!(wndPtr->dwStyle & TTS_ALWAYSTIP) && bShowTest) {
510 if (!TOOLTIPS_IsWindowActive (wndPtr->owner->hwndSelf))
511 return -1;
514 TRACE (tooltips, "tool %d\n", nTool);
516 return nTool;
520 static LRESULT
521 TOOLTIPS_Activate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
523 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
525 infoPtr->bActive = (BOOL32)wParam;
527 if (infoPtr->bActive)
528 TRACE (tooltips, "activate!\n");
530 if (!(infoPtr->bActive) && (infoPtr->nCurrentTool != -1))
531 TOOLTIPS_Hide (wndPtr, infoPtr);
533 return 0;
537 static LRESULT
538 TOOLTIPS_AddTool32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
540 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
541 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
542 TTTOOL_INFO *toolPtr;
544 if (lpToolInfo == NULL)
545 return FALSE;
546 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
547 return FALSE;
549 TRACE (tooltips, "add tool (%x) %x %d%s!\n",
550 wndPtr->hwndSelf, lpToolInfo->hwnd, lpToolInfo->uId,
551 (lpToolInfo->uFlags & TTF_IDISHWND) ? " TTF_IDISHWND" : "");
553 if (infoPtr->uNumTools == 0) {
554 infoPtr->tools = COMCTL32_Alloc (sizeof(TTTOOL_INFO));
555 toolPtr = infoPtr->tools;
557 else {
558 TTTOOL_INFO *oldTools = infoPtr->tools;
559 infoPtr->tools =
560 COMCTL32_Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools + 1));
561 memcpy (infoPtr->tools, oldTools,
562 infoPtr->uNumTools * sizeof(TTTOOL_INFO));
563 COMCTL32_Free (oldTools);
564 toolPtr = &infoPtr->tools[infoPtr->uNumTools];
567 infoPtr->uNumTools++;
569 /* copy tool data */
570 toolPtr->uFlags = lpToolInfo->uFlags;
571 toolPtr->hwnd = lpToolInfo->hwnd;
572 toolPtr->uId = lpToolInfo->uId;
573 toolPtr->rect = lpToolInfo->rect;
574 toolPtr->hinst = lpToolInfo->hinst;
576 if ((lpToolInfo->hinst) && (HIWORD((INT32)lpToolInfo->lpszText) == 0)) {
577 TRACE (tooltips, "add string id %x!\n", (int)lpToolInfo->lpszText);
578 toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
580 else if (lpToolInfo->lpszText) {
581 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACK32A) {
582 TRACE (tooltips, "add CALLBACK!\n");
583 toolPtr->lpszText = LPSTR_TEXTCALLBACK32W;
585 else {
586 INT32 len = lstrlen32A (lpToolInfo->lpszText);
587 TRACE (tooltips, "add text \"%s\"!\n", lpToolInfo->lpszText);
588 toolPtr->lpszText = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
589 lstrcpyAtoW (toolPtr->lpszText, lpToolInfo->lpszText);
593 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A))
594 toolPtr->lParam = lpToolInfo->lParam;
596 /* install subclassing hook */
597 if (toolPtr->uFlags & TTF_SUBCLASS) {
598 if (toolPtr->uFlags & TTF_IDISHWND) {
599 LPTT_SUBCLASS_INFO lpttsi =
600 (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass);
601 if (lpttsi == NULL) {
602 lpttsi =
603 (LPTT_SUBCLASS_INFO)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO));
604 lpttsi->wpOrigProc =
605 (WNDPROC32)SetWindowLong32A ((HWND32)toolPtr->uId,
606 GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc);
607 lpttsi->hwndToolTip = wndPtr->hwndSelf;
608 lpttsi->uRefCount++;
609 SetProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass,
610 (HANDLE32)lpttsi);
612 else
613 WARN (tooltips, "A window tool must only be listed once!\n");
615 else {
616 LPTT_SUBCLASS_INFO lpttsi =
617 (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, COMCTL32_aSubclass);
618 if (lpttsi == NULL) {
619 lpttsi =
620 (LPTT_SUBCLASS_INFO)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO));
621 lpttsi->wpOrigProc =
622 (WNDPROC32)SetWindowLong32A (toolPtr->hwnd,
623 GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc);
624 lpttsi->hwndToolTip = wndPtr->hwndSelf;
625 lpttsi->uRefCount++;
626 SetProp32A (toolPtr->hwnd, COMCTL32_aSubclass, (HANDLE32)lpttsi);
628 else
629 lpttsi->uRefCount++;
631 TRACE (tooltips, "subclassing installed!\n");
634 return TRUE;
638 static LRESULT
639 TOOLTIPS_AddTool32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
641 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
642 LPTTTOOLINFO32W lpToolInfo = (LPTTTOOLINFO32W)lParam;
643 TTTOOL_INFO *toolPtr;
645 if (lpToolInfo == NULL)
646 return FALSE;
647 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32W)
648 return FALSE;
650 TRACE (tooltips, "add tool (%x) %x %d%s!\n",
651 wndPtr->hwndSelf, lpToolInfo->hwnd, lpToolInfo->uId,
652 (lpToolInfo->uFlags & TTF_IDISHWND) ? " TTF_IDISHWND" : "");
654 if (infoPtr->uNumTools == 0) {
655 infoPtr->tools = COMCTL32_Alloc (sizeof(TTTOOL_INFO));
656 toolPtr = infoPtr->tools;
658 else {
659 TTTOOL_INFO *oldTools = infoPtr->tools;
660 infoPtr->tools =
661 COMCTL32_Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools + 1));
662 memcpy (infoPtr->tools, oldTools,
663 infoPtr->uNumTools * sizeof(TTTOOL_INFO));
664 COMCTL32_Free (oldTools);
665 toolPtr = &infoPtr->tools[infoPtr->uNumTools];
668 infoPtr->uNumTools++;
670 /* copy tool data */
671 toolPtr->uFlags = lpToolInfo->uFlags;
672 toolPtr->hwnd = lpToolInfo->hwnd;
673 toolPtr->uId = lpToolInfo->uId;
674 toolPtr->rect = lpToolInfo->rect;
675 toolPtr->hinst = lpToolInfo->hinst;
677 if ((lpToolInfo->hinst) && (HIWORD((INT32)lpToolInfo->lpszText) == 0)) {
678 TRACE (tooltips, "add string id %x!\n", (int)lpToolInfo->lpszText);
679 toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
681 else if (lpToolInfo->lpszText) {
682 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACK32W) {
683 TRACE (tooltips, "add CALLBACK!\n");
684 toolPtr->lpszText = LPSTR_TEXTCALLBACK32W;
686 else {
687 INT32 len = lstrlen32W (lpToolInfo->lpszText);
688 TRACE (tooltips, "add text \"%s\"!\n",
689 debugstr_w(lpToolInfo->lpszText));
690 toolPtr->lpszText = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
691 lstrcpy32W (toolPtr->lpszText, lpToolInfo->lpszText);
695 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32W))
696 toolPtr->lParam = lpToolInfo->lParam;
698 /* install subclassing hook */
699 if (toolPtr->uFlags & TTF_SUBCLASS) {
700 if (toolPtr->uFlags & TTF_IDISHWND) {
701 LPTT_SUBCLASS_INFO lpttsi =
702 (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass);
703 if (lpttsi == NULL) {
704 lpttsi =
705 (LPTT_SUBCLASS_INFO)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO));
706 lpttsi->wpOrigProc =
707 (WNDPROC32)SetWindowLong32A ((HWND32)toolPtr->uId,
708 GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc);
709 lpttsi->hwndToolTip = wndPtr->hwndSelf;
710 lpttsi->uRefCount++;
711 SetProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass,
712 (HANDLE32)lpttsi);
714 else
715 WARN (tooltips, "A window tool must only be listed once!\n");
717 else {
718 LPTT_SUBCLASS_INFO lpttsi =
719 (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, COMCTL32_aSubclass);
720 if (lpttsi == NULL) {
721 lpttsi =
722 (LPTT_SUBCLASS_INFO)COMCTL32_Alloc (sizeof(TT_SUBCLASS_INFO));
723 lpttsi->wpOrigProc =
724 (WNDPROC32)SetWindowLong32A (toolPtr->hwnd,
725 GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc);
726 lpttsi->hwndToolTip = wndPtr->hwndSelf;
727 lpttsi->uRefCount++;
728 SetProp32A (toolPtr->hwnd, COMCTL32_aSubclass, (HANDLE32)lpttsi);
730 else
731 lpttsi->uRefCount++;
733 TRACE (tooltips, "subclassing installed!\n");
736 return TRUE;
740 static LRESULT
741 TOOLTIPS_DelTool32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
743 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
744 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
745 TTTOOL_INFO *toolPtr;
746 INT32 nTool;
748 if (lpToolInfo == NULL)
749 return 0;
750 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
751 return 0;
752 if (infoPtr->uNumTools == 0)
753 return 0;
755 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
756 if (nTool == -1) return 0;
758 TRACE (tooltips, "tool %d\n", nTool);
760 /* delete text string */
761 toolPtr = &infoPtr->tools[nTool];
762 if ((toolPtr->hinst) && (toolPtr->lpszText)) {
763 if (toolPtr->lpszText != LPSTR_TEXTCALLBACK32W)
764 COMCTL32_Free (toolPtr->lpszText);
767 /* remove subclassing */
768 if (toolPtr->uFlags & TTF_SUBCLASS) {
769 if (toolPtr->uFlags & TTF_IDISHWND) {
770 LPTT_SUBCLASS_INFO lpttsi =
771 (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass);
772 if (lpttsi) {
773 SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
774 (LONG)lpttsi->wpOrigProc);
775 RemoveProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass);
776 COMCTL32_Free (&lpttsi);
778 else
779 ERR (tooltips, "Invalid data handle!\n");
781 else {
782 LPTT_SUBCLASS_INFO lpttsi =
783 (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, COMCTL32_aSubclass);
784 if (lpttsi) {
785 if (lpttsi->uRefCount == 1) {
786 SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
787 (LONG)lpttsi->wpOrigProc);
788 RemoveProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass);
789 COMCTL32_Free (&lpttsi);
791 else
792 lpttsi->uRefCount--;
794 else
795 ERR (tooltips, "Invalid data handle!\n");
799 /* delete tool from tool list */
800 if (infoPtr->uNumTools == 1) {
801 COMCTL32_Free (infoPtr->tools);
802 infoPtr->tools = NULL;
804 else {
805 TTTOOL_INFO *oldTools = infoPtr->tools;
806 infoPtr->tools =
807 COMCTL32_Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1));
809 if (nTool > 0)
810 memcpy (&infoPtr->tools[0], &oldTools[0],
811 nTool * sizeof(TTTOOL_INFO));
813 if (nTool < infoPtr->uNumTools - 1)
814 memcpy (&infoPtr->tools[nTool], &oldTools[nTool + 1],
815 (infoPtr->uNumTools - nTool - 1) * sizeof(TTTOOL_INFO));
817 COMCTL32_Free (oldTools);
820 infoPtr->uNumTools--;
822 return 0;
826 static LRESULT
827 TOOLTIPS_DelTool32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
829 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
830 LPTTTOOLINFO32W lpToolInfo = (LPTTTOOLINFO32W)lParam;
831 TTTOOL_INFO *toolPtr;
832 INT32 nTool;
834 if (lpToolInfo == NULL)
835 return 0;
836 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32W)
837 return 0;
838 if (infoPtr->uNumTools == 0)
839 return 0;
841 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
842 if (nTool == -1) return 0;
844 TRACE (tooltips, "tool %d\n", nTool);
846 /* delete text string */
847 toolPtr = &infoPtr->tools[nTool];
848 if ((toolPtr->hinst) && (toolPtr->lpszText)) {
849 if (toolPtr->lpszText != LPSTR_TEXTCALLBACK32W)
850 COMCTL32_Free (toolPtr->lpszText);
853 /* remove subclassing */
854 if (toolPtr->uFlags & TTF_SUBCLASS) {
855 if (toolPtr->uFlags & TTF_IDISHWND) {
856 LPTT_SUBCLASS_INFO lpttsi =
857 (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass);
858 if (lpttsi) {
859 SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
860 (LONG)lpttsi->wpOrigProc);
861 RemoveProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass);
862 COMCTL32_Free (&lpttsi);
864 else
865 ERR (tooltips, "Invalid data handle!\n");
867 else {
868 LPTT_SUBCLASS_INFO lpttsi =
869 (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, COMCTL32_aSubclass);
870 if (lpttsi) {
871 if (lpttsi->uRefCount == 1) {
872 SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
873 (LONG)lpttsi->wpOrigProc);
874 RemoveProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass);
875 COMCTL32_Free (&lpttsi);
877 else
878 lpttsi->uRefCount--;
880 else
881 ERR (tooltips, "Invalid data handle!\n");
885 /* delete tool from tool list */
886 if (infoPtr->uNumTools == 1) {
887 COMCTL32_Free (infoPtr->tools);
888 infoPtr->tools = NULL;
890 else {
891 TTTOOL_INFO *oldTools = infoPtr->tools;
892 infoPtr->tools =
893 COMCTL32_Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1));
895 if (nTool > 0)
896 memcpy (&infoPtr->tools[0], &oldTools[0],
897 nTool * sizeof(TTTOOL_INFO));
899 if (nTool < infoPtr->uNumTools - 1)
900 memcpy (&infoPtr->tools[nTool], &oldTools[nTool + 1],
901 (infoPtr->uNumTools - nTool - 1) * sizeof(TTTOOL_INFO));
903 COMCTL32_Free (oldTools);
906 infoPtr->uNumTools--;
908 return 0;
912 static LRESULT
913 TOOLTIPS_EnumTools32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
915 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
916 UINT32 uIndex = (UINT32)wParam;
917 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
918 TTTOOL_INFO *toolPtr;
920 if (lpToolInfo == NULL)
921 return FALSE;
922 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
923 return FALSE;
924 if (uIndex >= infoPtr->uNumTools)
925 return FALSE;
927 TRACE (tooltips, "index=%u\n", uIndex);
929 toolPtr = &infoPtr->tools[uIndex];
931 /* copy tool data */
932 lpToolInfo->uFlags = toolPtr->uFlags;
933 lpToolInfo->hwnd = toolPtr->hwnd;
934 lpToolInfo->uId = toolPtr->uId;
935 lpToolInfo->rect = toolPtr->rect;
936 lpToolInfo->hinst = toolPtr->hinst;
937 /* lpToolInfo->lpszText = toolPtr->lpszText; */
938 lpToolInfo->lpszText = NULL; /* FIXME */
940 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A))
941 lpToolInfo->lParam = toolPtr->lParam;
943 return TRUE;
947 static LRESULT
948 TOOLTIPS_EnumTools32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
950 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
951 UINT32 uIndex = (UINT32)wParam;
952 LPTTTOOLINFO32W lpToolInfo = (LPTTTOOLINFO32W)lParam;
953 TTTOOL_INFO *toolPtr;
955 if (lpToolInfo == NULL)
956 return FALSE;
957 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32W)
958 return FALSE;
959 if (uIndex >= infoPtr->uNumTools)
960 return FALSE;
962 TRACE (tooltips, "index=%u\n", uIndex);
964 toolPtr = &infoPtr->tools[uIndex];
966 /* copy tool data */
967 lpToolInfo->uFlags = toolPtr->uFlags;
968 lpToolInfo->hwnd = toolPtr->hwnd;
969 lpToolInfo->uId = toolPtr->uId;
970 lpToolInfo->rect = toolPtr->rect;
971 lpToolInfo->hinst = toolPtr->hinst;
972 /* lpToolInfo->lpszText = toolPtr->lpszText; */
973 lpToolInfo->lpszText = NULL; /* FIXME */
975 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32W))
976 lpToolInfo->lParam = toolPtr->lParam;
978 return TRUE;
982 static LRESULT
983 TOOLTIPS_GetCurrentTool32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
985 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
986 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
987 TTTOOL_INFO *toolPtr;
989 if (lpToolInfo == NULL)
990 return FALSE;
991 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
992 return FALSE;
994 if (lpToolInfo) {
995 if (infoPtr->nCurrentTool > -1) {
996 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
998 /* copy tool data */
999 lpToolInfo->uFlags = toolPtr->uFlags;
1000 lpToolInfo->rect = toolPtr->rect;
1001 lpToolInfo->hinst = toolPtr->hinst;
1002 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1003 lpToolInfo->lpszText = NULL; /* FIXME */
1005 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A))
1006 lpToolInfo->lParam = toolPtr->lParam;
1008 return TRUE;
1010 else
1011 return FALSE;
1013 else
1014 return (infoPtr->nCurrentTool != -1);
1016 return FALSE;
1020 static LRESULT
1021 TOOLTIPS_GetCurrentTool32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1023 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1024 LPTTTOOLINFO32W lpToolInfo = (LPTTTOOLINFO32W)lParam;
1025 TTTOOL_INFO *toolPtr;
1027 if (lpToolInfo == NULL)
1028 return FALSE;
1029 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32W)
1030 return FALSE;
1032 if (lpToolInfo) {
1033 if (infoPtr->nCurrentTool > -1) {
1034 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
1036 /* copy tool data */
1037 lpToolInfo->uFlags = toolPtr->uFlags;
1038 lpToolInfo->rect = toolPtr->rect;
1039 lpToolInfo->hinst = toolPtr->hinst;
1040 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1041 lpToolInfo->lpszText = NULL; /* FIXME */
1043 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32W))
1044 lpToolInfo->lParam = toolPtr->lParam;
1046 return TRUE;
1048 else
1049 return FALSE;
1051 else
1052 return (infoPtr->nCurrentTool != -1);
1054 return FALSE;
1058 static LRESULT
1059 TOOLTIPS_GetDelayTime (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1061 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1063 switch (wParam) {
1064 case TTDT_AUTOMATIC:
1065 return infoPtr->nAutomaticTime;
1067 case TTDT_RESHOW:
1068 return infoPtr->nReshowTime;
1070 case TTDT_AUTOPOP:
1071 return infoPtr->nAutoPopTime;
1073 case TTDT_INITIAL:
1074 return infoPtr->nInitialTime;
1077 return 0;
1081 static LRESULT
1082 TOOLTIPS_GetMargin (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1084 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1085 LPRECT32 lpRect = (LPRECT32)lParam;
1087 lpRect->left = infoPtr->rcMargin.left;
1088 lpRect->right = infoPtr->rcMargin.right;
1089 lpRect->bottom = infoPtr->rcMargin.bottom;
1090 lpRect->top = infoPtr->rcMargin.top;
1092 return 0;
1096 __inline__ static LRESULT
1097 TOOLTIPS_GetMaxTipWidth (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1099 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1101 return infoPtr->nMaxTipWidth;
1105 static LRESULT
1106 TOOLTIPS_GetText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1108 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1109 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
1110 INT32 nTool;
1112 if (lpToolInfo == NULL)
1113 return 0;
1114 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
1115 return 0;
1117 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1118 if (nTool == -1) return 0;
1120 lstrcpyWtoA (lpToolInfo->lpszText, infoPtr->tools[nTool].lpszText);
1122 return 0;
1126 static LRESULT
1127 TOOLTIPS_GetText32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1129 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1130 LPTTTOOLINFO32W lpToolInfo = (LPTTTOOLINFO32W)lParam;
1131 INT32 nTool;
1133 if (lpToolInfo == NULL)
1134 return 0;
1135 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32W)
1136 return 0;
1138 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
1139 if (nTool == -1) return 0;
1141 lstrcpy32W (lpToolInfo->lpszText, infoPtr->tools[nTool].lpszText);
1143 return 0;
1147 __inline__ static LRESULT
1148 TOOLTIPS_GetTipBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1150 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1151 return infoPtr->clrBk;
1155 __inline__ static LRESULT
1156 TOOLTIPS_GetTipTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1158 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1159 return infoPtr->clrText;
1163 __inline__ static LRESULT
1164 TOOLTIPS_GetToolCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1166 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1167 return infoPtr->uNumTools;
1171 static LRESULT
1172 TOOLTIPS_GetToolInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1174 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1175 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
1176 TTTOOL_INFO *toolPtr;
1177 INT32 nTool;
1179 if (lpToolInfo == NULL)
1180 return FALSE;
1181 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
1182 return FALSE;
1183 if (infoPtr->uNumTools == 0)
1184 return FALSE;
1186 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1187 if (nTool == -1)
1188 return FALSE;
1190 TRACE (tooltips, "tool %d\n", nTool);
1192 toolPtr = &infoPtr->tools[nTool];
1194 /* copy tool data */
1195 lpToolInfo->uFlags = toolPtr->uFlags;
1196 lpToolInfo->rect = toolPtr->rect;
1197 lpToolInfo->hinst = toolPtr->hinst;
1198 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1199 lpToolInfo->lpszText = NULL; /* FIXME */
1201 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A))
1202 lpToolInfo->lParam = toolPtr->lParam;
1204 return TRUE;
1208 static LRESULT
1209 TOOLTIPS_GetToolInfo32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1211 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1212 LPTTTOOLINFO32W lpToolInfo = (LPTTTOOLINFO32W)lParam;
1213 TTTOOL_INFO *toolPtr;
1214 INT32 nTool;
1216 if (lpToolInfo == NULL)
1217 return FALSE;
1218 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32W)
1219 return FALSE;
1220 if (infoPtr->uNumTools == 0)
1221 return FALSE;
1223 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
1224 if (nTool == -1)
1225 return FALSE;
1227 TRACE (tooltips, "tool %d\n", nTool);
1229 toolPtr = &infoPtr->tools[nTool];
1231 /* copy tool data */
1232 lpToolInfo->uFlags = toolPtr->uFlags;
1233 lpToolInfo->rect = toolPtr->rect;
1234 lpToolInfo->hinst = toolPtr->hinst;
1235 /* lpToolInfo->lpszText = toolPtr->lpszText; */
1236 lpToolInfo->lpszText = NULL; /* FIXME */
1238 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32W))
1239 lpToolInfo->lParam = toolPtr->lParam;
1241 return TRUE;
1245 static LRESULT
1246 TOOLTIPS_HitTest32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1248 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1249 LPTTHITTESTINFO32A lptthit = (LPTTHITTESTINFO32A)lParam;
1250 TTTOOL_INFO *toolPtr;
1251 INT32 nTool;
1253 if (lptthit == 0)
1254 return FALSE;
1256 nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lptthit->hwnd, &lptthit->pt);
1257 if (nTool == -1)
1258 return FALSE;
1260 TRACE (tooltips, "tool %d!\n", nTool);
1262 /* copy tool data */
1263 if (lptthit->ti.cbSize >= sizeof(TTTOOLINFO32A)) {
1264 toolPtr = &infoPtr->tools[nTool];
1266 lptthit->ti.uFlags = toolPtr->uFlags;
1267 lptthit->ti.hwnd = toolPtr->hwnd;
1268 lptthit->ti.uId = toolPtr->uId;
1269 lptthit->ti.rect = toolPtr->rect;
1270 lptthit->ti.hinst = toolPtr->hinst;
1271 /* lptthit->ti.lpszText = toolPtr->lpszText; */
1272 lptthit->ti.lpszText = NULL; /* FIXME */
1273 lptthit->ti.lParam = toolPtr->lParam;
1276 return TRUE;
1280 static LRESULT
1281 TOOLTIPS_HitTest32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1283 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1284 LPTTHITTESTINFO32W lptthit = (LPTTHITTESTINFO32W)lParam;
1285 TTTOOL_INFO *toolPtr;
1286 INT32 nTool;
1288 if (lptthit == 0)
1289 return FALSE;
1291 nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lptthit->hwnd, &lptthit->pt);
1292 if (nTool == -1)
1293 return FALSE;
1295 TRACE (tooltips, "tool %d!\n", nTool);
1297 /* copy tool data */
1298 if (lptthit->ti.cbSize >= sizeof(TTTOOLINFO32W)) {
1299 toolPtr = &infoPtr->tools[nTool];
1301 lptthit->ti.uFlags = toolPtr->uFlags;
1302 lptthit->ti.hwnd = toolPtr->hwnd;
1303 lptthit->ti.uId = toolPtr->uId;
1304 lptthit->ti.rect = toolPtr->rect;
1305 lptthit->ti.hinst = toolPtr->hinst;
1306 /* lptthit->ti.lpszText = toolPtr->lpszText; */
1307 lptthit->ti.lpszText = NULL; /* FIXME */
1308 lptthit->ti.lParam = toolPtr->lParam;
1311 return TRUE;
1315 static LRESULT
1316 TOOLTIPS_NewToolRect32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1318 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1319 LPTTTOOLINFO32A lpti = (LPTTTOOLINFO32A)lParam;
1320 INT32 nTool;
1322 if (lpti == NULL)
1323 return 0;
1324 if (lpti->cbSize < TTTOOLINFO_V1_SIZE32A)
1325 return FALSE;
1327 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpti);
1328 if (nTool == -1) return 0;
1330 infoPtr->tools[nTool].rect = lpti->rect;
1332 return 0;
1336 static LRESULT
1337 TOOLTIPS_NewToolRect32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1339 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1340 LPTTTOOLINFO32W lpti = (LPTTTOOLINFO32W)lParam;
1341 INT32 nTool;
1343 if (lpti == NULL)
1344 return 0;
1345 if (lpti->cbSize < TTTOOLINFO_V1_SIZE32W)
1346 return FALSE;
1348 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpti);
1349 if (nTool == -1) return 0;
1351 infoPtr->tools[nTool].rect = lpti->rect;
1353 return 0;
1357 __inline__ static LRESULT
1358 TOOLTIPS_Pop (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1360 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1362 TOOLTIPS_Hide (wndPtr, infoPtr);
1364 return 0;
1368 static LRESULT
1369 TOOLTIPS_RelayEvent (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1371 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1372 LPMSG32 lpMsg = (LPMSG32)lParam;
1373 POINT32 pt;
1375 if (lParam == 0) {
1376 ERR (tooltips, "lpMsg == NULL!\n");
1377 return 0;
1380 switch (lpMsg->message) {
1381 case WM_LBUTTONDOWN:
1382 case WM_LBUTTONUP:
1383 case WM_MBUTTONDOWN:
1384 case WM_MBUTTONUP:
1385 case WM_RBUTTONDOWN:
1386 case WM_RBUTTONUP:
1387 pt = lpMsg->pt;
1388 ScreenToClient32 (lpMsg->hwnd, &pt);
1389 infoPtr->nOldTool = infoPtr->nTool;
1390 infoPtr->nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lpMsg->hwnd, &pt);
1391 TRACE (tooltips, "tool (%x) %d %d\n",
1392 wndPtr->hwndSelf, infoPtr->nOldTool, infoPtr->nTool);
1393 TOOLTIPS_Hide (wndPtr, infoPtr);
1394 break;
1396 case WM_MOUSEMOVE:
1397 pt = lpMsg->pt;
1398 ScreenToClient32 (lpMsg->hwnd, &pt);
1399 infoPtr->nOldTool = infoPtr->nTool;
1400 infoPtr->nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lpMsg->hwnd, &pt);
1401 TRACE (tooltips, "tool (%x) %d %d\n",
1402 wndPtr->hwndSelf, infoPtr->nOldTool, infoPtr->nTool);
1403 TRACE (tooltips, "WM_MOUSEMOVE (%04x %d %d)\n",
1404 wndPtr->hwndSelf, pt.x, pt.y);
1405 if ((infoPtr->bActive) && (infoPtr->nTool != infoPtr->nOldTool)) {
1406 if (infoPtr->nOldTool == -1) {
1407 SetTimer32 (wndPtr->hwndSelf, ID_TIMERSHOW,
1408 infoPtr->nInitialTime, 0);
1409 TRACE (tooltips, "timer 1 started!\n");
1411 else {
1412 TOOLTIPS_Hide (wndPtr, infoPtr);
1413 SetTimer32 (wndPtr->hwndSelf, ID_TIMERSHOW,
1414 infoPtr->nReshowTime, 0);
1415 TRACE (tooltips, "timer 2 started!\n");
1418 if (infoPtr->nCurrentTool != -1) {
1419 SetTimer32 (wndPtr->hwndSelf, ID_TIMERLEAVE, 100, 0);
1420 TRACE (tooltips, "timer 3 started!\n");
1422 break;
1425 return 0;
1429 static LRESULT
1430 TOOLTIPS_SetDelayTime (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1432 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1433 INT32 nTime = (INT32)LOWORD(lParam);
1435 switch (wParam) {
1436 case TTDT_AUTOMATIC:
1437 if (nTime == 0) {
1438 infoPtr->nAutomaticTime = 500;
1439 infoPtr->nReshowTime = 100;
1440 infoPtr->nAutoPopTime = 5000;
1441 infoPtr->nInitialTime = 500;
1443 else {
1444 infoPtr->nAutomaticTime = nTime;
1445 infoPtr->nReshowTime = nTime / 5;
1446 infoPtr->nAutoPopTime = nTime * 10;
1447 infoPtr->nInitialTime = nTime;
1449 break;
1451 case TTDT_RESHOW:
1452 infoPtr->nReshowTime = nTime;
1453 break;
1455 case TTDT_AUTOPOP:
1456 infoPtr->nAutoPopTime = nTime;
1457 break;
1459 case TTDT_INITIAL:
1460 infoPtr->nInitialTime = nTime;
1461 break;
1464 return 0;
1468 static LRESULT
1469 TOOLTIPS_SetMargin (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1471 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1472 LPRECT32 lpRect = (LPRECT32)lParam;
1474 infoPtr->rcMargin.left = lpRect->left;
1475 infoPtr->rcMargin.right = lpRect->right;
1476 infoPtr->rcMargin.bottom = lpRect->bottom;
1477 infoPtr->rcMargin.top = lpRect->top;
1479 return 0;
1483 __inline__ static LRESULT
1484 TOOLTIPS_SetMaxTipWidth (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1486 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1487 INT32 nTemp = infoPtr->nMaxTipWidth;
1489 infoPtr->nMaxTipWidth = (INT32)lParam;
1491 return nTemp;
1495 __inline__ static LRESULT
1496 TOOLTIPS_SetTipBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1498 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1500 infoPtr->clrBk = (COLORREF)wParam;
1502 return 0;
1506 __inline__ static LRESULT
1507 TOOLTIPS_SetTipTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1509 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1511 infoPtr->clrText = (COLORREF)wParam;
1513 return 0;
1517 static LRESULT
1518 TOOLTIPS_SetToolInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1520 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1521 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
1522 TTTOOL_INFO *toolPtr;
1523 INT32 nTool;
1525 if (lpToolInfo == NULL)
1526 return 0;
1527 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
1528 return 0;
1530 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1531 if (nTool == -1) return 0;
1533 TRACE (tooltips, "tool %d\n", nTool);
1535 toolPtr = &infoPtr->tools[nTool];
1537 /* copy tool data */
1538 toolPtr->uFlags = lpToolInfo->uFlags;
1539 toolPtr->hwnd = lpToolInfo->hwnd;
1540 toolPtr->uId = lpToolInfo->uId;
1541 toolPtr->rect = lpToolInfo->rect;
1542 toolPtr->hinst = lpToolInfo->hinst;
1544 if ((lpToolInfo->hinst) && (HIWORD((INT32)lpToolInfo->lpszText) == 0)) {
1545 TRACE (tooltips, "set string id %x!\n", (INT32)lpToolInfo->lpszText);
1546 toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
1548 else if (lpToolInfo->lpszText) {
1549 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACK32A)
1550 toolPtr->lpszText = LPSTR_TEXTCALLBACK32W;
1551 else {
1552 if (toolPtr->lpszText) {
1553 COMCTL32_Free (toolPtr->lpszText);
1554 toolPtr->lpszText = NULL;
1556 if (lpToolInfo->lpszText) {
1557 INT32 len = lstrlen32A (lpToolInfo->lpszText);
1558 toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1559 lstrcpyAtoW (toolPtr->lpszText, lpToolInfo->lpszText);
1564 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A))
1565 toolPtr->lParam = lpToolInfo->lParam;
1567 return 0;
1571 static LRESULT
1572 TOOLTIPS_SetToolInfo32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1574 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1575 LPTTTOOLINFO32W lpToolInfo = (LPTTTOOLINFO32W)lParam;
1576 TTTOOL_INFO *toolPtr;
1577 INT32 nTool;
1579 if (lpToolInfo == NULL)
1580 return 0;
1581 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32W)
1582 return 0;
1584 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
1585 if (nTool == -1) return 0;
1587 TRACE (tooltips, "tool %d\n", nTool);
1589 toolPtr = &infoPtr->tools[nTool];
1591 /* copy tool data */
1592 toolPtr->uFlags = lpToolInfo->uFlags;
1593 toolPtr->hwnd = lpToolInfo->hwnd;
1594 toolPtr->uId = lpToolInfo->uId;
1595 toolPtr->rect = lpToolInfo->rect;
1596 toolPtr->hinst = lpToolInfo->hinst;
1598 if ((lpToolInfo->hinst) && (HIWORD((INT32)lpToolInfo->lpszText) == 0)) {
1599 TRACE (tooltips, "set string id %x!\n", (INT32)lpToolInfo->lpszText);
1600 toolPtr->lpszText = lpToolInfo->lpszText;
1602 else if (lpToolInfo->lpszText) {
1603 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACK32W)
1604 toolPtr->lpszText = LPSTR_TEXTCALLBACK32W;
1605 else {
1606 if (toolPtr->lpszText) {
1607 COMCTL32_Free (toolPtr->lpszText);
1608 toolPtr->lpszText = NULL;
1610 if (lpToolInfo->lpszText) {
1611 INT32 len = lstrlen32W (lpToolInfo->lpszText);
1612 toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1613 lstrcpy32W (toolPtr->lpszText, lpToolInfo->lpszText);
1618 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32W))
1619 toolPtr->lParam = lpToolInfo->lParam;
1621 return 0;
1625 static LRESULT
1626 TOOLTIPS_TrackActivate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1628 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1629 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
1631 if (lpToolInfo == NULL)
1632 return 0;
1633 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
1634 return FALSE;
1636 if ((BOOL32)wParam) {
1637 /* activate */
1638 infoPtr->nTrackTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1639 if (infoPtr->nTrackTool != -1) {
1640 TRACE (tooltips, "activated!\n");
1641 infoPtr->bTrackActive = TRUE;
1642 TOOLTIPS_TrackShow (wndPtr, infoPtr);
1645 else {
1646 /* deactivate */
1647 TOOLTIPS_TrackHide (wndPtr, infoPtr);
1649 infoPtr->bTrackActive = FALSE;
1650 infoPtr->nTrackTool = -1;
1652 TRACE (tooltips, "deactivated!\n");
1655 return 0;
1659 static LRESULT
1660 TOOLTIPS_TrackPosition (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1662 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1664 infoPtr->xTrackPos = (INT32)LOWORD(lParam);
1665 infoPtr->yTrackPos = (INT32)HIWORD(lParam);
1667 if (infoPtr->bTrackActive) {
1668 TRACE (tooltips, "[%d %d]\n",
1669 infoPtr->xTrackPos, infoPtr->yTrackPos);
1671 TOOLTIPS_TrackShow (wndPtr, infoPtr);
1674 return 0;
1678 static LRESULT
1679 TOOLTIPS_Update (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1681 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1683 if (infoPtr->nCurrentTool != -1)
1684 UpdateWindow32 (wndPtr->hwndSelf);
1686 return 0;
1690 static LRESULT
1691 TOOLTIPS_UpdateTipText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1693 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1694 LPTTTOOLINFO32A lpToolInfo = (LPTTTOOLINFO32A)lParam;
1695 TTTOOL_INFO *toolPtr;
1696 INT32 nTool;
1698 if (lpToolInfo == NULL)
1699 return 0;
1700 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32A)
1701 return FALSE;
1703 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1704 if (nTool == -1) return 0;
1706 TRACE (tooltips, "tool %d\n", nTool);
1708 toolPtr = &infoPtr->tools[nTool];
1710 /* copy tool text */
1711 toolPtr->hinst = lpToolInfo->hinst;
1713 if ((lpToolInfo->hinst) && (HIWORD((INT32)lpToolInfo->lpszText) == 0)){
1714 toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
1716 else if (lpToolInfo->lpszText) {
1717 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACK32A)
1718 toolPtr->lpszText = LPSTR_TEXTCALLBACK32W;
1719 else {
1720 if (toolPtr->lpszText) {
1721 COMCTL32_Free (toolPtr->lpszText);
1722 toolPtr->lpszText = NULL;
1724 if (lpToolInfo->lpszText) {
1725 INT32 len = lstrlen32A (lpToolInfo->lpszText);
1726 toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1727 lstrcpyAtoW (toolPtr->lpszText, lpToolInfo->lpszText);
1732 return 0;
1736 static LRESULT
1737 TOOLTIPS_UpdateTipText32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1739 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1740 LPTTTOOLINFO32W lpToolInfo = (LPTTTOOLINFO32W)lParam;
1741 TTTOOL_INFO *toolPtr;
1742 INT32 nTool;
1744 if (lpToolInfo == NULL)
1745 return 0;
1746 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZE32W)
1747 return FALSE;
1749 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
1750 if (nTool == -1)
1751 return 0;
1753 TRACE (tooltips, "tool %d\n", nTool);
1755 toolPtr = &infoPtr->tools[nTool];
1757 /* copy tool text */
1758 toolPtr->hinst = lpToolInfo->hinst;
1760 if ((lpToolInfo->hinst) && (HIWORD((INT32)lpToolInfo->lpszText) == 0)){
1761 toolPtr->lpszText = lpToolInfo->lpszText;
1763 else if (lpToolInfo->lpszText) {
1764 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACK32W)
1765 toolPtr->lpszText = LPSTR_TEXTCALLBACK32W;
1766 else {
1767 if (toolPtr->lpszText) {
1768 COMCTL32_Free (toolPtr->lpszText);
1769 toolPtr->lpszText = NULL;
1771 if (lpToolInfo->lpszText) {
1772 INT32 len = lstrlen32W (lpToolInfo->lpszText);
1773 toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1774 lstrcpy32W (toolPtr->lpszText, lpToolInfo->lpszText);
1779 return 0;
1783 static LRESULT
1784 TOOLTIPS_WindowFromPoint (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1786 return WindowFromPoint32 (*((LPPOINT32)lParam));
1791 static LRESULT
1792 TOOLTIPS_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1794 TOOLTIPS_INFO *infoPtr;
1795 NONCLIENTMETRICS32A nclm;
1796 INT32 nResult;
1798 /* allocate memory for info structure */
1799 infoPtr = (TOOLTIPS_INFO *)COMCTL32_Alloc (sizeof(TOOLTIPS_INFO));
1800 wndPtr->wExtra[0] = (DWORD)infoPtr;
1802 if (infoPtr == NULL) {
1803 ERR (tooltips, "could not allocate info memory!\n");
1804 return 0;
1807 /* initialize info structure */
1808 infoPtr->bActive = TRUE;
1809 infoPtr->bTrackActive = FALSE;
1810 infoPtr->clrBk = GetSysColor32 (COLOR_INFOBK);
1811 infoPtr->clrText = GetSysColor32 (COLOR_INFOTEXT);
1813 nclm.cbSize = sizeof(NONCLIENTMETRICS32A);
1814 SystemParametersInfo32A (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1815 infoPtr->hFont = CreateFontIndirect32A (&nclm.lfStatusFont);
1817 infoPtr->nMaxTipWidth = -1;
1818 infoPtr->nTool = -1;
1819 infoPtr->nOldTool = -1;
1820 infoPtr->nCurrentTool = -1;
1821 infoPtr->nTrackTool = -1;
1823 infoPtr->nAutomaticTime = 500;
1824 infoPtr->nReshowTime = 100;
1825 infoPtr->nAutoPopTime = 5000;
1826 infoPtr->nInitialTime = 500;
1828 nResult =
1829 (INT32) SendMessage32A (wndPtr->parent->hwndSelf, WM_NOTIFYFORMAT,
1830 (WPARAM32)wndPtr->hwndSelf, (LPARAM)NF_QUERY);
1831 if (nResult == NFR_ANSI)
1832 FIXME (tooltips, " -- WM_NOTIFYFORMAT returns: NFR_ANSI\n");
1833 else if (nResult == NFR_UNICODE)
1834 FIXME (tooltips, " -- WM_NOTIFYFORMAT returns: NFR_UNICODE\n");
1835 else
1836 FIXME (tooltips, " -- WM_NOTIFYFORMAT returns: error!\n");
1838 SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0,
1839 SWP_NOZORDER | SWP_HIDEWINDOW);
1841 return 0;
1845 static LRESULT
1846 TOOLTIPS_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1848 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1849 TTTOOL_INFO *toolPtr;
1850 INT32 i;
1852 /* free tools */
1853 if (infoPtr->tools) {
1854 for (i = 0; i < infoPtr->uNumTools; i++) {
1855 toolPtr = &infoPtr->tools[i];
1856 if ((toolPtr->hinst) && (toolPtr->lpszText)) {
1857 if (toolPtr->lpszText != LPSTR_TEXTCALLBACK32W)
1858 COMCTL32_Free (toolPtr->lpszText);
1861 /* remove subclassing */
1862 if (toolPtr->uFlags & TTF_SUBCLASS) {
1863 LPTT_SUBCLASS_INFO lpttsi;
1865 if (toolPtr->uFlags & TTF_IDISHWND)
1866 lpttsi = (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass);
1867 else
1868 lpttsi = (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, COMCTL32_aSubclass);
1870 if (lpttsi) {
1871 SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC,
1872 (LONG)lpttsi->wpOrigProc);
1873 RemoveProp32A ((HWND32)toolPtr->uId, COMCTL32_aSubclass);
1874 COMCTL32_Free (&lpttsi);
1878 COMCTL32_Free (infoPtr->tools);
1881 /* delete font */
1882 DeleteObject32 (infoPtr->hFont);
1884 /* free tool tips info data */
1885 COMCTL32_Free (infoPtr);
1887 return 0;
1891 static LRESULT
1892 TOOLTIPS_EraseBackground (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1894 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1895 RECT32 rect;
1896 HBRUSH32 hBrush;
1898 hBrush = CreateSolidBrush32 (infoPtr->clrBk);
1899 GetClientRect32 (wndPtr->hwndSelf, &rect);
1900 FillRect32 ((HDC32)wParam, &rect, hBrush);
1901 DeleteObject32 (hBrush);
1903 return FALSE;
1907 static LRESULT
1908 TOOLTIPS_GetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1910 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1912 return infoPtr->hFont;
1916 static LRESULT
1917 TOOLTIPS_MouseMessage (WND *wndPtr, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
1919 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1921 TOOLTIPS_Hide (wndPtr, infoPtr);
1923 return 0;
1927 static LRESULT
1928 TOOLTIPS_NCCreate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1930 wndPtr->dwStyle &= 0x0000FFFF;
1931 wndPtr->dwStyle |= (WS_POPUP | WS_BORDER | WS_CLIPSIBLINGS);
1933 return TRUE;
1937 static LRESULT
1938 TOOLTIPS_NCHitTest (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1940 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1941 INT32 nTool = (infoPtr->bTrackActive) ? infoPtr->nTrackTool : infoPtr->nTool;
1943 TRACE (tooltips, " nTool=%d\n", nTool);
1945 if ((nTool > -1) && (nTool < infoPtr->uNumTools)) {
1946 if (infoPtr->tools[nTool].uFlags & TTF_TRANSPARENT) {
1947 TRACE (tooltips, "-- in transparent mode!\n");
1948 return HTTRANSPARENT;
1952 return DefWindowProc32A (wndPtr->hwndSelf, WM_NCHITTEST, wParam, lParam);
1956 static LRESULT
1957 TOOLTIPS_Paint (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1959 HDC32 hdc;
1960 PAINTSTRUCT32 ps;
1962 hdc = (wParam == 0) ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
1963 TOOLTIPS_Refresh (wndPtr, hdc);
1964 if (!wParam)
1965 EndPaint32 (wndPtr->hwndSelf, &ps);
1966 return 0;
1970 static LRESULT
1971 TOOLTIPS_SetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1973 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1975 infoPtr->hFont = (HFONT32)wParam;
1977 if ((LOWORD(lParam)) & (infoPtr->nCurrentTool != -1)) {
1978 FIXME (tooltips, "full redraw needed!\n");
1981 return 0;
1985 static LRESULT
1986 TOOLTIPS_Timer (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1988 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
1990 TRACE (tooltips, "timer %d (%x) expired!\n", wParam, wndPtr->hwndSelf);
1992 switch (wParam)
1994 case ID_TIMERSHOW:
1995 KillTimer32 (wndPtr->hwndSelf, ID_TIMERSHOW);
1996 if (TOOLTIPS_CheckTool (wndPtr, TRUE) == infoPtr->nTool)
1997 TOOLTIPS_Show (wndPtr, infoPtr);
1998 break;
2000 case ID_TIMERPOP:
2001 TOOLTIPS_Hide (wndPtr, infoPtr);
2002 break;
2004 case ID_TIMERLEAVE:
2005 KillTimer32 (wndPtr->hwndSelf, ID_TIMERLEAVE);
2006 if (TOOLTIPS_CheckTool (wndPtr, FALSE) == -1) {
2007 infoPtr->nTool = -1;
2008 infoPtr->nOldTool = -1;
2009 TOOLTIPS_Hide (wndPtr, infoPtr);
2011 break;
2013 return 0;
2017 static LRESULT
2018 TOOLTIPS_WinIniChange (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2020 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
2021 NONCLIENTMETRICS32A nclm;
2023 infoPtr->clrBk = GetSysColor32 (COLOR_INFOBK);
2024 infoPtr->clrText = GetSysColor32 (COLOR_INFOTEXT);
2026 DeleteObject32 (infoPtr->hFont);
2027 nclm.cbSize = sizeof(NONCLIENTMETRICS32A);
2028 SystemParametersInfo32A (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
2029 infoPtr->hFont = CreateFontIndirect32A (&nclm.lfStatusFont);
2031 return 0;
2035 LRESULT CALLBACK
2036 TOOLTIPS_SubclassProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
2038 LPTT_SUBCLASS_INFO lpttsi =
2039 (LPTT_SUBCLASS_INFO)GetProp32A (hwnd, COMCTL32_aSubclass);
2040 WND *wndPtr;
2041 TOOLTIPS_INFO *infoPtr;
2042 UINT32 nTool;
2044 switch (uMsg) {
2045 case WM_LBUTTONDOWN:
2046 case WM_LBUTTONUP:
2047 case WM_MBUTTONDOWN:
2048 case WM_MBUTTONUP:
2049 case WM_RBUTTONDOWN:
2050 case WM_RBUTTONUP:
2052 wndPtr = WIN_FindWndPtr(lpttsi->hwndToolTip);
2053 infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
2054 nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd);
2056 TRACE (tooltips, "subclassed mouse message %04x\n", uMsg);
2057 infoPtr->nOldTool = infoPtr->nTool;
2058 infoPtr->nTool = nTool;
2059 TOOLTIPS_Hide (wndPtr, infoPtr);
2061 break;
2063 case WM_MOUSEMOVE:
2065 wndPtr = WIN_FindWndPtr(lpttsi->hwndToolTip);
2066 infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
2067 nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd);
2069 TRACE (tooltips, "subclassed WM_MOUSEMOVE\n");
2070 infoPtr->nOldTool = infoPtr->nTool;
2071 infoPtr->nTool = nTool;
2073 if ((infoPtr->bActive) &&
2074 (infoPtr->nTool != infoPtr->nOldTool)) {
2075 if (infoPtr->nOldTool == -1) {
2076 SetTimer32 (wndPtr->hwndSelf, ID_TIMERSHOW,
2077 infoPtr->nInitialTime, 0);
2078 TRACE (tooltips, "timer 1 started!\n");
2080 else {
2081 TOOLTIPS_Hide (wndPtr, infoPtr);
2082 SetTimer32 (wndPtr->hwndSelf, ID_TIMERSHOW,
2083 infoPtr->nReshowTime, 0);
2084 TRACE (tooltips, "timer 2 started!\n");
2087 if (infoPtr->nCurrentTool != -1) {
2088 SetTimer32 (wndPtr->hwndSelf, ID_TIMERLEAVE, 100, 0);
2089 TRACE (tooltips, "timer 3 started!\n");
2092 break;
2095 return CallWindowProc32A (lpttsi->wpOrigProc, hwnd, uMsg, wParam, lParam);
2099 LRESULT CALLBACK
2100 TOOLTIPS_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
2102 WND *wndPtr = WIN_FindWndPtr(hwnd);
2104 switch (uMsg)
2106 case TTM_ACTIVATE:
2107 return TOOLTIPS_Activate (wndPtr, wParam, lParam);
2109 case TTM_ADDTOOL32A:
2110 return TOOLTIPS_AddTool32A (wndPtr, wParam, lParam);
2112 case TTM_ADDTOOL32W:
2113 return TOOLTIPS_AddTool32W (wndPtr, wParam, lParam);
2115 case TTM_DELTOOL32A:
2116 return TOOLTIPS_DelTool32A (wndPtr, wParam, lParam);
2118 case TTM_DELTOOL32W:
2119 return TOOLTIPS_DelTool32W (wndPtr, wParam, lParam);
2121 case TTM_ENUMTOOLS32A:
2122 return TOOLTIPS_EnumTools32A (wndPtr, wParam, lParam);
2124 case TTM_ENUMTOOLS32W:
2125 return TOOLTIPS_EnumTools32W (wndPtr, wParam, lParam);
2127 case TTM_GETCURRENTTOOL32A:
2128 return TOOLTIPS_GetCurrentTool32A (wndPtr, wParam, lParam);
2130 case TTM_GETCURRENTTOOL32W:
2131 return TOOLTIPS_GetCurrentTool32W (wndPtr, wParam, lParam);
2133 case TTM_GETDELAYTIME:
2134 return TOOLTIPS_GetDelayTime (wndPtr, wParam, lParam);
2136 case TTM_GETMARGIN:
2137 return TOOLTIPS_GetMargin (wndPtr, wParam, lParam);
2139 case TTM_GETMAXTIPWIDTH:
2140 return TOOLTIPS_GetMaxTipWidth (wndPtr, wParam, lParam);
2142 case TTM_GETTEXT32A:
2143 return TOOLTIPS_GetText32A (wndPtr, wParam, lParam);
2145 case TTM_GETTEXT32W:
2146 return TOOLTIPS_GetText32W (wndPtr, wParam, lParam);
2148 case TTM_GETTIPBKCOLOR:
2149 return TOOLTIPS_GetTipBkColor (wndPtr, wParam, lParam);
2151 case TTM_GETTIPTEXTCOLOR:
2152 return TOOLTIPS_GetTipTextColor (wndPtr, wParam, lParam);
2154 case TTM_GETTOOLCOUNT:
2155 return TOOLTIPS_GetToolCount (wndPtr, wParam, lParam);
2157 case TTM_GETTOOLINFO32A:
2158 return TOOLTIPS_GetToolInfo32A (wndPtr, wParam, lParam);
2160 case TTM_GETTOOLINFO32W:
2161 return TOOLTIPS_GetToolInfo32W (wndPtr, wParam, lParam);
2163 case TTM_HITTEST32A:
2164 return TOOLTIPS_HitTest32A (wndPtr, wParam, lParam);
2166 case TTM_HITTEST32W:
2167 return TOOLTIPS_HitTest32W (wndPtr, wParam, lParam);
2169 case TTM_NEWTOOLRECT32A:
2170 return TOOLTIPS_NewToolRect32A (wndPtr, wParam, lParam);
2172 case TTM_NEWTOOLRECT32W:
2173 return TOOLTIPS_NewToolRect32W (wndPtr, wParam, lParam);
2175 case TTM_POP:
2176 return TOOLTIPS_Pop (wndPtr, wParam, lParam);
2178 case TTM_RELAYEVENT:
2179 return TOOLTIPS_RelayEvent (wndPtr, wParam, lParam);
2181 case TTM_SETDELAYTIME:
2182 return TOOLTIPS_SetDelayTime (wndPtr, wParam, lParam);
2184 case TTM_SETMARGIN:
2185 return TOOLTIPS_SetMargin (wndPtr, wParam, lParam);
2187 case TTM_SETMAXTIPWIDTH:
2188 return TOOLTIPS_SetMaxTipWidth (wndPtr, wParam, lParam);
2190 case TTM_SETTIPBKCOLOR:
2191 return TOOLTIPS_SetTipBkColor (wndPtr, wParam, lParam);
2193 case TTM_SETTIPTEXTCOLOR:
2194 return TOOLTIPS_SetTipTextColor (wndPtr, wParam, lParam);
2196 case TTM_SETTOOLINFO32A:
2197 return TOOLTIPS_SetToolInfo32A (wndPtr, wParam, lParam);
2199 case TTM_SETTOOLINFO32W:
2200 return TOOLTIPS_SetToolInfo32W (wndPtr, wParam, lParam);
2202 case TTM_TRACKACTIVATE:
2203 return TOOLTIPS_TrackActivate (wndPtr, wParam, lParam);
2205 case TTM_TRACKPOSITION:
2206 return TOOLTIPS_TrackPosition (wndPtr, wParam, lParam);
2208 case TTM_UPDATE:
2209 return TOOLTIPS_Update (wndPtr, wParam, lParam);
2211 case TTM_UPDATETIPTEXT32A:
2212 return TOOLTIPS_UpdateTipText32A (wndPtr, wParam, lParam);
2214 case TTM_UPDATETIPTEXT32W:
2215 return TOOLTIPS_UpdateTipText32W (wndPtr, wParam, lParam);
2217 case TTM_WINDOWFROMPOINT:
2218 return TOOLTIPS_WindowFromPoint (wndPtr, wParam, lParam);
2221 case WM_CREATE:
2222 return TOOLTIPS_Create (wndPtr, wParam, lParam);
2224 case WM_DESTROY:
2225 return TOOLTIPS_Destroy (wndPtr, wParam, lParam);
2227 case WM_ERASEBKGND:
2228 return TOOLTIPS_EraseBackground (wndPtr, wParam, lParam);
2230 case WM_GETFONT:
2231 return TOOLTIPS_GetFont (wndPtr, wParam, lParam);
2233 case WM_LBUTTONDOWN:
2234 case WM_LBUTTONUP:
2235 case WM_MBUTTONDOWN:
2236 case WM_MBUTTONUP:
2237 case WM_RBUTTONDOWN:
2238 case WM_RBUTTONUP:
2239 case WM_MOUSEMOVE:
2240 return TOOLTIPS_MouseMessage (wndPtr, uMsg, wParam, lParam);
2242 case WM_NCCREATE:
2243 return TOOLTIPS_NCCreate (wndPtr, wParam, lParam);
2245 case WM_NCHITTEST:
2246 return TOOLTIPS_NCHitTest (wndPtr, wParam, lParam);
2248 /* case WM_NOTIFYFORMAT: */
2249 /* return TOOLTIPS_NotifyFormat (wndPtr, wParam, lParam); */
2251 case WM_PAINT:
2252 return TOOLTIPS_Paint (wndPtr, wParam, lParam);
2254 case WM_SETFONT:
2255 return TOOLTIPS_SetFont (wndPtr, wParam, lParam);
2257 case WM_TIMER:
2258 return TOOLTIPS_Timer (wndPtr, wParam, lParam);
2260 case WM_WININICHANGE:
2261 return TOOLTIPS_WinIniChange (wndPtr, wParam, lParam);
2263 default:
2264 if (uMsg >= WM_USER)
2265 ERR (tooltips, "unknown msg %04x wp=%08x lp=%08lx\n",
2266 uMsg, wParam, lParam);
2267 return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
2269 return 0;
2273 VOID
2274 TOOLTIPS_Register (VOID)
2276 WNDCLASS32A wndClass;
2278 if (GlobalFindAtom32A (TOOLTIPS_CLASS32A)) return;
2280 ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
2281 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS;
2282 wndClass.lpfnWndProc = (WNDPROC32)TOOLTIPS_WindowProc;
2283 wndClass.cbClsExtra = 0;
2284 wndClass.cbWndExtra = sizeof(TOOLTIPS_INFO *);
2285 wndClass.hCursor = LoadCursor32A (0, IDC_ARROW32A);
2286 wndClass.hbrBackground = 0;
2287 wndClass.lpszClassName = TOOLTIPS_CLASS32A;
2289 RegisterClass32A (&wndClass);
2293 VOID
2294 TOOLTIPS_Unregister (VOID)
2296 if (GlobalFindAtom32A (TOOLTIPS_CLASS32A))
2297 UnregisterClass32A (TOOLTIPS_CLASS32A, (HINSTANCE32)NULL);