# VBForums CodeBank > CodeBank - Visual Basic 6 and earlier >  Create Custom ToolTips using API

## Wokawidget

This thread will grow over the next few days.

The idea of this thread is a tutorial on how to create your own custom tooltips since the standard tooltip is pretty limited...it doesn't even allow for multiline text.

Each project added to this thread will have more functionality than the previous project.

This will build up to a full blown graphical custom tool tip demo with features such as multiline text, icons, shading and graphical styles.

Woka

----------


## Wokawidget

This example merely creates tooltips using API for controls on a form at runtime.

Features:
Add ToolTipRemove ToolTipChange ToolTip Text

Woka

----------


## Wokawidget

Instead of letting windows create and draw the tooltip, we subclass the tooltip window and trap for the WM_PAINT message. When this arrives we create our own drawing area, and manually draw text and graphics to make up the tooltip.

New features:
ToolTip can now display multiline strings.

Woka

----------


## Wokawidget

BallonColor and Text color properties have now been added to the ToolTip class. When we manually draw the tooltip we can specify the colors to be used.

New features:
BalloonColorTextColor

Woka

----------


## kleinma

this is really cool.. how is it regarding performance? 

1 suggestion.. since you create a collection of tooltips.. perhaps you could create a global settings object... where you could set everything but the text and maybe optional icon of the tooltip and that would be applied to ALL tooltips added to project, this would save the user from having to call their own sub to set the properties for each tool tip, maybe a class called Defaults that is in mobjTips so if they dont set a property it uses the default one they specified? just an idea...

----------


## Wokawidget

I have thought about this, and my initial code worked lie this.
But I wanted to set one of them to red, as it was an important one...and I couldn't.

There is nothing wrong with doing:

VB Code:
Option Explicit
 Private mobjTips As ToolTips
 Private Sub Form_Load()
DIm objTip As ToolTip
   Set mobjTips = New ToolTips
   Set objTip = mobjTips.Add(Command1, "Woof woof")
   FormatTip pobjTip
End Sub
 Private Sub FormatTip(ByRef pobjTip As ToolTip)
   With pobjTip
      .Bold = True
      .BalloonColor = RGB(34,65,123)
   End With
End Sub

Woof

----------


## Wokawidget

Right, if you have downloaded Stage 2 and Stage 3, and looked at the code, you will notice that the manual drawing of the tooltip is quite "messy"...Lots of constants flying about, not to mention all those evil API commands.
If things stay like this, and we keep adding to the drawing code then sooner or later it will become so much of a mess that it will be very hard to add to it easily.
This can be solved by creating a new class, clsDraw. This wraps up all this horrible API code and just has some simple methods exposed so that the drawing is made way easier.

No new features have been implemented at this stage.

Woka

----------


## Wokawidget

As suggested by kleinma I have added the ability to create styles.
The project now as 3 new classes:
ToolTipStyleTextStyleBalloonStyle
The class ToolTipStyle holds references to the TextStyle and BalloonStyle classes.
So, for example, to get the TextColor we now do:

VB Code:
Dim objStyle As ToolTipStyle
   Set objStyle = New ToolTipStyle
   MsgBox objStyle.TextStyle.Color
   Set objStyle = Nothing
The reason I have written it like this is because over the next few days we are going to add many many properties to the project that allows you to change the appearance of the ToolTip, some related to text, some related to the balloon.
Since these properties are for different things I thought I'd create a class to hold them. This makes things slightly easier in the long run. I admitt it's a little overkill for the color properties we have now, but you will soon see the benefits of this structure.

New features:
Ability to create and set styles to individual tooltips

Woka

----------


## Wokawidget

I have added a few properties for both the balloon style and text style.
The balloon can now have rounded corners. The level of rounding can be set by the property CurveIndex in the BalloonStyle class. If CurveIndex is 0 then a square balloon is drawn. By default this is set to 7.

Margin properties have been added to the text style class. This allows you to specify the gap between the edge of the balloon and the text. All 4 margins, Top, Bottom, Left and Right, are available to change by the user. By default ALL margins are set to 5.

