views:

238

answers:

2

I would like to get the index (start position) for the selected text in a WebBrowser control. Similar to the index you would get when doing a regular expression search.

I want to get the "line and column number" of the selected text. These can be determined based on the index of the selection.

I have tried using an IHTMLTxtRange in combination with IDisplayServices/IHTMLCaret but the best i can get are point locations.

If the "point locations" can be converted to a character position that would also work.

What would be the easiest way of doing this?

+1  A: 

You can try MoveMarkupPointerToCaret and IMarkupPointer::Left or IMarkupPointer2::GetMarkupPosition to inspect the caret's location.

Sheng Jiang 蒋晟
I tried using the MoveMarkupPointerToCaret function but did not manage to get the results i was looking for. I guess need to spend some more time on it. I ended up doing something else for now (see added answer)
barry
any error code?
Sheng Jiang 蒋晟
A: 

As a quick fix i ended up using the MouseUp event of an extended WebBrowser control to get the cursor position. I used this to get the Element at the current clicked/selected text in the WebBrowser control.

Dim ScreenCoord As New Point(MousePosition.X, MousePosition.Y)
Dim BrowserCoord As Point = webBrowser1.PointToClient(ScreenCoord)
Dim elem As HtmlElement = webbrowser1.Document.GetElementFromPoint(BrowserCoord)

I used a helper function to get the index of the element at the cursor location.

Function getIndexforElement(elem As htmlElement, browser As webbrowser) As Integer
    Dim page as mshtml.HTMLdocument
    Dim Elements as mshtml.IHTMLElementCollection
    Dim elemCount As Integer = 0
    page = browser.document.Domdocument
    elements = page.getElementsByTagName(elem.TagName)
    For Each element As mshtml.IHTMLElement In elements
     elemCount = elemCount + 1
     If (elem.OffsetRectangle.Top = element.offsetTop) And (elem.OffsetRectangle.Left = element.offsetLeft) Then
      Exit For
     End If
    Next
    If elemCount > 0 Then
     Dim matches as MatchCollection = regex.Matches(browser.DocumentText,"<" & elem.TagName,regexoptions.IgnoreCase Or regexoptions.Multiline)
     Return matches(elemCount-1).Index + 1
    Else
     Return 0
    End If 
End Function

Having the index of the element a simple regular expression could be used to find the line number in the original html file.

Function getLineNumber(textIn As String, index As Integer) As Integer
    textIn = textIn.Replace(VbCrLf,VbLf)
    Dim line as Integer = regex.Matches(textIn.Substring(0,index),"\n",RegexOptions.Multiline).Count + 1                             
    If line < 1 Then line = 1
    Return line
End Function
barry