RTF-Based Tooltips

This code demonstrates using rich text in tooltips, as seen in Query Analyser utility of MS SQL Server 7.

It is more like a proof-of-concept then a finished code, and is heavily based on two classes from CodeGuru : TFXDataTip by S. Wilson and CAutoRichEditCtrl by Jeremy Iverson

First class was modifyed to hold a hidden AutoRichEdit control as a static member and use it for rendering the RTF text to the window. Function of AutoRichEdit are used to load text into the control.

Most of the magic behind the code is in the OnPaint handler of the tooltip window. The idea is to utilise RichEdit printing functions to copy the picture to screen DC instead of printer.

void TFXDataTip::OnPaint() 
	CPaintDC dc(this); // device context for painting

    CRect rect;



		fr.hdc = dc;
		fr.hdcTarget = dc;
		fr.rc = CRect((rect.Width( ) / 2), (_border / 2) ,m_size.cx*15, m_size.cy*15);
		fr.rcPage = CRect(0,0,0,0);
		fr.chrg.cpMin = 0;
		fr.chrg.cpMax = -1;
		_richCtrl->FormatRange( &fr );


Using it from the dialog is also rather simple :

void CRich1Dlg::OnMouseMove(UINT nFlags, CPoint point) 
	CWnd *pwnd = ChildWindowFromPoint(point);
		int nID = pwnd->GetDlgCtrlID();

				m_datatip.Set(point, m_tip1);
			case IDC_TEXT:
				m_datatip.Set(point, m_tip2);
				m_datatip.Set(point, m_tip3);
	CDialog::OnMouseMove(nFlags, point);

