不靠谱的tooltip

typedef struct tagTOOLINFOA {
    UINT cbSize;
    UINT uFlags;
    HWND hwnd;
    UINT_PTR uId;
    RECT rect;
    HINSTANCE hinst;
    LPSTR lpszText;
#if (_WIN32_IE >= 0x0300)
    LPARAM lParam;
#endif
#if (_WIN32_WINNT >= 0x0501)
    void *lpReserved;
#endif
} TTTOOLINFOA, NEAR *PTOOLINFOA, *LPTTTOOLINFOA;

如果#define _WIN32_WINNT 0x0500,那么tooltip一切正常
当有一天#define _WIN32_WINNT 0x0501了,
这时设置tooltip.cbSize = sizeof(TOOLINFO)的时候就让人崩溃了。
编译调试不显示任何错误,但是tooltip就是显示不出来了。。。(they were just failing silently without knowing why)
因为系统默认加载comctl 5.82,这个版本里面的tooltip的size根本没有sizeof(TOOLINFO),里面没有void *lpReserved;
所以cbSize设大了,出错了。。。
这时需要写成tooltip.cbSize = TTTOOLINFOA_V2_SIZE;
或者强制指定comctl 6.0
#pragma comment(linker, "\"/manifestdependency:type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'\"")

ps: 指定#define _WIN32_WINNT 0x0501将导致程序只能运行在xp及以上系统。

测试程序:
#define _WIN32_WINNT 0x0501
#define WINVER 0x0501

#include <windows.h>
#include <commctrl.h>
#include <stdio.h>

#pragma comment(lib, "user32.lib")
#pragma comment(lib, "comctl32.Lib")
#pragma comment(lib, "gdi32.Lib")

#pragma comment(linker, "\"/manifestdependency:type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'\"")
int count;
TCHAR str[1000];

HWND g_hwndTrackingTT;
TOOLINFO g_toolItem;
HINSTANCE g_hInst;
BOOL g_TrackingMouse = FALSE;

LRESULT CALLBACK WindowFunc(HWND,UINT,WPARAM,LPARAM);

HWND CreateTrackingToolTip(int toolID, HWND hDlg, char *pText);

TCHAR szWinName[] = TEXT("MyWin");

int WINAPI WinMain(HINSTANCE hThisInst,HINSTANCE hPrevInst,LPSTR lpszArgs,int nWinMode)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wcl;
INITCOMMONCONTROLSEX ic;
BOOL ret;

g_hInst = hThisInst;
ic.dwSize = sizeof(INITCOMMONCONTROLSEX);
ic.dwICC = 0x00004000;//ICC_STANDARD_CLASSES|ICC_BAR_CLASSES;
ret = InitCommonControlsEx(&ic);
wcl.cbSize = sizeof(WNDCLASSEX);
wcl.hInstance = hThisInst;
wcl.lpszClassName = szWinName;
wcl.lpfnWndProc = WindowFunc;
wcl.style = CS_HREDRAW|CS_VREDRAW;
wcl.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wcl.hIconSm = NULL;
wcl.hCursor = LoadCursor(NULL,IDC_ARROW);
wcl.lpszMenuName = NULL;
wcl.cbClsExtra = 0;
wcl.cbWndExtra = 0;
wcl.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
if(!RegisterClassEx(&wcl)) return 0;
hwnd = CreateWindowEx(
WS_EX_WINDOWEDGE,
szWinName,
TEXT("Window Title"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
HWND_DESKTOP,
NULL,
hThisInst,
NULL
);
ShowWindow(hwnd,nWinMode);
UpdateWindow(hwnd);

while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WindowFunc(HWND hwnd,UINT message,WPARAM
wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
static int cxClient = 0, cyClient = 0, oldX, oldY;
int newX, newY;
char coords[12];
POINT pt;

switch(message){
case WM_CREATE:
g_hwndTrackingTT = CreateTrackingToolTip(456, hwnd, "");
return 0;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
EndPaint(hwnd, &ps);
return 0;
case WM_MOUSELEAVE:
// The mouse pointer has left our window.
// Deactivate the ToolTip.
SendMessage(g_hwndTrackingTT, TTM_TRACKACTIVATE, (WPARAM)
FALSE, (LPARAM)&g_toolItem);
g_TrackingMouse = FALSE;
return FALSE;
case WM_MOUSEMOVE:
if (!g_TrackingMouse)
// The mouse has just entered the window.
{
// Request notification when the mouse leaves.
TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT) };
tme.hwndTrack = hwnd;
tme.dwFlags = TME_LEAVE;
TrackMouseEvent(&tme);

// Activate the ToolTip.
SendMessage(g_hwndTrackingTT, TTM_TRACKACTIVATE,
(WPARAM)TRUE, (LPARAM)&g_toolItem);
g_TrackingMouse = TRUE;
}

newX = LOWORD(lParam);
newY = HIWORD(lParam);
// Make sure the mouse has actually moved. The presence of the ToolTip
// causes Windows to send the message continuously.
if ((newX != oldX) || (newY != oldY))
{
oldX = newX;
oldY = newY;
// Update the text.
sprintf(coords, "%d, %d", newX, newY);
g_toolItem.lpszText = coords;
SendMessage(g_hwndTrackingTT, TTM_SETTOOLINFO, 0, (LPARAM)
&g_toolItem);

// Position the ToolTip.
// The coordinates are adjusted so that the ToolTip does not
// overlap the mouse pointer.
pt.x = newX;
pt.y = newY;
ClientToScreen(hwnd, &pt);
SendMessage(g_hwndTrackingTT, TTM_TRACKPOSITION,
0, (LPARAM)MAKELONG(pt.x + 10, pt.y - 20));
}
return FALSE;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,message,wParam,lParam);
}

