By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,572 Members | 1,439 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,572 IT Pros & Developers. It's quick & easy.

defining on which line the cursor is in a textbox

P: n/a
Hi,

For my application I need the following behavior: When I press F4 the cursor
has to move to the next line in my multiline textbox which begins with "0".

Finding lines starting with 0 isn't that difficult, but to find the next
line is more difficult. For exemple: if my cursor is on line 200, it has to
start searching on line 201, and not on line 1.

Anybody has any ideas?

I guess that posotioning the cursor on the lien I foudn is also something I
will need, so if somebody knows how to do that... :-)

Thansk a lot in advance,

Pieter
Nov 20 '05 #1
Share this Question
Share on Google+
22 Replies


P: n/a
Hi,

As far as I remember, this can be done at the API level. Take a look at the
text box messages (starting with the EM_ prefix), especially EM_LINEFROMCHAR
and EM_LINEINDEX.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE
"DraguVaso" <pi**********@hotmail.com> wrote in message
news:40**********************@news.skynet.be...
Hi,

For my application I need the following behavior: When I press F4 the cursor has to move to the next line in my multiline textbox which begins with "0".
Finding lines starting with 0 isn't that difficult, but to find the next
line is more difficult. For exemple: if my cursor is on line 200, it has to start searching on line 201, and not on line 1.

Anybody has any ideas?

I guess that posotioning the cursor on the lien I foudn is also something I will need, so if somebody knows how to do that... :-)

Thansk a lot in advance,

Pieter


Nov 20 '05 #2

P: n/a
Cor
Hi Pieter,

Did you look for
textbox.lines

Something as (roughly written here not tested and never tried)
\\\\
for i as integer = 200 to textbox1.lines.length-1
if x................
next
////
I hope this helps?

Cor

For my application I need the following behavior: When I press F4 the cursor has to move to the next line in my multiline textbox which begins with "0".
Finding lines starting with 0 isn't that difficult, but to find the next
line is more difficult. For exemple: if my cursor is on line 200, it has to start searching on line 201, and not on line 1.

Anybody has any ideas?

I guess that posotioning the cursor on the lien I foudn is also something I will need, so if somebody knows how to do that... :-)

Nov 20 '05 #3

P: n/a
* "DraguVaso" <pi**********@hotmail.com> scripsit:
For my application I need the following behavior: When I press F4 the cursor
has to move to the next line in my multiline textbox which begins with "0".

Finding lines starting with 0 isn't that difficult, but to find the next
line is more difficult. For exemple: if my cursor is on line 200, it has to
start searching on line 201, and not on line 1.


Quick and dirty: Use a loop and loop through the textbox's 'Lines'
property and sum up the length of the lines (+ the length of the line
separator). Then set the position by using the overloaded version of
the textbox's 'Select' method.

--
Herfried K. Wagner [MVP]
<http://www.mvps.org/dotnet>
Nov 20 '05 #4

P: n/a
I found this VB functions:

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
Const EM_LINEFROMCHAR = &HC9

Function GetTextBoxCurrentLine(TB As TextBox) As Long
GetTextBoxCurrentLine = SendMessage(TB.hWnd, EM_LINEFROMCHAR, -1, _
ByVal 0&) + 1
End Function
But I'm not able to 'translate' them in VB.NET. Anybody can help with this?

"Dmitriy Lapshin [C# / .NET MVP]" <x-****@no-spam-please.hotpop.com> wrote
in message news:eh**************@TK2MSFTNGP09.phx.gbl...
Hi,

As far as I remember, this can be done at the API level. Take a look at the text box messages (starting with the EM_ prefix), especially EM_LINEFROMCHAR and EM_LINEINDEX.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE
"DraguVaso" <pi**********@hotmail.com> wrote in message
news:40**********************@news.skynet.be...
Hi,

For my application I need the following behavior: When I press F4 the cursor
has to move to the next line in my multiline textbox which begins with

"0".

Finding lines starting with 0 isn't that difficult, but to find the next
line is more difficult. For exemple: if my cursor is on line 200, it has

to
start searching on line 201, and not on line 1.

Anybody has any ideas?

I guess that posotioning the cursor on the lien I foudn is also

something I
will need, so if somebody knows how to do that... :-)

Thansk a lot in advance,

Pieter

Nov 20 '05 #5