New Feautures:
Add rounded corners to balloonSpecify margin gaps to position the text in the balloon

Regards,

Woka

----------


## Wokawidget

A new class has been added, Shadow. This holds properties related to a shadow, ie X and Y offsets, color and whether it's visible or not.
The shadow class is used by the text style class and the balloon style class.
You'll notice that while drawing the tooltip, there is a little bit more work to be done to work out the position of grafix that are drawn to the screen. This is the only really messy thing that we have to do now, but it's unavoidable.

New Features:
Balloon ShadowsText Shadows

Woka

----------


## Wokawidget

At this stage I have added font attributes to the TextStyle class.
These are used when drawing text onto our tooltip.

New Features:
Font TypeFont SizeBoldItalicUnderline

We now have a fully functional method of creating custom tooltips.
We can create nice tips, like the one I like in this example (not sure about the bold though), or we can create evil tips that look crap, like the 2 buttons in the middle.
It's all about what properties you set.
if you don't create a style then the default style is used. This is demonstrated by the 1st button of the form.

We could leave it at this...but an icon would be nice don't you think?
The next stage will have the ability to add an icon to the tooltip.

Woka

----------


## Wokawidget

I am a fool.
Here's the Stage 6 code... :Smilie: 

Woka

----------


## Wokawidget

The ballon class now has a new property, Image.
An image can be set by using:

VB Code:
objTip.Style.BalloonStyle.Image = Image1.Picture
If a background image is specified then this overrides the background color.

I have also changed the demo app.
This now incorporates a listview and allows you to set tooltips for individual listitems, and for the listview itself if no item is selected.

New Features:
Ability to add a background image to the tooltip

Woka

----------


## Wokawidget

I am not sure if this would be a widely used feature, but I added it in because I could, and because I have just fixed a bug in the drawing code  :Smilie: 
The bug was in the clsDraw class. I was creating the HDC, setting it's background to Transparent, and then moving it to the desired position. This caused a few pixels to be out of place in the top right hand corner of the tool tip.
The clsDraw class has been changed so that it moves the window 1st, then starts the painting on the hDC.
This bug is in all previous versions posted here. To rectify this you can download the zip attached to this post and add the clsDarw class to previous versions. Then in the drawtooltip sub, in modDrawToolTip, the old code was:

VB Code:
With objDraw
   .Start pobjTip.hWnd     
   .GetTextSize pobjTip.Text, lngTxtWidth, lngTxtHeight
   .Move udtPT.x + CURSOR_OFFSET_X, udtPT.y + CURSOR_OFFSET_Y, lngTxtWidth + (2 * TEXT_OFFSET_X), lngTxtHeight + (2 * TEXT_OFFSET_Y)
   'blah blah blah
This needs to be changing to:

VB Code:
With objDraw
   .hWnd =  pobjTip.hWnd     
   .GetTextSize pobjTip.Text, lngTxtWidth, lngTxtHeight
   .Move udtPT.x + CURSOR_OFFSET_X, udtPT.y + CURSOR_OFFSET_Y, lngTxtWidth + (2 * TEXT_OFFSET_X), lngTxtHeight + (2 * TEXT_OFFSET_Y)
   .StartPainting
   'blah blah blah
It's not a huge major bug, but more of annoying ich  :Frown: 

Anyways, to add sound when displaying a tooltip use the WavFile property on the Style class:

VB Code:
ObjTip.Style.WavFile = "C:\Woof.wav"

New Features:
Play asynchronous sound when displaying tooltip

Woka

----------


## vbNeo

This seriously kicks *ss, good work!

----------


## Wokawidget

Cheers  :Smilie: 

Any features you can think of that I have missed out?

Am working on adding an icon to the tooltip. This is easy, but I am bogged down with work, so bear with me  :Frown: 

Woka

----------


## manavo11

Good stuff  :Thumb:  Take your time  :Alien Frog:

----------


## i00

good job - the shadows etc r buggie when not compilled on mine

----------


## Steve Etter

This is really good stuff, Wokawidget.  Very nice work.   :Thumb:  

One other feature I could use is being able to set the location of the ToolTip balloon.  I found where the cursor position is controlled by the two constants CURSOR_OFFSET_X and CURSOR_OFFSET_Y in the modDrawToolTip module, but that is about as far I have been able to get.

What can we do to make these two constants into variables and make them accessable?

----------


## laatkeur

Is it possible to add controls in the balloon tooltip ?  Like adding a WithEvents button or a linklabel ?

----------


## Wokawidget

in europe travelling. In saltzburg, austria at the moment.
will be back in 5 days. will be able to help zou then.
sorry for the delay.

Woooof

----------


## Wokawidget

> Is it possible to add controls in the balloon tooltip ?  Like adding a WithEvents button or a linklabel ?


Sorry for the late reply.

Not easily no  :Frown: 
The tooltip is drawn using API commands, and therefore the controls would have to be created at runtime using API too.

It is perfectly possible, and there is many examples of creating controls using API out there. But it's very complicated and very fiddley  :Frown: 

Not only would you have to be good at general vb6 stuff to achieve this, but your knowledge of API would have to be quite high too.

Woka

----------


## Divot

Hi Woka,

Thanks for writing such an excellent component!   :big yellow:  

One question for you - do you know of any limitations of this control running on Win2000? At this stage, it looks like it doesn't work ...

----------


## Wokawidget

Cheers  :Smilie: 

Doesn't work?
Why? Does the screen turn purple?

Woka

----------


## Divot

> Cheers 
> 
> Doesn't work?
> Why? Does the screen turn purple?
> 
> Woka


Sorry for the late reply ... I had forgotten about this post ...

No, nothing like a CTD (crash to desktop), the control works fine on XP, but on 2000 machines, nothing appears at all. It is very strange. While I have discovered this on my own program, I have not yet tested it on a 2000 machine using your samples. I will do so and let you know...

----------


## Sticker

Hey Woka,

I have done some further testing based upon Divot's comments. 

Before I proceed, I would also like to thank you for developing the multiline code.

I have tested the code downloaded from this thread under windows 2000 and no tooltips appear at all during normal running.

I have also tested another application (that has tooltip code integrated) under windows 2000 - with the same result of no tooltip showing.

When the code from both applications is tested under XP it works without a problem.

Further information:
I had noticed when testing under windows 2000, if the screensaver activates and the mouse is moved to recover the screen, the tooltip does appear briefly as the application window is redrawn. But then vanishes, not to be seen until returning from a mouse move after the screensaver loads again. (During normal operation of the applications under windows 2000 there are no multiline tooltips displayed.)

(I have made sure that in each instance of testing, that the mouse is over the multiline active segment of the application.)

Thanks again for the work you have put into this!

----------


## zeek840

Thats fantastic work. I was wondering if you were planning to do .Net version?

----------


## Wokawidget

Cheers. I have always always intended to write .NET code for all my apps in my sig. But with my new job and moving house etc I haven't had time over the last 6 months.
I know it's lazy of me, I should realy get it done.

The dll does work in .NET though.

Woka

----------


## shirazamod

Thanks for the great stuff, woka!

----------


## Nisei

This works quite well!

Couple of observations:

Can't add tips to certain objects. I'm guessing it's those objects that do not have a ToolTip property (e.g., menus, shapes).

StatusBar panels have a ToolTip property seperate from the statusbar itself. However this does not work:


VB Code:
mobjTips.Add StatusBar1.Panels(1), "This is panel 1."

My workaround was this:


VB Code:
Private Sub StatusBar1_MouseMove(Button As Integer, Shift As Integer, _
                                 x As Single, y As Single)
  With StatusBar1
    If x >= .Panels(1).Left And _
       x <= (.Panels(1).Left + .Panels(1).Width) Then
      mobjTips.Item(StatusBar1).Text = "Pointing to panel 1"
    ElseIf x >= .Panels(2).Left And _
           x <= (.Panels(2).Left + .Panels(2).Width) Then
      mobjTips.Item(StatusBar1).Text = "Pointing to panel 2"
    Else
      mobjTips.Item(StatusBar1).Text = "Status Bar"
    End If
  End With
End Sub

If someone has suggestions to a better way to the above, I welcome them.