HWND CreateTrackingToolTip(int toolID, HWND hDlg, char *pText)
{
// Create a ToolTip.
HWND hwndTT = CreateWindowEx(WS_EX_TOPMOST,
TOOLTIPS_CLASS, NULL,
WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
hDlg, NULL, g_hInst,NULL);
if (!hwndTT)
{
return NULL;
}
// Set up tool information.
// In this case, the "tool" is the entire parent window.
g_toolItem.cbSize = sizeof(TOOLINFO);
//g_toolItem.cbSize = TTTOOLINFOA_V2_SIZE;
g_toolItem.uFlags = TTF_IDISHWND | TTF_TRACK | TTF_ABSOLUTE;
g_toolItem.hwnd = hDlg;
g_toolItem.hinst = g_hInst;
g_toolItem.lpszText = pText;
g_toolItem.uId = (UINT_PTR)hDlg;
GetClientRect (hDlg, &g_toolItem.rect);

// Associate the ToolTip with the tool window.
SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO)&g_toolItem);
return hwndTT;
}
<think>好的,用户想在ECharts中隐藏或禁用Tooltip功能。我需要先回忆一下ECharts的相关配置。记得Tooltip是全局的提示框组件,通常在option中配置。首先,可能的方法是将tooltip的show属性设为false。比如在配置项里写tooltip: {show:false }。这样应该能直接隐藏Tooltip。另外,用户提到禁用,可能只是隐藏,还要防止在某些交互中触发。比如,当用户鼠标悬停或移动时,Tooltip可能会显示。这时候可能需要设置trigger为'none',或者调整triggerOn为'none'。过查看文档,trigger的合法值包括'item'、'axis'、'none'等,设置trigger:'none'应该也能禁用Tooltip的触发。还要考虑动态控制的情况,比如通过事件来关闭。用户可能需要在某些条件下关闭Tooltip,这时候可以使用实例的dispatchAction方法,调用hideTip来隐藏。过这种方法可能只是临时隐藏,是彻底禁用。另外,用户提供的引用中有提到在手机端控制Tooltip显示和滚动的问题,比如引用3中的代码,通过监听点击事件来控制Tooltip的显示和隐藏。这可能涉及到更复杂的交互,但用户当前的需求只是简单地禁用,所以可能需要这么复杂。需要验证这两种方法:设置show:false和trigger: 'none'。哪种更有效?可能两者都可以,但根据文档,show是控制显示与否,而trigger是决定触发条件。比如,即使show为true,如果trigger设为'none',也会显示。但为了保险起见,同时设置两者可能更好。 另外,检查是否有其他配置会影响Tooltip,比如系列中的tooltip配置,但通常全局的tooltip配置已经足够。还要注意,如果用户使用的是Vue或其他框架,可能需要确保配置正确传递给了ECharts实例。总结,最简单的解决方案是在option中配置tooltip.show为false,或者在初始化图表时设置tooltip:{ show: false}。这样就能有效隐藏Tooltip了。</think>### 如何在ECharts中禁用或隐藏Tooltip? 在ECharts中隐藏或禁用Tooltip功能,可以通过以下两种方式实现: --- #### **方法1:通过配置项直接关闭** 在图表配置项的`tooltip`对象中设置`show: false`,这将全局禁用Tooltip的显示。 **示例代码**: ```javascript option = { tooltip: { show: false // 直接关闭Tooltip }, xAxis: { type: 'category' }, yAxis: {}, series: [{ type: 'line', data: [5, 20, 36, 10, 10] }] }; ``` --- #### **方法2:动态控制Tooltip显隐** 若需根据交互条件动态控制,可通过`dispatchAction`触发`hideTip`操作: ```javascript // 隐藏Tooltip myChart.dispatchAction({ type: 'hideTip' }); // 显示Tooltip(若需恢复) myChart.dispatchAction({ type: 'showTip' }); ``` --- #### **扩展场景:移动端特殊处理** 如果涉及移动端滑动与Tooltip的冲突(如引用[3]所述),可通过监听事件动态控制: ```javascript myChart.on('click', () => { // 点击时显示Tooltip并禁止滚动 myChart.setOption({ tooltip: { show: true } }); // 禁用容器滚动逻辑(需自行实现) }); // Tooltip隐藏后恢复滚动 myChart.on('globalout', () => { myChart.setOption({ tooltip: { show: false } }); // 恢复容器滚动逻辑 }); ``` --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@井九

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值