P: n/a
Indeed dirty, but not quick I'm affraid. Somewhere else I have to work
alreaddy with ther Lines-property and loop through all of them, but it takes
a lot of time! I sometimes have really big amounts of text! It can take
easily 10 seconds.

"Herfried K. Wagner [MVP]" <hi***************@gmx.at> wrote in message
news:bu************@ID-208219.news.uni-berlin.de...
* "DraguVaso" <pi**********@hotmail.com> scripsit:
For my application I need the following behavior: When I press F4 the cursor has to move to the next line in my multiline textbox which begins with "0".
Finding lines starting with 0 isn't that difficult, but to find the next
line is more difficult. For exemple: if my cursor is on line 200, it has to start searching on line 201, and not on line 1.


Quick and dirty: Use a loop and loop through the textbox's 'Lines'
property and sum up the length of the lines (+ the length of the line
separator). Then set the position by using the overloaded version of
the textbox's 'Select' method.

--
Herfried K. Wagner [MVP]
<http://www.mvps.org/dotnet>

Nov 20 '05 #6

P: n/a
DraguVaso <pi**********@hotmail.com> wrote:
Indeed dirty, but not quick I'm affraid. Somewhere else I have to work
alreaddy with ther Lines-property and loop through all of them, but it takes
a lot of time! I sometimes have really big amounts of text! It can take
easily 10 seconds.


That sounds pretty excessive - how are you doing it? If you're doing it
in a way that repeatedly uses the Lines property, that would be pretty
slow. If you fetch the Lines property value once and then repeatedly
use that "cached" value it shouldn't take long at all.

You'll need to be very careful in case you've got some \n and some \r\n
separators in there though - you should definitely check whether or not
that confuses things.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 20 '05 #7

P: n/a
Cor
Hi Pieter,

What are you storing in that textbox, The bible?

But to be serious, I saw that the lines is not an implementation of Ilist,
so maybe you can copy it first to an Ilist array to get it faster.

Just an Idea.

Cor
Indeed dirty, but not quick I'm affraid. Somewhere else I have to work
alreaddy with ther Lines-property and loop through all of them, but it takes a lot of time! I sometimes have really big amounts of text! It can take
easily 10 seconds.

Nov 20 '05 #8

P: n/a
Hehe,

No bible, but coda-files :-) Files with bankmovements etc. According to the
format it has for every record 1-3 lines with a lenght of 128 or 360, and
can eaisliy have 2000 records in it, so a total of 5000 lines isn't an
exception. For that I need to get a key to go quick to some special marks in
it.

I guess that's a good idea to put it first in an other kind of list,
although I don't know the 'IList", but I'm gonna try all these usggestions
out now.

Thansk a lot, I let you guys know something.

Pieter

"Cor" <no*@non.com> wrote in message
news:#w**************@TK2MSFTNGP12.phx.gbl...
Hi Pieter,

What are you storing in that textbox, The bible?

But to be serious, I saw that the lines is not an implementation of Ilist,
so maybe you can copy it first to an Ilist array to get it faster.

Just an Idea.

Cor
Indeed dirty, but not quick I'm affraid. Somewhere else I have to work
alreaddy with ther Lines-property and loop through all of them, but it

takes
a lot of time! I sometimes have really big amounts of text! It can take
easily 10 seconds.


Nov 20 '05 #9

P: n/a
* "DraguVaso" <pi**********@hotmail.com> scripsit:
I found this VB functions:

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
Const EM_LINEFROMCHAR = &HC9


Untested:

\\\
Private Declare Auto Function SendMessage Lib "user32.dll" ( _
ByVal hWnd As IntPtr, _
ByVal wMsg As Int32, _
ByVal wParam As Int32, _
ByVal lParam As Int32 _
)

Private Const EM_LINEFROMCHAR As Int32 = &HC9
..
..
..
Public Function GetTextBoxCurrentLine(ByVal TB As TextBox) As Integer
Return SendMessage(TB.Handle, EM_LINEFROMCHAR, -1, 0)
End Function
///

--
Herfried K. Wagner [MVP]
<http://www.mvps.org/dotnet>
Nov 20 '05 #10

P: n/a
* "Cor" <no*@non.com> scripsit:
What are you storing in that textbox, The bible?


For example, a large log-file?

