How do you set the cursor and caret location in code using EM_ ?
EM_SETSEL does not appear to work since I need the line in order to select it.
If I loop the lines EM_LINEINDEX returns the correct value since I pass
the line in order to return the index.
However, if I call "GetLineNumber (see function below loop) Always returns
the top line showing -- (wParam = -1) because the caret does not appear to
be moving along with the loop counter.
Code:
For l = 0 To Len(oRTB.Text)
LockWindowUpdate oRTBBase.hWnd
line = GetLineNumber(oRTBBase) 'This DOES NOT Return the same as l
'but the top line showing
lIndex = LineIndex(oRTBBase, l)
oRTBBase.SelStart = lIndex
lLen = LineLength(oRTBBase, l)
oRTBBase.SelLength = lLen
oRTBBase.SelColor = vbRed
LockWindowUpdate 0
Next
Private Function GetLineNumber(ByVal oRTB As RichTextBox) As Long
' Return the current line number.
'EM_LINEFROMCHAR message
'
'Gets the index of the line that contains the specified character index in a multiline edit control.
'A character index is the zero-based index of the character from the beginning of the edit control.
'You can send this message to either an edit control or a rich edit control.
'Parameters
'wParam
' The character index of the character contained in the line whose number is to be retrieved.
' If this parameter is –1, EM_LINEFROMCHAR retrieves either the line number of the current line
' (the line containing the caret) or, if there is a selection, the line number of the line
' containing the beginning of the selection.
'lParam
' This parameter is not used.
'Return value
'The return value is the zero-based line number of the line containing the character index specified by wParam.
GetLineNumber = SendMessageAsLong(oRTB.hWnd, EM_LINEFROMCHAR, -1, 0)
End Function
Last edited by dw85745; Apr 4th, 2014 at 12:09 PM.
Can you please tell us what you're trying to accomplish? Also, please show us how you've declared the relevant API functions and constants.
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
I have some free time so working on a program to compare computer code (e.g. modules. classes, etc) to identify duplicate files as well as lines within Subs, Functions, etc. that may differ. Planned to release to codebank when done.
Got a lot of it working, but found it interesting that in getting the line position of each line that looping the lines from the beginning of the file gave me the correct line (here I used EM_LINEINDEX to return the cursorpos for the line), while
calling the function posted (GetLineNumber) which uses EM_LINEFROMCHAR with a wParam = -1, did NOT return the correct line when looping the lines. However when calling function GetLineNumber and using the the mouse on the object (RichText Edit box in this case) the correct line is returned.
So obviously the cursor is Not moving when looping the file.
So my question is how do I move the cursor to the beginning of a line using EM_{whatever} -- OR -- does EM_LINEINDEX actually move the cursor when a line number is assigned and that is in fact the way to move it to a line of choice in code {didn't think of testing this that fact till this posting- so will test, but question still stands}?
=============
cobraide
Have looked at most of those examples and have Not got the answer I'm seeking above.
Yes. This works great when using the mouse. However, when called from code (see example) the cursorpos does Not seem to be returned in the correct position for the line.
How do you set the cursor and caret location in code using EM_ ?
EM_SETSEL does not appear to work since I need the line in order to select it.
Code:
SendMessageAsLong oRTB.hWnd, EM_SETSEL, 100&, 100& '<-- Same as oRTB.SelStart = 100&
Originally Posted by dw85745
So my question is how do I move the cursor to the beginning of a line using EM_{whatever} -- OR -- does EM_LINEINDEX actually move the cursor when a line number is assigned and that is in fact the way to move it to a line of choice in code {didn't think of testing this that fact till this posting- so will test, but question still stands}?
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
EM_LINEINDEX returns charIndex 82 for line 1.
Any idea how they are calculating 82?
Code:
? Len("The EM_GETLINECOUNT message does not pass additional parameters to the API in the ")
82
According to the documentation of the EM_LINEINDEX message, wParam specifies "the zero-based line number". That means you were actually telling the RichTextBox to get the character index of the first character of the second line. Note that the character index is also a zero-based index, so the result you're getting is indeed correct.
Originally Posted by dw85745
Command7:
Code:
EM_SETSEL always seems to return character position 862 no matter what the value
is placed for the charIndex.
The 4th parameter of your SendMessage API function was declared as [ByRef] lParam As Any. You were passing the charIndex variable as:
Therefore, you were actually passing a pointer to the charIndex variable for the lParam parameter rather than passing its value directly. Thus, what happened was that every character index starting from 300 up to whatever was the value of the pointed to memory address (which likely exceeded the maximum number of characters the RichTextBox held) was being selected. You should pass that variable ByVal instead (ByVal charIndex).
BTW, even though the EM_SETSEL message states that it "does not return a value", I've found out that it apparently does return a meaningful value. Specifically, it returns "the ending character position of the selection". In your example project though, I'm not sure why it returns 862. Len(RichTextBox1.Text) gives 860, but the starting character position isn't 0, so that return value is quite puzzling indeed.
Last edited by Bonnie West; Apr 8th, 2014 at 04:20 AM.
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Thanks Bonnie West.
GOT IT!!
Missed the "ByVal" big time when I copied over some of my code to extend Birch's example.
A GREAT Reminder to pay attention!!!
Have updated ZIP for others.
One thing I find a headache is that the cursor is hidden so "visual" feedback is lacking. For example, if you
1) position the cursor in the middle of the text
2) select Command1 to Command4 in sequence
3) then again select Command3 and Command4
it initally threw me for a loop until I realized the cursor had in fact changed positions.
One thing I find a headache is that the cursor is hidden so "visual" feedback is lacking.
I believe that is how carets are supposed to behave. Aside from "indicating the place at which text or graphics will be inserted", carets also serves as a visual cue that a particular window has the keyboard focus and is thus the active window. If a window's caret has been hidden, it usually means that that particular window does not have the keyboard focus.
Originally Posted by dw85745
Anyway to keep the cursor showing??
I tried the ShowCaret function, but it didn't work. You could, however, programmatically set the focus back to the RTB control after clicking any of the buttons.
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0