From: mayayana on
> EM_LINEFROMCHAR seems to be a very convenient way to find the character.
>

I'm still confused about what you're trying to do.
I thought you were trying to use EM_CHARFROMPOS
to get the char. offset. But your second post sounded
like you're actually trying to get the line number.
I'm guessing that's what Bill McCarthy was answering.
EM_LINEFROMCHAR (or EM_EXLINEFROMCHAR, which is
recommended) is actually for getting the line number.

(More confusing docs there: The docs say it returns the
"line index", meaning that it returns the line number. Then
there's EM_LINEINDEX, which returns the offset of the
first char. in the line. :)

And note that sending -1 to EM_LINEFROMCHAR gets you the
*beginning* of the selection. That's not necessarily the line
where mouseup happened, but it's OK if you want SelStart.

> @mayayana:
> could you please tell me how to manage the char offset as input for the
> GetCharPos in Eduardo's Richedit?
>

Again, I think it would be easier for everyone if
you try to make more clear exactly what you need
to do.

Eduardo's function takes the char. offset
(SelStart in an RTB, assuming you want the position
where the mouse just clicked). It returns line number
and/or offset ("index") of the first char. in the line.
This is the code:

'----------------------------
Public Sub GetCharPos(ByVal CharIndex As Long, Optional Line As Long,
Optional Column As Long)
Dim lFirstCharPos As Long

' Get the line index
Line = SendMessage(m_hWndRE, EM_EXLINEFROMCHAR, 0, ByVal CharIndex)

' Get the index of the first char in line
lFirstCharPos = SendMessage(m_hWndRE, EM_LINEINDEX, Line, ByVal 0&)

' Calculate the column
Column = CharIndex - lFirstCharPos + 1

' Increment the line to
' make it 1 based
Line = Line + 1

End Sub
'------------------------------

Do you want to find the char. offset of where the
mouse clicked, but you're not finding EM_CHARFROMPOS
to be what you wanted? And then maybe you want to
get the line number? Here's another approach for
a basic SelStart function, returning the offset where
the caret currently is, or more specifically, where the
beginning of the selection is:

Dim CR1 As CHARRANGE
SendMessage hRTB, EM_EXGETSEL, 0, CR1
SelStart = CR1.cpMin

You might want to read up on the EM_ calls. There
are a lot of them. You can sometimes accomplish something
in more than one way.

I'm sorry if this is getting confusing. I'm not sure
of what you need and I'm not really familiar with
Eduardo's control. I looked at the .ctl file but the
control itself won't load for me. It causes an error.
From looking at the .ctl there seem to be a lot of
things lacking, not least of which is SelStart.
Frankly, if it were me I might be inclined to try
the vbAccelerator RTB if you need v. 2 and don't
want to mess with creating it yourself. Eduardo
Morcillo does some interesting stuff, but in my
experience his code is usually quirky, "adventurous"
and oftern partial. He often seems to be just writing
the code as an exercise to explore this or that. And
it always lacks documentation.
(On the up side, he's written code for things that are
hard to find elsewhere.)




From: mayayana on
The following works well for me in an RTB. I can't
try it in Eduardo Morcillo's RTB, since I can't load it.
This code loads a file into an RTB. There are also 4
textboxes on the form. When the RTB is clicked they
show X, Y, SelStart, and word clicked.
(It's rough code. If you click before a word the last
word is highlighted. To do a thorough job you need
to look for delimiters.)

'---------------------------------------------------------

Private Type point
x As Long
y As Long
End Type

Private Const WM_USER = &H400
Private Const EM_CHARFROMPOS& = &HD7
Private Const EM_FINDWORDBREAK = (WM_USER + 76)
Private Const WB_RIGHTBREAK = 7&
Private Const WB_MOVEWORDRIGHT = 5&
Private Const WB_MOVEWORDLEFT = 4&

Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA"
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam
As Long) As Long
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 Sub Form_Load()
RTB.LoadFile "C:\windows\desktop\error codes.txt"
End Sub

Private Sub RTB_MouseUp(Button As Integer, Shift As Integer, x As Single, y
As Single)
Text1.Text = x \ Screen.TwipsPerPixelX
Text2.Text = y \ Screen.TwipsPerPixelY
Dim Pt1 As point
Dim LRet As Long, CPos As Long, LLeft As Long, LEnd As Long

Pt1.x = x \ Screen.TwipsPerPixelX
Pt1.y = y \ Screen.TwipsPerPixelY

'-- get character offset.
LRet = SendMessage(RTB.hwnd, EM_CHARFROMPOS, 0&, Pt1)
Text3.Text = LRet

LLeft = SendMessageLong(RTB.hwnd, EM_FINDWORDBREAK, WB_MOVEWORDLEFT, LRet)
LEnd = SendMessageLong(RTB.hwnd, EM_FINDWORDBREAK, WB_RIGHTBREAK, LLeft)

With RTB
.SelStart = LLeft
.SelLength = LEnd - LLeft
Text4.Text = .SelText
End With
End Sub


'---------------------------------------------------------






> Yes, that's the problem. I am still experimenting, but so far the value
> returned from CHARFROMPOS is not usable. I changed
> Pt1.x = 1 to Pt1.x = x to get a bit closer, but still not much
> success.
>
> Jan
>
> > Doesn't EM_CHARFROMPOS do that, regardless of font size?
> > Maybe you should explain what you're trying to accomplish.
>
>


From: mayayana on
Interesting problems here...
There seem to be some quirks between RTB
v. 1 and v. 2. The code I just posted worked
well with a VB RTB (v. 1), but when I tried it
with my own version of an RTB v. 2, I get nothing
no matter where I click. LLeft
and LEnd return the same value. But if I add
1 to LLeft on the second call it works fine, except
for the fine-tuning quirks. (Ex, clicking in front
of the first letter of a wrod selects the prior word.)


LEnd = SendMessageLong(RTB.hwnd, EM_FINDWORDBREAK, WB_RIGHTBREAK, LLeft + 1)

I don't know if that helps, except to demonstrate
that RichEdit v. 1 and v. 2 seem to have some minor
compatibility issues.




From: Jan Opitz on
I assume the EM_CHARFROMPOS unfortunately does not work with Eduard's RE,
anyway not with the code for a RTB. The RE is different in many ways. That
is why I tried to use the EM_LINEFROMCHAR value and then calculate from the
x value the character closest to the cursor. But this due to font changes
and character width differences ist not accurate emough. Also, I am working
with Asean languages, so there is no wordbreak.

In a MouseUp procedure I am able to retreive the Character following the
EM_EXGETSEL you suggested, thank you.

I may have to use a RTB as an (unvisible) mirror of the RE, just for
position calculations, since the RE is the better choice for processing
non-ANSI strings.

Jan


> The following works well for me in an RTB. I can't
> try it in Eduardo Morcillo's RTB, since I can't load it.
> This code loads a file into an RTB. There are also 4
> textboxes on the form. When the RTB is clicked they
> show X, Y, SelStart, and word clicked.

>
>


First  |  Prev  | 
Pages: 1 2 3
Prev: SendInput and Unicode
Next: Run Time Creating Controls