如何实施跟踪工具提示

跟踪工具提示在应用程序明确关闭之前始终可见,并可动态改变在屏幕上的位置。 版本 4.70 及更高版本的通用控件支持这些控件。

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

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

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

  • 默认情况下,工具提示会显示在相应工具的旁边,其位置由控件选择。 选择的位置与通过此信息提供的坐标相对应。
  • 如果在 TOOLINFO 结构的成员中包含 TTF_ABSOLUTE 值,则会在信息中指定的像素位置显示工具提示。 在这种情况下,控件不会根据提供的坐标来更改工具提示窗口的位置。

需要了解的事项

技术

先决条件

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

说明

实施就地工具提示

示例中使用的 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;

使用工具提示控件