2009. május 21., csütörtök
How to detect a mouse movement over a word in a TRichEdit
Problem/Question/Abstract:
How to detect a mouse movement over a word in a TRichEdit
Answer:
Solve 1:
How can I detect when the mouse runs over a word or an expression in a TRichEdit?
You start by adding a handler to the TRichEdit's OnMouseMove event. In the handler you get to the character under the mouse with:
uses
richedit; {for EM_EXLINEFROMCHAR}
var
pt: TPoint;
charindex, lineindex, charoffset: Integer;
begin
pt := Point(X, Y);
charindex := richedit.perform(Messages.EM_CHARFROMPOS, 0, integer(@pt));
if charindex >= 0 then
begin
lineindex := richedit.perform(EM_EXLINEFROMCHAR, 0, charindex);
charoffset := charindex - richedit.perform(EM_LINEINDEX, lineindex, 0);
end;
end;
Lineindex and charoffset now allow you to get the line out of the richedit.Lines array and look at the characters value. Note that you have to use charoffset+1 as index into the string, e.g.:
S := richedit.lines[lineindex];
charundercursor := S[charoffset + 1];
If charundercursor is a letter (IsCharAlpha( charundercursor )) you could now walk backwards in S to find the start of the word and forward to find its end. Similar for an "expression" (whatever that may mean in your context).
Solve 2:
Using the source code above, how can I determine, whether the mouse is over a phrase like 'Inprise Delphi', which has the text attribute Bold and the colour Lime?
Well, you have to jump through some hoops, I'm afraid. The TRichEdit component has a method FindText that can be used to search for text, ignoring any text attributes. It would go something like this:
{additional vars required}
S: string;
foundPos, oldSelStart: Integer;
{after determining charindex as above}
S := 'Inprise Delphi'; {text to search for}
foundpos := richedit.FindText(S, charindex - Length(S) + 1, charindex + Length(S),
[stWholeWord, stMatchCase]);
if foundpos > = 0 then
begin
{found the text, check attributes}
{for this we need to select the text}
oldSelStart := richedit.SelStart;
richedit.SelStart := foundPos;
richedit.SelLength := Length(S);
with richedit.SelAttributes do
if ((ConsistentAttributes * [caBold, caColor]) = [caBold, caColor]) and
(Color = clLime) and (fsBold in Style) then
{we have a match!}
else
SelStart := oldSelStart;
end;
Solve 3:
How can I tell from a WM_MOUSEMOVE message that the mouse cursor is over a particular character or line of a TRichedit? I am simulating a very simplistic browser and want to know when the user is over a "hyperlink" which is really just a TRichedit with some of the text underlined. That way I can tell the cursor to change from crHand and back.
uses
richedit;
var
pt: TPoint;
charindex, row, col: Integer;
{ ... }
GetCursorPos(pt);
pt := richedit.screentoclient(pt);
charindex := richedit1.perform(Messages.EM_CHARFROMPOS, 0, integer(@pt));
Row := richedit1.PerForm(EM_EXLINEFROMCHAR, 0, charindex);
Col := charindex - richedit1.Perform(EM_LINEINDEX, Row, 0);
Solve 4:
Looking for a way to find the character position the mouse is over during a TRichEdit.onMouseMove event.
var
msg: TMessage;
pt: TPoint;
pos: integer; {offset into RichEdit.Text}
{ ... }
pt.x := X;
pt.y := Y;
msg.Result := SendMessage(RichEdit.handle, EM_CHarFromPos, 0, Integer(@pt));
pos := msg.ResultLo;
if RichEdit.Text[pos] = '?' then
{ ... }
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése