call: SCI_GETTEXTRANGE, Scite crash,why? Topic is solved

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
cgx5871
Posts: 319
Joined: 26 Jul 2018, 14:02

Re: call: SCI_GETTEXTRANGE, Scite crash,why?

03 Sep 2023, 10:18

teadrinker wrote:
03 Sep 2023, 09:55
If you are running this code, it is not for SciTE.
I can't understand the meaning of this sentence
You mean using hotkeys?

Code: Select all

F12::
{
MsgBox Sci_GetTextRange(hSci, 3, 15)
}
still empty
teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: call: SCI_GETTEXTRANGE, Scite crash,why?

03 Sep 2023, 10:23

No, I meant you need using this code for SciTE. If it doesn't work, I have no idea why. For me it works.
neogna2
Posts: 600
Joined: 15 Sep 2016, 15:44

Re: call: SCI_GETTEXTRANGE, Scite crash,why?

03 Sep 2023, 11:00

Thank you teadrinker!

Your version with SCI_GETTEXTRANGEFULL works for me in the most recent Notepad++ v8.5.6, even in a test on 256MB text with end set to -1.

Two suggestions for things you could update in this thread, to help people finding and reading the thread later:
1. rename the version using SCI_GETTEXTRANGEFULL to Sci_GetTextRangeFull
2. update the older version (that works for Scite4AutoHotkey 3.1.00) to also have the fullTextLength steps so that end pos -1 is supported there too.

I can confirm what you wrote earlier: in the most recent Notepad++ the Sci_CharacterRange struct has changed so that even SCI_GETTEXTRANGE calls (just like SCI_GETTEXTRANGEFULL calls) needs size A_PtrSize * 3 (not 4+4+A_PtrSize). The most recent doc at https://www.scintilla.org/ScintillaDoc.html#Sci_TextRange seems not updated to describe that change, it still says "These structures are defined to be exactly the same shape as the Win32 TEXTRANGE and CHARRANGE" and CHARRANGE is 4+4 bytes (LONG+LONG)


Perhaps some (versions of some) app out there has a Scintilla control without SCI_GETTEXTRANGEFULL (< v5.2.3) but with the Sci_CharacterRange struct change (> v?.?.?) and so need a third version of the function.
teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: call: SCI_GETTEXTRANGE, Scite crash,why?  Topic is solved

03 Sep 2023, 12:26

neogna2 wrote: Perhaps some (versions of some) app out there has a Scintilla control without SCI_GETTEXTRANGEFULL (< v5.2.3) but with the Sci_CharacterRange struct change (> v?.?.?) and so need a third version of the function.
The changelog says that these changes came starting with v5.2.3, so we'll be guided by that.
Duplicate APIs to support 64-bit document positions on Win32: SCI_GETTEXTRANGEFULL, SCI_FINDTEXTFULL, and SCI_FORMATRANGEFULL.
So, there are two options, first for versions <= 5.2.2, second for versions >= 5.2.3. Some apps still use old versions, like SciTE4AutoHotkey. Notepad++ uses new versions.
For v <= 5.2.2:

Code: Select all

#Requires AutoHotkey v2

start := 0
end := 100
hSci := ControlGetHwnd('Scintilla1', 'ahk_class SciTEWindow')
MsgBox Sci_GetTextRange(hSci, start, end)

; for Scintilla versions <= 5.2.2 (SciTE4AutoHotkey)
Sci_GetTextRange(hSci, start, end) {
    static SCI_GETTEXTRANGE := 2162, SCI_GETTEXTLENGTH := 2183, SCI_GETCODEPAGE := 2137
    fullTextLength := SendMessage(SCI_GETTEXTLENGTH,,, hSci)
    if start >= fullTextLength {
        throw Error('The starting position exceeds the total length of the text')
    }
    if end < -1 || (end != -1 && end <= start) {
        throw Error('Invalid end position')
    }
    if end > fullTextLength {
        end := fullTextLength
    }
    textSize := end = -1 ? fullTextLength - start : end - start
    PID := WinGetPID(hSci)
    ptrSize := GetProcessBitness(PID) // 8
    Sci_TextRange := Buffer(size := 8 + ptrSize, 0)
    RB := RemoteBuffer(PID, size + textSize + 1)
    NumPut('UInt', start, 'Int', end, ptrSize = 4 ? 'UInt' : 'Int64', RB.ptr + size, Sci_TextRange)
    RB.Write(Sci_TextRange)
    textSize := SendMessage(SCI_GETTEXTRANGE,, RB.ptr, hSci) + 1
    textBuf := Buffer(textSize, 0)
    RB.Read(textBuf, size)
    return StrGet(textBuf, "CP" . SendMessage(SCI_GETCODEPAGE,,, hSci))
}

GetProcessBitness(PID) {
    static flag := PROCESS_QUERY_INFORMATION := 0x400
    if !A_Is64bitOS
        return 32
    hProc := DllCall('OpenProcess', 'UInt', flag, 'UInt', 0, 'UInt', PID, 'Ptr')
    DllCall('IsWow64Process', 'Ptr', hProc, 'IntP', &is32 := 0)
    DllCall('CloseHandle', 'Ptr', hProc)
    return 32 << !is32
}

class RemoteBuffer
{
    __New(PID, size) {
        static flags := (PROCESS_VM_OPERATION := 0x8) | (PROCESS_VM_WRITE := 0x20) | (PROCESS_VM_READ := 0x10)
            , Params := ['UInt', MEM_COMMIT := 0x1000, 'UInt', PAGE_READWRITE := 0x4, 'Ptr']

        if !this.hProc := DllCall('OpenProcess', 'UInt', flags, 'Int', 0, 'UInt', PID, 'Ptr')
            throw OSError('Can`'t open remote process PID = ' . PID . '`nA_LastError: ' . A_LastError, 'RemoteBuffer.__New')

        if !this.ptr := DllCall('VirtualAllocEx', 'Ptr', this.hProc, 'Ptr', 0, 'Ptr', size, Params*) {
            DllCall('CloseHandle', 'Ptr', this.hProc)
            throw OSError('Can`'t allocate memory in remote process PID = ' . PID . '`nA_LastError: ' . A_LastError, 'RemoteBuffer.__New')
        }
    }
    __Delete() {
        DllCall('VirtualFreeEx', 'Ptr', this.hProc, 'Ptr', this.ptr, 'UInt', 0, 'UInt', MEM_RELEASE := 0x8000)
        DllCall('CloseHandle', 'Ptr', this.hProc)
    }
    Read(BufObj, offset := 0) {
        if !DllCall('ReadProcessMemory', 'Ptr', this.hProc, 'Ptr', this.ptr + offset, 'Ptr', BufObj, 'Ptr', BufObj.Size, 'PtrP', &bytesRead := 0)
            throw OSError('Can`'t read data from remote buffer`nA_LastError: ' . A_LastError, 'RemoteBuffer.Read')
        return bytesRead
    }
    Write(BufObj, offset := 0) {
        if !res := DllCall('WriteProcessMemory', 'Ptr', this.hProc, 'Ptr', this.ptr + offset, 'Ptr', BufObj, 'Ptr', BufObj.Size, 'PtrP', &bytesWritten := 0)
            throw OSError('Can`'t write data to remote buffer`nA_LastError: ' . A_LastError, 'RemoteBuffer.Write')
        return bytesWritten
    }
}
For v >= 5.2.3:

Code: Select all

#Requires AutoHotkey v2

start := 0
end := 100
hSci := ControlGetHwnd('Scintilla1', 'ahk_class Notepad++')
MsgBox Sci_GetTextRangeFull(hSci, start, end)