Issues and possible enhancements :

  • More 'standard' tooltip behaviour, such as ability to assign text to control IDs etc.
  • Some framework for dynamically producing RTF based on a template could be nice
  • Images included in RTF files doesn't show up.
  • Any explanation for '15' constant in rc member of a FORMATRANGE struct ? What units are used there ?
  • Possibly cache rendered text to avoid having to load it into RichEdit control every time.

    Download demo project - 10 KB

    Download source - 26 KB

  • Comments

    • Picture Not Showing

      Posted by Legacy on 01/23/2004 12:00am

      Originally posted by: gush

      why is the picture not showing in the tooltip?

    • How to do this with a Html Edit Control?

      Posted by Legacy on 12/20/2003 12:00am

      Originally posted by: Appstmd


      Is it possible to do the same thing with the Microsoft Html Edit ActiveX Control?

      What are the equivalent printing functions for this control?

      Thks in advance.

    • How to feed text to Richedit control

      Posted by Legacy on 02/08/2003 12:00am

      Originally posted by: Vikas

      I have a string which has some rtf text to be printed. I have created a richedit control and then I feed the string to the control using WM_SETTEXT message. The problem that I am facing is that Richedit control only consumes the text worth of one paragraph instead of the whole text. How can I make this text consume the whole text?

    • I know why 15, but 15 is uncertain!

      Posted by Legacy on 10/13/2001 12:00am

      Originally posted by: Edwin Zhang

      MSDN says very clearly that:
      for rc and rcPage in FORMATRANGE, their unit should be measured in twips, and we all know 1 inch is 1440 twips,
      so you can write as:

      long lWidth = ::MulDiv(rect.Width(), 1440, dc.GetDeviceCaps(LOGPIXELSX));
      long lHeight = ::MulDiv(rect.Height(), 1440, dc.GetDeviceCaps(LOGPIXELSY));

      CRect rcPage(0, 0, lWidth, lHeight);
      fr.rc = rcPage;
      fr.rcPage = rcPage;

      For dc.GetDeviceCaps(LOGPIXELSX) usually equals 96, so 1440 / 96 = 15. but you know you can not use 15 for safety reason.

    • RE: concerning the '15' constant

      Posted by Legacy on 07/17/2001 12:00am

      Originally posted by: JMB

      concerning the '15' constant

      I have no idea about your CRTfxxx project,

      but 15 sounds to me as the VB TxipPerPixels? constants
      (? being X or Y, in a std 'small fonts' environment)

      Please refer to MSDN/VB docs for the definition of the TWIP as a device-independent[???] unit )

      Maybe this might be a hint - no other ambition implied



    • Auto complete prompting

      Posted by Legacy on 05/21/2001 12:00am

      Originally posted by: Shrinivas


      I'm trying to do the Atocomplete prompting in my MDI application with CRichEditView.
      Atocomplete prompting - In MS Word if you type Janu, a yellow tooltip kind of box pops up above the current caret position with word "January" in it and now if you hit Enter key half typed Janu gets replaced by word January.
      I want to do the similar kind of functionality in my application for some selected words. Is it anything to do with the tool tips?

      Any pointer to this is highly appreciated.


    • Some little modifications

      Posted by Legacy on 07/24/1999 12:00am

      Originally posted by: FRED

      This control like a lot we can find on this site is great. But, poor
      programer we can't thinks about all! Me the first one!!
      I've tryed successfully to implement this control on my code.
      But, i've some problem with the init size of 0. The result was a little
      and large tooltip.

      This is because the program calculate the size of the window like this

      void TFXDataTip::Display( )
      // OLD CODE
      if(m_size == CSize(0,0))
      m_size = dc.GetTextExtent(m_tip);

      now after this code :
      if (wndRect.right > dc.GetDeviceCaps(HORZRES)) {
      wndRect.OffsetRect(-wndRect.Width(), 0);
      } else {

      -->REPLACE IT bY ADDING this one:
      int cx = wndRect.Width(), cy = wndRect.Height();

      CRect rect;

      fr.hdc = dc;
      fr.hdcTarget = dc;
      fr.rc = CRect((rect.Width( ) / 2), (_border / 2) ,m_size.cx*15, m_size.cy*15);
      fr.rcPage = CRect(0,0,0,0);
      fr.chrg.cpMin = 0;
      fr.chrg.cpMax = -1;

      _richCtrl->FormatRange(&fr, FALSE); // Specify FALSE to not redraw

      // Now resize the window
      cx = ((fr.rc.right-fr.rc.left)/15)+15; // We add 15 to not round inf
      cy = ((fr.rc.bottom - fr.rc.top)/15)+15;

      THEN Modify the SetWindowPos FUNCTion

      // update window position and display
      cx, // UPDATE replace Width
      cy, // UPDATE replace

      in the OnPaint Function remove the line who make:
      now there is no reason to let it here because we have assigned this value
      in the Display Function

      To use this control correctly you must have in mind that your choice must be the width
      or the height not the both. In this sample my choice was the width.


    • Rect coordinates in the FORMATRANGE struct

      Posted by Legacy on 04/23/1999 12:00am

      Originally posted by: Bartosz Bien

      As VC6 MSDN library says, rectangles of rendering area and entire "page" area are in twips (which is 1/1440 of an inch). I'm not sure if the '15' is universal for all devices/devmodes.

    Leave a Comment
    • Your email address will not be published. All fields are required.

    Top White Papers and Webcasts

    • Enterprises are increasingly looking to platform as a service (PaaS) to lower their costs and speed their time to market for new applications. Developing, deploying, and managing applications in the cloud eliminates the time and expense of managing a physical infrastructure to support them. PaaS offerings must deliver additional long-term benefits, such as a lower total cost of ownership (TCO), rapid scalability, and ease of integration, all while providing robust security and availability. This report …

    • Anthony Christie, the Chief Marketing Officer for Level Communications, is responsible for customer experience, worldwide marketing and product management. In this informative asset, he shares his insights into why a private network connection to cloud-bases applications is the right decision for your enterprise. Download now to find out more.

    Most Popular Programming Stories

    More for Developers

    RSS Feeds

    Thanks for your registration, follow us on our social networks to keep up-to-date