How to detect a mouse movement over a word in a TRichEdit (Views: 720)
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 { ... } |