--
Herfried K. Wagner [MVP]
<http://www.mvps.org/dotnet>
Nov 20 '05 #11

P: n/a
Cor
> For example, a large log-file?

You knew it and I remembered it me also when I saw the answer from Pieter.

Cor

Nov 20 '05 #12

P: n/a
DraguVaso <pi**********@hotmail.com> wrote:
No bible, but coda-files :-) Files with bankmovements etc. According to the
format it has for every record 1-3 lines with a lenght of 128 or 360, and
can eaisliy have 2000 records in it, so a total of 5000 lines isn't an
exception. For that I need to get a key to go quick to some special marks in
it.


5000 lines shouldn't take long to parse at all - so long as you only
need to parse them *once* rather than once (or more) per line.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 20 '05 #13

P: n/a
100
Hi DraguVaso,

If it is possible and if you don't like using P\Invole my suggestion is to
go with RichEditBox control.
RichEditBox supports methods like GetCharIndexFromPosition and
GetLineFromCharIndex. Combining these methods will give you what you need.
I believe changing EditBox with RichEditBox won't be a pain.

B\rgds
100
"DraguVaso" <pi**********@hotmail.com> wrote in message
news:40**********************@news.skynet.be...
Hi,

For my application I need the following behavior: When I press F4 the cursor has to move to the next line in my multiline textbox which begins with "0".
Finding lines starting with 0 isn't that difficult, but to find the next
line is more difficult. For exemple: if my cursor is on line 200, it has to start searching on line 201, and not on line 1.

Anybody has any ideas?

I guess that posotioning the cursor on the lien I foudn is also something I will need, so if somebody knows how to do that... :-)

Thansk a lot in advance,

Pieter

Nov 20 '05 #14

P: n/a
100
Hi DraguVaso,
I misundertood your question. Sorry about that.
I take that when you say cursor you mean the caret not the mouse cursor.
Right?
If it is the caret you can go again with RichTextBox.
The position of the carret you can get from SelectionStart property. This is
position is in terms of char index.
Then you can get the line where the caret currently is by using
GetLineFromCharIndex.
However, this will work only if the WordWrap is turned off.
GetLineFormCharIndex returns the physical line on the screen. If a line has
been splited by the WordWrap RichTextBox considers this line as two or more
physical lines.

My second idea:

You can consider using RichTextBox' Find method. It has whole bunch of
overloads.
You can look for '0' this is what your lines begin with. When you find it
you have to make sure it is at the begining of the line. This is not easy.
Unfortunately Find method cannot search for new-line characters.
Thus, you cannot do Find("\n0") it won't find anything. So the first
solution I came up with is to check whether the '0' character you have found
and the character before it are on the same physical line. If they are not
'0' is at the begining of the line.
If they are, though, the '0' may be or may be not what you are looking for.
This will work only of '0' is the very first character in the line; no
whitspaces or stuff.

You can test the following code and see of it works for you. Just create a
form with one button and one RichTextBox on it and paste the following
button's event handler.
BTW the example is in c#, but the translation should be a piece of cake.

private void button1_Click(object sender, System.EventArgs e)
{

int index = richTextBox1.Find(new char[]{'0'},
richTextBox1.SelectionStart + 1);
if(index >= 0)
{
int foundTextLine = richTextBox1.GetLineFromCharIndex(index);
if(foundTextLine > richTextBox1.GetLineFromCharIndex(index) -1)
{
//Begining of the line found
richTextBox1.SelectionStart = index;
}

}
//Just to show the caret.
richTextBox1.Focus();

}
BTW, is your TextBox readonly or it can be change by the user? If it is
readonly you can cache the text and do the searching in the copy. Reading
Lines property is slow operation because it envolves sending the
underlaying windows control messages and then split the text into lines.
"100" <10*@100.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
Hi DraguVaso,

If it is possible and if you don't like using P\Invole my suggestion is to
go with RichEditBox control.
RichEditBox supports methods like GetCharIndexFromPosition and
GetLineFromCharIndex. Combining these methods will give you what you need.
I believe changing EditBox with RichEditBox won't be a pain.

B\rgds
100
"DraguVaso" <pi**********@hotmail.com> wrote in message
news:40**********************@news.skynet.be...
Hi,

For my application I need the following behavior: When I press F4 the cursor
has to move to the next line in my multiline textbox which begins with