Regards.   :wave:

----------


## Wokawidget

nope. this is the same for a listview too, like in my demo.

 :Frown: 

Woof

----------


## Eugenious

This code is awesome but It doesn't seem to work with Control indexes. I keep getting this message:

This Key is already associated with an element of this collection

Any Ideas how to make this work

----------


## Wokawidget

ths is because it uses the control name for a key, and the control name is the same for all controls in an array. U need to modify the code to change the key it's saving in the collection when adding a tooltip to a control.

Woka

----------


## Eugenious

I notice when I'm testing my project (in evironment mode) and the program initiates one of the tool tip text options, whenever I End the project from the standard toolbar that my project disappears and I have to re-load the project - any ideas?.

Thanks

----------


## Wokawidget

Yes. NEVER end a program that is subclassing  :Big Grin: 
It will crash the VB IDE.

Always close the program down gracefully.

WOof

----------


## rajeshkpat

Wokawidget,you've done a fantastic job by posting the codes for creating custom tooltip.You effort is worthy of the highest praise.It's because of such greatness that developer's forums have become all the more popular.
     I hate downloading codings sans thanking the author,wherever it's possible.

----------


## Wokawidget

Thanks. Glad you like it  :Big Grin: 

Woof

----------


## maj3091

Hi,

I came across this thread in a search for multi-line tooltips. Firstly I'd like to say what a useful feature this is to have, but I have one small problem. I wanted to use it to added tooltips to image controls to replace the tooltip feature of the image. It seems the image control doesn't have and hWnd property associated with it.

Is there a way to get around this?

Thanks in advance.

Mark

----------


## Wokawidget

You could use a picture box....bad I know, but it's an option.

I also think there is some way of getting the hWnd to an image control, but cannot remember how. Do a search on google.

Or you could try something like:

http://www.developerfusion.co.uk/show/3890/

Woof

----------


## maj3091

Thanks for the reply.

I'd like to keep to the image control as I'm overlaying them on a picturebox and like the transparancy that I can get with (mmmm - thinking now, haven't tried a picturebox with that, but I beleive PictureBoxes are more resource hungry and I need to display quite a lot at one time).

I've been having a look at getting the Hwnd to the image, but no joy as yet. If you do remember I'd appreciate you posting back. I'll do the same if I find it.

Thanks again.


[EDIT]
Found a quick get around for now based on the idea of Nisei above. As my image controls are placed in a PictureBox container, I can create a single ToolTip object for the picture box with out any text as this seems to keep it hidden.

When I move my mouse over one of the images I set my ToolTip text to what I want for that image. When I move it back over the Picturebox I set the text back to "".


VB Code:
Private Sub imgTruck_MouseMove(Index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single)
     mobjTips.Item(pic1).Text = imgTruck(Index).Tag
 End Sub
  Private Sub pic1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
     mobjTips.Item(pic1).Text = ""
 End Sub


Maybe not the most elegant but it seems to work quite well.

----------


## rama_ssn

Hello,

I need your help on using the tooltip, for a Combo. In the sense when the Mouse moves over each of the ListItems in the Combo, a respective TootTip must trigger. 

Say A,B,C are the listItems, then on mouseOver, a respective Tooltip needs to be displayed.

I guess as the Combo does not have a MouseOver event, will it be possible to establish this using some APIs.

Can you tell me on how to do this?

Thanks & Regards

Ramasubramanian Radhakkrishnan

----------


## Wokawidget

You need to subclass the combo and then trap for the event that if fired when moving the mouse over the items. I am afraid I don't know what the exact windows msg is that you would have to handle.

If you look in the tooltips project there is a module called modMsgHook. This is used to subclass the tooptip window. This can also be used to subclass the combo box.

You can only set opne tooltip for each control, so once you handle the moveover event you need to change the entire tooltip for the combo. An example of this is shown in the demo app using the listview control...as the mouse moves over each listitem the listviews tooltip gets changed.

Hope this helps.

Woka

----------


## Lord Orwell

Just a thought, but any chance of adding code for clickable links in the tooltip?

----------


## Wokawidget

That is perfectly possibe, however, I have not developed in VB6 for 2-3 years now and I have stopped maintaining and adding features to my VB6 source codes.
Feel free to give it a go yourself.

Woka

----------


## nepalbinod

Hi,

I am using your code in my software and it is working 100% fine.  But I would be really grateful if it will be applicable on the following conditions:

Is is possible to show tooltips on controls (having .text property) without mouse intervention. If I come straight to the point, can the tips be shown on control_change() event or control_gotfocus() event.

----------


## Wokawidget

Yes. Just trap the msg in the message handler class and call the draw tooltip function.

Woka

----------


## nepalbinod

> Yes. Just trap the msg in the message handler class and call the draw tooltip function.
> 
> Woka


Could you just show me how to handle the events cos' I have no idea. It would be thankful if you show both ways:

1.  TextBox_Change()
2.  TextBox_GotFocus()

----------


## nUflAvOrS

> ths is because it uses the control name for a key, and the control name is the same for all controls in an array. U need to modify the code to change the key it's saving in the collection when adding a tooltip to a control.
> 
> Woka


Hi Woka ,

 Thanks your work of this, Can you guide me how to save the control array to the collection ?

Thanks woka :-)

