|
|
|
Sometimes you might need to find out the closest character index in textbox/richtextbox from your mouse position. If you are doing drag n drop text and you want to drop it at a specified location in the textbox based on your current mouse position then you will surely need this code. This simple code will show you the following techniques.
- How to get the closest character in the textbox from mouse coordinates. - How to create a custom carate and show at a specified character location in textbox - How to get/set caret default blink time.
Step-By-Step Example
- Create a windows application project - Add one textbox on the form1, set multiline=true and scrollbar=both - Add the following code in form code section (after form class declaration) |
Click here to copy the following block | Imports System.Runtime.InteropServices
Public Class Form1 Inherits System.Windows.Forms.Form
Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" ( _ ByVal hwnd As IntPtr, _ ByVal wMsg As Integer, _ ByVal wParam As Integer, _ ByVal lParam As Integer) As Integer
Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" ( _ ByVal hwnd As IntPtr, _ ByVal wMsg As Integer, _ ByVal wParam As Integer, _ ByVal lParam As IntPtr) As Integer
Public Const EM_LINEINDEX = &HBB Public Const EM_POSFROMCHAR = &HD6 Friend WithEvents GroupBox1 As System.Windows.Forms.GroupBox Friend WithEvents TextBox1 As System.Windows.Forms.RichTextBox Public Const EM_CHARFROMPOS = &HD7
Public Declare Function CreateCaret Lib "user32" ( _ ByVal hWnd As Integer, _ ByVal hBitmap As Integer, _ ByVal nWidth As Integer, _ ByVal nHeight As Integer) As Integer
Public Declare Function ShowCaret Lib "user32" ( _ ByVal hWnd As Integer) As Integer
Public Declare Function SetCaretBlinkTime Lib "user32" ( _ ByVal wMSeconds As Integer) As Integer Public Declare Function GetCaretBlinkTime Lib "user32" () As Integer
Public Structure POINTAPI Public X As Integer Public Y As Integer End Structure
Function GetCharFromPos(ByVal txt As TextBoxBase, ByVal pt As Point) As Integer
Dim xy As Integer = (pt.X And &HFFFF) + ((pt.Y And &HFFFF) << 16) Dim res As Integer If TypeOf (txt) Is RichTextBox Then Dim p As POINTAPI p.X = pt.X p.Y = pt.Y Dim lp As IntPtr = IntPtr.Zero lp = Marshal.AllocCoTaskMem(Marshal.SizeOf(p)) Marshal.StructureToPtr(p, lp, False) res = SendMessage(txt.Handle, EM_CHARFROMPOS, 0, lp) Marshal.FreeCoTaskMem(lp) Else res = SendMessage(txt.Handle, EM_CHARFROMPOS, 0, xy) End If
Dim lineNumber As Integer = ((res And &HFFFF) >> 16) Dim charIndex As Integer = (res And &HFFFF)
Dim lineStartIndex As Integer = SendMessage(txt.Handle, EM_LINEINDEX, lineNumber, 0)
Return lineStartIndex + charIndex End Function
Sub ShowCustomCaret(ByVal ctl As Windows.Forms.Control, _ Optional ByVal width As Integer = 3, _ Optional ByVal height As Integer = 16, _ Optional ByVal CaretBlinkTimeinMs As Integer = 400)
On Error Resume Next With ctl CreateCaret(.Handle.ToInt32, 0, width, height) ShowCaret(.Handle.ToInt32)
Debug.Write("Current blinktime : " & GetCaretBlinkTime) SetCaretBlinkTime(CaretBlinkTimeinMs) End With End Sub
Private Sub TextBox1_GotFocus(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles TextBox1.GotFocus
ShowCustomCaret(sender, 3, 16) End Sub Private Sub TextBox2_GotFocus(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles TextBox2.GotFocus
ShowCustomCaret(sender, 3, 16) End Sub Private Sub TextBox1_MouseMove(ByVal sender As Object, _ ByVal e As System.Windows.Forms.MouseEventArgs) Handles TextBox1.MouseMove
Try Dim pt As Point Dim ret As Integer pt = New Point(e.X, e.Y)
ret = GetCharFromPos(TextBox1, pt) TextBox1.Select(ret, 0) Me.Text = "Character Pos at (Y=" & pt.X & ",Y=" & pt.Y & ") is [" & ret & "]" Catch ex As Exception
End Try
End Sub
Private Sub TextBox2_MouseMove(ByVal sender As Object, _ ByVal e As System.Windows.Forms.MouseEventArgs) Handles TextBox2.MouseMove
Try Dim pt As Point Dim ret As Integer pt = New Point(e.X, e.Y)
ret = GetCharFromPos(TextBox2, pt) TextBox2.Select(ret, 0) Me.Text = "Character Pos at (Y=" & pt.X & ",Y=" & pt.Y & ") is [" & ret & "]" Catch ex As Exception End Try
End Sub
#Region " Windows Form Designer generated code "
Public Sub New() MyBase.New()
InitializeComponent()
End Sub
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then If Not (components Is Nothing) Then components.Dispose() End If End If MyBase.Dispose(disposing) End Sub
Private components As System.ComponentModel.IContainer
Friend WithEvents TextBox2 As System.Windows.Forms.TextBox Friend WithEvents Label1 As System.Windows.Forms.Label <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(Form1)) Me.TextBox2 = New System.Windows.Forms.TextBox Me.Label1 = New System.Windows.Forms.Label Me.GroupBox1 = New System.Windows.Forms.GroupBox Me.TextBox1 = New System.Windows.Forms.RichTextBox Me.GroupBox1.SuspendLayout() Me.SuspendLayout() Me.TextBox2.Font = New System.Drawing.Font("Courier New", 9.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) Me.TextBox2.Location = New System.Drawing.Point(6, 19) Me.TextBox2.Multiline = True Me.TextBox2.Name = "TextBox2" Me.TextBox2.ScrollBars = System.Windows.Forms.ScrollBars.Both Me.TextBox2.Size = New System.Drawing.Size(309, 159) Me.TextBox2.TabIndex = 1 Me.TextBox2.Text = resources.GetString("TextBox2.Text") Me.TextBox2.WordWrap = False Me.Label1.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) Me.Label1.ForeColor = System.Drawing.Color.Blue Me.Label1.Location = New System.Drawing.Point(8, 200) Me.Label1.Name = "Label1" Me.Label1.Size = New System.Drawing.Size(336, 40) Me.Label1.TabIndex = 4 Me.Label1.Text = "Click on the textbox and then try to move mouse over the textbox to find the clos" & _ "est character position " Me.GroupBox1.Controls.Add(Me.TextBox2) Me.GroupBox1.Location = New System.Drawing.Point(11, 13) Me.GroupBox1.Name = "GroupBox1" Me.GroupBox1.Size = New System.Drawing.Size(321, 184) Me.GroupBox1.TabIndex = 5 Me.GroupBox1.TabStop = False Me.GroupBox1.Text = "GroupBox1" Me.TextBox1.Location = New System.Drawing.Point(360, 32) Me.TextBox1.Name = "TextBox1" Me.TextBox1.Size = New System.Drawing.Size(327, 165) Me.TextBox1.TabIndex = 6 Me.TextBox1.Text = resources.GetString("TextBox1.Text") Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13) Me.ClientSize = New System.Drawing.Size(713, 237) Me.Controls.Add(Me.TextBox1) Me.Controls.Add(Me.GroupBox1) Me.Controls.Add(Me.Label1) Me.Name = "Form1" Me.Text = "Form1" Me.GroupBox1.ResumeLayout(False) Me.GroupBox1.PerformLayout() Me.ResumeLayout(False)
End Sub
#End Region End Class |
|
|
|
Submitted By :
Nayan Patel
(Member Since : 5/26/2004 12:23:06 PM)
|
|
|
Job Description :
He is the moderator of this site and currently working as an independent consultant. He works with VB.net/ASP.net, SQL Server and other MS technologies. He is MCSD.net, MCDBA and MCSE. In his free time he likes to watch funny movies and doing oil painting. |
View all (893) submissions by this author
(Birth Date : 7/14/1981 ) |
|
|