AlexCode Posted November 11, 2004 Posted November 11, 2004 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 Quote Software bugs are impossible to detect by anybody except the end user.
Administrators PlausiblyDamp Posted November 11, 2004 Administrators Posted November 11, 2004 Try changing the longs to integers as a starting point, also you may want to see if http://www.pinvoke.net already has a declare for this api. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
AlexCode Posted November 12, 2004 Author Posted November 12, 2004 Nop... still can't manage to implement this stuff... :( Alex :p Quote Software bugs are impossible to detect by anybody except the end user.
Piruças Posted November 12, 2004 Posted November 12, 2004 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 ;) Quote
AlexCode Posted November 12, 2004 Author Posted November 12, 2004 Really works!!!!!! Your code rocks! Thanks... Alex :p Quote Software bugs are impossible to detect by anybody except the end user.
xposure Posted February 12, 2005 Posted February 12, 2005 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 Quote
chettu Posted July 27, 2005 Posted July 27, 2005 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 Quote
xposure Posted July 27, 2005 Posted July 27, 2005 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 Quote
Recommended Posts