Click here to Skip to main content
15,861,168 members
Articles / Programming Languages / C#
Article

Building a BallonToolTip provider in C#

Rate me:
Please Sign up or sign in to vote.
5.00/5 (11 votes)
3 Mar 2004CPOL4 min read 116.4K   2.1K   46   21
Shows how to create a ToolTip provider that supports Balloon Tooltips, including issues related to creating extender properties and using the NativeWindow class.

Sample Image - BallonTipExample.jpg

Introduction

The System.Windows.Forms namespace includes a built-in class for displaying tooltips on a control. However, this ToolTip control does not support creating the cute balloon tooltips that are available with IE 3.0 and above. This class provides a managed wrapper for the Win32 Tooltip common control that supports displaying Balloon Tool Tips.

Using the Control

The control provides functionality exactly like the current ToolTip provider that ships with .NET. To use it on a form or control, you simply drag an instance of the control onto the form from the Visual Studio .Net toolbox. Once added, each control on the form will have a new ToolTip property that you can set for the particular object. Visual Studio will automatically add the needed code to hook the control's tooltip to the BallonToolTip provider.

API

The API consists of the same properties and methods as the standard ToolTip class that the .NET Framework provides. Each instance of the BallonToolTip class can support tool tips for several controls. To set the tooltip for a control, you use the SetToolTip method:

C#
public void SetToolTip(Control control, string tooltip)

Similarly, to retrieve the tooltip for a given control, use the GetToolTip method:

C#
public string GetToolTip(Control control)

Designer Support

Like the ToolTip class, the BallonToolTip class includes support for setting tooltips at design time. Adding this support for any property is relatively easy. First, the class must derive from System.ComponentModel.Component. Second, the class must be decorated with ProvideProperty attribute and implement the IExtenderProvider interface. The ProvideProperty attribute provides the designer with the name and type of the property that should be added to any control that the IExtenderProvider.CanExtend method returns true for. These two elements work together to support providing a ToolTip property for each control on a form. The BallonToolTip class is declared as follows:

C#
[ProvideProperty("ToolTip", typeof(Control))]

public class BallonToolTip : Component, IExtenderProvider

There are a few tricks to using the ProviderProperty attribute. For one, the class it is added to must provide both GetX and SetX methods, where X is the name of the property passed to the ProvideProperty attribute. Also, your GetX method should be decorated with a DefaultValue attribute to reduce the amount of code the designer has to create. In the case of the BallonToolTip provider, the GetToolTip method is decorated as follows:

C#
[DefaultValue("")]
public string GetToolTip(Control control)

Annoyingly, when SetToolTip is called from the InitializeComponent method of the class the tooltip is present on, the controls may not yet have handles. To handle this case, the BallonToolTip control hooks the HandleCreate event of the Control base class when any control is passed to SetToolTip. When this event fires, the tooltip provider automatically updates the underlying Win32 tooltip window with the information for the newly created control. For completeness, the SetToolTip method also hooks the HandleDestroyed event to delete the native tooltips when a control is destroyed (in a typical form, this is not really an issue, since the control will be destroyed more or less at the same time as the provider).

Using the NativeWindow class

A little known class in the System.Windows.Forms namespace is the NativeWindow class. This class' one and only goal is to provide a managed wrapper around the Win32 CreateWindowEx function. In the BallonToolTip method, I have created a derived NativeWindow class (NativeTooltipWindow) that provides a few useful wrappers around this class. For example, NativeTooltipWindow builds the CreateParams structure used to create the native ToolTip provider without input from outside classes. This way, knowledge about how to create the window is enclosed in the class that actually does the creation (see the source code for additional comments and information).

Supporting Win9X

When sending messages to the underlying Win32 Tooltip window, some messages are required to send different values based on whether we are running on a Windows 9x machine (which uses ASCII based text) versus a NT based system (which uses Unicode). During the construction of the class, we set up the readonly ints to make dealing with this difference easier in the code:

C#
private const int TTM_ADDTOOLA = 1028;
private const int TTM_ADDTOOLW = 1074;
private const int TTM_UPDATETIPTEXTA = 1036;
private const int TTM_UPDATETIPTEXTW = 1081;
private const int TTM_DELTOOLA = 1029;
private const int TTM_DELTOOLW = 1075;

