Click here to Skip to main content
Click here to Skip to main content

A ToolTip with Title, Multiline Contents, and Image

By , 3 Aug 2010
 
Prize winner in Competition "Best VB.NET article of August 2010"
Custom tooltip using title, text, and image.

alltooltip.PNG

Custom tooltip using text only.

contentonlytooltip.PNG

Custom tooltip using title only.

titleonlytooltip.PNG

Custom tooltip using image only.

imageonlytooltip.PNG

Introduction

There are several ways to show additional information about a control, including ToolTip. When we used standard ToolTip, the tooltip is shown as a rectangular window with text inside, and often the tooltip covers the main object and it will interfere with our work, unless you call Show method of the tooltip and provide its relative position from the main object. The main issue is that the tooltip is always a rectangular box, except if the IsBallon property of the tooltip is set to true, but still we can't create a tooltip that has a custom shape. So, I need a tooltip that can display provided title, content, image, and avoid the area of main object by default, can be shown either relative location from the main object, or absolute location on the screen, and can be created using custom shape.

Features

This tooltip will provides ToolTip, ToolTipTitle, and ToolTipImage properties to each Control and ToolStripItem available. By default, this tooltip will be shown as a rounded corner rectangle, contains provided property (tooltip (as main content), title, and image), avoiding the area of the main object, show a little shadow on the right and bottom side, and uses fade effect.

Provided properties by this ToolTip.

providedproperties.PNG

Below are several custom properties of this tooltip:

  • AnimationSpeed property, to determine the fade effect takes time, in milliseconds.
  • AutoClose property, determine the length of the time tooltip will be displayed. This property is used when the EnableAutoClose property is set to True.
  • EnableAutoClose property, if True, the tooltip will be automatically closed when a period of time provided by AutoClose property is passed, otherwise, the tooltip will be closed when MouseLeave or MouseDown event have occurred.
  • Location property, determine how the tooltip will be located.
  • CustomLocation property, custom location where the tool tip will be displayed, used when the Location property is set to CustomScreen or CustomClient.
  • OwnerDraw property, if true, the tooltip's surface will be drawn by your code, Popup and Draw events will be raised, otherwise, the tooltip surface will be drawn itself.
  • OwnerDrawBackground property, if true, both background and surface of the tooltip will be drawn by your code, Popup, DrawBackground, and Draw events will be raised, otherwise, the tooltip background will be drawn itself.

ToolTip Properties

tooltipproperties.PNG

ToolTipLocation enumeration, this is the value of the Location property.

  • Auto, the tooltip location is automatically calculated in an appropriate location and avoiding the main object area.
  • MousePointer, the tooltip will be located around the mouse pointer.
  • CustomScreen, the tooltip will be located in specified location provided by CustomLocation property on the screen.
  • CustomClient, the tooltip will be located in specified location provided by CustomLocation property relative to the client area of the main object.

How Does It Work

To show a tooltip window, I create a window inherited from Form. This window has WS_EX_LAYERED on it extended window style.

' This is how to create a layered window.
Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
	Get
		Dim cp As CreateParams = MyBase.CreateParams
		cp.ExStyle = cp.ExStyle Or WS_EX_LAYERED
		Return cp
	End Get
End Property

After the window has been created, I use ShowWindow and SetWindowPos functions to display the window.

' Prevent window to activate itself.
ShowWindow(Me.Handle, SW_NOACTIVATE)
' Show window at the top most location.
SetWindowPos(Me.Handle, HWND_TOPMOST, Me.Left, Me.Top, Me.Width, Me.Height, _
	SWP_NOSIZE Or SWP_NOMOVE Or SWP_NOACTIVATE)

After the window has been created and displayed, now to draw the window. I use a bitmap as a canvas to draw the tooltip, and draw the bitmap to the screen on the window bounds.

Private Sub setBitmap(ByVal aBmp As Bitmap)
	Dim screenDC As IntPtr = GetDC(IntPtr.Zero)
	Dim memDC As IntPtr = CreateCompatibleDC(screenDC)
	Dim hBitmap As IntPtr = IntPtr.Zero
	Dim oldBitmap As IntPtr = IntPtr.Zero
	Try
		hBitmap = aBmp.GetHbitmap(Color.FromArgb(0))
		oldBitmap = SelectObject(memDC, hBitmap)

		Dim size As Size = New Size(aBmp.Width, aBmp.Height)
		Dim pointSource As Point = New Point(0, 0)
		Dim topPos As Point = New Point(Me.Left, Me.Top)
		Dim blend As BLENDFUNCTION = New BLENDFUNCTION
		blend.BlendOp = AC_SRC_OVER
		blend.BlendFlags = 0
		blend.SourceConstantAlpha = 255
		blend.AlphaFormat = AC_SRC_ALPHA
		UpdateLayeredWindow(Me.Handle, screenDC, topPos, _
			size, memDC, pointSource, 0, blend, ULW_ALPHA)
	Catch ex As Exception
	Finally
		ReleaseDC(IntPtr.Zero, screenDC)
		If hBitmap <> IntPtr.Zero Then
			SelectObject(memDC, oldBitmap)
			DeleteObject(hBitmap)
		End If
		DeleteDC(memDC)
	End Try
End Sub

Creating Custom Shaped ToolTip

If you want to create a custom shaped ToolTip, you need to set OwnerDrawBackground property of the tooltip to True, and then, handle the Popup, Draw, and DrawBackground event raised by ToolTip.

