Controlling where text is dropped in a textbox

robertb_NZ

Well-known member
Joined
May 11, 2010
Messages
146
Location
Auckland, New Zealand
Programming Experience
10+
I am trying to implement a drag-and-drop into a textbox, where the text is dropped into the cursor position.

For testing I have pre-filled my textbox (called "txtScreen") with data and set its font to a fixed-pitch font (Consolas), so that it starts out looking like this: -
00....*....1....*....2....*....3....*....4....*....5....*....6....*....7....*....8
01....*....1....*....2....*....3....*....4....*....5....*....6....*....7....*....8
02....*....1....*....2....*....3....*....4....*....5....*....6....*....7....*....8
03....*....1....*....2....*....3....*....4....*....5....*....6....*....7....*....8
04....*....1....*....2....*....3....*....4....*....5....*....6....*....7....*....8
05....*....1....*....2....*....3....*....4....*....5....*....6....*....7....*....8
06....*....1....*....2....*....3....*....4....*....5....*....6....*....7....*....8
07....*....1....*....2....*....3....*....4....*....5....*....6....*....7....*....8
08....*....1....*....2....*....3....*....4....*....5....*....6....*....7....*....8
09....*....1....*....2....*....3....*....4....*....5....*....6....*....7....*....8
10....*....1....*....2....*....3....*....4....*....5....*....6....*....7....*....8

I have a treeview elsewhere in the window. I drag an entry from the treeview and drop it somewhere, say line 02, character "1" (=position 12 on this line). If the text passed across is "xxxx", then I want line 2 to become
02....*....xxxx.*....2....*....3....*....4....*....5....*....6....*....7....*....8
But the "xxxx" is going somewhere else.

Here is my code that is handling the DragDrop: -

Private Sub txtScreen_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles txtScreen.DragDrop
' Paste the text.
Dim DropPoint As Point
Dim Linenbr, CharIndex As Integer
DropPoint = New Point(e.X, e.Y)
Debug.Print(DropPoint.X & ", " & DropPoint.Y)

CharIndex = txtScreen.GetCharIndexFromPosition(DropPoint)
Linenbr = txtScreen.GetLineFromCharIndex(CharIndex)
Debug.Print("CharIndex:" & CharIndex & ", LineNbr:" & Linenbr)

Mid(txtScreen.Text, CharIndex, Len(e.Data.GetData(DataFormats.Text))) = e.Data.GetData(DataFormats.Text)
End Sub

The Debug.print diagnostics show
614, 276
CharIndex:2099, LineNbr:24

No matter what the values of DropPoint, in this series of tests CharIndex is always 2099 and LineNbr = 24. Other tests have given different results, but none have been correct. The actual text dropped is correct, it's just dropped in the wrong position.

I assume that I'm making a dumb mistake with
CharIndex = txtScreen.GetCharIndexFromPosition(DropPoint)

Can somebody tell me what I'm doing wrong?

Thank you, Robert
 
As it clearly states in the documentation (which you should have read so you should know) the X and Y properties of the DragEventArgs class are in screen coordinates, NOT relative to the control you're dropping on. As such, you must call that control's PointToClient method to convert the screen coordinates to client coordinates. The rest of your code should work once you do that.
 
Thank you very much. I added
DropPoint = txtScreen.PointToClient(DropPoint)
to my code, and everything worked perfectly. For the benefit of any later readers, here is my full code without diagnostics: -
Private Sub txtScreen_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles txtScreen.DragDrop
    ' Paste the text.
    Dim DropPoint As Point
    Dim Linenbr, CharIndex As Integer
    DropPoint = New Point(e.X, e.Y)
    DropPoint = txtScreen.PointToClient(DropPoint)
    CharIndex = txtScreen.GetCharIndexFromPosition(DropPoint)
    Mid(txtScreen.Text, CharIndex, Len(e.Data.GetData(DataFormats.Text))) = e.Data.GetData(DataFormats.Text)
End Sub

Where is this documentation I'm supposed to have read? I searched the web for tutorials on using drag and drop, I read several before doing this, but nothing I read mentioned anything about PointToClient.

BTW, how do I flag this post as answered? In the ASP.NET forums (where I've spent most of my time so far) there is a button "Mark as answer".
 
Last edited by a moderator:
Where is this documentation I'm supposed to have read?
Um, the same place the documentation is for many thousands of other Windows apps: under the Help menu.
I searched the web for tutorials on using drag and drop, I read several before doing this, but nothing I read mentioned anything about PointToClient.
That's not necessarily a surprise because it has nothing specific to do with drag'n'drop. Even the documentation I mentioned would not have pointed you to that method specifically. Waht it would have told you is that what you were getting in the event handler are screen coordinates and then you would have known that you needed to find a way to get those coordinates relative to the TextBox. That search may well have led you to the PointToClient method or, if not, you could have asked that question specifically. Either way, you would not have wasted time with code that you thought should work but was doomed from the start. That's why you should always read the documentation for new types and members but especially when things don't work as you expect.
BTW, how do I flag this post as answered? In the ASP.NET forums (where I've spent most of my time so far) there is a button "Mark as answer".
You can edit your first post and change the prefix to "Answered" from whatever it was originally, which should be "Question" if you're asking a question.
 
Back
Top