"0".

Finding lines starting with 0 isn't that difficult, but to find the next
line is more difficult. For exemple: if my cursor is on line 200, it has

to
start searching on line 201, and not on line 1.

Anybody has any ideas?

I guess that posotioning the cursor on the lien I foudn is also

something I
will need, so if somebody knows how to do that... :-)

Thansk a lot in advance,

Pieter


Nov 20 '05 #15

P: n/a
Ok, I have a solution that works allmost fine, hehe :-)
Copyng the Textbox.Lines to a string() worked great! It improved speed
amazingly.

Some little remarks that I didn't expect: to synchronize the
Textbox.SelectionStart with the sum of the lenghts of all the lines I had to
add 2 to eacht line. I expected 1 for the carriage return, and still don't
really know why it was 2, but whatever, hehe.

Another thing: it works really fine with small files, but with big files
(5000 lines, more than three 0-records in it) it has some weird behaviour:
Somewhere it doesn't calculate enough positions to the total lenght
(lngLengte in the routine). I tested it on a file whith records which have
all a lenght of 128. For the first 0-record it found it putted the cursor at
the end of the file (perfect), the second 0-record was alreaddy the
beginning. The third it was 2 records before the 0-record (so like +- 250
positions before it, and it was like record 2000), and the fourth 0-record
it foudn it putted the position of the cursor +- 10 lines before it (or 1200
positions, on +- record 5000).

Anybody got any idea what causes this?

The full code you find underneath:

Private Sub ZoekVolgendBestand()
Dim lngX As Long
Dim lngBeginPos, lngBeginL As Long
Dim lngFound As Long
Dim lngLengte As Long

lngBeginPos = txtText.SelectionStart()
lngLengte = 0
lngBeginL = 0
Dim strT As String()
'store the textbox in a string()
strT = txtText.Lines

'search the current line number + position
Do Until lngLengte > lngBeginPos
lngLengte = lngLengte + strT(lngBeginL).Length
If lngBeginL > UBound(strT) Then
'end of file: no line with a 0 found
Exit Sub
End If
lngBeginL = lngBeginL + 1
Loop

lngFound = -1

'search next 0-line
For lngX = lngBeginL To UBound(strT)
lngLengte = lngLengte + strT(lngX).Length + 2 '2 = carriage
return
If Microsoft.VisualBasic.Left(strT(lngX), 1) = "0" Then
lngFound = lngX
Exit For
End If
Next

'end of file but not yet found one: go to begin of file and keep on
searching
If (lngFound < 0) Then
lngLengte = 0
For lngX = 0 To lngBeginL
lngLengte = lngLengte + strT(lngX).Length + 2 '2 =
carriage return
If Microsoft.VisualBasic.Left(strT(lngX), 1) = "0" Then
lngFound = lngX
Exit For
End If
Next
End If