; for Scintilla versions >= 5.2.3 (Notepad++)
Sci_GetTextRangeFull(hSci, start, end) {
    static SCI_GETTEXTRANGEFULL := 2039, SCI_GETTEXTLENGTH := 2183, SCI_GETCODEPAGE := 2137
    fullTextLength := SendMessage(SCI_GETTEXTLENGTH,,, hSci)
    if start >= fullTextLength {
        throw Error('The starting position exceeds the total length of the text')
    }
    if end < -1 || (end != -1 && end <= start) {
        throw Error('Invalid end position')
    }
    if end > fullTextLength {
        end := fullTextLength
    }
    textSize := end = -1 ? fullTextLength - start : end - start
    PID := WinGetPID(hSci)
    ptrSize := GetProcessBitness(PID) // 8
    Sci_TextRange := Buffer(size := ptrSize * 3, 0)
    RB := RemoteBuffer(PID, size + textSize + 1)
    type := ptrSize = 4 ? 'UInt' : 'Int64'
    NumPut(type, start, type, end, type, RB.ptr + size, Sci_TextRange)
    RB.Write(Sci_TextRange)
    textSize := SendMessage(SCI_GETTEXTRANGEFULL,, RB.ptr, hSci) + 1
    textBuf := Buffer(textSize, 0)
    RB.Read(textBuf, size)
    return StrGet(textBuf, 'CP' . SendMessage(SCI_GETCODEPAGE,,, hSci))
}

GetProcessBitness(PID) {
    static flag := PROCESS_QUERY_INFORMATION := 0x400
    if !A_Is64bitOS
        return 32
    hProc := DllCall('OpenProcess', 'UInt', flag, 'UInt', 0, 'UInt', PID, 'Ptr')
    DllCall('IsWow64Process', 'Ptr', hProc, 'IntP', &is32 := 0)
    DllCall('CloseHandle', 'Ptr', hProc)
    return 32 << !is32
}

class RemoteBuffer
{
    __New(PID, size) {
        static flags := (PROCESS_VM_OPERATION := 0x8) | (PROCESS_VM_WRITE := 0x20) | (PROCESS_VM_READ := 0x10)
            , Params := ['UInt', MEM_COMMIT := 0x1000, 'UInt', PAGE_READWRITE := 0x4, 'Ptr']

        if !this.hProc := DllCall('OpenProcess', 'UInt', flags, 'Int', 0, 'UInt', PID, 'Ptr')
            throw OSError('Can`'t open remote process PID = ' . PID . '`nA_LastError: ' . A_LastError, 'RemoteBuffer.__New')

        if !this.ptr := DllCall('VirtualAllocEx', 'Ptr', this.hProc, 'Ptr', 0, 'Ptr', size, Params*) {
            DllCall('CloseHandle', 'Ptr', this.hProc)
            throw OSError('Can`'t allocate memory in remote process PID = ' . PID . '`nA_LastError: ' . A_LastError, 'RemoteBuffer.__New')
        }
    }
    __Delete() {
        DllCall('VirtualFreeEx', 'Ptr', this.hProc, 'Ptr', this.ptr, 'UInt', 0, 'UInt', MEM_RELEASE := 0x8000)
        DllCall('CloseHandle', 'Ptr', this.hProc)
    }
    Read(BufObj, offset := 0) {
        if !DllCall('ReadProcessMemory', 'Ptr', this.hProc, 'Ptr', this.ptr + offset, 'Ptr', BufObj, 'Ptr', BufObj.Size, 'PtrP', &bytesRead := 0)
            throw OSError('Can`'t read data from remote buffer`nA_LastError: ' . A_LastError, 'RemoteBuffer.Read')
        return bytesRead
    }
    Write(BufObj, offset := 0) {
        if !res := DllCall('WriteProcessMemory', 'Ptr', this.hProc, 'Ptr', this.ptr + offset, 'Ptr', BufObj, 'Ptr', BufObj.Size, 'PtrP', &bytesWritten := 0)
            throw OSError('Can`'t write data to remote buffer`nA_LastError: ' . A_LastError, 'RemoteBuffer.Write')
        return bytesWritten
    }
}
Last edited by teadrinker on 03 Sep 2023, 16:00, edited 8 times in total.
cgx5871
Posts: 319
Joined: 26 Jul 2018, 14:02

Re: call: SCI_GETTEXTRANGE, Scite crash,why?

03 Sep 2023, 14:30

@teadrinker
I found some reasons,
1. I click run from Scite, when running the script. Scite will crash
image.png
image.png (60.38 KiB) Viewed 1321 times
image.png
image.png (14.28 KiB) Viewed 1321 times
2. I double-click to run the script from the resource manager. GetTextRange can be read normally
image.png
image.png (61.96 KiB) Viewed 1321 times

