guti

Search of the text in the SciTE editor.

8 posts in this topic

#1 ·  Posted

In advance excuse for my bad English

Prompt please in what an error. I try to find and select the text, but
in search result I receive "-1".

How to obtain more essential information:
  1) initial and finite characters,
  2) the text (if it is possible to select it)
  3) number of the line

Functions are taken from "_SciLexer.au3"

Thanks in advance.

Global $user32
$Sci = ControlGetHandle("[CLASS:SciTEWindow]", "", "[CLASS:Scintilla; INSTANCE:1]")

$user32 = DllOpen("user32.dll")

;=== $ss=-1  !!! ? More Information? ====================================== ???
$ss = Sci_Search($Sci, "CLASS")
ConsoleWrite(@ScriptLineNumber & "): " & $ss & @CRLF)


DllClose("user32.dll")

#Region Search Find Word (Text)

Func Sci_Search($Sci, $sSearch, $iStartPos = 0, $iEndPos = 0)

    $sc_TargStart = 2190
    $sc_TargEnd = 2192
    $sc_TargSearch = 2197
    $sc_GetLength = 2006
    ;=== To set search boundaries
    If Not $iEndPos Then $iEndPos = SendMessage($Sci, $sc_GetLength, 0, 0) ;Sci_GetLenght($Sci) ;SCI_GETLENGTH 2006
    SendMessage($Sci, $sc_TargStart, $iStartPos, 0) ;SCI_SETTARGETSTART 2190
    SendMessage($Sci, $sc_TargEnd, $iEndPos, 0) ;SCI_SETTARGETEND 2192

    Return SendMessageString($Sci, $sc_TargSearch, StringLen($sSearch), $sSearch) ;SCI_SEARCHINTARGET 2197

EndFunc   ;==>Sci_Search

Func SendMessage($hwnd, $msg, $wp, $lp)
  ;=== $msg = SCI_SEARCHINTARGET
    Local $ret
    $ret = DllCall($user32, "long", "SendMessageA", "long", $hwnd, "int", $msg, "int", $wp, "int", $lp)
    If @error Then
        SetError(1)
        Return 0
    Else
        SetError(0)
        Return $ret[0]
    EndIf

EndFunc   ;==>SendMessage

Func SendMessageString($hwnd, $msg, $wp, $str)
    Local $ret
    $ret = DllCall($user32, "int", "SendMessageA", "hwnd", $hwnd, "int", $msg, "int", $wp, "str", $str)
    Return $ret[0]
EndFunc   ;==>SendMessageString

 

Share this post


Link to post
Share on other sites



#3 ·  Posted

As suggested by Jos in the previous link from genius257  it works using a workaround

#include <SciteConstants.au3> 

WinActivate("[CLASS:SciTEWindow]", "")
$Sci = ControlGetHandle("[CLASS:SciTEWindow]", "", "[CLASS:Scintilla; INSTANCE:1]")

$str = "ContinueLoop"  ;"CLASS"
$len = StringLen($str)
$txt = ControlGetText("[CLASS:SciTEWindow]", "", "[CLASS:Scintilla; INSTANCE:1]")
$start = StringInStr($txt, $str)-1
SendMessage($Sci, $SCI_SETSEL, $start, $start+StringLen($str))
Sleep(50)
$line = SendMessage($Sci, $SCI_LINEFROMPOSITION, $start, 0)+1
Msgbox(0,"", $line)


Func SendMessage($hwnd, $msg, $wp, $lp)
    Local $ret
    $ret = DllCall("user32.dll", "long", "SendMessageA", "hwnd", $hwnd, "int", $msg, "int", $wp, "int", $lp)
    If @error Then Return SetError(1)
    Return $ret[0]
EndFunc   ;==>SendMessage

 

1 person likes this

Share this post


Link to post
Share on other sites

#4 ·  Posted

Thanks for links, genius257.
Unfortunately, there is too much "include" in that code.

mikell, your example - super.

