简体   繁体   English

Win32 C++ 中的跟踪工具提示

[英]Tracking tooltip in Win32 C++

In a Win32 / C++ app, running under 64-bit Windows 7, using Visual Studio 16.7.7, I want to implement tracking tooltips in the main (and only) window.在 Win32/C++ 应用程序中,在 64 位 Windows 7 下运行,使用 Visual Studio 16.7.7,我想在主(也是唯一)窗口中实现跟踪工具提示。 Following the examples in Microsoft SDK documentation , the tracking seems to work, but the tooltip window itself does not appear.按照Microsoft SDK 文档中的示例,跟踪似乎有效,但工具提示窗口本身并未出现。

I have verified, using the debugger, that the tooltip is activated and deactivated, that the expected mouse tracking is occurring, that the screen coordinates in the TTM_TRACKPOSITION message are correct, and the text is OK.我已经使用调试器验证了工具提示已激活和停用,正在发生预期的鼠标跟踪, TTM_TRACKPOSITION消息中的屏幕坐标是否正确,以及文本是否正常。 The app is Unicode, and I have checked that the structures are the Unicode versions, and common controls are initialized, and that the current version of the common controls library is linked.该应用程序是 Unicode,我已经检查过结构是 Unicode 版本,并且初始化了常用控件,并且链接了当前版本的常用控件库。 The tooltip window has the WS_EX_TOPMOST and WS_EX_TOOLWINDOW extended styles, per Spy++.根据 Spy++,工具提示窗口具有WS_EX_TOPMOSTWS_EX_TOOLWINDOW扩展样式。

What changes are needed to make the tooltip show?需要进行哪些更改才能显示工具提示?

Here is the code I am using:这是我正在使用的代码:

Global variables:全局变量:

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

Initialization:初始化:

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;
}

Window procedure:窗口程序:

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;
...

The following line is required:需要以下行:

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

Refer to " Using Manifests or Directives to Ensure That Visual Styles Can Be Applied to Applications " for more detailed information.有关更多详细信息,请参阅“ 使用清单或指令确保视觉样式可以应用于应用程序”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM