Click here to Skip to main content
15,867,308 members
Articles / Programming Languages / Visual Basic

Text Cursor (xCursor)

Rate me:
Please Sign up or sign in to vote.
4.72/5 (22 votes)
7 Jan 2009CPOL4 min read 66.6K   2.6K   63   13
A semi-transparent cursor that displays text based on property settings
mockup of the xCursor in action

Introduction

I've had to build an application that displays contact information in an expandable Tree control. My users can grab the Contact from that Tree and drag it to several locations on various forms. Instead of having the same-ole-same-ole *yawn* dragdrop cursor, I thought it would be kind of cool to mimick the Firefox browser's drag cursor...

Those of you that use the Firefox Internet Browser have almost certainly at one time or another selected a chunk of text and dragged it to another location on the screen... If you have not, try it and check out the Drag Cursor: It's an exact duplicate of the text you selected and goes from slightly faded in the middle to completely transparent at the edges. That's exactly what the xCursor is: A semi-transparent cursor that displays text based on property settings.

So, like all developers with just enough knowledge to be dangerous, I started digging around on the internet to see if anyone's already got this bad-boy out there. Nope. Then I started to see if anyone had anything similar I could learn from. Nope. So finally I started to look to see if *anyone* had *anything* that utilized a custom cursor and bingo! A whopping 5 articles on CodeProject.com: C++, C++, C++, C# and C# - and here's me: a VB.NET developer... Surely I can take one of the C# articles and convert it? C# and VB.NET are (more or less) identical right? Normally, I would agree with that last statement but for this - and from here forward, I will have to say NO!

What was the problem you might be asking yourselves right about now? I'll tell ya: The WinAPI calls that generate custom cursors are expecting not the graphics object - but a POINTER to the graphics object and guess what the Rocket Scientists at Microsoft forgot to give VB.NET developers?? That's right: pointers.

Knowing what I do about VB.NET, I was certain there was a way to pull this off and sure enough, there is: It's called Marshalling... So with my newly discovered Marshalling information and a nice article by Alexander Bekrenev, I was able to pull it off. Thanks Alex!

Background

The xCursor and demo application were written in VB.NET (VS 2005) and for those of you out there who insist C# is the only way to go... I also have a C# version available upon request.

Using the Cursor

Just add a reference to xCursor.dll into your project and you're all set.

xCursor has the following seven properties:

  • CursorText: This is the text to be displayed as a cursor. Multi lined cursors are supported but you have to create the line breaks in the text.
  • Font: The font to use for the xCursor
  • Fade: If True, the text will fade to transparent along the edge
    *NOTE* Textcolor will be IGNORED if Fade=True
  • TextColor: The color of the text used in the cursor
  • TextTransparency: 0-255 where 0=100% transparent and 255= solid.
    *NOTE* because of how the cursor is created, all transparencies will have a blueish tint. I am searching for way to prevent this - any thoughts or help would be greatly appreciated!
  • GoodDrop: This is used to tell the cursor if its currently over a good or no-drop location - or to not draw an icon at all.
  • Shrinkage: If you are dragging a large chunk of text, you might want to reduce the size of the font used in the cursor: This property tells the cursor how much to reduce the size by.

Using the Cursor

Using the cursor can be as simple as this:

VB.NET
Dim myCursor As TextCursor.xCursor = New TextCursor.xCursor
myCursor.CursorText = "This is a test cursor"
Me.Cursor = myCursor.GetCursor

But as many of you know, setting up and using a custom cursor for Drag/Drop operations requires a little more work:

VB.NET
Private _Dragging As Boolean		' Indicates that Dragging has begun
Private _DragSource As Integer = 0		' The source of the drag

' Here's my custom cursor
Private myCursor As TextCursor.xCursor = New TextCursor.xCursor

''' <summary>
''' Begin our Dragging - setup a few cursor properties
''' </summary>
Private Sub DragLabel_MouseDown(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.MouseEventArgs) Handles DragLabel.MouseDown
	_Dragging = True

	myCursor.Shrinkage = 1
	myCursor.Fade = True
	myCursor.Font = DragLabel.Font
	myCursor.CursorText = DragLabel.Text

End Sub

''' <summary>
''' If dragging has begun, fire off the dragdrop and stuff the Object
''' </summary>
Private Sub DragLabel_MouseMove(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.MouseEventArgs) Handles DragLabel.MouseMove
	If _Dragging Then
		_DragSource = 1
		DragLabel.DoDragDrop(DragLabel.Text, DragDropEffects.Copy)
	End If
	_Dragging = False
End Sub

''' <summary>
''' If you don't do this, you'll get the standard "You can't drop here" cursor
''' </summary>
Private Sub DragLabel_DragOver(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.DragEventArgs) Handles DragLabel.DragOver
	If e.Data.GetDataPresent(DataFormats.StringFormat) Then
		e.Effect = DragDropEffects.None
	End If
End Sub

''' <summary>
''' This bad boy is DragDrop UI's Golden Child.  
''' This will fire during the dragging operation
''' (once the DoDragDrop method has been started) and allow you to trap while dragging
'''
''' In the case of this Demo - I'm checking to see if we have a valid drop location:
''' we'll have both an effect AND a true Copy condition set.
''' </summary>
Private Sub DragLabel_GiveFeedback(ByVal sender As Object, _
  ByVal e As System.Windows.Forms.GiveFeedbackEventArgs) Handles DragLabel.GiveFeedback
	e.UseDefaultCursors = False
	If ((e.Effect And DragDropEffects.Copy) = DragDropEffects.Copy) Then
		myCursor.GoodDrop = TextCursors.xCursor.DropValid.GoodDrop
		Cursor.Current = myCursor.GetCursor
	Else
		myCursor.GoodDrop = TextCursors.xCursor.DropValid.BadDrop
		Cursor.Current = myCursor.GetCursor
	End If
End Sub

''' <summary>
''' Let the ap know we're over a good drop location
''' Share that knowledge with the User by changing our Drag Cursor and 
''' alter the drop control's bg color
''' </summary>
Private Sub DropLabel_DragOver(ByVal sender As Object, _
	ByVal e As System.Windows.Forms.DragEventArgs) Handles DropLabel.DragOver
	If e.Data.GetDataPresent(DataFormats.StringFormat) Then
		e.Effect = DragDropEffects.Copy
	End If
End Sub

''' <summary>
''' Perform the drop - if anyone knows a more intelligent way to determine 
''' WHERE the drag CAME FROM
''' I would love to hear about it!
''' </summary>
Private Sub DropLabel_DragDrop(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.DragEventArgs) Handles DropLabel.DragDrop
	If (e.Data.GetDataPresent(GetType(System.String))) Then
		Dim item As Object = CType(e.Data.GetData(GetType(System.String)), _
								System.Object)
		If _DragSource = 2 Then
			DropLabel.Font = AnotherDrag.Font
		Else
			DropLabel.Font = DragLabel.Font
		End If
		DropLabel.Text = item.ToString
	End If
End Sub

The key is the GiveFeedback method. This method allows you to evaluate whether or not your cursor is over a valid drop location and even gives you a chance to make sure that the location is valid for the specific item being dragged.

You may also notice that I am trapping the DragOver of the DRAG SOURCE and not just the Drag Destination. That's because I want to give feedback to the cursor that I'm over a "No Drop" location so I'll get my custom cursor and not the defaults, windows no-drop cursor.

Interesting...?

There are a pair of GIF images added to the cursor as resources. You could conceivably add your own good/no drop image properties and pass them to the cursor, or just replace the ones I made with your own.

Acknowledgements

I'd like to thank Alexander Bekrenev for his article showing how to create a custom cursor. Thanks again, Alex.

History

  • 12/23/2008: Control is introduced to CodeProject
  • 1/5/2009: Added C# source code

License

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


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionC# Code missing some properties available in the VB.Net version Pin
Tim8w8-Apr-22 6:41
Tim8w8-Apr-22 6:41 
QuestionCursor Missing, only Text as Cursor Pin
kassipopassi12-Nov-12 2:05
kassipopassi12-Nov-12 2:05 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey16-Feb-12 23:49
professionalManoj Kumar Choubey16-Feb-12 23:49 
GeneralTake care of memory leaks! Pin
RS1980_20-Jan-09 4:06
RS1980_20-Jan-09 4:06 
GeneralRe: Take care of memory leaks! Pin
Elkay20-Jan-09 5:36
Elkay20-Jan-09 5:36 
GeneralRe: Take care of memory leaks! Pin
Elkay5-Feb-09 4:45
Elkay5-Feb-09 4:45 
GeneralPlease send C# version Pin
cp200804283-Jan-09 7:18
cp200804283-Jan-09 7:18 
GeneralRe: Please send C# version Pin
Elkay4-Jan-09 10:24
Elkay4-Jan-09 10:24 
GeneralRe: Please send C# version Pin
Elkay7-Jan-09 6:18
Elkay7-Jan-09 6:18 
I submitted the article changes that include the (limited) C# source but I'm not certain how long it'll take for the actual article to be updated.

I'll check again in a few days and if its still not displaying the download link, I'll bring it to the attention of the Codeproject folks.
General[Message Deleted] Pin
NormDroid7-Jan-09 21:26
professionalNormDroid7-Jan-09 21:26 
GeneralRe: Please send C# version Pin
Elkay8-Jan-09 5:24
Elkay8-Jan-09 5:24 
General[Message Deleted] Pin
NormDroid8-Jan-09 20:45
professionalNormDroid8-Jan-09 20:45 
GeneralRe: Please send C# version Pin
Elkay9-Jan-09 6:44
Elkay9-Jan-09 6:44 

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.