If lngFound >= 0 Then
'found one
txtText.SelectionStart = lngLengte
txtText.ScrollToCaret()
Else
MessageBox.Show("Cannot find a file", "Find file",
MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Sub
I'm gonna try the other solutiosn here also, already big thanks for all the
help I got here!

Pieter
"Cor" <no*@non.com> wrote in message
news:#w**************@TK2MSFTNGP12.phx.gbl...
Hi Pieter,

What are you storing in that textbox, The bible?

But to be serious, I saw that the lines is not an implementation of Ilist,
so maybe you can copy it first to an Ilist array to get it faster.

Just an Idea.

Cor
Indeed dirty, but not quick I'm affraid. Somewhere else I have to work
alreaddy with ther Lines-property and loop through all of them, but it

takes
a lot of time! I sometimes have really big amounts of text! It can take
easily 10 seconds.


Nov 20 '05 #16

P: n/a
Thanks, but unfortunately it doesn't work, it gave me an error:
Run-time exception thrown :
System.Runtime.InteropServices.MarshalDirectiveExc eption - PInvoke
restriction: can not return variants.

I didn't manage to find the solution for that error :-(

"Herfried K. Wagner [MVP]" <hi***************@gmx.at> wrote in message
news:bu************@ID-208219.news.uni-berlin.de...
* "DraguVaso" <pi**********@hotmail.com> scripsit:
I found this VB functions:

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
Const EM_LINEFROMCHAR = &HC9


Untested:

\\\
Private Declare Auto Function SendMessage Lib "user32.dll" ( _
ByVal hWnd As IntPtr, _
ByVal wMsg As Int32, _
ByVal wParam As Int32, _
ByVal lParam As Int32 _
)

Private Const EM_LINEFROMCHAR As Int32 = &HC9
.
.
.
Public Function GetTextBoxCurrentLine(ByVal TB As TextBox) As Integer
Return SendMessage(TB.Handle, EM_LINEFROMCHAR, -1, 0)
End Function
///

--
Herfried K. Wagner [MVP]
<http://www.mvps.org/dotnet>

Nov 20 '05 #17

P: n/a
Hi,

Your second idea takes to much time, hehe. There are too many 0's in the
files. After 10 seconds it has only looked into 1500 records.

Regarding your first solution: that works ideal to find the current line,
but unfortunately there doesn't seem to be a functionthat does the reverse:
when I found my 0-line: giving me the position so I can set the
SelectionStart to it. In case you would know a way to get aroudn this
problem, it woudl be nice if you could tell me.

Thanks a lot!

Pieter

"100" <10*@100.com> wrote in message
news:uW**************@tk2msftngp13.phx.gbl...
Hi DraguVaso,
I misundertood your question. Sorry about that.
I take that when you say cursor you mean the caret not the mouse cursor.
Right?
If it is the caret you can go again with RichTextBox.
The position of the carret you can get from SelectionStart property. This is position is in terms of char index.
Then you can get the line where the caret currently is by using
GetLineFromCharIndex.
However, this will work only if the WordWrap is turned off.
GetLineFormCharIndex returns the physical line on the screen. If a line has been splited by the WordWrap RichTextBox considers this line as two or more physical lines.

My second idea:

You can consider using RichTextBox' Find method. It has whole bunch of
overloads.
You can look for '0' this is what your lines begin with. When you find it
you have to make sure it is at the begining of the line. This is not easy.
Unfortunately Find method cannot search for new-line characters.
Thus, you cannot do Find("\n0") it won't find anything. So the first
solution I came up with is to check whether the '0' character you have found and the character before it are on the same physical line. If they are not
'0' is at the begining of the line.
If they are, though, the '0' may be or may be not what you are looking for. This will work only of '0' is the very first character in the line; no
whitspaces or stuff.

You can test the following code and see of it works for you. Just create a
form with one button and one RichTextBox on it and paste the following
button's event handler.
BTW the example is in c#, but the translation should be a piece of cake.

private void button1_Click(object sender, System.EventArgs e)
{

int index = richTextBox1.Find(new char[]{'0'},
richTextBox1.SelectionStart + 1);
if(index >= 0)
{
int foundTextLine = richTextBox1.GetLineFromCharIndex(index);
if(foundTextLine > richTextBox1.GetLineFromCharIndex(index) -1)
{
file://Begining of the line found
richTextBox1.SelectionStart = index;
}

}
file://Just to show the caret.
richTextBox1.Focus();

}
BTW, is your TextBox readonly or it can be change by the user? If it is
readonly you can cache the text and do the searching in the copy. Reading
Lines property is slow operation because it envolves sending the
underlaying windows control messages and then split the text into lines.
"100" <10*@100.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
Hi DraguVaso,

If it is possible and if you don't like using P\Invole my suggestion is to go with RichEditBox control.
RichEditBox supports methods like GetCharIndexFromPosition and
GetLineFromCharIndex. Combining these methods will give you what you need. I believe changing EditBox with RichEditBox won't be a pain.

B\rgds
100
"DraguVaso" <pi**********@hotmail.com> wrote in message
news:40**********************@news.skynet.be...
Hi,

For my application I need the following behavior: When I press F4 the

cursor
has to move to the next line in my multiline textbox which begins with

"0".

Finding lines starting with 0 isn't that difficult, but to find the next line is more difficult. For exemple: if my cursor is on line 200, it
has to
start searching on line 201, and not on line 1.

Anybody has any ideas?

I guess that posotioning the cursor on the lien I foudn is also

something
I
will need, so if somebody knows how to do that... :-)

Thansk a lot in advance,

Pieter



Nov 20 '05 #18

P: n/a
Hehe, I found the reason why: I forgot in the first loop to add the extra 2
to my line-lenght :-)