private readonly int TTM_ADDTOOL;
private readonly int TTM_UPDATETIPTEXT;
private readonly int TTM_DELTOOL;

/// <SUMMARY>
/// Initializes a new instance of the
/// <SEE cref="ToolTipLibrary.BallonToolTip" /> class.
/// </SUMMARY>
public BallonToolTip()
{    
    m_controls = new Hashtable();
    m_active = true;
    m_showAlways = false;

    //Create a new native window.
    m_window = new NativeTooltipWindow();

    if (Marshal.SystemDefaultCharSize == 1)
    {
        //Win9x machines
        TTM_ADDTOOL = TTM_ADDTOOLA;
        TTM_UPDATETIPTEXT = TTM_UPDATETIPTEXTA;
        TTM_DELTOOL = TTM_DELTOOLA;
    }
    else
    {
        //WinNT machines
        TTM_ADDTOOL = TTM_ADDTOOLW;
        TTM_UPDATETIPTEXT = TTM_UPDATETIPTEXTW;
        TTM_DELTOOL = TTM_DELTOOLW;
    }

    InitializeComponent();
}

In the code, we never use the constants above. Instead, we always reference the readonly member variables to ensure we are sending the right message for the platform.

Changes

3/4/2004 - Fixed a bug in the CreateHandle method to create the tooltip handle when it does not exist.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
I've been a software engineer since 1999. I tend to focus on C# and .NET technologies when possible.

Comments and Discussions

 
Generalfind which control is shown Pin
hamid_m7-Aug-07 4:25
hamid_m7-Aug-07 4:25 
GeneralHELP C# :Button User control and Tooltip Pin
crazychris6420-Jul-07 3:40
crazychris6420-Jul-07 3:40 
Questionhelp me plz Pin
mr nasr6-Feb-07 21:50
mr nasr6-Feb-07 21:50 
GeneralUsing in commercial application Pin
escristian18-Sep-06 5:32
escristian18-Sep-06 5:32 
GeneralRe: Using in commercial application Pin
wilsone818-Sep-06 9:38
wilsone818-Sep-06 9:38 
Generaldoesn't work on .NET 2.0 Pin
SLoW_Ru28-Feb-06 20:01
SLoW_Ru28-Feb-06 20:01 
GeneralRe: doesn't work on .NET 2.0 Pin
wilsone87-Mar-06 9:18
wilsone87-Mar-06 9:18 
GeneralIcon and Title Pin
asgerb27-Sep-05 2:42
asgerb27-Sep-05 2:42 
Jokemultiline support Pin
Jeff J Anderson30-Aug-05 11:27
Jeff J Anderson30-Aug-05 11:27 
GeneralRe: multiline support Pin
Seishin#7-Nov-06 0:44
Seishin#7-Nov-06 0:44 
QuestionBut can you make them go away? Pin
sam898837823-Jun-05 10:10
sam898837823-Jun-05 10:10 
AnswerRe: But can you make them go away? Pin
wilsone87-Mar-06 10:44
wilsone87-Mar-06 10:44 
GeneralRe: But can you make them go away? Pin
sam89883789-Mar-06 8:40
sam89883789-Mar-06 8:40 
QuestionMultiline? Pin
BigAndy8-Jun-05 5:55
BigAndy8-Jun-05 5:55 
GeneralMultiLine Pin
phongta20-Nov-04 3:17
phongta20-Nov-04 3:17 
GeneralBefore displaying the ToolTip Pin
masontwo2-Sep-04 11:37
masontwo2-Sep-04 11:37 
Generallittle error Pin
nadia.giusti3-Mar-04 0:25
nadia.giusti3-Mar-04 0:25 
GeneralRe: little error Pin
wilsone84-Mar-04 11:05
wilsone84-Mar-04 11:05 
Questionwhat's WrOng ? Pin
Just Greeky Creek27-Feb-04 2:28
Just Greeky Creek27-Feb-04 2:28 
AnswerRe: what's WrOng ? Pin
wilsone84-Mar-04 11:05
wilsone84-Mar-04 11:05 
Generalany sample project Pin
THMok27-Feb-04 1:17
THMok27-Feb-04 1:17 

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.