CToolTipDialog class : a simple WTL class to enable tooltips in your dialogs
CToolTipDialog class : a simple WTL class to enable tooltips in your dialogs
Introduction
I am working on a WTL application with many dialogs, so I searched for some code implementing tooltips in dialogs in a straightforward way. I found much interesting code, but nothing was really what I needed, so I wrote this simple class which fits nearly all my needs. Hopefully it will fit yours.
Using the code
Before anything else
Before using the code you must include atlctrls.h and ToolTipDialog.h in your VC project. The best place to insert the code is the end of your stdafx.h file, otherwise you have to add it in each of your (existing and future) dialog file headers.
//
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
...
...
#include <span class="code-keyword"><atlctrls.h></span>
#include <span class="code-string">"ToolTipDialog.h"</span>
By the way if you want to use the nice balloon style, you must set the correct version of _WIN32_IE
at the beginning of stdafx.h. The WTL Appwizard defaults it to 0x0400
and you would compile without this style.
//
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#define _WIN32_IE 0x0500
Very simple usage
This is what you will find in the sample About Dialog.
In any CDialogImpl
derived class, for instance a CAboutDlg
generated by appwizard or any existing CDialogImpl<MyDialog>
of yours, do the following:
- Add
CToolTipDialog<CMyDialog>
to the inheritance list// class CAboutDlg : public CDialogImpl<CAboutDlg>, public CToolTipDialog<CAboutDlg> {
- Add
CHAIN_MSG_MAP(CToolTipDialog<CMyDialog>)
on top of your dialog message map.// BEGIN_MSG_MAP(CAboutDlg) CHAIN_MSG_MAP(CToolTipDialog<CAboutDlg>)
You are nearly done.
From now, in the dialog initialization, a CToolTipCtrl
will be created and all the dialog controls with an ID not equal to IDC_STATIC
will get - if it exists in the string table - the string with same ID as tooltip. If there is no such string, you will have to use TTSetTxt
(see later).
It is likely that most of your About dialog controls are static and have IDC_STATIC
ID, so you may need to change their ID and create their tooltip string.
Go to the Dialog Editor, select the About dialog, select the application icon, go to properties, give the icon control a particular ID, say IDC_APPICON
, and don't forget to check the notify property on. Same for the static text, let's call it IDC_APPTEXT
.
Go to the string table editor and create the initial tooltip strings for the controls. This is what you can find in the sample and paste into your string table editor:
IDC_APPICON This is the Application Icon
IDC_APPTEXT This is the Application Copyright and Version
At last create a string table entry for the whole dialog with your dialog IDD_xxx
:
IDD_ABOUTBOX This About Dialog is displaying information tips on itself
You are done. Build and enjoy.
Simple usage
This is what you will find in the sample Main Dialog.
As your dialog inherits from CToolTipDialog
you can :
- Activate or deactivate the ToolTip Control:
void TTActivate( BOOL bActivate )
- Set the ToolTip width:
void TTSize( int nPixel )
- Set a control or the whole dialog Tooltip text
- by ID:
void TTSetTxt( UINT idTool, _U_STRINGorID text )
- by
HWND
:void TTSetTxt( HWND hTool, _U_STRINGorID text )
- by ID:
Both TTSetTxt
methods will accept a resource ID or a LPTSTR
as second parameter. You should use the HWND
when you have a member for the control and for the whole dialog: it has no ID.
Here is the code in the sample which makes use of these methods :
LRESULT CMainDlg::OnBnClickedActivate(WORD /*wNotifyCode*/,
WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
TTActivate( IsDlgButtonChecked( wID ));
return 0;
}
LRESULT CMainDlg::OnEnChangeEditTt(WORD /*wNotifyCode*/,
WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
...
TTSetTxt( m_hWnd , txt );
...
}
LRESULT CMainDlg::OnNMReleasedcaptureSizeTt(int idCtrl,
LPNMHDR /*pNMHDR*/, BOOL& /*bHandled*/
{
TTSize( 4 * SendDlgItemMessage(idCtrl,TBM_GETPOS,0,0));
return 0;
}
Advanced usage
The GetTT()
member will return a reference to the CToolTipCtrl
(or other, see later) through which you can perform any operation.
For instance:
//
...
CToolTipCtrl & rTT=GetTT();
rTT.SetDelayTime( TTDT_AUTOPOP, 10000 )// set the show delay to 10 seconds
...
If you want to change the initial style of the ToolTip Control
you may change it in your dialog class constructor. Construct the ToolTip with different parameters, but remember that TTF_SUBCLASS
is what makes it work. The constructor is:
CToolTipDialog::CToolTipDialog( UINT uTTSTyle= TTS_NOPREFIX | TTS_BALLOON , UINT uToolFlags = TTF_IDISHWND | TTF_SUBCLASS )
If you dynamically add controls
you can associate them a tooltip with:
BOOL TTAdd( HWND hTool )
orBOOL TTAdd( UINT idTool )
Both will create the tooltip and assign it the string of same control ID if it exists. They return TRUE
on success, FALSE
on failure.
If you dynamically remove controls
prudently use:
void TTRemove( HWND hTool )
orvoid TTRemove( UINT idTool )
before deletion.
For any window with controls or children
which is not a dialog or property page, you will have to explicitly call void TTInit()
. If you want a default ToolTip string, your class must have an IDD
member (as dialog classes): simply insert in the class declaration
enum { IDD = IDD_MYWINDOW };
and put the relevant string in the string table.
Very advanced usage
You can use your own ToolTip class, simply declare it through the second template parameter:
//
class CMyDlg : public CDialogImpl<CMyDlg>,
public CToolTipDialog<CMyDlg, CMyToolTip>
{
The GetTT()
member will then return a reference to the CMyToolTip
. You will not have to derive from CToolTipDialog
if your tooltip control members expose the same signature, for instance if CMyToolTip
is derived from CToolTipCtrl
.