jhance
asked on
Multi-line ToolTips
How does one implement a multi-line tooltip? I've tried putting various characters (like \r and \n) in the string resource to be display but I always get:
This is line 1|This is line 2
If the line is too long, it gets truncated.
This is line 1|This is line 2
If the line is too long, it gets truncated.
Microsoft's ToolTip control does NOT currently support multi-line text. You will have to write i your self.
ASKER
If that is the case, then what method does MS use in IE4.0 for the tooltips which appear on the toolbar icons? They seem to have the capability of having a multi-line display.
Just use Spy to watch for tooltips and toolbar messages used inside IE 4.0 and make sure that you are using the same common control library as IE 4.0. It gives you list of messages and the rest(what do they mean and how to use them) you will have to figure out yourself.
MS does support multi-line tooltips.
You just need to set the width of the tooltip control and it will automatically extend to multiple lines (with word-wrap) to fit the text in.
I can show you code to do this.
You just need to set the width of the tooltip control and it will automatically extend to multiple lines (with word-wrap) to fit the text in.
I can show you code to do this.
ASKER
RONSLOW,
Some more information on how to do this would help. I'm not creating a tooltip control explicitly in MFC. How do you get a handle to it to control it's width?
Some more information on how to do this would help. I'm not creating a tooltip control explicitly in MFC. How do you get a handle to it to control it's width?
I'll dig it out. I do this myself because I have long descriptive strings and they look very silly when all one one long skinny tooltip.
Hang on and I'll find my code...
Hang on and I'll find my code...
you send the control a TTM_SETMAXTIPWIDTH
more digging...
more digging...
BTW: Have a look at "Tiptoe Through the ToolTips With Our All-Encompassing ToolTip Programmer's Guide" in MSJ Apr 97 (also on MSDN). It uses \n for multi-line tooltips.
ASKER
Like I said earlier, I tried using "\n" in the ToolTip text but just get a bold "|" in the tip. I'm not sure how to send a TTM_SETMAXTIPWIDTH to the control since I never created a control. I'm just calling EnableToolTips() and handling the WM_NEEDTEXT message.
after enabling your tooltip with EnableToolTips you should be try doing this after EnableToolTips (assuming that is what you are doing)
CToolTipCtrl* pToolTip = AfxGetThreadState()->m_pTo olTip;
if (pToolTip->GetSafeHwnd() != NULL) {
pToolTip->SendMessage(TTM_ SETMAXTIPW IDTH, 0, 160);
}
change 160 to whatever size you want (in pixels).
CToolTipCtrl* pToolTip = AfxGetThreadState()->m_pTo
if (pToolTip->GetSafeHwnd() != NULL) {
pToolTip->SendMessage(TTM_
}
change 160 to whatever size you want (in pixels).
ASKER
Well, this method does make the tool tip wider but I still am not able to get more than a single line. Any other ideas?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
I havesample code now that uses EnableToolTips and the SetTipMaxWidth call .. and it works giving multi-line tooltips.
I started with the MSJ March 97 C++ article sample code (Virgil) and modified the OnGetTooltipText by adding the lines for getting the tooltip and setting its width. NOTE: I couldn't do this at the point of the EnableToolTip's because the enabled tool tip control isn't created until it is first needed. SO I set the width here instead
void CMainFrame::OnGetTooltipTe xt(NMHDR* pNMHDR, LRESULT* plRes)
{
CToolTipCtrl* pToolTip = AfxGetThreadState()->m_pTo olTip;
if (pToolTip->GetSafeHwnd() != NULL) {
pToolTip->SendMessage(TTM_ SETMAXTIPW IDTH, 0, 10);
}
TOOLTIPTEXT& ttt = *((TOOLTIPTEXT*)pNMHDR);
strncpy(ttt.szText,
GetWhoItIs(CPoint (pNMHDR->idFrom)),
sizeof(ttt.szText));
}
I started with the MSJ March 97 C++ article sample code (Virgil) and modified the OnGetTooltipText by adding the lines for getting the tooltip and setting its width. NOTE: I couldn't do this at the point of the EnableToolTip's because the enabled tool tip control isn't created until it is first needed. SO I set the width here instead
void CMainFrame::OnGetTooltipTe
{
CToolTipCtrl* pToolTip = AfxGetThreadState()->m_pTo
if (pToolTip->GetSafeHwnd() != NULL) {
pToolTip->SendMessage(TTM_
}
TOOLTIPTEXT& ttt = *((TOOLTIPTEXT*)pNMHDR);
strncpy(ttt.szText,
GetWhoItIs(CPoint (pNMHDR->idFrom)),
sizeof(ttt.szText));
}
ASKER
OK, I'll give that a try. Thanks for hanging with me here.
S'alright .. that's what I'm here for :-)
ASKER
That did it, thanks!
Still not sure why \n is not allowed in Enable tool tips method .. but seems to work ok in manually created tooltip (I've run the sample code that uses \n in the tooltip and it seems to work fine). But at least you can make your tips look a little nicer now.
ASKER
I think I graded you too soon. Or perhaps I wan't complete clear on what I was asking. Anyway, I'm getting multi-line tooltips but I still only get the first 80 (79 actually) characters displayed regardless of how wide I make the tooltip. Any other ideas?
Thanks...
Thanks...
ASKER
Hmmm, poking around in MFC source code produces the following revelation:
typedef struct tagNMTTDISPIFNOA {
NMHDR hdr;
LPSTR lpszText;
char szText[80];
HINSTANCE hinst;
UINT uFlags;
LPARAM lParam;
} NMTTDISPINFOA, FAR *LPNMTTDISPINFOA;
Note that szText is fixed at 80 characters! Is it possible to provide my own structure instead of this stupid one?
typedef struct tagNMTTDISPIFNOA {
NMHDR hdr;
LPSTR lpszText;
char szText[80];
HINSTANCE hinst;
UINT uFlags;
LPARAM lParam;
} NMTTDISPINFOA, FAR *LPNMTTDISPINFOA;
Note that szText is fixed at 80 characters! Is it possible to provide my own structure instead of this stupid one?
There is a limit on the length .. which you have found. You never said you wanted really long tips, though.
I believe that you can put a pointer to a string into lpszText instead .. I don't think there is a limit if you do it that way .. and I think you CAN use '\n' in that case.
I believe that you can put a pointer to a string into lpszText instead .. I don't think there is a limit if you do it that way .. and I think you CAN use '\n' in that case.
Of course, that string need to not go out of scope after the function returns. Make it a static (or a member var or whatever) .. as long as it doesn't disappear when the TTN_NEEDTEXT handler returns.
ASKER
It's interesting. I _was_ using the lpszText pointer, BUT, I was loading the string from a string table resource instead of just a char *. If I just point lpszText at a long char * string, I get multi-line AND the \n works.
Go figure. Thanks again.
Go figure. Thanks again.
Looks like you've got a few alternatives now and a better understand of the mysteries of tool tips (although some mysteries reamin just that .. like when \n works).
Glad to help.
Glad to help.