SendMessage($Sci, $SCI_SETSEL, $start, $start+StringLen($str))
$line = SendMessage($Sci, $SCI_LINEFROMPOSITION, $start, 0)+1

 is that it is necessary!

By analogy, continuing a code, I received the text of the whole line.

$lineLen = SendMessage($Sci, 2350, $line-1, 0) ; SCI_LINELENGTH 2350
$lineIPos = SendMessage($Sci, 2128, $line-1, 0) ; SCI_GETLINEINDENTPOSITION 2128
MsgBox( 0, @ScriptLineNumber & ") ", StringMid($txt,$lineIPos,$lineLen))

But perhaps there is more refined method?

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

I'm not sure about what you exactly want to do. If you want to get the text of the whole line then you will run into the problem described by martin :
"Then if you want to get the text of a particular line you have a problem. You can find the length of a line by sending a message. To get the text of a line there is a message $SCI_GETLINE, which you know, but you have to pass it the line number (first is 0) and the address of a buffer where it can write the result. If the editor is part of your program this is not a problem, but since it isn't (...) then the program which has the editor cannot write to the memory owned by your program."
So you will need the same workaround and your method is the good one

If you want to get other occurences of the search with details then in the loop I (personally) prefer the use of regex to make the search more versatile

#include <SciteConstants.au3> 

WinActivate("[CLASS:SciTEWindow]", "")
$Sci = ControlGetHandle("[CLASS:SciTEWindow]", "", "[CLASS:Scintilla; INSTANCE:1]")

$str = "CLASS"
$len = StringLen($str)
$txt = ControlGetText("[CLASS:SciTEWindow]", "", "[CLASS:Scintilla; INSTANCE:1]")
Local $offset = 1
While 1
    $res = StringRegExp($txt, '(\Q' & $str & '\E)', 1, $offset)
    $offset = @extended
    If not IsArray($res) Then Exitloop
    $end = $offset-1 
    $start = $end - StringLen($res[0])
    ; SendMessage($Sci, $SCI_SETSEL, $start, $end)
    ; Sleep(800)
    $line = SendMessage($Sci, $SCI_LINEFROMPOSITION, $start, 0)+1
    Consolewrite("found at pos " & $start & " - in line " & $line & @crlf)
Wend

Func SendMessage($hwnd, $msg, $wp, $lp)
    Local $ret
    $ret = DllCall("user32.dll", "long", "SendMessageA", "hwnd", $hwnd, "int", $msg, "int", $wp, "int", $lp)
    If @error Then Return SetError(1)
    Return $ret[0]
EndFunc   ;==>SendMessage

 

Edited by mikell
1 person likes this

Share this post


Link to post
Share on other sites

#6 ·  Posted

Thanks for the response, mikell.

Earlier I did by such method
(if the regular expressions aren't necessary):

;=== Get text 
$txt = ControlGetText("...") ;=== Or by reading of file

;=== Then I received an array
$arr = StringSplit($txt, ...)

;=== Later I received Number of Line and Text of Line
For $i = 0 To UBound($arr) - 1
    If StringInStr($txt, $strsearch, ...) Then
        ;=== Get Rezult =========================
        $iNmbLine = $i ;=== Number of Line
        $sTextLine = $arr[$i] ;=== Text of Line
        ConsoleWrite(@ScriptLineNumber & "): " & $iNmbLine & "): " & $sTextLine" & @CRLF)
        
    Next
Next

Can be simpler to use such method for search?
Method of processing of "Strings".
Here it isn't necessary to think about addressing.

And messages like "Sci_SendMessage"
to use only for visual changes in the editor's window? (Hide a line, change color, select word, ...)?

How you think of it?

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Yes, by default the EOL is CRLF in Scite,  so "StringSplit($txt, @crlf, 1)" does the trick and your method is reliable - and simpler indeed, if you don't need to know the position in the text
:)


 

Edited by mikell
1 person likes this

Share this post


Link to post
Share on other sites

#8 ·  Posted

mikell, many thanks for the help!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now