2017-01-18 106 views
0

我正在寻找一个解决方案,我WinAPI的程序显示一个菜单项的提示。如何提示添加到菜单项

ID_MAIN_MENU MENU 
    BEGIN 
     ... 
    END 
    MENUITEM "?", ID_RIGHT_BUTTON, HELP 
END 

我能够add tooltip for a controlTOOLINFO结构和TTM_ADDTOOL消息,但这似乎并不适用于HMENU手柄。

我发现some C++ libraries该工具提示添加到菜单项,但我使用C.
而且这是不可能使用WM_MENUSELECT消息,该消息将只发送点击菜单上的,而不是上空盘旋。

Tooltip on single menu item的我想要什么的假想形象。

任何建议表示赞赏。

+0

不知道这一点,但你尝试任何WM_MOUSEHOVER,WM_MOUSEMOVE或WM_NCMOUSEMOVE的事件,无论他们的工作? – Laszlo

+0

@Laszlo:'WM_NCMOUSEMOVE'是唯一有用的:'wParam'总是在整个菜单上,但是'lParam' x和y鼠标坐标......我可以用'GetMenuItemRect()'来标识按钮! – Salvador

+0

只要菜单项*被选中*,无论是从滚动/悬停在菜单项上,还是使用键盘,都会发送WM_MENUSELECT。这是处理显示工具提示的正确消息。它工作正常。如果您无法使用它,请显示您的实际代码。 –

回答

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返回1309 ERROR_NO_IMPERSONATION_TOKEN
为了解决这个问题,create a manifest file和资源(.RC)文件中添加一行:

CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "YourApp.exe.manifest" 
0

最后得出一个解决方案不够好,使工具提示上出现鼠标消失,鼠标了(不完美的,因为没有初始也不autopop延迟时间)。

#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