【问题标题】:Tracking tooltip in Win32 C++Win32 C++ 中的跟踪工具提示
【发布时间】:2020-11-01 19:11:59
【问题描述】:

在一个 Win32 / C++ 应用程序中,在 64 位 Windows 7 下运行,使用 Visual Studio 16.7.7,我想在主(也是唯一的)窗口中实现跟踪工具提示。按照Microsoft SDK documentation 中的示例,跟踪似乎可以工作,但工具提示窗口本身并没有出现。

我已经使用调试器验证了工具提示已激活和停用,正在发生预期的鼠标跟踪,TTM_TRACKPOSITION 消息中的屏幕坐标正确,并且文本正常。该应用程序是 Unicode,我检查了结构是 Unicode 版本,并且初始化了公共控件,并且链接了当前版本的公共控件库。根据 Spy++,工具提示窗口具有 WS_EX_TOPMOSTWS_EX_TOOLWINDOW 扩展样式。

需要进行哪些更改才能显示工具提示?

这是我正在使用的代码:

全局变量:

HINSTANCE hInst;
HWND hWnd;
HWND hwndTT;
WCHAR ttText[12];
TOOLINFO toolTipInfo;
BOOL trackingMouse;

初始化:

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

   if (!hWnd)
   {
      return FALSE;
   }

   // Set up for mouse tracking (tooltips)
   INITCOMMONCONTROLSEX icc;
   icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
   icc.dwICC = ICC_BAR_CLASSES;
   BOOL ok=InitCommonControlsEx(&icc);
   trackingMouse = FALSE;//
   WCHAR nullString[15] = { L"After create" };
   hwndTT = CreateTrackingToolTip(0 /*toolID*/, hWnd, nullString);
   ...

HWND CreateTrackingToolTip(int toolID, HWND hWndParent, WCHAR* pText)
{
    // Create a tooltip.
    HWND h = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL,
        WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        hWndParent, NULL, hInst, NULL);

    if(!h)
    {
        return NULL;
    }

    // Set up the tool information. In this case, the "tool" is the entire parent window.
    memset(&toolTipInfo, 0, sizeof(TOOLINFO));
    toolTipInfo.cbSize = sizeof(TOOLINFO);
    toolTipInfo.uFlags = TTF_IDISHWND | TTF_TRACK | TTF_ABSOLUTE;
    toolTipInfo.hwnd = hWndParent;
    toolTipInfo.hinst = hInst;
    toolTipInfo.lpszText = pText;
    toolTipInfo.uId = (UINT_PTR)hWndParent;

    GetClientRect(hWndParent, &toolTipInfo.rect);

    // Associate the tooltip with the tool window.
    SendMessage(h, TTM_ADDTOOL, 0, (LPARAM)(LPTOOLINFO)&toolTipInfo);

    return h;
}

窗口程序:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_MOUSELEAVE: // The mouse pointer has left our window. Deactivate the tooltip.

        SendMessage(hwndTT, TTM_TRACKACTIVATE, (WPARAM)FALSE, (LPARAM)&toolTipInfo);
        trackingMouse = FALSE;
        TRACE(L"\nDeactivate tooltip");
        return FALSE;

    case WM_MOUSEMOVE:
            static int oldX, oldY;
        int newX, newY;

        if(!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;

            BOOL ok=TrackMouseEvent(&tme);

            // Activate the tooltip.
            SendMessage(hwndTT, TTM_TRACKACTIVATE, (WPARAM)TRUE, (LPARAM)&toolTipInfo);
            trackingMouse = TRUE;
            TRACE(L"\nActivate tooltip");
        }

        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.
            swprintf_s(ttText, ARRAYSIZE(ttText), L"%d, %d", newX, newY);
            toolTipInfo.lpszText = ttText;
            SendMessage(hwndTT, TTM_SETTOOLINFO, 0, (LPARAM)&toolTipInfo);

            // Position the tooltip. The coordinates are adjusted so that the tooltip does not overlap the mouse pointer.
            POINT pt = { newX, newY };
            ClientToScreen(hWnd, &pt);
            SendMessage(hwndTT, TTM_TRACKPOSITION, 0, (LPARAM)MAKELONG(pt.x + 10, pt.y - 20));
        }
    return FALSE;
...

【问题讨论】:

  • 先尝试通过发送TTM_ACTIVATE 消息(将wParam 设置为TRUE)来启用控件。
  • @Jonathan Potter:在 TTM_ADDTOOL 之后发送 TTM_ACTIVATE 不会改变任何东西。工具提示仍未出现。
  • 奇怪的解决方案;据我所知,跟踪工具提示不仅仅是 comctrl v6 的一个功能。

标签: c++ winapi tooltip


【解决方案1】:

以下行是必需的:

#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

有关详细信息,请参阅“Using Manifests or Directives to Ensure That Visual Styles Can Be Applied to Applications”。

【讨论】:

  • Rita Han - 添加此行确实可以正常工作。我认为这将由清单(链接器/MANIFEST)处理。链接器也显示“正在搜索 C:\Program Files (x86)\Windows Kits\10\lib\10.0.18362.0\um\x64\Comctl32.lib”。
猜你喜欢
  • 1970-01-01
  • 2014-01-24
  • 1970-01-01
  • 1970-01-01
  • 2015-08-21
  • 1970-01-01
  • 1970-01-01
  • 2011-08-24
  • 1970-01-01
相关资源
最近更新 更多