----------


## Wokawidget

I dont have a machine with VB6 on it I am afraid, so can't test this.
But in the function that adds the control to the collection it uses the controls name as the key.
You need to modify that 1 line of code so that it:

a) Tests if the control is part of an arry
b) If so then get index of control and add that to the control name to get your unique key
c) You need to modify the code where it gets the control tooltip from the array in the same manner. it needs the index adding to the name.

Woka

----------


## nUflAvOrS

Thanks woka,

I will try your suggested method.. 




NuFLaVoRs

----------


## nbj622

Anyone know how to get the tooltip to work with a LABEL.  It seems to work with most other controls...

----------


## Wokawidget

This is because the code requires the control to have a handle, hWnd, which a label simply does not have.

You will need to create your own label usercontrol that has a hWnd property. This is simply a limitation of a VB6 label, nothing really you can do about it.

Do a search on google for this code.

Woka

----------


## drag0n_45

Anyone know how to only bold a part of the text you want in the tooltip and not all of it?

----------


## fenrisW0lf

I have tried this tooltip out and it works great. However, I ran into a problem if the tooltip is set on a button and the button launches a form. The tooltip doesn't appear for that button anymore.

In the "Stage 10" code, if you add an empty form and paste this code into one of the buttons click events:



```
Dim f As Form1
Set f = New Form1

f.Show vbModal

Set f = Nothing
```

If you hover over the button before clicking, the tip shows up. After clicking and dismissing the form it doesn't show up any more. Any ideas?

Thanks...

----------


## Wokawidget

> Anyone know how to only bold a part of the text you want in the tooltip and not all of it?


This would be a lot more complex to handle...off the top of my head you could pass in text like: "This is <b>MY</b> tooltip", and then in the code that writes the message you would have to validate your text and write different bits out with different formatting.

The code does not handle this natively as it stands now.

Woka

----------


## Wokawidget

> I have tried this tooltip out and it works great. However, I ran into a problem if the tooltip is set on a button and the button launches a form. The tooltip doesn't appear for that button anymore.
> 
> In the "Stage 10" code, if you add an empty form and paste this code into one of the buttons click events:
> 
> 
> 
> ```
> Dim f As Form1
> Set f = New Form1
> ...


This is because you used vbModal.
This locks the Form1 as the top most form in a windows app. The form below it does not receive mouse events.
I do not have VB6 installed on this PC anymore, but from what I can remember even a normal default vb6 tooltip would fail on this.

Woka

Try using vbModeless instead.

----------


## zounds

I found this thread very helpful and the code supplied here works perfectly, except one thing... From version 2 it doesn't work with non-English text... I try to print something in Greek and it doesn't work... Only the first version displays Greek correctly... 
Anyone has an idea?

PS I know this is a very old thread and i probably won't get an answer...

----------


## jpskiller

this is good but does not support labels, has anyone modified it or knows of one similar that does labels as well

----------