Why is this happening?
How to solve this problem.
Because the requirement is to debug the script in Scite.
teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: call: SCI_GETTEXTRANGE, Scite crash,why?

03 Sep 2023, 15:12

I realized what the problem is. Most likely, you have SciTE using 32 bit AHK interpreter, and when you run the script with double click, 64 bit is used. The SciTe process is 64 bit, when the script is run with the 32 bit interpreter, the A_PtrSize does not match. I edited the code to take this nuance into account, check it out, it should work now.
cgx5871
Posts: 319
Joined: 26 Jul 2018, 14:02

Re: call: SCI_GETTEXTRANGE, Scite crash,why?

03 Sep 2023, 22:24

@teadrinker
thank you very much
Sure enough, this is the reason.
Originally for compatibility with Excel. It used x32.
Thanks again for your help.
It bothered me for a week.
cgx5871
Posts: 319
Joined: 26 Jul 2018, 14:02

Re: call: SCI_GETTEXTRANGE, Scite crash,why?

06 Sep 2023, 13:19

@teadrinker
I imitated your code and wrote a Sci_GetSelection
But found that the returned bytes are missing the first 16 characters.
For example: selection:="1234567890abcdefgh" it only returns "gh"
I don't know anything about these "numput" "buffer" "dllcall" mechanisms.
Can you help me see where is the problem in the code?

Code: Select all

#SingleInstance

hSci := ControlGetHwnd('Scintilla1', 'ahk_class SciTEWindow')
MsgBox Sci_GetSelection()
;~ ____________________________________________ 1234567890abcdefgh
Sci_GetSelection() {
    static SCI_GETCODEPAGE := 2137, SCI_GETSELTEXT := 2161
	;~ ;Get length. SCI_GETSELTEXT
	textSize:=SendMessage(SCI_GETSELTEXT, 0, 0,,hSci)

    PID := WinGetPID(hSci)
    ptrSize := GetProcessBitness(PID) // 8
    TextRange := Buffer(size := 8 + ptrSize, 0)
    RB := RemoteBuffer(PID, size + textSize + 1)
            NumPut(ptrSize = 4 ? 'UInt' : 'Int64', RB.ptr + size, TextRange)
    RB.Write(TextRange)
    textSize := SendMessage(SCI_GETSELTEXT,, RB.ptr, hSci) + 1
    textBuf := Buffer(textSize, 0)
    RB.Read(textBuf, size)
    return StrGet(textBuf, "CP" . SendMessage(SCI_GETCODEPAGE,,, hSci))
}
GetProcessBitness(PID) {
    static flag := PROCESS_QUERY_INFORMATION := 0x400
    if !A_Is64bitOS
        return 32
    hProc := DllCall('OpenProcess', 'UInt', flag, 'UInt', 0, 'UInt', PID, 'Ptr')
    DllCall('IsWow64Process', 'Ptr', hProc, 'IntP', &is32 := 0)
    DllCall('CloseHandle', 'Ptr', hProc)
    return 32 << !is32
}

class RemoteBuffer
{
    __New(PID, size) {
        static flags := (PROCESS_VM_OPERATION := 0x8) | (PROCESS_VM_WRITE := 0x20) | (PROCESS_VM_READ := 0x10)
            , Params := ['UInt', MEM_COMMIT := 0x1000, 'UInt', PAGE_READWRITE := 0x4, 'Ptr']

        if !this.hProc := DllCall('OpenProcess', 'UInt', flags, 'Int', 0, 'UInt', PID, 'Ptr')
            throw OSError('Can`'t open remote process PID = ' . PID . '`nA_LastError: ' . A_LastError, 'RemoteBuffer.__New')

        if !this.ptr := DllCall('VirtualAllocEx', 'Ptr', this.hProc, 'Ptr', 0, 'Ptr', size, Params*) {
            DllCall('CloseHandle', 'Ptr', this.hProc)
            throw OSError('Can`'t allocate memory in remote process PID = ' . PID . '`nA_LastError: ' . A_LastError, 'RemoteBuffer.__New')
        }
    }
    __Delete() {
        DllCall('VirtualFreeEx', 'Ptr', this.hProc, 'Ptr', this.ptr, 'UInt', 0, 'UInt', MEM_RELEASE := 0x8000)
        DllCall('CloseHandle', 'Ptr', this.hProc)
    }
    Read(BufObj, offset := 0) {
        if !DllCall('ReadProcessMemory', 'Ptr', this.hProc, 'Ptr', this.ptr + offset, 'Ptr', BufObj, 'Ptr', BufObj.Size, 'PtrP', &bytesRead := 0)
            throw OSError('Can`'t read data from remote buffer`nA_LastError: ' . A_LastError, 'RemoteBuffer.Read')
        return bytesRead
    }
    Write(BufObj, offset := 0) {
        if !res := DllCall('WriteProcessMemory', 'Ptr', this.hProc, 'Ptr', this.ptr + offset, 'Ptr', BufObj, 'Ptr', BufObj.Size, 'PtrP', &bytesWritten := 0)
            throw OSError('Can`'t write data to remote buffer`nA_LastError: ' . A_LastError, 'RemoteBuffer.Write')
        return bytesWritten
    }
}
image.png
image.png (10.48 KiB) Viewed 1216 times
teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: call: SCI_GETTEXTRANGE, Scite crash,why?

