Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

Hi guys...

I need some help here translating an API call from VB6 to .net...

 

The use of this is to be able to know the cursor position on a RichTextBox.

 

The VB6 code looks like this:

Option Explicit

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Const EM_LINEFROMCHAR = &HC9
Private Const EM_LINEINDEX = &HBB
Private Const EM_GETSEL = &HB0

Private Declare Function SendMessageReferenceParams Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByRef wParam As Long, ByRef lParam As Long) As Long

Private Sub CheckPosition()
Dim start_pos As Long
Dim end_pos As Long
Dim row As Long
Dim col As Long

   SendMessageReferenceParams _
       Text1.hwnd, EM_GETSEL, start_pos, end_pos

   row = SendMessage(Text1.hwnd, EM_LINEFROMCHAR, start_pos, 0) + 1
   col = start_pos - SendMessage(Text1.hwnd, EM_LINEINDEX, -1, 0) + 1

   lblPosition.Caption = "(" & Format$(row) & ", " & Format$(col) & ")"
End Sub

Private Sub Form_Resize()
Dim hgt As Single

   hgt = ScaleHeight - lblPosition.Height
   If hgt < 120 Then hgt = 120
   Text1.Move 0, 0, ScaleWidth, hgt
   lblPosition.Move 0, hgt, ScaleWidth
End Sub

 

I really can't port this stuff to vb.net...

 

Thanks!

 

Alex :p

Software bugs are impossible to detect by anybody except the end user.
Posted

Get the column and row position from a RichTextBox

 

Hi Alex! With this code you can retrive a column number from a specific line from a text opened in a RichTextBox. This is like the "oldie" MS-DOS "Edit.exe" where you could see in what row and in what column you were from your selected character.

 

[font=Courier New]    <DllImport("User32.dll", CharSet:=CharSet.Auto, Entrypoint:="SendMessage")> _
   Private Shared Function SendMessageReferenceParams(ByVal hwnd As IntPtr, ByVal wMsg As Int32, _
       ByRef wparam As Int32, ByRef lparam As Int32) As Int32
   End Function

   <DllImport("User32.dll", CharSet:=CharSet.Auto, Entrypoint:="SendMessage")> _
   Private Shared Function SendMessageLong(ByVal hwnd As IntPtr, ByVal wMsg As Int32, _
       ByVal wparam As Int32, ByVal lparam As Int32) As Int32
   End Function

   Private Const EM_LINEFROMCHAR = &HC9
   Private Const EM_LINEINDEX = &HBB
   Private Const EM_GETSEL = &HB0


   Private Function CheckPosition() as String
       Dim start_pos As Integer
       Dim end_pos As Integer
       Dim row As Integer
       Dim col As Integer
       Dim result as String

       SendMessageReferenceParams(myRichTextBox.Handle, EM_GETSEL, start_pos, end_pos)

       row = SendMessageLong(myRichTextBox.Handle, EM_LINEFROMCHAR, start_pos, 0) + 1
       col = start_pos - SendMessageLong(myRichTextBox.Handle, EM_LINEINDEX, -1, 0) + 1

      result = "(" & Format$(row) & ", " & Format$(col) & ")"

      Return result
   End Sub[/font]

 

I hope this will help you ;)

  • 3 months later...
Posted

The .Net way

 

