From 96388c85b150b51f166383eff6e66f4408f9a4a3 Mon Sep 17 00:00:00 2001
From: Eric Kohl <ekohl@abo.rhein-zeitung.de>
Date: Sun, 11 Oct 1998 13:19:17 +0000
Subject: [PATCH] Added tracking support and fixed loading of resource strings.
 Added unregister code.

---
 dlls/comctl32/tooltips.c | 190 ++++++++++++++++++++++++++++++++-------
 include/tooltips.h       |   3 +-
 2 files changed, 159 insertions(+), 34 deletions(-)

diff --git a/dlls/comctl32/tooltips.c b/dlls/comctl32/tooltips.c
index 419f6059db3..2990835dfa1 100644
--- a/dlls/comctl32/tooltips.c
+++ b/dlls/comctl32/tooltips.c
@@ -4,7 +4,8 @@
  * Copyright 1998 Eric Kohl
  *
  * TODO:
- *   - Tracking tooltips (under construction).
+ *   - Tracking tooltips (finished, except smart placement).
+ *   - Transparent tooltips (under construction).
  *   - TTS_ALWAYSTIP (undefined).
  *   - Unicode support.
  *   - Custom draw support.
@@ -68,11 +69,11 @@ TOOLTIPS_Refresh (WND *wndPtr, HDC32 hdc)
 
 
 static VOID