06 Sep 2023, 13:35

In this case the Sci_TextRange structure is not used, a simple buffer of textSize is needed here.

Code: Select all

#SingleInstance

hSci := ControlGetHwnd('Scintilla1', 'ahk_class SciTEWindow')
MsgBox Sci_GetSelection(hSci)

Sci_GetSelection(hSci) {
    static SCI_GETCODEPAGE := 2137, SCI_GETSELTEXT := 2161
    PID := WinGetPID(hSci)
	textSize := SendMessage(SCI_GETSELTEXT,,, hSci) + 1
    RB := RemoteBuffer(PID, textSize)
    SendMessage(SCI_GETSELTEXT,, RB.ptr, hSci)
    textBuf := Buffer(textSize, 0)
    RB.Read(textBuf)
    return StrGet(textBuf, "CP" . SendMessage(SCI_GETCODEPAGE,,, hSci))
}

class RemoteBuffer
{
    __New(PID, size) {
        static flags := (PROCESS_VM_OPERATION := 0x8) | (PROCESS_VM_WRITE := 0x20) | (PROCESS_VM_READ := 0x10)
            , Params := ['UInt', MEM_COMMIT := 0x1000, 'UInt', PAGE_READWRITE := 0x4, 'Ptr']

        if !this.hProc := DllCall('OpenProcess', 'UInt', flags, 'Int', 0, 'UInt', PID, 'Ptr')
            throw OSError('Can`'t open remote process PID = ' . PID . '`nA_LastError: ' . A_LastError, 'RemoteBuffer.__New')

        if !this.ptr := DllCall('VirtualAllocEx', 'Ptr', this.hProc, 'Ptr', 0, 'Ptr', size, Params*) {
            DllCall('CloseHandle', 'Ptr', this.hProc)
            throw OSError('Can`'t allocate memory in remote process PID = ' . PID . '`nA_LastError: ' . A_LastError, 'RemoteBuffer.__New')
        }
    }
    __Delete() {
        DllCall('VirtualFreeEx', 'Ptr', this.hProc, 'Ptr', this.ptr, 'UInt', 0, 'UInt', MEM_RELEASE := 0x8000)
        DllCall('CloseHandle', 'Ptr', this.hProc)
    }
    Read(BufObj, offset := 0) {
        if !DllCall('ReadProcessMemory', 'Ptr', this.hProc, 'Ptr', this.ptr + offset, 'Ptr', BufObj, 'Ptr', BufObj.Size, 'PtrP', &bytesRead := 0)
            throw OSError('Can`'t read data from remote buffer`nA_LastError: ' . A_LastError, 'RemoteBuffer.Read')
        return bytesRead
    }
    Write(BufObj, offset := 0) {
        if !res := DllCall('WriteProcessMemory', 'Ptr', this.hProc, 'Ptr', this.ptr + offset, 'Ptr', BufObj, 'Ptr', BufObj.Size, 'PtrP', &bytesWritten := 0)
            throw OSError('Can`'t write data to remote buffer`nA_LastError: ' . A_LastError, 'RemoteBuffer.Write')
        return bytesWritten
    }
}
Last edited by teadrinker on 06 Sep 2023, 13:44, edited 3 times in total.
teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: call: SCI_GETTEXTRANGE, Scite crash,why?