although the above works its not the .net way:) you lose portability plus your making calls to unmanaged code on the other hand her is a nice snippet you can use, just inherit a richtextbox and add the following

 

   
   Private Const EM_LINELENGTH = &HC1
   Private Const EM_GETLINE = &HC4
   Private Const EM_GETLINECOUNT = &HBA
   Private Const EM_LINEFROMCHAR = &HC9
   Private Const EM_LINEINDEX = &HBB
   Private Const EM_GETFIRSTVISIBLELINE = &HCE
   Private Const EM_LINESCROLL = &HB6
   Private Const EM_POSFROMCHAR = &HD6
   Private Const EM_GETSEL = &HB0
   Private Const EM_SETSEL = &HB1
   Private Const EM_CANUNDO = &HC6
   Private Const EM_SETTEXTEX = (WM_USER + 97)
   Private Const EM_GETTEXTEX = (WM_USER + 94)
   Private Const EM_GETSELTEXT = (WM_USER + 62)
   Private Const EM_REPLACESEL = &HC2
   Private Const EM_STREAMOUT = (WM_USER + 74)
   Private Const EM_STREAMIN = (WM_USER + 73)
   Private Const EM_SCROLLCARET = &HB7
   Private Const EM_FINDTEXTEX = (WM_USER + 79)
   Private Const EM_CHARFROMPOS = &HD7
   Private Const EM_GETRECT = &HB2
   Private Const EM_SETRECT = &HB3



   Public Function GetLine(ByVal charindex As Integer) As Integer
       Dim m As Message = Message.Create(Me.Handle, EM_LINEFROMCHAR, New IntPtr(charindex), New IntPtr(0))
       MyBase.WndProc(m)
       Return m.Result.ToInt32
   End Function

   Public Function GetLineStart(ByVal line As Integer) As Integer
       Dim m As Message = Message.Create(Me.Handle, EM_LINEINDEX, New IntPtr(line), New IntPtr(0))
       MyBase.WndProc(m)
       Return m.Result.ToInt32
   End Function

   Public Function GetLineLength(ByVal line As Integer) As Integer
       Dim m As Message = Message.Create(Me.Handle, EM_LINELENGTH, New IntPtr(line), New IntPtr(0))
       MyBase.WndProc(m)
       Return m.Result.ToInt32
   End Function

   Public Function GetLineCount() As Integer
       Dim m As Message = Message.Create(Me.Handle, EM_GETLINECOUNT, New IntPtr(0), New IntPtr(0))
       MyBase.WndProc(m)
       Return m.Result.ToInt32
   End Function

   Public Function GetCurrentLineStart() As Integer
       Dim m As Message = Message.Create(Me.Handle, EM_LINEINDEX, New IntPtr(-1), New IntPtr(0))
       MyBase.WndProc(m)
       Return m.Result.ToInt32
   End Function

   Public Function GetCurrentLine() As Integer
       Dim m As Message = Message.Create(Me.Handle, EM_LINEFROMCHAR, New IntPtr(-1), New IntPtr(0))
       MyBase.WndProc(m)
       Return m.Result.ToInt32
   End Function

   Public Function GetFirstVisibleLine() As Integer
       Dim m As Message = Message.Create(Me.Handle, EM_GETFIRSTVISIBLELINE, New IntPtr(0), New IntPtr(0))
       MyBase.WndProc(m)
       Return m.Result.ToInt32
   End Function

   Public Function GetLastVisibleLine() As Integer
       Return Me.GetLine(Me.GetCharIndexFromPosition(New Point(0, Me.Height - iHortBorderWidth)))
   End Function


 

 

i know some of the above are duplicated from what it already has for example getlinefromcharindex, but do a performance test on mine vs the control its 4-5 times faster go figure....

 

-Xposure

  • 5 months later...
Posted

EM_GETLINE messsage id problem

 

Hi

The code snippet provided is working fine but i am not able to do use the EM_GETLINE message id coz i am not able to send the third parameter.. i am doin it in the following way

 

char[] buffer = new char[255];

buffer[0] = (char)255;

Message msg = Message.Create(this.Handle, EM_GETLINE, (IntPtr)Index, (IntPtr)buffer[0]);

base.DefWndProc(ref msg);

return msg.Result.ToInt32();

 

but i get an corrupt meemory exception.. can u jus help on this...

 

Thx & regards

 

 

