Solved

Tracking tooltips in Visual C++

Posted on 2008-06-24
3
1,470 Views
Last Modified: 2013-11-20
I wish to create a simple dialog-based application (using MFC) with a tooltip that can display different text according to where the mouse pointer is located, and also switch off this tooltip at other regions
of the dialog.

Any suggestions or pointers to existing code would be most welcome.

Thanks in advance

Andy
0
Comment
Question by:arrayjet_vin
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
3 Comments
 
LVL 19

Accepted Solution

by:
mrwad99 earned 125 total points
ID: 21857783
Whenever I want to add a tooltip to a control, I use the following tooltip class, featured in "Programming Windows with MFC" by Jeff Prosise.

class CMyToolTipCtrl : public CToolTipCtrl
{
public:
    BOOL AddWindowTool (CWnd* pWnd, LPCTSTR pszText);
    BOOL AddRectTool (CWnd* pWnd, LPCTSTR pszText,
        LPCRECT pRect, UINT nIDTool);
};

BOOL CMyToolTipCtrl::AddWindowTool (CWnd* pWnd, LPCTSTR pszText)
{
    TOOLINFO ti;
    ti.cbSize = sizeof (TOOLINFO);
    ti.uFlags = TTF_IDISHWND ¦ TTF_SUBCLASS;
    ti.hwnd = pWnd->GetParent ()->GetSafeHwnd ();
    ti.uId = (UINT) pWnd->GetSafeHwnd ();
    ti.hinst = AfxGetInstanceHandle ();
    ti.lpszText = (LPTSTR) pszText;

    return (BOOL) SendMessage (TTM_ADDTOOL, 0, (LPARAM) &ti);
}

BOOL CMyToolTipCtrl::AddRectTool (CWnd* pWnd, LPCTSTR pszText,
    LPCRECT lpRect, UINT nIDTool)
{
    TOOLINFO ti;
    ti.cbSize = sizeof (TOOLINFO);
    ti.uFlags = TTF_SUBCLASS;
    ti.hwnd = pWnd->GetSafeHwnd ();
    ti.uId = nIDTool;
    ti.hinst = AfxGetInstanceHandle ();
    ti.lpszText = (LPTSTR) pszText;
    ::CopyRect (&ti.rect, lpRect);

    return (BOOL) SendMessage (TTM_ADDTOOL, 0, (LPARAM) &ti);
}

"With this infrastructure in place, creating a tool from a child window controlsubclassing and allrequires just one simple statement:

m_ctlTT.AddWindowTool (pWnd, _T ("This is a window"));

Creating a tool from a rectangle in a window is equally simple:

m_ctlTT.AddRectTool (pWnd, _T ("This is a rectangle"),
    CRect (32, 32, 64, 64), IDT_RECTANGLE);
"

Assuming m_ctlTT is a CMyToolTipCtrl object, which has been constructed and Create()'d, in the code above, we add a tooltip to the control 'pwnd' and the rectangle with bounds (32, 32, 64, 64) within 'pwnd'.

I think that has answered your question body, but your question *title* mentions "tracking" tooltips, which are tooltips that redraw themselves very quickly so the effect of "tracking" with the mouse pointer is achieved.  The above code does not satisy that, and, interestingly enough, I myself have never found a working solution to achieve this, although I have seen it many times in various apps.

HTH
0
 

Author Comment

by:arrayjet_vin
ID: 21865786
Thanks for the feedback mrwad99.

I think I have figured out how to track the tooltip, inside the message handling function dealing with mouse movements. It seems to work fine, I've omitted irrelevant imformation to help clarify it a bit:

void CMultiplePrintrunDialog::OnMouseMove( UINT nFlags, CPoint point )
{      
      // extraneous code here etc    

        BOOL bToolTip = // Code to set BOOL bToolTip to TRUE/FALSE, a function of the [x,y] position of the            
                                    // mouse pointer and various other things...

      // If TRUE then activate tooltip                   
      if ( bToolTip == TRUE )
      {
            // Set the tooltip text to be displayed            
            CString tooltip = // depends on location of mouse pointer and other stuff...;                  
            
            // Create the tooltip
            hwndTT = CreateWindowEx(
                                    WS_EX_TOPMOST,
                                    TOOLTIPS_CLASS,
                                    NULL,
                                    TTS_NOPREFIX | TTS_ALWAYSTIP,            
                                    CW_USEDEFAULT,
                                    CW_USEDEFAULT,
                                    CW_USEDEFAULT,
                                    CW_USEDEFAULT,
                                    NULL,
                                    NULL,
                                    NULL,
                                    NULL
                                    );

            // Initialise members of the TOOLINFO structure, including the text to be displayed            
            ti.cbSize = sizeof( TOOLINFO );
            ti.uFlags = TTF_TRACK;
            ti.hwnd   = NULL;
            ti.hinst  = NULL;
            ti.uId    = 0;
            ti.lpszText = (LPSTR)(LPCSTR) tooltip;                              
            
            // Register tool with tooltip control
            ::SendMessage(
                        hwndTT,
                        TTM_ADDTOOL,
                        0,
                        (LPARAM) (LPTOOLINFO) &ti
                        );

            // Set the position of the tracking ToolTip
                int x_val = // Some code to ascertain this;
            int y_val = // ditto
            ::SendMessage(
                        hwndTT,
                        TTM_TRACKPOSITION,
                        0,
                        (LPARAM)(DWORD) MAKELONG( x_val, y_val )
                        );

            // Activate the tracking tooltip
            ::SendMessage(
                        hwndTT,
                        TTM_TRACKACTIVATE,
                        TRUE,
                        (LPARAM)(LPTOOLINFO) &ti
                        );            
      }      
        // Otherwise deactivate the tracking tooltip
      else
      {                  
            ::SendMessage(
                        hwndTT,
                        TTM_TRACKACTIVATE,
                        FALSE,
                        (LPARAM)(LPTOOLINFO) &ti
                        );                              
      }
            
      CDialog::OnMouseMove(nFlags, point);
}
0
 
LVL 19

Expert Comment

by:mrwad99
ID: 21865931
Glad you got it sorted.  If you feel my comment assisted, please close this question by accepting it as an answer :)
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
sumDigits challenge 9 178
sum67 challenge 35 130
only14 challenge 19 89
Adjust the codes 3 63
In Easy String Encryption Using CryptoAPI in C++ (http://www.experts-exchange.com/viewArticle.jsp?aid=1193) I described how to encrypt text and recommended that the encrypted text be stored as a series of hexadecimal digits -- because cyphertext may…
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

738 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question