' Assumes you have created a ToolTip object named ToolTip1
' This event fired when the tooltip needs to draw its surface.
' Called when the OwnerDraw or OwnerDrawBackground property is set to true.
Private Sub ToolTip1_Draw(ByVal sender As Object, ByVal e As Ai.Control.DrawEventArgs) _
	Handles ToolTip1.Draw
	Dim strFormat As StringFormat = New StringFormat
	strFormat.LineAlignment = StringAlignment.Center
	strFormat.Alignment = StringAlignment.Center
	e.Graphics.DrawString("This is when OwnerDrawnBackground of _
	the ToolTip is set to True", Me.Font, Brushes.Black, e.Rectangle, strFormat)
End Sub
' This event fired when the tooltip needs to draw its background.
' Called only when OwnerDrawBackground property is set to true.
Private Sub ToolTip1_DrawBackground(ByVal sender As Object, _
	ByVal e As Ai.Control.DrawEventArgs) Handles ToolTip1.DrawBackground
	e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
	e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
	e.Graphics.FillEllipse(Brushes.White, e.Rectangle)
	e.Graphics.DrawEllipse(Pens.Black, e.Rectangle)
End Sub
' This event fired before tooltip is displayed, mainly to provide the tooltip's size.
' Called when the OwnerDraw or OwnerDrawBackground property is set to true.
Private Sub ToolTip1_Popup(ByVal sender As Object, _
	ByVal e As Ai.Control.PopupEventArgs) Handles ToolTip1.Popup
	e.Size = New Size(100, 100)
End Sub

This code will produce a ToolTip like this:

Custom shaped tooltip by setting OwnerDrawBackground property of the ToolTip to True.

ownerdrawbackground.PNG

History

  • 3rd August, 2010: Initial post

License

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

About the Author

red_moon
Software Developer (Senior) Ai Software
Indonesia Indonesia
Member
Keep moving ...
Learn the different ...
Get the advantages ...
 
And ... knowing everything ...

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberPolinia17 May '13 - 2:01 
To greats.....
QuestionNo AutomaticDelay? really?memberpitoloko9 Jan '13 - 19:52 
The tooltip appears instantly when mousehover,
 
I think that property is one of the most important.
 
please someone can fix it by adding the AutomaticDelay property updating the source?
QuestionRight to Left Tooltipmemberhackerspk8 Nov '12 - 21:10 
Great Code, but i wonder if there is any option for RightToLeft Languages like Arabic with text and image draw from right to left.
AnswerRe: Right to Left Tooltipmembertweber201217 Dec '12 - 22:05 
Yes, that would be really important.
Thank you very much!!!
BugDoesn't appear on first mouseover event [modified]memberBarbara Crane30 Aug '12 - 12:58 
My beta testers like the tooltips, but are puzzled, and I am concerned, that they do NOT appear on the first mouseover/mouseenter/hover event for a control. You can hover as long as you like; they won't appear.
 
Mouse away from the control, and then back in, and the tooltip appears promptly. This feels like a bug. Any suggestions?
 
Thanks in advance.
Barbara Crane
Auction Systems
www.auctionsystems.com
Fundraising Auction Software


modified 5 Sep '12 - 20:08.

Questiontanyamemberdiar raid22 Aug '12 - 16:12 
mas, saya sudah coba code di atas, tapi masih bingung nih.. karena saya masih awam.
sudah coba download sourcenya tapi ga bisa running di vb 2010 Frown | :(
mungkin mas nyabisa kasih tutor lebih rinci untuk di gunakan di vb 2010.
terima kasih.
AnswerRe: tanyamemberred_moon25 Aug '12 - 20:27 
Wah, maaf, saya harus coba dulu di vb 2010.
Untuk lebih lanjutnya, lebih baik anda kirim email langsung ke ashari_mail@yahoo.com, atau via YM di alamat yg sama.
It's easy to laugh, but, it's so hard to smile ...

BugLove this, two minor bugsmemberBarbara Crane10 Aug '12 - 7:12 
First, I LOVE this control; it does almost everything I was hoping to find in a tooltip.
 
I have run into a characteristic that i would like to resolve. When the tooltip is extremely short, it displays perfectly. As the tooltip content length increases, the drawn box is less accurate in size. It clips the bottom edge of the contents in some cases. Our selected font is Segoe UI. On OUR controls we set this to bold as our clients appreciate the clarity, but we are not setting this on the tooltip.
 
I am not expert in owner draw functions. i can probably come up with a hack to increase the length a little bit, but would welcome any pointers to a better way to manage the length.
 
Second, when a tooltip exists for a datagrid, the tooltip is displayed above the grid, starting at the top edge, rather than near the cursor. Is this something we could modify?
 
Thanks in advance for any help, and thanks SO much for a great control.
Barbara Crane
Auction Systems
www.auctionsystems.com
Fundraising Auction Software

GeneralRe: Love this, two minor bugsmemberred_moon10 Aug '12 - 22:18 
The first issue is came up with string measurement, the string is wider when rendered with AntiAliasGridFit.
 
The second issue is the purpose of this tooltip, to not covers the control's area, thus, the tooltip is positioned above, below, left, or right the control. For such complex control, use show(System.Windows.Forms.Control control, Rectangle rect) function.
 
I'll try a lot more experience with string measurement, and I hope I can find a better solution in the future.
It's easy to laugh, but, it's so hard to smile ...

GeneralRe: Love this, two minor bugsmemberBarbara Crane11 Aug '12 - 6:18 
Thank you for responding so promptly.
 
Right now, I've added a tweak to handle the height; so far it works for my tooltips:
    tooltipSize.Height = CInt(1.08 * tooltipSize.Height)
right after line 128 of the tooltip class. Since there are three different SHOW routines with different overloads, I need to add this to the other two SHOW routines as well. The extra height is relatively inconspicuous for short tooltips, and handles the longer ones reasonably well.
 
As I studied your code, I understood the positioning on the grid control better, and will try your suggestion. Thanks again for your prompt response.
Barbara Crane
Auction Systems
www.auctionsystems.com
Fundraising Auction Software

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

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 4 Aug 2010
Article Copyright 2010 by red_moon
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid