我正在寻找一个解决方案来显示我的WinAPI程序中单个菜单项的工具提示。
ID_MAIN_MENU MENU
BEGIN
...
END
MENUITEM "?", ID_RIGHT_BUTTON, HELP
END
我可以使用TOOLINFO
结构和TTM_ADDTOOL
消息add tooltip for a control,但这似乎不适用于HMENU
句柄。
我发现some C++ libraries向菜单项添加了工具提示,但我使用了C.
此外,它无法使用WM_MENUSELECT
消息,该消息仅在点击菜单时发送,而不是悬停在上面。
任何建议都表示赞赏。
答案 0 :(得分:0)
最后找到一个足够好的解决方案,使鼠标悬停在工具提示上,并在鼠标输出时消失(不完美,因为没有初始或自动延迟时间)。
#define _WIN32_IE 0x0300 // to reach TTM_TRACKACTIVATE in <commctrl.h>
#include <windows.h>
#include <commctrl.h>
HWND hToolTip;
TOOLINFO ti = {0};
// WndProc
case WM_CREATE: {
HMENU hmenu = CreateMenu();
AppendMenu( hmenu, MF_HELP, 123, "?" );
SetMenu( hWnd, hmenu );
hToolTip = CreateWindow( TOOLTIPS_CLASS, 0, WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, hWnd, 0, 0, 0);
ti.cbSize = sizeof(TOOLINFO);
ti.hwnd = hWnd;
ti.uId = (UINT)hToolTip;
ti.lpszText = "My tooltip";
SendMessage( hToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti );
break;
}
case WM_NCMOUSEMOVE: {
RECT rect;
GetMenuItemRect( hWnd, GetMenu(hWnd), 0, &rect );
// ^ zero-based position of the menu item
int x = LOWORD(lParam);
int y = HIWORD(lParam);
if ( x>=rect.left && y>=rect.top && x<rect.right && y<rect.bottom )
SendMessage( hToolTip, TTM_TRACKACTIVATE, TRUE, (LPARAM)&ti );
else
SendMessage( hToolTip, TTM_TRACKACTIVATE, FALSE, (LPARAM)&ti );
break;
}
case WM_MOUSEMOVE:
SendMessage( hToolTip, TTM_TRACKACTIVATE, FALSE, (LPARAM)&ti );
break;
为什么我使用TTM_TRACKACTIVATE
代替TTM_POPUP
?
TTM_POPUP
中未定义commctrl.h
。{/ li>
TTM_POPUP
需要Visual Styles enabled with manifest。TTM_POPUP
无效。答案 1 :(得分:0)
我提出了一种更简单,更有效的解决方案,为单个菜单项创建工具提示:
#include <windows.h>
#include <commctrl.h>
#define ID_BUTTON 123
HWND hToolTip;
TOOLINFO ti = {0};
// WndProc
case WM_CREATE: {
// create menu
HMENU hmenu = CreateMenu();
AppendMenu( hmenu, MF_HELP, ID_BUTTON, "?" );
SetMenu( hWnd, hmenu );
InitCommonControls(); // necessary in Windows XP to register TOOLTIPS_CLASS
// create tooltip
hToolTip = CreateWindow( TOOLTIPS_CLASS, 0, WS_POPUP, 0, 0, 0, 0, hWnd, 0, 0, 0 );
ti.cbSize = sizeof(TOOLINFO);
ti.uFlags = TTF_SUBCLASS;
ti.hwnd = hWnd; // main window handle
ti.uId = (UINT)ID_BUTTON; // distinguish it from eventual other tooltips
ti.lpszText = "My tooltip";
SendMessage(hToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti);
break;
}
case WM_SIZE:
ti.uId = (UINT)ID_BUTTON;
// get new coordinates of item
GetMenuItemRect( hWnd, GetMenu(hWnd), 0, &ti.rect );
// ^ zero-based position of the menu item
// convert from screen to client coordinates
MapWindowPoints( NULL, hWnd, (LPPOINT)&ti.rect, 2 );
// ^ desktop handle ^ POINT structures that is one RECT
SendMessage(hToolTip, TTM_NEWTOOLRECT, 0, (LPARAM)&ti);
break;
我使用InitCommonControls
因为它更短且有效,但也已过时,应使用InitCommonControlsEx
。
以上代码也在Windows XP上进行了测试:它可以正常运行,但GetLastError
CreateWindow
后返回1309 ERROR_NO_IMPERSONATION_TOKEN
。
为了解决它,create a manifest file和资源(.rc)文件中添加以下行:
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "YourApp.exe.manifest"