Click here to Skip to main content
15,867,851 members
Articles / Desktop Programming / MFC
Article

Tooltips in modal dialog boxes

Rate me:
Please Sign up or sign in to vote.
3.53/5 (12 votes)
20 Nov 19994 min read 196.9K   4.1K   72   23
A demonstration of how to show tooltips in modal dialog bozes
  • Download demo project - 18 Kb
  • Download source files - 2 Kb
  • Introduction

    This sample demonstrates how to show tooltips in modal dialog boxes. Besides that, it illustrates some basic principles of code reuse and the spirit of MFC programming. The sample was created using Visual C++ 6.0, but should work from 4.2 on.

    How to integrate the sample in your application

    • Include the file ToolTipDialog.cpp in your application.
    • In stdafx.h, add the line
      #include "ToolTipDialog.h"
    • Derive your dialogs from CToolTipDialog instead of CDialog.
    • Be sure to call CToolTipDialog::OnInitDialog instead of CDialog::OnInitDialog.
    • Add string to your resource file with the same IDs as the controls in your dialogs.
    • If you have an Options dialog, include the options "Show tooltips in dialogs". When this setting changes, call CToolTipDialog::EnableToolTips().

    How it works

    The sample uses the MFC CToolTipCtrl, which is built around a Windows Common Control. This common control does all the work for us. The only thing to do is create the control, assign tooltips to windows and relay the mouse messages. The function CToolTipDialog::OnInitDialog() looks up all strings with ID's that match the ID of a control.

    BOOL CToolTipDialog::OnInitDialog()
    {
    	BOOL bResult = CDialog::OnInitDialog();
    	m_wndToolTip.Create(this);
    	m_wndToolTip.Activate(c_bShowToolTips);
    	CWnd *pWndChild = GetWindow(GW_CHILD);
    	CString strToolTip;
    	while (pWndChild)
    	{
    		int nID = pWndChild->GetDlgCtrlID();
    		if (strToolTip.LoadString(nID))
    		{
    			m_wndToolTip.AddTool(pWndChild, strToolTip);
    		}
    		pWndChild = pWndChild->GetWindow(GW_HWNDNEXT);
    	}
    	return bResult;
    }

    The standard windows program has a main loop that calls GetMessage(), TranslateMessage() and DispatchMessage() continuously. The MFC main loop and the modal loops contain some extra's. One of these is calling PreTranslateMessage() before TranslateMessage(). This gives us the chance to peek at every message or to filter messages before they are dispatched. This is the place where we can intercept all mouse messages and relay them to the tooltip control.

    BOOL CToolTipDialog::PreTranslateMessage(MSG *pMsg)
    {
    	if (c_bShowToolTips &&
    		pMsg->message >= WM_MOUSEFIRST &&
    		pMsg->message <= WM_MOUSELAST)
    	{
    		MSG msg;
    		::CopyMemory(&msg, pMsg, sizeof(MSG));
    		HWND hWndParent = ::GetParent(msg.hwnd);
    		while (hWndParent && hWndParent != m_hWnd)
    		{
    			msg.hwnd = hWndParent;
    			hWndParent = ::GetParent(hWndParent);
    		}
    		if (msg.hwnd)
    		{
    			ListBoxTextExpand(&msg);
    			m_wndToolTip.RelayEvent(&msg);
    		}
    	}
    	return CDialog::PreTranslateMessage(pMsg);
    }

    As pointed out by Richard Collins, it is not enough to just relay the mouse events to the tooltip control. This would not work for controls that have child windows. A combo box for example has an edit control as a child. When a mouse message is sent to this edit control, hWndParent will be the combo box, not the dialog. The message is adjusted to make the tooltip control believe it was actually sent to the combo box. Of course, the original message is passed on to the base class function.

    Automatic expansion of listbox strings

    Murali Soundararajan added the code to show listbox strings in the tooltip. To do this, you just give your listbox the string TOOLTIPEXPAND. All the rest is done for you. The tooltip will show the text of the listbox item beneath the mouse. This will not work with owner drawn listboxes. This is what the call to ListBoxTextExpand(&msg) is needed for.

    Code Reuse

    The CodeGuru site already contains an article by Dave Bixler that does just the same. However, Dave tells us to write the same code over and over again for every dialog. There are two reasons why you should avoid this:

    • My highschool math teacher used to say a mathematician should be as lazy as possible. This goes even more for a programmer. You should always write as few code as possible.
    • Chances are you will want to change this code later on. Maybe you'll want to display your tooltips as a marquee in an oval window. At that moment, you will want to change your code at exactly one place.

    Extending MFC

    This sample only contains a very small piece of code. You might wonder if it is worth the effort of making a general base class and deriving from it. However, you can put other stuff in this class later on, and all your dialogs will get the new stuff for free. This is a general principle that should be adhered to. When deriving a class from an MFC class, you should always create a middle class like this one. Everything that is general goes in the base class, everything that is application specific goes in the derived one. The result: When you are finished creating an application, you will have your own extension library to MFC. All functionality is there to be used in a new application.

    Putting strings in the resource file

    This may not be clear to Americans, but Europeans know all about it: you should put all your strings in a resource file. Microsoft has warned us often enough. Why? Because one day or another, people start asking if they can get a French, German,... version of your software. It might happen to you to, once your application is starting to get known all over the world.

    Making thing go automatically

    The spirit of MFC is making things go automatically. All kinds of terrible macros are invented to make the framework usable by wizards and all kinds of resources are loaded without you knowing it. As an example, tool tips for toolbars ae automatically loaded. This does not always enhance the readability of the MFC source, but it does make life easier for programmers. When extending MFC (or simply using it), you should follow the same principles. This is why the resource strings have the same ID as the controls. You should always try to find tricks like this. It can even sometimes be useful to create new macros that fit in the message maps or other maps.

    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here


    Written By
    Web Developer
    Belgium Belgium
    Henk studied computer science at the University of Ghent, specializing in theoretical computer science.
    He is now working for Artwork Systems, Belgium, and Whirling Dervishes Software, Belgium.
    Henk knows a little something about networking, graphics, object-oriented design, AI, embedded systems. He knows most of the PDF specs by heart.
    Henk developed NSELib, the NameSpace Extension Library.
    You can find his latest freeware software at regxplor.com. It contains a namespace extension that puts the registry in Windows Explorer. The newest commercial project is Alpha ZIP, an explorer-embedded ZIP file utility.

    Comments and Discussions

     
    QuestionLicense terms Pin
    Member 1289173821-Feb-19 2:38
    Member 1289173821-Feb-19 2:38 
    GeneralIt's flicker when add a edit ctrl Pin
    adintr13-Aug-08 21:33
    adintr13-Aug-08 21:33 
    Questionhow to make the gui moveable Pin
    lokchan23-Dec-05 21:28
    lokchan23-Dec-05 21:28 
    GeneralTool Tip Appearance Time Pin
    Marty1020304019-Sep-03 6:10
    Marty1020304019-Sep-03 6:10 
    QuestionRe: Tool Tip Appearance Time Pin
    Sergi Díaz1-Feb-06 1:03
    Sergi Díaz1-Feb-06 1:03 
    GeneralTooltips for formview Pin
    Anonymous26-Nov-02 1:05
    Anonymous26-Nov-02 1:05 
    GeneralBetter way Pin
    KarstenK13-Nov-02 20:49
    mveKarstenK13-Nov-02 20:49 
    GeneralRe: Better way Pin
    Anonymous27-Sep-04 2:41
    Anonymous27-Sep-04 2:41 
    Generalcombobox tooltips Pin
    Ravig26-Sep-02 4:42
    Ravig26-Sep-02 4:42 
    GeneralNice Work.. Pin
    Koshy Panicker John12-May-02 7:24
    Koshy Panicker John12-May-02 7:24 
    Questioncan I use this in my PropertyPage? Pin
    23-Mar-02 17:48
    suss23-Mar-02 17:48 
    Questionhow to change tooltip fonts and styles Pin
    5-Mar-01 18:34
    suss5-Mar-01 18:34 
    AnswerRe: how to change tooltip fonts and styles Pin
    Henk Devos5-Mar-01 21:58
    Henk Devos5-Mar-01 21:58 
    QuestionModeless Dialog ??? Pin
    Andrei Borenstein25-Oct-00 6:09
    sussAndrei Borenstein25-Oct-00 6:09 
    AnswerRe: Modeless Dialog ??? Pin
    10-Apr-01 23:23
    suss10-Apr-01 23:23 
    AnswerRe: Modeless Dialog ??? Pin
    Ed The C28-Apr-03 11:54
    Ed The C28-Apr-03 11:54 
    GeneralRe: Modeless Dialog ??? Pin
    Marty1020304018-Sep-03 10:52
    Marty1020304018-Sep-03 10:52 
    GeneralRe: Modeless Dialog ??? Pin
    User 404115-Aug-05 2:09
    User 404115-Aug-05 2:09 
    GeneralRe: Modeless Dialog ??? Pin
    pei-vvictoria4-Dec-06 15:48
    pei-vvictoria4-Dec-06 15:48 
    Generalnice work fella. Pin
    Alastair Taylor25-Jul-00 11:17
    Alastair Taylor25-Jul-00 11:17 
    GeneralEuropean Language DLL's Pin
    Anonymous7-Jun-00 13:42
    Anonymous7-Jun-00 13:42 
    GeneralRe: European Language DLL's Pin
    6-Mar-02 0:39
    suss6-Mar-02 0:39 
    GeneralRe: European Language DLL's Pin
    David Pritchard22-Jul-03 5:46
    David Pritchard22-Jul-03 5:46 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.