06 Sep 2023, 13:39

Also, in this case you don't need to determine the pointer size in the SciTE process, so the GetProcessBitness() function is also unnecessary.
cgx5871
Posts: 319
Joined: 26 Jul 2018, 14:02

Re: call: SCI_GETTEXTRANGE, Scite crash,why?

06 Sep 2023, 14:54

@teadrinker
Thanks again
cgx5871
Posts: 319
Joined: 26 Jul 2018, 14:02

Re: call: SCI_GETTEXTRANGE, Scite crash,why?

06 Sep 2023, 22:50

I tried to write a piece of code and found that the insertion was garbled
help me, thanks

SCI_INSERTTEXT(position pos, const char *text)
*This inserts the zero terminated text string at position pos or at the current position if pos is -1. If the current position is after the insertion point then it is moved along with its surrounding text but no scrolling is performed.

Code: Select all

#SingleInstance

hSci := ControlGetHwnd('Scintilla1', 'ahk_class SciTEWindow')
Sci_INSERTTEXT("AAA",5)

;~ _________________________________
Sci_INSERTTEXT(txt,pos) {
    static Sci_INSERTTEXT:=2003,SCI_GETCODEPAGE:=2137,SCI_GETCODEPAGE := 2137

            textSize := StrPut(txt,"CP" . SendMessage(SCI_GETCODEPAGE,,, hSci))	;  textsize
        PID := WinGetPID(hSci)
        ptrSize := GetProcessBitness(PID) // 8
        Sci_TextRange := Buffer(size := 8 + ptrSize, 0)
        RB := RemoteBuffer(PID, size + textSize + 1)
            NumPut('UInt', pos, ptrSize = 4 ? 'UInt' : 'Int64', RB.ptr + size, Sci_TextRange)		; pos
        RB.Write(Sci_TextRange)
        SendMessage(Sci_INSERTTEXT,pos, RB.ptr, hSci) + 1
}

;~ ================================
GetProcessBitness(PID) {
    static flag := PROCESS_QUERY_INFORMATION := 0x400
    if !A_Is64bitOS
        return 32
    hProc := DllCall('OpenProcess', 'UInt', flag, 'UInt', 0, 'UInt', PID, 'Ptr')
    DllCall('IsWow64Process', 'Ptr', hProc, 'IntP', &is32 := 0)
    DllCall('CloseHandle', 'Ptr', hProc)
    return 32 << !is32
}
class RemoteBuffer
{
    __New(PID, size) {
        static flags := (PROCESS_VM_OPERATION := 0x8) | (PROCESS_VM_WRITE := 0x20) | (PROCESS_VM_READ := 0x10)
            , Params := ['UInt', MEM_COMMIT := 0x1000, 'UInt', PAGE_READWRITE := 0x4, 'Ptr']

        if !this.hProc := DllCall('OpenProcess', 'UInt', flags, 'Int', 0, 'UInt', PID, 'Ptr')
            throw OSError('Can`'t open remote process PID = ' . PID . '`nA_LastError: ' . A_LastError, 'RemoteBuffer.__New')

        if !this.ptr := DllCall('VirtualAllocEx', 'Ptr', this.hProc, 'Ptr', 0, 'Ptr', size, Params*) {
            DllCall('CloseHandle', 'Ptr', this.hProc)
            throw OSError('Can`'t allocate memory in remote process PID = ' . PID . '`nA_LastError: ' . A_LastError, 'RemoteBuffer.__New')
        }
    }
    __Delete() {
        DllCall('VirtualFreeEx', 'Ptr', this.hProc, 'Ptr', this.ptr, 'UInt', 0, 'UInt', MEM_RELEASE := 0x8000)
        DllCall('CloseHandle', 'Ptr', this.hProc)
    }
    Read(BufObj, offset := 0) {
        if !DllCall('ReadProcessMemory', 'Ptr', this.hProc, 'Ptr', this.ptr + offset, 'Ptr', BufObj, 'Ptr', BufObj.Size, 'PtrP', &bytesRead := 0)
            throw OSError('Can`'t read data from remote buffer`nA_LastError: ' . A_LastError, 'RemoteBuffer.Read')
        return bytesRead
    }
    Write(BufObj, offset := 0) {
        if !res := DllCall('WriteProcessMemory', 'Ptr', this.hProc, 'Ptr', this.ptr + offset, 'Ptr', BufObj, 'Ptr', BufObj.Size, 'PtrP', &bytesWritten := 0)
            throw OSError('Can`'t write data to remote buffer`nA_LastError: ' . A_LastError, 'RemoteBuffer.Write')
        return bytesWritten
    }
}
teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: call: SCI_GETTEXTRANGE, Scite crash,why?