So this is the working code, which also goes the fastest.

Private Sub ZoekVolgendBestand()
Dim lngX As Long
Dim lngBeginPos, lngBeginL As Long
Dim lngFound As Long
Dim lngLengte As Long

lngBeginPos = txtText.SelectionStart()
lngLengte = 0
lngBeginL = 0
Dim strT As String()
'store the textbox in a string()
strT = txtText.Lines

'search the current line number + position
Do Until lngLengte > lngBeginPos
lngLengte = lngLengte + strT(lngBeginL).Length + 2 '2 =
carriage return
If lngBeginL > UBound(strT) Then
'end of file: no line with a 0 found
Exit Sub
End If
lngBeginL = lngBeginL + 1
Loop

lngFound = -1
Dim lngLast As Long

'search next 0-line
For lngX = lngBeginL To UBound(strT)
lngLast = strT(lngX).Length + 2
lngLengte = lngLengte + lngLast '2 = carriage return
If Microsoft.VisualBasic.Left(strT(lngX), 1) = "0" Then
lngFound = lngX
Exit For
End If
Next

'end of file but not yet found one: go to begin of file and keep on
searching
If (lngFound < 0) Then
lngLengte = 0
For lngX = 0 To lngBeginL
lngLast = strT(lngX).Length + 2
lngLengte = lngLengte + lngLast '2 = carriage return
If Microsoft.VisualBasic.Left(strT(lngX), 1) = "0" Then
lngFound = lngX
Exit For
End If
Next
End If

If lngFound >= 0 Then
'found one
txtText.SelectionStart = lngLengte - lngLast
txtText.SelectionLength = lngLast - 1
txtText.ScrollToCaret()
Else
MessageBox.Show("Cannot find a file", "Find file",
MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Sub

Thanks a lot everybody, especially Cor, who came with the ward-winning tip
of storing everything in an other list! hahaha :-)

See you later guys!

Pieter
Nov 20 '05 #19

P: n/a
Ensure the API function declared as one returning Long value. One of the
declarations given by Herfried misses the return value which is assumed
Variant by default. You should specify System.Int32 or its VB.NET equivalent
(most likely Integer).

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

"DraguVaso" <pi**********@hotmail.com> wrote in message
news:40**********************@news.skynet.be...
Thanks, but unfortunately it doesn't work, it gave me an error:
Run-time exception thrown :
System.Runtime.InteropServices.MarshalDirectiveExc eption - PInvoke
restriction: can not return variants.

I didn't manage to find the solution for that error :-(


Nov 20 '05 #20

P: n/a
* "DraguVaso" <pi**********@hotmail.com> scripsit:
Thanks, but unfortunately it doesn't work, it gave me an error:
Run-time exception thrown :
System.Runtime.InteropServices.MarshalDirectiveExc eption - PInvoke
restriction: can not return variants.


Sorry, typo. I forgot to mark the return value as 'Int32'.
Private Declare Auto Function SendMessage Lib "user32.dll" ( _
ByVal hWnd As IntPtr, _
ByVal wMsg As Int32, _
ByVal wParam As Int32, _
ByVal lParam As Int32 _
) As Int32


--
Herfried K. Wagner [MVP]
<http://www.mvps.org/dotnet>
Nov 20 '05 #21

P: n/a
100
Hi,
Yes, you are right there is no way to find char index from line. It looks
like it meant to be used only for reporting the caret position in the status
bar. So I give up the idea. But the second one... You said it is too slow.
And you said that it takes 10 second for the first 1500 records. Of cource I
have no idea what the structure of the file looks like, however, my idea is
to start seaching from the current position of the caret to the next line.
If the next line means the next record it doesn't have to look for all 1500
records to find the begining of the next line. Or may be one line has many
records... So how big one line can be? How many '0' one line can have? And
is it only the '0' that marks the begining of the line?

I agree that if the edit control is readonly caching the text is the best
solution. In this case you can optimize the searching verry well.

B\rgds
100
"DraguVaso" <pi**********@hotmail.com> wrote in message
news:40***********************@news.skynet.be...
Hi,

Your second idea takes to much time, hehe. There are too many 0's in the
files. After 10 seconds it has only looked into 1500 records.

