Fame th
Fame th

Reputation: 1038

How to redraw MFC tooltip when a mouse is moved?

This one is a c++/MFC project. I need to display a position of the cursor. So I must redraw tooltip everytime when a mouse is moving. I can draw a tooltip but a tooltip was drawn isn't cleared.

enter image description here

The OnShowTooltip() function will be called if mouse is moving.

     void OnShowToolTip(const CPoint& ptMousePosition,CString strText)
     {
        UpdateData(true);   
        if (bToolTip)
        {
         unsigned int uid = 0;       // for ti initialization
         // CREATE A TOOLTIP WINDOW
         hwndTT = CreateWindowEx(WS_EX_TOPMOST,
                            TOOLTIPS_CLASS,
                            NULL,
                            TTS_NOPREFIX ,      
                            CW_USEDEFAULT,
                            CW_USEDEFAULT,
                            CW_USEDEFAULT,
                            CW_USEDEFAULT,
                            NULL,
                            NULL,
                            NULL,
                            NULL
                           );

         // INITIALIZE MEMBERS OF THE TOOLINFO STRUCTURE
         //ti.cbSize = sizeof(TOOLINFO);
         ti.cbSize = TTTOOLINFO_V1_SIZE;
         ti.uFlags = TTF_TRACK;
         ti.hwnd = NULL;
         ti.hinst = NULL;
         ti.uId = uid;
         ti.lpszText = (LPSTR)(LPCSTR) strText;     
         // ToolTip control will cover the whole window
         ti.rect.left = 0;
         ti.rect.top = 0;
         ti.rect.right = 0;
         ti.rect.bottom = 0;        

         // SEND AN ADDTOOL MESSAGE TO THE TOOLTIP CONTROL WINDOW
         ::SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);

         ::SendMessage(hwndTT, TTM_TRACKPOSITION, 0, (LPARAM)(DWORD) MAKELONG(ptMousePosition.x, ptMousePosition.y));
              ::SendMessage(hwndTT, TTM_TRACKACTIVATE, true, (LPARAM)(LPTOOLINFO) &ti);

              bToolTip=false;
     }else{
              ::SendMessage(hwndTT, TTM_TRACKACTIVATE, false, (LPARAM)(LPTOOLINFO) &ti);
              bToolTip=true;
     }
    }

I have a function for handling mouse events like below

 BOOL DoDragPoint2D(CPoint point,CString strPositions)
 {
    switch (msg.message)
    {

        case WM_MOUSEMOVE:                
            bToolTip = TRUE;
            OnShowToolTip(point,strPositions);
        break;

       case WM_LBUTTONUP:
             bToolTip = FALSE;
             OnShowToolTip(point,strPositions);
    }
 }

Although I set bTooltip to be FALSE. But It cannot to remove tooltip. Moreover I try to call Invalidate() function but a tooltip still display until a dubbuging is stopped.

Upvotes: 1

Views: 448

Answers (1)

Strive Sun
Strive Sun

Reputation: 6299

Each time the mouse moves, a new tooltip is created.

You only need to create the tooltip once in WM_CREATE event.

Then send TTM_SETTOOLINFO message to update ti.lpszText.

ep.

    case WM_CREATE:
    {
        unsigned int uid = 0;       // for ti initialization
        hwndTT = CreateWindowEx(WS_EX_TOPMOST,
            TOOLTIPS_CLASS,
            NULL,
            TTS_NOPREFIX,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            NULL,
            NULL,
            NULL,
            NULL
        );

        // INITIALIZE MEMBERS OF THE TOOLINFO STRUCTURE
        //ti.cbSize = sizeof(TOOLINFO);
        ti.cbSize = TTTOOLINFO_V1_SIZE;
        ti.uFlags = TTF_TRACK;
        ti.hwnd = NULL;
        ti.hinst = NULL;
        ti.uId = uid;
        ti.lpszText = const_cast <wchar_t*>(L"");
        // ToolTip control will cover the whole window
        ti.rect.left = 0;
        ti.rect.top = 0;
        ti.rect.right = 0;
        ti.rect.bottom = 0;
        ::SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM)(LPTOOLINFO)&ti);
    }
    break;

   case WM_MOUSEMOVE:
     ...  
     ti.lpszText = (LPSTR)(LPCSTR) strText;
     ::SendMessage(hwndTT, TTM_SETTOOLINFO, 0, (LPARAM)&ti);
     ::SendMessage(hwndTT, TTM_TRACKPOSITION, 0, (LPARAM)(DWORD) MAKELONG(ptMousePosition.x, ptMousePosition.y));
     ::SendMessage(hwndTT, TTM_TRACKACTIVATE, true, (LPARAM)(LPTOOLINFO) &ti);
     ...

Upvotes: 3

Related Questions