Translate VB6 SendMessage API to .net

AlexCode

Well-known member
Joined
Jul 7, 2003
Messages
931
Location
Portugal
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:
Code:
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 cant port this stuff to vb.net...

Thanks!

Alex :p
 
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.

Code:
[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 ;)
 
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

Code:
    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
 
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


xposure said:
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

Code:
    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
 
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 im also not sure when your trying to give it a buffer, the message handler wont 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
 
Back
Top