Regarding your first solution: that works ideal to find the current line,
but unfortunately there doesn't seem to be a functionthat does the reverse: when I found my 0-line: giving me the position so I can set the
SelectionStart to it. In case you would know a way to get aroudn this
problem, it woudl be nice if you could tell me.

Thanks a lot!

Pieter

"100" <10*@100.com> wrote in message
news:uW**************@tk2msftngp13.phx.gbl...
Hi DraguVaso,
I misundertood your question. Sorry about that.
I take that when you say cursor you mean the caret not the mouse cursor.
Right?
If it is the caret you can go again with RichTextBox.
The position of the carret you can get from SelectionStart property. This
is
position is in terms of char index.
Then you can get the line where the caret currently is by using
GetLineFromCharIndex.
However, this will work only if the WordWrap is turned off.
GetLineFormCharIndex returns the physical line on the screen. If a line has
been splited by the WordWrap RichTextBox considers this line as two or

more
physical lines.

My second idea:

You can consider using RichTextBox' Find method. It has whole bunch of
overloads.
You can look for '0' this is what your lines begin with. When you find it you have to make sure it is at the begining of the line. This is not easy. Unfortunately Find method cannot search for new-line characters.
Thus, you cannot do Find("\n0") it won't find anything. So the first
solution I came up with is to check whether the '0' character you have

found
and the character before it are on the same physical line. If they are not '0' is at the begining of the line.
If they are, though, the '0' may be or may be not what you are looking

for.
This will work only of '0' is the very first character in the line; no
whitspaces or stuff.

You can test the following code and see of it works for you. Just create a form with one button and one RichTextBox on it and paste the following
button's event handler.
BTW the example is in c#, but the translation should be a piece of cake.

private void button1_Click(object sender, System.EventArgs e)
{

int index = richTextBox1.Find(new char[]{'0'},
richTextBox1.SelectionStart + 1);
if(index >= 0)
{
int foundTextLine = richTextBox1.GetLineFromCharIndex(index);
if(foundTextLine > richTextBox1.GetLineFromCharIndex(index) -1)
{
file://Begining of the line found
richTextBox1.SelectionStart = index;
}

}
file://Just to show the caret.
richTextBox1.Focus();

}
BTW, is your TextBox readonly or it can be change by the user? If it is
readonly you can cache the text and do the searching in the copy. Reading Lines property is slow operation because it envolves sending the
underlaying windows control messages and then split the text into lines.
"100" <10*@100.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
Hi DraguVaso,

If it is possible and if you don't like using P\Invole my suggestion is to go with RichEditBox control.
RichEditBox supports methods like GetCharIndexFromPosition and
GetLineFromCharIndex. Combining these methods will give you what you need. I believe changing EditBox with RichEditBox won't be a pain.

B\rgds
100
"DraguVaso" <pi**********@hotmail.com> wrote in message
news:40**********************@news.skynet.be...
> Hi,
>
> For my application I need the following behavior: When I press F4
the cursor
> has to move to the next line in my multiline textbox which begins with "0".
>
> Finding lines starting with 0 isn't that difficult, but to find the

next > line is more difficult. For exemple: if my cursor is on line 200, it has to
> start searching on line 201, and not on line 1.
>
> Anybody has any ideas?
>
> I guess that posotioning the cursor on the lien I foudn is also

something
I
> will need, so if somebody knows how to do that... :-)
>
> Thansk a lot in advance,
>
> Pieter
>
>



Nov 20 '05 #22

P: n/a
I thought your solution was: to look for a 0, and than look if the character
before that 0 is on another line.

The fact is: my records (which have mostly a lenght of 128 of 360
characters) contain a whole bunch of 0's, hehe. Not to say that the 0 is the
most used character, hahaha :-)

1 file contains +- 5000 records, and 1 until 10 records start with a 0.

But I have now a solution that doesn't take any time and works perfect (see
somewhere else in this thread). It wasn't really the most 'beautiful'
solution, but it had with a lot of advance the best result :-)

Thanks anyway,

Pieter

"100" <10*@100.com> wrote in message
news:#L**************@tk2msftngp13.phx.gbl...> Hi,
Yes, you are right there is no way to find char index from line. It looks
like it meant to be used only for reporting the caret position in the status bar. So I give up the idea. But the second one... You said it is too slow.
And you said that it takes 10 second for the first 1500 records. Of cource I have no idea what the structure of the file looks like, however, my idea is to start seaching from the current position of the caret to the next line.
If the next line means the next record it doesn't have to look for all 1500 records to find the begining of the next line. Or may be one line has many records... So how big one line can be? How many '0' one line can have? And
is it only the '0' that marks the begining of the line?