although the above works its not the .net way:) you lose portability plus your making calls to unmanaged code on the other hand her is a nice snippet you can use, just inherit a richtextbox and add the following

 

   
   Private Const EM_LINELENGTH = &HC1
   Private Const EM_GETLINE = &HC4
   Private Const EM_GETLINECOUNT = &HBA
   Private Const EM_LINEFROMCHAR = &HC9
   Private Const EM_LINEINDEX = &HBB
   Private Const EM_GETFIRSTVISIBLELINE = &HCE
   Private Const EM_LINESCROLL = &HB6
   Private Const EM_POSFROMCHAR = &HD6
   Private Const EM_GETSEL = &HB0
   Private Const EM_SETSEL = &HB1
   Private Const EM_CANUNDO = &HC6
   Private Const EM_SETTEXTEX = (WM_USER + 97)
   Private Const EM_GETTEXTEX = (WM_USER + 94)
   Private Const EM_GETSELTEXT = (WM_USER + 62)
   Private Const EM_REPLACESEL = &HC2
   Private Const EM_STREAMOUT = (WM_USER + 74)
   Private Const EM_STREAMIN = (WM_USER + 73)
   Private Const EM_SCROLLCARET = &HB7
   Private Const EM_FINDTEXTEX = (WM_USER + 79)
   Private Const EM_CHARFROMPOS = &HD7
   Private Const EM_GETRECT = &HB2
   Private Const EM_SETRECT = &HB3



   Public Function GetLine(ByVal charindex As Integer) As Integer
       Dim m As Message = Message.Create(Me.Handle, EM_LINEFROMCHAR, New IntPtr(charindex), New IntPtr(0))
       MyBase.WndProc(m)
       Return m.Result.ToInt32
   End Function

   Public Function GetLineStart(ByVal line As Integer) As Integer
       Dim m As Message = Message.Create(Me.Handle, EM_LINEINDEX, New IntPtr(line), New IntPtr(0))
       MyBase.WndProc(m)
       Return m.Result.ToInt32
   End Function

   Public Function GetLineLength(ByVal line As Integer) As Integer
       Dim m As Message = Message.Create(Me.Handle, EM_LINELENGTH, New IntPtr(line), New IntPtr(0))
       MyBase.WndProc(m)
       Return m.Result.ToInt32
   End Function

   Public Function GetLineCount() As Integer
       Dim m As Message = Message.Create(Me.Handle, EM_GETLINECOUNT, New IntPtr(0), New IntPtr(0))
       MyBase.WndProc(m)
       Return m.Result.ToInt32
   End Function

   Public Function GetCurrentLineStart() As Integer
       Dim m As Message = Message.Create(Me.Handle, EM_LINEINDEX, New IntPtr(-1), New IntPtr(0))
       MyBase.WndProc(m)
       Return m.Result.ToInt32
   End Function

   Public Function GetCurrentLine() As Integer
       Dim m As Message = Message.Create(Me.Handle, EM_LINEFROMCHAR, New IntPtr(-1), New IntPtr(0))
       MyBase.WndProc(m)
       Return m.Result.ToInt32
   End Function

   Public Function GetFirstVisibleLine() As Integer
       Dim m As Message = Message.Create(Me.Handle, EM_GETFIRSTVISIBLELINE, New IntPtr(0), New IntPtr(0))
       MyBase.WndProc(m)
       Return m.Result.ToInt32
   End Function

   Public Function GetLastVisibleLine() As Integer
       Return Me.GetLine(Me.GetCharIndexFromPosition(New Point(0, Me.Height - iHortBorderWidth)))
   End Function


 

 

i know some of the above are duplicated from what it already has for example getlinefromcharindex, but do a performance test on mine vs the control its 4-5 times faster go figure....

 

-Xposure

Posted

the problem your having is the last param needs to be null, aka new IntPtr(0)

 

 

Message msg = Message.Create(this.Handle, EM_GETLINE, (IntPtr)Index, (IntPtr)buffer[0]);

 

 

the bold is the problem, but i'm also not sure when your trying to give it a buffer, the message handler won't work with a user created buffer, when your doing base.DefWndProc(ref msg); that, your telling the underlying control to process the message, which it expects null because its using its own internal buffer.

 

If i read that wrong please reply and clarify.

 

-Xposure

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...