Redo the show/hide logic and add a comment to explain what's going on.

Fix TTM_{S|G}ETDELAYTIME to use the double click time as default.
Fix handling of TTDT_AUTOMATIC.
Relayed mouse messages should extract the position from lParam not
msg.pt
SubclassProc now unified with TTM_RELAYEVENT.
Change all lstrcpyxtox to use win32 APIs.
This commit is contained in:
Huw D M Davies 2000-08-03 22:18:15 +00:00 committed by Alexandre Julliard
parent 87194855a1
commit 4e095e6e2b
2 changed files with 211 additions and 196 deletions

View File

@ -12,8 +12,51 @@
* The second cdrom (chapter 3) contains executables activate.exe, * The second cdrom (chapter 3) contains executables activate.exe,
* curtool.exe, deltool.exe, enumtools.exe, getinfo.exe, getiptxt.exe, * curtool.exe, deltool.exe, enumtools.exe, getinfo.exe, getiptxt.exe,
* hittest.exe, needtext.exe, newrect.exe, updtext.exe and winfrpt.exe. * hittest.exe, needtext.exe, newrect.exe, updtext.exe and winfrpt.exe.
*
* Timer logic.
*
* One important point to remember is that tools don't necessarily get
* a WM_MOUSEMOVE once the cursor leaves the tool, an example is when
* a tool sets TTF_IDISHWND (i.e. an entire window is a tool) because
* here WM_MOUSEMOVEs only get sent when the cursor is inside the
* client area. Therefore the only reliable way to know that the
* cursor has left a tool is to keep a timer running and check the
* position every time it expires. This is the role of timer
* ID_TIMERLEAVE.
*
*
* On entering a tool (detected in a relayed WM_MOUSEMOVE) we start
* ID_TIMERSHOW, if this times out and we're still in the tool we show
* the tip. On showing a tip we start both ID_TIMERPOP and
* ID_TIMERLEAVE. On hiding a tooltip we kill ID_TIMERPOP.
* ID_TIMERPOP is restarted on every relayed WM_MOUSEMOVE. If
* ID_TIMERPOP expires the tool is hidden and ID_TIMERPOP is killed.
* ID_TIMERLEAVE remains running - this is important as we need to
* determine when the cursor leaves the tool.
*
* When ID_TIMERLEAVE expires or on a relayed WM_MOUSEMOVE if we're
* still in the tool do nothing (apart from restart ID_TIMERPOP if
* this is a WM_MOUSEMOVE) (ID_TIMERLEAVE remains running). If we've
* left the tool and entered another one then hide the tip and start
* ID_TIMERSHOW with time ReshowTime and kill ID_TIMERLEAVE. If we're
* outside all tools hide the tip and kill ID_TIMERLEAVE. On Relayed
* mouse button messages hide the tip but leave ID_TIMERLEAVE running,
* this again will let us keep track of when the cursor leaves the
* tool.
*
*
* infoPtr->nTool is the tool the mouse was on on the last relayed MM
* or timer expiry or -1 if the mouse was not on a tool.
*
* infoPtr->nCurrentTool is the tool for which the tip is currently
* displaying text for or -1 if the tip is not shown. Actually this
* will only ever be infoPtr-nTool or -1, so it could be changed to a
* BOOL.
*
*/ */
#include <string.h> #include <string.h>
#include "winbase.h" #include "winbase.h"
@ -116,12 +159,15 @@ TOOLTIPS_GetTipText (HWND hwnd, TOOLTIPS_INFO *infoPtr, INT nTool)
} }
} }
else if (ttnmdi.szText[0]) { else if (ttnmdi.szText[0]) {
lstrcpynAtoW (infoPtr->szTipText, ttnmdi.szText, 80); MultiByteToWideChar(CP_ACP, 0, ttnmdi.szText, 80,
infoPtr->szTipText, INFOTIPSIZE);
if (ttnmdi.uFlags & TTF_DI_SETITEM) { if (ttnmdi.uFlags & TTF_DI_SETITEM) {
INT len = lstrlenA (ttnmdi.szText); INT len = MultiByteToWideChar(CP_ACP, 0, ttnmdi.szText,
80, NULL, 0);
toolPtr->hinst = 0; toolPtr->hinst = 0;
toolPtr->lpszText = COMCTL32_Alloc ((len+1)* sizeof(WCHAR)); toolPtr->lpszText = COMCTL32_Alloc (len * sizeof(WCHAR));
lstrcpyAtoW (toolPtr->lpszText, ttnmdi.szText); MultiByteToWideChar(CP_ACP, 0, ttnmdi.szText, 80,
toolPtr->lpszText, len);
} }
} }
else if (ttnmdi.lpszText == 0) { else if (ttnmdi.lpszText == 0) {
@ -129,12 +175,15 @@ TOOLTIPS_GetTipText (HWND hwnd, TOOLTIPS_INFO *infoPtr, INT nTool)
infoPtr->szTipText[0] = L'\0'; infoPtr->szTipText[0] = L'\0';
} }
else if (ttnmdi.lpszText != LPSTR_TEXTCALLBACKA) { else if (ttnmdi.lpszText != LPSTR_TEXTCALLBACKA) {
lstrcpynAtoW (infoPtr->szTipText, ttnmdi.lpszText, INFOTIPSIZE); MultiByteToWideChar(CP_ACP, 0, ttnmdi.lpszText, -1,
infoPtr->szTipText, INFOTIPSIZE);
if (ttnmdi.uFlags & TTF_DI_SETITEM) { if (ttnmdi.uFlags & TTF_DI_SETITEM) {
INT len = lstrlenA (ttnmdi.lpszText); INT len = MultiByteToWideChar(CP_ACP, 0, ttnmdi.lpszText,
-1, NULL, 0);
toolPtr->hinst = 0; toolPtr->hinst = 0;
toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR)); toolPtr->lpszText = COMCTL32_Alloc (len * sizeof(WCHAR));
lstrcpyAtoW (toolPtr->lpszText, ttnmdi.lpszText); MultiByteToWideChar(CP_ACP, 0, ttnmdi.lpszText, -1,
toolPtr->lpszText, len);
} }
} }
else { else {
@ -200,7 +249,7 @@ TOOLTIPS_Show (HWND hwnd, TOOLTIPS_INFO *infoPtr)
infoPtr->nCurrentTool = infoPtr->nTool; infoPtr->nCurrentTool = infoPtr->nTool;
TRACE("Show tooltip pre %d!\n", infoPtr->nTool); TRACE("Show tooltip pre %d! (%04x)\n", infoPtr->nTool, hwnd);
TOOLTIPS_GetTipText (hwnd, infoPtr, infoPtr->nCurrentTool); TOOLTIPS_GetTipText (hwnd, infoPtr, infoPtr->nCurrentTool);
@ -277,6 +326,9 @@ TOOLTIPS_Show (HWND hwnd, TOOLTIPS_INFO *infoPtr)
UpdateWindow(hwnd); UpdateWindow(hwnd);
SetTimer (hwnd, ID_TIMERPOP, infoPtr->nAutoPopTime, 0); SetTimer (hwnd, ID_TIMERPOP, infoPtr->nAutoPopTime, 0);
TRACE("timer 2 started!\n");
SetTimer (hwnd, ID_TIMERLEAVE, infoPtr->nReshowTime, 0);
TRACE("timer 3 started!\n");
} }
@ -286,11 +338,12 @@ TOOLTIPS_Hide (HWND hwnd, TOOLTIPS_INFO *infoPtr)
TTTOOL_INFO *toolPtr; TTTOOL_INFO *toolPtr;
NMHDR hdr; NMHDR hdr;
TRACE("Hide tooltip %d! (%04x)\n", infoPtr->nCurrentTool, hwnd);
if (infoPtr->nCurrentTool == -1) if (infoPtr->nCurrentTool == -1)
return; return;
toolPtr = &infoPtr->tools[infoPtr->nCurrentTool]; toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
TRACE("Hide tooltip %d!\n", infoPtr->nCurrentTool);
KillTimer (hwnd, ID_TIMERPOP); KillTimer (hwnd, ID_TIMERPOP);
hdr.hwndFrom = hwnd; hdr.hwndFrom = hwnd;
@ -500,21 +553,6 @@ TOOLTIPS_GetToolFromPoint (TOOLTIPS_INFO *infoPtr, HWND hwnd, LPPOINT lpPt)
} }
static INT
TOOLTIPS_GetToolFromMessage (TOOLTIPS_INFO *infoPtr, HWND hwndTool)
{
DWORD dwPos;
POINT pt;
dwPos = GetMessagePos ();
pt.x = (INT)LOWORD(dwPos);
pt.y = (INT)HIWORD(dwPos);
ScreenToClient (hwndTool, &pt);
return TOOLTIPS_GetToolFromPoint (infoPtr, hwndTool, &pt);
}
static BOOL static BOOL
TOOLTIPS_IsWindowActive (HWND hwnd) TOOLTIPS_IsWindowActive (HWND hwnd)
{ {
@ -566,7 +604,7 @@ TOOLTIPS_Activate (HWND hwnd, WPARAM wParam, LPARAM lParam)
if (infoPtr->bActive) if (infoPtr->bActive)
TRACE("activate!\n"); TRACE("activate!\n");
if (!(infoPtr->bActive) && (infoPtr->nCurrentTool != -1)) if (!(infoPtr->bActive) && (infoPtr->nCurrentTool != -1))
TOOLTIPS_Hide (hwnd, infoPtr); TOOLTIPS_Hide (hwnd, infoPtr);
return 0; return 0;
@ -622,10 +660,12 @@ TOOLTIPS_AddToolA (HWND hwnd, WPARAM wParam, LPARAM lParam)
toolPtr->lpszText = LPSTR_TEXTCALLBACKW; toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
} }
else { else {
INT len = lstrlenA (lpToolInfo->lpszText); INT len = MultiByteToWideChar(CP_ACP, 0, lpToolInfo->lpszText, -1,
NULL, 0);
TRACE("add text \"%s\"!\n", lpToolInfo->lpszText); TRACE("add text \"%s\"!\n", lpToolInfo->lpszText);
toolPtr->lpszText = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR)); toolPtr->lpszText = COMCTL32_Alloc (len * sizeof(WCHAR));
lstrcpyAtoW (toolPtr->lpszText, lpToolInfo->lpszText); MultiByteToWideChar(CP_ACP, 0, lpToolInfo->lpszText, -1,
toolPtr->lpszText, len);
} }
} }
@ -1102,20 +1142,22 @@ TOOLTIPS_GetDelayTime (HWND hwnd, WPARAM wParam, LPARAM lParam)
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd); TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
switch (wParam) { switch (wParam) {
case TTDT_AUTOMATIC: case TTDT_RESHOW:
return infoPtr->nAutomaticTime; return infoPtr->nReshowTime;
case TTDT_RESHOW: case TTDT_AUTOPOP:
return infoPtr->nReshowTime; return infoPtr->nAutoPopTime;
case TTDT_AUTOPOP: case TTDT_INITIAL:
return infoPtr->nAutoPopTime; case TTDT_AUTOMATIC: /* Apparently TTDT_AUTOMATIC returns TTDT_INITIAL */
return infoPtr->nInitialTime;
case TTDT_INITIAL: default:
return infoPtr->nInitialTime; WARN("Invalid wParam %x\n", wParam);
break;
} }
return 0; return -1;
} }
@ -1158,7 +1200,12 @@ TOOLTIPS_GetTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo); nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
if (nTool == -1) return 0; if (nTool == -1) return 0;
lstrcpyWtoA (lpToolInfo->lpszText, infoPtr->tools[nTool].lpszText); /* NB this API is broken, there is no way for the app to determine
what size buffer it requires nor a way to specify how long the
one it supplies is. We'll assume it's upto INFOTIPSIZE */
WideCharToMultiByte(CP_ACP, 0, infoPtr->tools[nTool].lpszText, -1,
lpToolInfo->lpszText, INFOTIPSIZE, NULL, NULL);
return 0; return 0;
} }
@ -1399,16 +1446,6 @@ inline static LRESULT
TOOLTIPS_Pop (HWND hwnd, WPARAM wParam, LPARAM lParam) TOOLTIPS_Pop (HWND hwnd, WPARAM wParam, LPARAM lParam)
{ {
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd); TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
/*
* Need to set nCurrentTool to nOldTool so we hide the tool.
* nTool and nOldTool values change when the mouse leaves the window.
* If using TTM_UPDATETIPTEXT we can end up with an nCurrentTool = -1 if the
* text can't be found, thus the tooltip would never be hidden.
*/
if (infoPtr->nTool != infoPtr->nOldTool)
infoPtr->nCurrentTool = infoPtr->nOldTool;
TOOLTIPS_Hide (hwnd, infoPtr); TOOLTIPS_Hide (hwnd, infoPtr);
return 0; return 0;
@ -1421,6 +1458,7 @@ TOOLTIPS_RelayEvent (HWND hwnd, WPARAM wParam, LPARAM lParam)
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd); TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
LPMSG lpMsg = (LPMSG)lParam; LPMSG lpMsg = (LPMSG)lParam;
POINT pt; POINT pt;
INT nOldTool;
if (lParam == 0) { if (lParam == 0) {
ERR("lpMsg == NULL!\n"); ERR("lpMsg == NULL!\n");
@ -1434,46 +1472,45 @@ TOOLTIPS_RelayEvent (HWND hwnd, WPARAM wParam, LPARAM lParam)
case WM_MBUTTONUP: case WM_MBUTTONUP:
case WM_RBUTTONDOWN: case WM_RBUTTONDOWN:
case WM_RBUTTONUP: case WM_RBUTTONUP:
pt = lpMsg->pt; pt.x = LOWORD(lParam);
ScreenToClient (lpMsg->hwnd, &pt); pt.y = HIWORD(lParam);
infoPtr->nOldTool = infoPtr->nTool;
infoPtr->nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lpMsg->hwnd, &pt); infoPtr->nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lpMsg->hwnd, &pt);
TRACE("tool (%x) %d %d\n", TRACE("tool (%x) %d %d\n",
hwnd, infoPtr->nOldTool, infoPtr->nTool); hwnd, infoPtr->nTool, infoPtr->nCurrentTool);
TOOLTIPS_Hide (hwnd, infoPtr); TOOLTIPS_Hide (hwnd, infoPtr);
break; break;
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
pt = lpMsg->pt; pt.x = LOWORD(lpMsg->lParam);
ScreenToClient (lpMsg->hwnd, &pt); pt.y = HIWORD(lpMsg->lParam);
infoPtr->nOldTool = infoPtr->nTool; nOldTool = infoPtr->nTool;
infoPtr->nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lpMsg->hwnd, &pt); infoPtr->nTool = TOOLTIPS_GetToolFromPoint(infoPtr, lpMsg->hwnd,
TRACE("tool (%x) %d %d\n", &pt);
hwnd, infoPtr->nOldTool, infoPtr->nTool); TRACE("tool (%x) %d %d %d\n", hwnd, nOldTool,
TRACE("WM_MOUSEMOVE (%04x %ld %ld)\n", infoPtr->nTool, infoPtr->nCurrentTool);
hwnd, pt.x, pt.y); TRACE("WM_MOUSEMOVE (%04x %ld %ld)\n", hwnd, pt.x, pt.y);
if ((infoPtr->bActive) && (infoPtr->nTool != infoPtr->nOldTool)) {
if (infoPtr->nOldTool == -1) { if (infoPtr->nTool != nOldTool) {
SetTimer (hwnd, ID_TIMERSHOW, infoPtr->nInitialTime, 0); if(infoPtr->nTool == -1) { /* Moved out of all tools */
TRACE("timer 1 started!\n"); TOOLTIPS_Hide(hwnd, infoPtr);
KillTimer(hwnd, ID_TIMERLEAVE);
} else if (nOldTool == -1) { /* Moved from outside */
if(infoPtr->bActive) {
SetTimer(hwnd, ID_TIMERSHOW, infoPtr->nInitialTime, 0);
TRACE("timer 1 started!\n");
}
} else { /* Moved from one to another */
TOOLTIPS_Hide (hwnd, infoPtr);
KillTimer(hwnd, ID_TIMERLEAVE);
if(infoPtr->bActive) {
SetTimer (hwnd, ID_TIMERSHOW, infoPtr->nReshowTime, 0);
TRACE("timer 1 started!\n");
}
} }
else { } else if(infoPtr->nCurrentTool != -1) { /* restart autopop */
/* KillTimer(hwnd, ID_TIMERPOP);
* Need to set nCurrentTool to nOldTool so we hide the tool. SetTimer(hwnd, ID_TIMERPOP, infoPtr->nAutoPopTime, 0);
* nTool and nOldTool values change when the mouse leaves the window. TRACE("timer 2 restarted\n");
* If using TTM_UPDATETIPTEXT we can end up with an nCurrentTool = -1 if the
* text can't be found, thus the tooltip would never be hidden.
*/
if (infoPtr->nTool != infoPtr->nOldTool)
infoPtr->nCurrentTool = infoPtr->nOldTool;
TOOLTIPS_Hide (hwnd, infoPtr);
SetTimer (hwnd, ID_TIMERSHOW, infoPtr->nReshowTime, 0);
TRACE("timer 2 started!\n");
}
}
if (infoPtr->nCurrentTool != -1) {
SetTimer (hwnd, ID_TIMERLEAVE, 100, 0);
TRACE("timer 3 started!\n");
} }
break; break;
} }
@ -1489,32 +1526,35 @@ TOOLTIPS_SetDelayTime (HWND hwnd, WPARAM wParam, LPARAM lParam)
INT nTime = (INT)LOWORD(lParam); INT nTime = (INT)LOWORD(lParam);
switch (wParam) { switch (wParam) {
case TTDT_AUTOMATIC: case TTDT_AUTOMATIC:
if (nTime == 0) { if (nTime <= 0)
infoPtr->nAutomaticTime = 500; nTime = GetDoubleClickTime();
infoPtr->nReshowTime = 100; infoPtr->nReshowTime = nTime / 5;
infoPtr->nAutoPopTime = 5000; infoPtr->nAutoPopTime = nTime * 10;
infoPtr->nInitialTime = 500; infoPtr->nInitialTime = nTime;
} break;
else {
infoPtr->nAutomaticTime = nTime; case TTDT_RESHOW:
infoPtr->nReshowTime = nTime / 5; if(nTime < 0)
infoPtr->nAutoPopTime = nTime * 10; nTime = GetDoubleClickTime() / 5;
infoPtr->nInitialTime = nTime; infoPtr->nReshowTime = nTime;
} break;
case TTDT_AUTOPOP:
if(nTime < 0)
nTime = GetDoubleClickTime() * 10;
infoPtr->nAutoPopTime = nTime;
break;
case TTDT_INITIAL:
if(nTime < 0)
nTime = GetDoubleClickTime();
infoPtr->nInitialTime = nTime;
break; break;
case TTDT_RESHOW: default:
infoPtr->nReshowTime = nTime; WARN("Invalid wParam %x\n", wParam);
break; break;
case TTDT_AUTOPOP:
infoPtr->nAutoPopTime = nTime;
break;
case TTDT_INITIAL:
infoPtr->nInitialTime = nTime;
break;
} }
return 0; return 0;
@ -1611,9 +1651,11 @@ TOOLTIPS_SetToolInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
toolPtr->lpszText = NULL; toolPtr->lpszText = NULL;
} }
if (lpToolInfo->lpszText) { if (lpToolInfo->lpszText) {
INT len = lstrlenA (lpToolInfo->lpszText); INT len = MultiByteToWideChar(CP_ACP, 0, lpToolInfo->lpszText,
toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR)); -1, NULL, 0);
lstrcpyAtoW (toolPtr->lpszText, lpToolInfo->lpszText); toolPtr->lpszText = COMCTL32_Alloc (len * sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, lpToolInfo->lpszText, -1,
toolPtr->lpszText, len);
} }
} }
} }
@ -1781,9 +1823,11 @@ TOOLTIPS_UpdateTipTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
toolPtr->lpszText = NULL; toolPtr->lpszText = NULL;
} }
if (lpToolInfo->lpszText) { if (lpToolInfo->lpszText) {
INT len = lstrlenA (lpToolInfo->lpszText); INT len = MultiByteToWideChar(CP_ACP, 0, lpToolInfo->lpszText,
toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR)); -1, NULL, 0);
lstrcpyAtoW (toolPtr->lpszText, lpToolInfo->lpszText); toolPtr->lpszText = COMCTL32_Alloc (len * sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, lpToolInfo->lpszText, -1,
toolPtr->lpszText, len);
} }
} }
} }
@ -1883,14 +1927,10 @@ TOOLTIPS_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
infoPtr->nMaxTipWidth = -1; infoPtr->nMaxTipWidth = -1;
infoPtr->nTool = -1; infoPtr->nTool = -1;
infoPtr->nOldTool = -1;
infoPtr->nCurrentTool = -1; infoPtr->nCurrentTool = -1;
infoPtr->nTrackTool = -1; infoPtr->nTrackTool = -1;
infoPtr->nAutomaticTime = 500; TOOLTIPS_SetDelayTime(hwnd, TTDT_AUTOMATIC, 0L);
infoPtr->nReshowTime = 100;
infoPtr->nAutoPopTime = 5000;
infoPtr->nInitialTime = 500;
nResult = (INT) SendMessageA (GetParent (hwnd), WM_NOTIFYFORMAT, nResult = (INT) SendMessageA (GetParent (hwnd), WM_NOTIFYFORMAT,
(WPARAM)hwnd, (LPARAM)NF_QUERY); (WPARAM)hwnd, (LPARAM)NF_QUERY);
@ -2098,50 +2138,59 @@ static LRESULT
TOOLTIPS_OnWMGetText (HWND hwnd, WPARAM wParam, LPARAM lParam) TOOLTIPS_OnWMGetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
{ {
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd); TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
INT length;
if(!infoPtr || !(infoPtr->szTipText)) if(!infoPtr || !(infoPtr->szTipText))
return 0; return 0;
length = lstrlenW(infoPtr->szTipText); return WideCharToMultiByte(CP_ACP, 0, infoPtr->szTipText, -1,
/* When wParam is smaller than the lenght of the tip text (LPSTR)lParam, wParam, NULL, NULL);
copy wParam characters of the tip text and return wParam */
if(wParam < length)
{
lstrcpynWtoA((LPSTR)lParam, infoPtr->szTipText,(UINT)wParam);
return wParam;
}
lstrcpyWtoA((LPSTR)lParam, infoPtr->szTipText);
return length;
} }
static LRESULT static LRESULT
TOOLTIPS_Timer (HWND hwnd, WPARAM wParam, LPARAM lParam) TOOLTIPS_Timer (HWND hwnd, WPARAM wParam, LPARAM lParam)
{ {
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd); TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
INT nOldTool;
TRACE("timer %d (%x) expired!\n", wParam, hwnd); TRACE("timer %d (%x) expired!\n", wParam, hwnd);
switch (wParam) switch (wParam) {
{ case ID_TIMERSHOW:
case ID_TIMERSHOW: KillTimer (hwnd, ID_TIMERSHOW);
KillTimer (hwnd, ID_TIMERSHOW); nOldTool = infoPtr->nTool;
if (TOOLTIPS_CheckTool (hwnd, TRUE) == infoPtr->nTool) if ((infoPtr->nTool = TOOLTIPS_CheckTool (hwnd, TRUE)) == nOldTool)
TOOLTIPS_Show (hwnd, infoPtr); TOOLTIPS_Show (hwnd, infoPtr);
break; break;
case ID_TIMERPOP: case ID_TIMERPOP:
TOOLTIPS_Hide (hwnd, infoPtr); TOOLTIPS_Hide (hwnd, infoPtr);
break; break;
case ID_TIMERLEAVE: case ID_TIMERLEAVE:
KillTimer (hwnd, ID_TIMERLEAVE); nOldTool = infoPtr->nTool;
if (TOOLTIPS_CheckTool (hwnd, FALSE) == -1) { infoPtr->nTool = TOOLTIPS_CheckTool (hwnd, FALSE);
infoPtr->nTool = -1; TRACE("tool (%x) %d %d %d\n", hwnd, nOldTool,
infoPtr->nOldTool = -1; infoPtr->nTool, infoPtr->nCurrentTool);
TOOLTIPS_Hide (hwnd, infoPtr); if (infoPtr->nTool != nOldTool) {
if(infoPtr->nTool == -1) { /* Moved out of all tools */
TOOLTIPS_Hide(hwnd, infoPtr);
KillTimer(hwnd, ID_TIMERLEAVE);
} else if (nOldTool == -1) { /* Moved from outside */
ERR("How did this happen?\n");
} else { /* Moved from one to another */
TOOLTIPS_Hide (hwnd, infoPtr);
KillTimer(hwnd, ID_TIMERLEAVE);
if(infoPtr->bActive) {
SetTimer (hwnd, ID_TIMERSHOW, infoPtr->nReshowTime, 0);
TRACE("timer 1 started!\n");
}
} }
break; }
break;
default:
ERR("Unknown timer id %d\n", wParam);
break;
} }
return 0; return 0;
} }
@ -2170,58 +2219,26 @@ TOOLTIPS_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
LPTT_SUBCLASS_INFO lpttsi = LPTT_SUBCLASS_INFO lpttsi =
(LPTT_SUBCLASS_INFO)GetPropA (hwnd, COMCTL32_aSubclass); (LPTT_SUBCLASS_INFO)GetPropA (hwnd, COMCTL32_aSubclass);
TOOLTIPS_INFO *infoPtr; MSG msg;
UINT nTool;
switch (uMsg) { switch(uMsg) {
case WM_LBUTTONDOWN: case WM_MOUSEMOVE:
case WM_LBUTTONUP: case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN: case WM_LBUTTONUP:
case WM_MBUTTONUP: case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN: case WM_MBUTTONUP:
case WM_RBUTTONUP: case WM_RBUTTONDOWN:
infoPtr = TOOLTIPS_GetInfoPtr(lpttsi->hwndToolTip); case WM_RBUTTONUP:
if (!infoPtr) msg.hwnd = hwnd;
break; msg.message = uMsg;
nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd); msg.wParam = wParam;
msg.lParam = lParam;
TOOLTIPS_RelayEvent(lpttsi->hwndToolTip, 0, (LPARAM)&msg);
break;
TRACE("subclassed mouse message %04x\n", uMsg); default:
infoPtr->nOldTool = infoPtr->nTool; break;
infoPtr->nTool = nTool;
TOOLTIPS_Hide (lpttsi->hwndToolTip, infoPtr);
break;
case WM_MOUSEMOVE:
infoPtr = TOOLTIPS_GetInfoPtr (lpttsi->hwndToolTip);
if (!infoPtr)
break;
nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd);
TRACE("subclassed WM_MOUSEMOVE\n");
infoPtr->nOldTool = infoPtr->nTool;
infoPtr->nTool = nTool;
if ((infoPtr->bActive) &&
(infoPtr->nTool != infoPtr->nOldTool)) {
if (infoPtr->nOldTool == -1) {
SetTimer (hwnd, ID_TIMERSHOW,
infoPtr->nInitialTime, 0);
TRACE("timer 1 started!\n");
}
else {
TOOLTIPS_Hide (lpttsi->hwndToolTip, infoPtr);
SetTimer (hwnd, ID_TIMERSHOW,
infoPtr->nReshowTime, 0);
TRACE("timer 2 started!\n");
}
}
if (infoPtr->nCurrentTool != -1) {
SetTimer (hwnd, ID_TIMERLEAVE, 100, 0);
TRACE("timer 3 started!\n");
}
break;
} }
return CallWindowProcA (lpttsi->wpOrigProc, hwnd, uMsg, wParam, lParam); return CallWindowProcA (lpttsi->wpOrigProc, hwnd, uMsg, wParam, lParam);
} }

View File

@ -44,10 +44,8 @@ typedef struct tagTOOLTIPS_INFO
INT yTrackPos; INT yTrackPos;
INT nMaxTipWidth; INT nMaxTipWidth;
INT nTool; INT nTool;
INT nOldTool;
INT nCurrentTool; INT nCurrentTool;
INT nTrackTool; INT nTrackTool;
INT nAutomaticTime;
INT nReshowTime; INT nReshowTime;
INT nAutoPopTime; INT nAutoPopTime;
INT nInitialTime; INT nInitialTime;