如何实现跟踪工具提示

跟踪工具提示在应用程序显式关闭之前保持可见,并且可以动态更改屏幕上的位置。 通用控件 的版本 4.70 及更高版本支持它们。

若要创建跟踪工具提示,请在发送TTM_ADDTOOL消息时,在 TOOLINFO 结构的 uFlags 成员中包含TTF_TRACK标志。

应用程序必须通过发送TTM_TRACKACTIVATE消息手动激活 (显示) 并停用 (隐藏 ) 跟踪工具提示。 当跟踪工具提示处于活动状态时,应用程序必须通过将 TTM_TRACKPOSITION 消息发送到工具提示控件来指定工具提示的位置。 由于应用程序处理诸如定位工具提示之类的任务,因此跟踪工具提示不使用 TTF_SUBCLASS 标志或 TTM_RELAYEVENT 消息。

TTM_TRACKPOSITION消息导致工具提示控件使用两种放置样式之一显示窗口:

  • 默认情况下,工具提示显示在控件选择的位置上的相应工具旁边。 选择的位置相对于使用此消息提供的坐标。
  • 如果在 TOOLINFO 结构的成员中包含TTF_ABSOLUTE值,则工具提示将显示在消息中指定的像素位置。 在这种情况下,控件不会尝试从所提供的坐标更改工具提示窗口的位置。

需要了解的事项

技术

先决条件

  • C/C++
  • Windows用户界面编程

Instructions

实现In-Place工具提示

示例中使用的 TOOLINFO 结构的 uFlags 成员包括TTF_ABSOLUTE标志。 如果没有此标志,工具提示控件将选择显示工具提示的位置,并且相对于对话框的位置可能会在鼠标指针移动时突然更改。

注意

g_toolItem 是全局 TOOLINFO 结构。

 

以下示例演示如何创建跟踪工具提示控件。 该示例将主窗口的整个工作区指定为工具。

HWND CreateTrackingToolTip(int toolID, HWND hDlg, WCHAR* 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 the tool information. In this case, the "tool" is the entire parent window.
    
    g_toolItem.cbSize   = sizeof(TOOLINFO);
    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;
}
            

窗口过程实现

当鼠标指针位于工作区中时,工具提示处于活动状态,并显示光标坐标,如下图所示。

screen shot of a dialog box; a tooltip shows the x and y coordinates of the mouse pointer

以下示例代码来自对话框的窗口过程,该对话框显示在前面的示例中创建的跟踪工具提示。 全局布尔变量 g_TrackingMouse 用于确定是否有必要重新激活工具提示并重置鼠标跟踪,以便当鼠标指针离开对话框的工作区时通知应用程序。

//g_hwndTrackingTT is a global HWND variable

case WM_INITDIALOG:

        InitCommonControls();
        g_hwndTrackingTT = CreateTrackingToolTip(IDC_BUTTON1, hDlg, L"");
        return TRUE;

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:

    static int oldX, oldY;
    int newX, newY;

    if (!g_TrackingMouse)   // The mouse has just entered the window.
    {                       // Request notification when the mouse leaves.
    
        TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT) };
        tme.hwndTrack       = hDlg;
        tme.dwFlags         = TME_LEAVE;
        
        TrackMouseEvent(&tme);

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

    newX = GET_X_LPARAM(lParam);
    newY = GET_Y_LPARAM(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.
        WCHAR coords[12];
        swprintf_s(coords, ARRAYSIZE(coords), L"%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.
        
        POINT pt = { newX, newY }; 
        ClientToScreen(hDlg, &pt);
        SendMessage(g_hwndTrackingTT, TTM_TRACKPOSITION, 0, (LPARAM)MAKELONG(pt.x + 10, pt.y - 20));
    }
    return FALSE;

使用工具提示控件