-TOOLTIPS_GetTipText (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
+TOOLTIPS_GetTipText (WND *wndPtr, TOOLTIPS_INFO *infoPtr, INT32 nTool)
 {
-    TTTOOL_INFO *toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
+    TTTOOL_INFO *toolPtr = &infoPtr->tools[nTool];
 
-    if (toolPtr->hinst) {
+    if ((toolPtr->hinst) && (HIWORD((UINT32)toolPtr->lpszText) == 0)) {
 	TRACE (tooltips, "get res string %x %x\n",
 	       toolPtr->hinst, (int)toolPtr->lpszText);
 	LoadString32A (toolPtr->hinst, (UINT32)toolPtr->lpszText,
@@ -94,7 +95,7 @@ TOOLTIPS_GetTipText (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
 	    SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
 			    (WPARAM32)toolPtr->uId, (LPARAM)&ttnmdi);
 
-	    if (ttnmdi.hinst) {
+	    if ((ttnmdi.hinst) && (HIWORD((UINT32)ttnmdi.szText) == 0)) {
 		LoadString32A (ttnmdi.hinst, (UINT32)ttnmdi.szText,
 			       infoPtr->szTipText, INFOTIPSIZE);
 		if (ttnmdi.uFlags & TTF_DI_SETITEM) {
@@ -126,8 +127,10 @@ TOOLTIPS_GetTipText (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
 		    lstrcpy32A (toolPtr->lpszText, ttnmdi.lpszText);
 		}
 	    }
-	    else
+	    else {
 		ERR (tooltips, "recursive text callback!\n");
+		infoPtr->szTipText[0] = '\0';
+	    }
 	}
 	else
 	    lstrcpyn32A (infoPtr->szTipText, toolPtr->lpszText, INFOTIPSIZE);
@@ -187,7 +190,7 @@ TOOLTIPS_Show (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
 
     TRACE (tooltips, "Show tooltip pre %d!\n", infoPtr->nTool);
 
-    TOOLTIPS_GetTipText (wndPtr, infoPtr);
+    TOOLTIPS_GetTipText (wndPtr, infoPtr, infoPtr->nCurrentTool);
 
     if (infoPtr->szTipText[0] == '\0') {
 	infoPtr->nCurrentTool = -1;
@@ -208,11 +211,7 @@ TOOLTIPS_Show (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
     TOOLTIPS_CalcTipSize (wndPtr, infoPtr, &size);
     TRACE (tooltips, "size %d - %d\n", size.cx, size.cy);
 
-    if ((toolPtr->uFlags & TTF_TRACK) && (toolPtr->uFlags & TTF_ABSOLUTE)) {
-	rect.left = infoPtr->xTrackPos;
-	rect.top  = infoPtr->yTrackPos;
-    }
-    else if (toolPtr->uFlags & TTF_CENTERTIP) {
+    if (toolPtr->uFlags & TTF_CENTERTIP) {
 	RECT32 rc;
 
 	if (toolPtr->uFlags & TTF_IDISHWND)
@@ -236,7 +235,6 @@ TOOLTIPS_Show (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
 
     AdjustWindowRectEx32 (&rect, wndPtr->dwStyle, FALSE, wndPtr->dwExStyle);
 
-//    SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 1, 1,
     SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, rect.left, rect.top,
 		    rect.right - rect.left, rect.bottom - rect.top,
 		    SWP_SHOWWINDOW);
@@ -271,6 +269,117 @@ TOOLTIPS_Hide (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
 }
 
 
+static VOID
+TOOLTIPS_TrackShow (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
+{
+    TTTOOL_INFO *toolPtr;
+    RECT32 rect;
+    SIZE32 size;
+    NMHDR hdr;
+
+    if (infoPtr->nTrackTool == -1) {
+	TRACE (tooltips, "invalid tracking tool (-1)!\n");
+	return;
+    }
+
+    TRACE (tooltips, "show tracking tooltip pre %d!\n", infoPtr->nTrackTool);
+
+    TOOLTIPS_GetTipText (wndPtr, infoPtr, infoPtr->nTrackTool);
+
+    if (infoPtr->szTipText[0] == '\0') {
+	infoPtr->nTrackTool = -1;
+	return;
+    }
+
+    TRACE (tooltips, "show tracking tooltip %d!\n", infoPtr->nTrackTool);
+    toolPtr = &infoPtr->tools[infoPtr->nTrackTool];
+
+    hdr.hwndFrom = wndPtr->hwndSelf;
+    hdr.idFrom = toolPtr->uId;
+    hdr.code = TTN_SHOW;
+    SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
+		    (WPARAM32)toolPtr->uId, (LPARAM)&hdr);
+
+    TRACE (tooltips, "\"%s\"\n", infoPtr->szTipText);
+
+    TOOLTIPS_CalcTipSize (wndPtr, infoPtr, &size);
+    TRACE (tooltips, "size %d - %d\n", size.cx, size.cy);
+
+    if (toolPtr->uFlags & TTF_ABSOLUTE) {
+	rect.left = infoPtr->xTrackPos;
+	rect.top  = infoPtr->yTrackPos;
+
+	if (toolPtr->uFlags & TTF_CENTERTIP) {
+	    rect.left -= (size.cx / 2);
+	    rect.top  -= (size.cy / 2);
+	}
+    }
+    else {
+#if 0
+	/* FIXME: do smart placement */
+	RECT32 rcTool;
+
+	if (toolPtr->uFlags & TTF_IDISHWND)
+	    GetWindowRect32 ((HWND32)toolPtr->uId, &rcTool);
+	else {
+	    rcTool = toolPtr->rect;
+	    MapWindowPoints32 (toolPtr->hwnd, (HWND32)0, (LPPOINT32)&rcTool, 2);
+	}
+#endif
+	GetCursorPos32 ((LPPOINT32)&rect);
+	rect.top += 20;
+#if 0
+	/* smart placement */
+	if ((rect.left + size.cx > rcTool.left) && (rect.left < rcTool.right))
+	    rect.left = rcTool.right;
+
+	if ((rect.top + size.cy > rcTool.top) &&
+	    (rect.top < rcTool.bottom))
+	    rect.top = rcTool.bottom;
+
+
+	if (toolPtr->uFlags & TTF_CENTERTIP) {
+
+	}
+#endif
+    }
+
+    TRACE (tooltips, "pos %d - %d\n", rect.left, rect.top);
+
+    rect.right = rect.left + size.cx;
+    rect.bottom = rect.top + size.cy;
+
+    AdjustWindowRectEx32 (&rect, wndPtr->dwStyle, FALSE, wndPtr->dwExStyle);
+
+    SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, rect.left, rect.top,
+		    rect.right - rect.left, rect.bottom - rect.top,
+		    SWP_SHOWWINDOW);
+}
+
+
+static VOID
+TOOLTIPS_TrackHide (WND *wndPtr, TOOLTIPS_INFO *infoPtr)
+{
+    TTTOOL_INFO *toolPtr;
+    NMHDR hdr;
+
+    if (infoPtr->nTrackTool == -1)
+	return;
+
+    toolPtr = &infoPtr->tools[infoPtr->nTrackTool];
+    TRACE (tooltips, "hide tracking tooltip %d!\n", infoPtr->nTrackTool);
+
+    hdr.hwndFrom = wndPtr->hwndSelf;
+    hdr.idFrom = toolPtr->uId;
+    hdr.code = TTN_POP;
+    SendMessage32A (toolPtr->hwnd, WM_NOTIFY,
+		    (WPARAM32)toolPtr->uId, (LPARAM)&hdr);
+
+    SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0,
+		    SWP_NOZORDER | SWP_HIDEWINDOW);
+}
+
+
 static INT32
 TOOLTIPS_GetToolFromInfoA (TOOLTIPS_INFO *infoPtr, LPTTTOOLINFO32A lpToolInfo)
 {
@@ -387,7 +496,7 @@ TOOLTIPS_Activate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 	TRACE (tooltips, "activate!\n");
 
     if (!(infoPtr->bActive) && (infoPtr->nCurrentTool != -1)) 
-	    TOOLTIPS_Hide (wndPtr, infoPtr);
+	TOOLTIPS_Hide (wndPtr, infoPtr);
 
     return 0;
 }
@@ -432,7 +541,7 @@ TOOLTIPS_AddTool32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
     toolPtr->rect   = lpToolInfo->rect;
     toolPtr->hinst  = lpToolInfo->hinst;
 
-    if (lpToolInfo->hinst) {
+    if ((lpToolInfo->hinst) && (HIWORD((INT32)lpToolInfo->lpszText) == 0)) {
 	TRACE (tooltips, "add string id %x!\n", (int)lpToolInfo->lpszText);
 	toolPtr->lpszText = lpToolInfo->lpszText;
     }
@@ -1042,7 +1151,8 @@ TOOLTIPS_SetToolInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
     toolPtr->rect   = lpToolInfo->rect;
     toolPtr->hinst  = lpToolInfo->hinst;
 
-    if (lpToolInfo->hinst) {
+    if ((lpToolInfo->hinst) && (HIWORD((INT32)lpToolInfo->lpszText) == 0)) {
+	TRACE (tooltips, "set string id %x!\n", (INT32)lpToolInfo->lpszText);
 	toolPtr->lpszText = lpToolInfo->lpszText;
     }
     else if (lpToolInfo->lpszText) {
@@ -1081,17 +1191,19 @@ TOOLTIPS_TrackActivate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 	/* activate */
 	infoPtr->nTrackTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
 	if (infoPtr->nTrackTool != -1) {
+	    TRACE (tooltips, "activated!\n");
 	    infoPtr->bTrackActive = TRUE;
-
-	    /* FIXME : show tool tip ??? */
+	    TOOLTIPS_TrackShow (wndPtr, infoPtr);
 	}
     }
     else {
 	/* deactivate */
-	/* FIXME : hide tool tip ??? */
+	TOOLTIPS_TrackHide (wndPtr, infoPtr);
 
 	infoPtr->bTrackActive = FALSE;
 	infoPtr->nTrackTool = -1;
+
+	TRACE (tooltips, "deactivated!\n");
     }
 
     return 0;
@@ -1107,8 +1219,10 @@ TOOLTIPS_TrackPosition (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
     infoPtr->yTrackPos = (INT32)HIWORD(lParam);
 
     if (infoPtr->bTrackActive) {
+	TRACE (tooltips, "[%d %d]\n",
+	       infoPtr->xTrackPos, infoPtr->yTrackPos);
 
-	FIXME (tooltips, "set position!\n");
+	TOOLTIPS_TrackShow (wndPtr, infoPtr);
     }
 
     return 0;
@@ -1150,7 +1264,7 @@ TOOLTIPS_UpdateTipText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
     /* copy tool text */
     toolPtr->hinst  = lpToolInfo->hinst;
 
-    if (lpToolInfo->hinst) {
+    if ((lpToolInfo->hinst) && (HIWORD((INT32)lpToolInfo->lpszText) == 0)){
 	toolPtr->lpszText = lpToolInfo->lpszText;
     }
     else if (lpToolInfo->lpszText) {
@@ -1294,12 +1408,13 @@ TOOLTIPS_GetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 
 
 static LRESULT
-TOOLTIPS_MouseMove (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+TOOLTIPS_MouseMessage (WND *wndPtr, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
 {
     TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr);
     TTTOOL_INFO *toolPtr = &infoPtr->tools[infoPtr->nTool];
 
     if (toolPtr->uFlags & TTF_TRANSPARENT) {
+	FIXME (tooltips, "transparent tooltips not implemented yet!\n");
 #if 0
 	POINT32 pt;
 	RECT32  rc;
@@ -1310,7 +1425,7 @@ TOOLTIPS_MouseMove (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
 	GetClientRect32 (toolPtr->hwnd, &rc);
 	ScreenToClient32 (toolPtr->hwnd, &pt);
 	if (PtInRect32 (&rc, pt))
-	    SendMessage32A (toolPtr->hwnd, WM_MOUSEMOVE, wParam, lParam);
+	    SendMessage32A (toolPtr->hwnd, uMsg, wParam, lParam);
 #endif
     }
     else
@@ -1326,9 +1441,6 @@ TOOLTIPS_NcCreate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
     wndPtr->dwStyle &= 0x0000FFFF;
     wndPtr->dwStyle |= (WS_POPUP | WS_BORDER | WS_CLIPSIBLINGS);
 
-//    FIXME (tooltips, "style 0x%08x\n", wndPtr->dwStyle);
-//    SetParent32 (wndPtr->hwndSelf, NULL);
-
     return TRUE;
 }
 
@@ -1339,7 +1451,7 @@ TOOLTIPS_Paint (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
     HDC32 hdc;
     PAINTSTRUCT32 ps;
 
-    hdc = wParam==0 ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
+    hdc = (wParam == 0) ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
     TOOLTIPS_Refresh (wndPtr, hdc);
     if (!wParam)
 	EndPaint32 (wndPtr->hwndSelf, &ps);
@@ -1602,11 +1714,15 @@ TOOLTIPS_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
 
 //	case WM_GETTEXT:
 //	case WM_GETTEXTLENGTH:
-//	case WM_LBUTTONDOWN:
-//	case WM_MBUTTONDOWN:
 
+	case WM_LBUTTONDOWN:
+	case WM_LBUTTONUP:
+	case WM_MBUTTONDOWN:
+	case WM_MBUTTONUP:
+	case WM_RBUTTONDOWN:
+	case WM_RBUTTONUP:
 	case WM_MOUSEMOVE:
-	    return TOOLTIPS_MouseMove (wndPtr, wParam, lParam);
+	    return TOOLTIPS_MouseMessage (wndPtr, uMsg, wParam, lParam);
 
 	case WM_NCCREATE:
 	    return TOOLTIPS_NcCreate (wndPtr, wParam, lParam);
@@ -1618,7 +1734,6 @@ TOOLTIPS_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
 	    return TOOLTIPS_Paint (wndPtr, wParam, lParam);
 
 //	case WM_PRINTCLIENT:
-//	case WM_RBUTTONDOWN:
 
 	case WM_SETFONT:
 	    return TOOLTIPS_SetFont (wndPtr, wParam, lParam);
@@ -1641,8 +1756,8 @@ TOOLTIPS_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
 }
 
 
-void
-TOOLTIPS_Register (void)
+VOID
+TOOLTIPS_Register (VOID)
 {
     WNDCLASS32A wndClass;
 
@@ -1659,3 +1774,12 @@ TOOLTIPS_Register (void)
  
     RegisterClass32A (&wndClass);
 }
+
+
+VOID
+TOOLTIPS_Unregister (VOID)
+{
+    if (GlobalFindAtom32A (TOOLTIPS_CLASS32A))
+	UnregisterClass32A (TOOLTIPS_CLASS32A, (HINSTANCE32)NULL);
+}
+
diff --git a/include/tooltips.h b/include/tooltips.h
index c38e94c9a14..34d1d2757c2 100644
--- a/include/tooltips.h
+++ b/include/tooltips.h
@@ -54,6 +54,7 @@ typedef struct tagTOOLTIPS_INFO
 } TOOLTIPS_INFO;
 
 
-extern void TOOLTIPS_Register (void);
+extern VOID TOOLTIPS_Register (VOID);
+extern VOID TOOLTIPS_Unregister (VOID);
 
 #endif  /* __WINE_TOOLTIPS_H */
-- 
GitLab