07 Sep 2023, 03:05

You have to understand how it works. You read the description, does it say anything about Sci_TextRange? So why are you trying to use it again? You just need to write the text to a buffer and pass it to the process.
cgx5871
Posts: 319
Joined: 26 Jul 2018, 14:02

Re: call: SCI_GETTEXTRANGE, Scite crash,why?

07 Sep 2023, 23:42

@teadrinker
After studying for a day, I modified it.
Still can't figure it out. When you have time, help me find out where the problem is in the code.

Code: Select all

#Include <RemoteBuffer>
hSci := ControlGetHwnd("Scintilla2", "ahk_class SciTEWindow")
cp:="CP" . SendMessage(2137,,, hSci)    ;~ SCI_GETCODEPAGE:=2137

Sci_InsertText("aaa",2)

Sci_InsertText(Text, pos := -1) {
	textSize := StrPut(Text, cp)
    TextCnv := Buffer(textSize)
    PID := WinGetPID(hSci)
    RB := RemoteBuffer(PID, textSize)
	StrPut(Text, TextCnv, cp)
	RB.Write(TextCnv, textSize + 1)
    
    /**SCI_INSERTTEXT(position pos, const char *text) := 2003 
      *This inserts the zero terminated text string at position pos or at the current position if pos is -1. 
      *If the current position is after the insertion point then it is moved along with its surrounding text but no scrolling is performed.
    */
	SendMessage(2003, pos, RB.ptr, , hSci)
}
neogna2
Posts: 600
Joined: 15 Sep 2016, 15:44

Re: call: SCI_GETTEXTRANGE, Scite crash,why?

08 Sep 2023, 01:10

@cgx5871 you're close but some things need fixing
- in the RB.Write call you shouldn't set any offset (An offset is how many bytes from the start of the buffer that writing should start. In this case we should write at the start of the buffer so set no offset.)
- the control name is Scintilla1 (not Scintilla2) in Scite4AutoHotkey
- in SendMessage hSci is parameter 4 (Control) (not 5, WinTitle)

Code: Select all

hSci := ControlGetHwnd("Scintilla1", "ahk_class SciTEWindow")
cp := "CP" . SendMessage(2137,,, hSci)    ;~ SCI_GETCODEPAGE:=2137
Sci_InsertText("aaa",2)

Sci_InsertText(Text, pos := -1) {
    ;calculate needed buffer size to fit the text (including a NUL zero terminator at the end)
    textSize := StrPut(Text, cp)
    ;create local Buffer that fits text and NUL
    ;zero-initialising ensures that the last character is NUL (0)
    TextCnv := Buffer(textSize, 0)
    PID := WinGetPID(hSci)
    ;create remote Buffer that fits text and NUL
    RB := RemoteBuffer(PID, textSize)
    StrPut(Text, TextCnv, cp)
    ;write local buffer to remote buffer without offset
    RB.Write(TextCnv)
    SendMessage(2003, pos, RB.ptr, hSci)
}
(edit2: updated text and code to remove unnecessary +1 buffer size step. Because StrPut in 2-parameter mode returns a size that includes space for a zero terminator character.)
cgx5871
Posts: 319
Joined: 26 Jul 2018, 14:02

Re: call: SCI_GETTEXTRANGE, Scite crash,why?

08 Sep 2023, 07:41

@neogna2

thanks for your reply.
Thank you for your detailed notes.
I am using chatGPT, slowly understand some.

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: big-jg, Rohwedder, zizanie13 and 49 guests