I agree that if the edit control is readonly caching the text is the best
solution. In this case you can optimize the searching verry well.

B\rgds
100
"DraguVaso" <pi**********@hotmail.com> wrote in message
news:40***********************@news.skynet.be...
Hi,

Your second idea takes to much time, hehe. There are too many 0's in the
files. After 10 seconds it has only looked into 1500 records.

Regarding your first solution: that works ideal to find the current line,
but unfortunately there doesn't seem to be a functionthat does the reverse:
when I found my 0-line: giving me the position so I can set the
SelectionStart to it. In case you would know a way to get aroudn this
problem, it woudl be nice if you could tell me.

Thanks a lot!

Pieter

"100" <10*@100.com> wrote in message
news:uW**************@tk2msftngp13.phx.gbl...
Hi DraguVaso,
I misundertood your question. Sorry about that.
I take that when you say cursor you mean the caret not the mouse cursor. Right?
If it is the caret you can go again with RichTextBox.
The position of the carret you can get from SelectionStart property. This
is
position is in terms of char index.
Then you can get the line where the caret currently is by using
GetLineFromCharIndex.
However, this will work only if the WordWrap is turned off.
GetLineFormCharIndex returns the physical line on the screen. If a line has
been splited by the WordWrap RichTextBox considers this line as two or

more
physical lines.

My second idea:

You can consider using RichTextBox' Find method. It has whole bunch of
overloads.
You can look for '0' this is what your lines begin with. When you find it you have to make sure it is at the begining of the line. This is not easy. Unfortunately Find method cannot search for new-line characters.
Thus, you cannot do Find("\n0") it won't find anything. So the first
solution I came up with is to check whether the '0' character you have

found
and the character before it are on the same physical line. If they are not '0' is at the begining of the line.
If they are, though, the '0' may be or may be not what you are looking

for.
This will work only of '0' is the very first character in the line; no
whitspaces or stuff.

You can test the following code and see of it works for you. Just
create a form with one button and one RichTextBox on it and paste the following
button's event handler.
BTW the example is in c#, but the translation should be a piece of
cake.
private void button1_Click(object sender, System.EventArgs e)
{

int index = richTextBox1.Find(new char[]{'0'},
richTextBox1.SelectionStart + 1);
if(index >= 0)
{
int foundTextLine = richTextBox1.GetLineFromCharIndex(index);
if(foundTextLine > richTextBox1.GetLineFromCharIndex(index) -1)
{
file://Begining of the line found
richTextBox1.SelectionStart = index;
}

}
file://Just to show the caret.
richTextBox1.Focus();

}
BTW, is your TextBox readonly or it can be change by the user? If it is readonly you can cache the text and do the searching in the copy.

Reading Lines property is slow operation because it envolves sending the
underlaying windows control messages and then split the text into lines.

"100" <10*@100.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
> Hi DraguVaso,
>
> If it is possible and if you don't like using P\Invole my suggestion is
to
> go with RichEditBox control.
> RichEditBox supports methods like GetCharIndexFromPosition and
> GetLineFromCharIndex. Combining these methods will give you what you

need.
> I believe changing EditBox with RichEditBox won't be a pain.
>
> B\rgds
> 100
>
>
> "DraguVaso" <pi**********@hotmail.com> wrote in message
> news:40**********************@news.skynet.be...
> > Hi,
> >
> > For my application I need the following behavior: When I press F4

the > cursor
> > has to move to the next line in my multiline textbox which begins with > "0".
> >
> > Finding lines starting with 0 isn't that difficult, but to find

the next
> > line is more difficult. For exemple: if my cursor is on line 200,
it has
> to
> > start searching on line 201, and not on line 1.
> >
> > Anybody has any ideas?
> >
> > I guess that posotioning the cursor on the lien I foudn is also
something
> I
> > will need, so if somebody knows how to do that... :-)
> >
> > Thansk a lot in advance,
> >
> > Pieter
> >
> >
>
>



Nov 20 '05 #23

This discussion thread is closed

Replies have been disabled for this discussion.