<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; AHK: Поиск в Notepad++ с помощью Scintilla]]></title>
	<link rel="self" href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=17362&amp;type=atom" />
	<updated>2022-09-11T20:59:12Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.script-coding.com/viewtopic.php?id=17362</id>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Поиск в Notepad++ с помощью Scintilla]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=154730#p154730" />
			<content type="html"><![CDATA[<p>Отлично, работает, огромное спасибо!</p>]]></content>
			<author>
				<name><![CDATA[Vadus]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=25975</uri>
			</author>
			<updated>2022-09-11T20:59:12Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=154730#p154730</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Поиск в Notepad++ с помощью Scintilla]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=154729#p154729" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>Vadus пишет:</cite><blockquote><div class="codebox"><pre><code>remoteBuff.Read(&amp;localBuff, charCount)</code></pre></div></blockquote></div><p>Здесь нужно передавать не адрес, а саму переменную, смотрите, что принимает метод Read().</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2022-09-11T20:38:34Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=154729#p154729</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Поиск в Notepad++ с помощью Scintilla]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=154721#p154721" />
			<content type="html"><![CDATA[<p>В продолжение темы поиска в Notepad++ — код выше позволяет найти и выделить фразу, но я хотел бы получить сам <strong>текст найденной фразы</strong>, поскольку поиск идет по регулярному выражению.<br />Я попробовал использовать Scintilla-команду SCI_GETTARGETTEXT. Добавил ее в код поиска:<br /></p><div class="codebox"><pre><code>

SCI_SETSEL          := 2160
SCI_SETSEARCHFLAGS  := 2198
SCFIND_REGEXP 		:= 0x00200000
SCI_SETTARGETSTART 	:= 2190
SCI_SETTARGETEND 	:= 2192
SCI_SEARCHINTARGET 	:= 2197
SCI_GETTARGETSTART 	:= 2191
SCI_GETTARGETEND 	:= 2193   
SCI_GETSEARCHFLAGS 	:= 2199

ControlGet, hScintilla, hwnd,, Scintilla1, ahk_class Notepad++
if !hScintilla {
   MsgBox, Scintilla not found
   ExitApp
}

;--- Устанавливаем флаги поиска SCI_SETSEARCHFLAGS
SendMessage, SCI_SETSEARCHFLAGS, SCFIND_REGEXP,,, ahk_id %hScintilla% ;опция поиска, когда строку поиска следует интерпретировать как регулярное выражение}

;Получаем длину всего текста в редакторе
SendMessage, SCI_GETTEXTLENGTH := 2183, 0,,, ahk_id %hScintilla%
ДлинаТекста := ErrorLevel
; MsgBox ДлинаТекста: &#039;%ДлинаТекста%&#039;

;Получаем номер текущей позиции курсора во всем тексте
SendMessage, SCI_GETCURRENTPOS := 2008, 0,,, ahk_id %hScintilla%
currentPosition := ErrorLevel
; MsgBox currentPosition: %currentPosition%

;--- Устанавливаем целевой диапазон поиска — от начала до конца текста
SendMessage, SCI_SETTARGETSTART, 0,,, ahk_id %hScintilla%
SendMessage, SCI_SETTARGETEND, ДлинаТекста,,, ahk_id %hScintilla%

;--- Производим поиск с помощью регулярных выражений
firstMatchPos := Func_SEARCHINTARGET(hScintilla, &quot;русск.+?поиска&quot;) ;ищем русский текст
;в firstMatchPos — позиция начала найденного текста или -1, если не нашли
; MsgBox firstMatchPos: &#039;%firstMatchPos%&#039;  

;--- Получаем позиции найденной фразы, помещенные в TARGET
 SendMessage, SCI_GETTARGETSTART,,,, ahk_id %hScintilla%
 foundStart := ErrorLevel
 ; MsgBox foundStart: &#039;%foundStart%&#039; ;выводит 0

 SendMessage, SCI_GETTARGETEND,,,, ahk_id %hScintilla%
 foundEnd := ErrorLevel
 ; MsgBox foundEnd: &#039;%foundEnd%&#039; ;выводит 0

; Прокрутить экран до найденной фразы и установить на нее курсор
SendMessage, SCI_SETSEL, foundStart, foundEnd,, ahk_id %hScintilla%

НайденныйТекст := GETTARGETTEXT(WinExist(&quot;ahk_class Notepad++&quot;)) ;получаем выделенный текст слов в Notepad++
MsgBox НайденныйТекст: &#039;%НайденныйТекст%&#039;

GETTARGETTEXT(hNPP)  {
;Получить ;получаем текст строки в Notepad++ по ее номеру (начиная с 0). См. C:\!!Work\AutoHotkey.docx{[Текст_строки_по_номеру]}
;31.07.22 Сделал на основе функции Получить текст текущей строки в Notepad++, просто заменил заменил SCI_GETCURLINE := 2027 на SCI_GETLINE := 2153, %НомерСтроки%

   if !WinExist(&quot;ahk_id&quot; hNPP)  {
      MsgBox, Окно Notepad++ не найдено
      Return
   }
   WinGet, PID, PID
   ControlGetFocus, focused
   if InStr(focused, &quot;Scintilla&quot;)
      ControlGet, hScintilla, hwnd,, % focused
   else
      hScintilla := GetCurrentScintilla(PID)
   
   if !hScintilla  {
      MsgBox, Не удалось определить текущее поле редактирования
      Return
   }
   WinWait, ahk_id %hScintilla%
   SendMessage, SCI_GETTARGETTEXT := 2687
      
   charCount := ErrorLevel
   if (charCount &lt; 2)
      Return
   
   MsgBox charCount: &#039;%charCount%&#039; ;длина найденного текста
   
   remoteBuff := new RemoteBuffer(PID, charCount)
   SendMessage, SCI_GETTARGETTEXT := 2687,, remoteBuff.ptr
   
   VarSetCapacity(localBuff, charCount, 0)
   remoteBuff.Read(&amp;localBuff, charCount)
   SendMessage, SCI_GETCODEPAGE := 2137
   Return StrGet(&amp;localBuff, &quot;CP&quot; . ErrorLevel)
}


GetCurrentScintilla(PID)  {
   remoteBuff := new RemoteBuffer(PID, 4)
   SendMessage, NPPM_GETCURRENTSCINTILLA := 2028,, remoteBuff.ptr
   VarSetCapacity(localBuff, 4, 0)
   remoteBuff.Read(&amp;localBuff, 4)
   
   if handles := GetScintillaHandles()
      Return handles[ NumGet(localBuff, &quot;Int&quot;) + 1 ]
}

GetScintillaHandles()  {
   WinGet, list, ControlList
   WinGet, listHwnd, ControlListHwnd
   arrClassNN := StrSplit(list, &quot;`n&quot;)
   arrHwnd := StrSplit(listHwnd, &quot;`n&quot;)
   for k, v in arrClassNN  {
      if InStr(prevClass, &quot;Scintilla&quot;) &amp;&amp; InStr(v, &quot;Scintilla&quot;)
         Return [ arrHwnd[k - 1], arrHwnd[k] ]
      prevClass := v
   }
}
   

Func_SEARCHINTARGET(hScintilla, text) 
;Функция поиска в Notepad++ с помощью регулярного выражения
{
	SCI_SEARCHINTARGET := 2197
	firstMatchPos := -1
	WinGet, PID, PID, ahk_id %hScintilla%
	; size := StrPut(text, &quot;UTF-8&quot;) ;чтобы работал поиск кириллицы в файле с кодировкой UTF-8
	size := StrPut(text, &quot;CP1251&quot;) ;чтобы работал поиск кириллицы в файле с ANSI-кодировкой
	RB := new RemoteBuffer(PID, size) ;создаем новый RemoteBuffer
	VarSetCapacity(buf, size, 0)
	; StrPut(text, &amp;buf, &quot;UTF-8&quot;);чтобы работал поиск кириллицы в файле с кодировкой UTF-8
	StrPut(text, &amp;buf, &quot;CP1251&quot;) ;чтобы работал поиск кириллицы в файле с ANSI-кодировкой
	RB.Write(&amp;buf, size)
	SendMessage, SCI_SEARCHINTARGET, 10, RB.ptr,, ahk_id %hScintilla%
	firstMatchPos := ErrorLevel
	Return firstMatchPos
}


class RemoteBuffer
{
   __New(PID, size) {
      static flags := (PROCESS_VM_OPERATION := 0x8) | (PROCESS_VM_WRITE := 0x20) | (PROCESS_VM_READ := 0x10)
           , Params := [&quot;UInt&quot;, MEM_COMMIT := 0x1000, &quot;UInt&quot;, PAGE_READWRITE := 0x4, &quot;Ptr&quot;]
         
      if !this.hProc := DllCall(&quot;OpenProcess&quot;, &quot;UInt&quot;, flags, &quot;Int&quot;, 0, &quot;UInt&quot;, PID, &quot;Ptr&quot;)
         throw Exception(&quot;Can&#039;t open remote process PID = &quot; . PID . &quot;`nA_LastError: &quot; . A_LastError, &quot;RemoteBuffer.__New&quot;)
      
      if !this.ptr := DllCall(&quot;VirtualAllocEx&quot;, &quot;Ptr&quot;, this.hProc, &quot;Ptr&quot;, 0, &quot;Ptr&quot;, size, Params*) {
         DllCall(&quot;CloseHandle&quot;, &quot;Ptr&quot;, this.hProc)
         throw Exception(&quot;Can&#039;t allocate memory in remote process PID = &quot; . PID . &quot;`nA_LastError: &quot; . A_LastError, &quot;RemoteBuffer.__New&quot;)
      }
   }
   __Delete() {
      DllCall(&quot;VirtualFreeEx&quot;, &quot;Ptr&quot;, this.hProc, &quot;Ptr&quot;, this.ptr, &quot;UInt&quot;, 0, &quot;UInt&quot;, MEM_RELEASE := 0x8000)
      DllCall(&quot;CloseHandle&quot;, &quot;Ptr&quot;, this.hProc)
   }  
   Read(ByRef localBuff, size, offset = 0) {
      VarSetCapacity(localBuff, size, 0)
      if !DllCall(&quot;ReadProcessMemory&quot;, &quot;Ptr&quot;, this.hProc, &quot;Ptr&quot;, this.ptr + offset, &quot;Ptr&quot;, &amp;localBuff, &quot;Ptr&quot;, size, &quot;PtrP&quot;, bytesRead)
         throw Exception(&quot;Can&#039;t read data from remote buffer`nA_LastError: &quot; . A_LastError, &quot;RemoteBuffer.Read&quot;)
      Return bytesRead
   }
   Write(pData, size, offset = 0) {
      if !res := DllCall(&quot;WriteProcessMemory&quot;, &quot;Ptr&quot;, this.hProc, &quot;Ptr&quot;, this.ptr + offset, &quot;Ptr&quot;, pData, &quot;Ptr&quot;, size, &quot;PtrP&quot;, bytesWritten)
         throw Exception(&quot;Can&#039;t write data to remote buffer`nA_LastError: &quot; . A_LastError, &quot;RemoteBuffer.Write&quot;)
      Return bytesWritten
   }
}
</code></pre></div><p>Но </p><div class="codebox"><pre><code>MsgBox НайденныйТекст: &#039;%НайденныйТекст%&#039;</code></pre></div><p> почему-то <strong>возвращает пустую строку</strong>, хотя в C++ аналогичный код работает.</p><p>Делал подпрограмму GETTARGETTEXT по аналогии с GetSelTextFromNPP(hNPP)&nbsp; — получить выделенный текст. Она вот отсюда: <a href="https://forum.script-coding.com/viewtopic.php?pid=112088#p112088">https://forum.script-coding.com/viewtop … 88#p112088</a> и хорошо работает.<br /><strong>В чем на этот раз может быть ошибка</strong>, что попробовать?</p>]]></content>
			<author>
				<name><![CDATA[Vadus]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=25975</uri>
			</author>
			<updated>2022-09-11T12:54:22Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=154721#p154721</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Поиск в Notepad++ с помощью Scintilla]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=154687#p154687" />
			<content type="html"><![CDATA[<p>Спасибо, teadrinker! Исправил, теперь работает. Находит и выделяет фразу, в том числе кириллицу. Прокручивает экран до нее:</p><div class="codebox"><pre><code>SCI_SETSEL          := 2160
SCI_SETSEARCHFLAGS  := 2198
SCFIND_REGEXP 		:= 0x00200000
SCI_SETTARGETSTART 	:= 2190
SCI_SETTARGETEND 	:= 2192
SCI_SEARCHINTARGET 	:= 2197
SCI_GETTARGETSTART 	:= 2191
SCI_GETTARGETEND 	:= 2193   
SCI_GETSEARCHFLAGS 	:= 2199

ControlGet, hScintilla, hwnd,, Scintilla1, ahk_class Notepad++
if !hScintilla {
   MsgBox, Scintilla not found
   ExitApp
}

;--- Устанавливаем флаги поиска SCI_SETSEARCHFLAGS
SendMessage, SCI_SETSEARCHFLAGS, SCFIND_REGEXP,,, ahk_id %hScintilla% ;опция поиска, когда строку поиска следует интерпретировать как регулярное выражение}

;Получаем длину всего текста в редакторе
SendMessage, SCI_GETTEXTLENGTH := 2183, 0,,, ahk_id %hScintilla%
ДлинаТекста := ErrorLevel
; MsgBox ДлинаТекста: &#039;%ДлинаТекста%&#039;

;Получаем номер текущей позиции курсора во всем тексте
SendMessage, SCI_GETCURRENTPOS := 2008, 0,,, ahk_id %hScintilla%
currentPosition := ErrorLevel
; MsgBox currentPosition: %currentPosition%

;--- Устанавливаем целевой диапазон поиска — от начала до конца текста
SendMessage, SCI_SETTARGETSTART, 0,,, ahk_id %hScintilla%
SendMessage, SCI_SETTARGETEND, ДлинаТекста,,, ahk_id %hScintilla%


;--- Производим поиск с помощью регулярных выражений
firstMatchPos := Func_SEARCHINTARGET(hScintilla, &quot;русск.+?поиска&quot;) ;ищем русский текст
;в firstMatchPos — позиция начала найденного текста или -1, если не нашли
; MsgBox firstMatchPos: &#039;%firstMatchPos%&#039;  

;--- Получаем позиции найденной фразы, помещенные в TARGET
 SendMessage, SCI_GETTARGETSTART,,,, ahk_id %hScintilla%
 foundStart := ErrorLevel
 ; MsgBox foundStart: &#039;%foundStart%&#039; ;выводит 0

 SendMessage, SCI_GETTARGETEND,,,, ahk_id %hScintilla%
 foundEnd := ErrorLevel
 ; MsgBox foundEnd: &#039;%foundEnd%&#039; ;выводит 0

; Прокрутить экран до найденной фразы и установить на нее курсор
SendMessage, SCI_SETSEL, foundStart, foundEnd,, ahk_id %hScintilla%

Func_SEARCHINTARGET(hScintilla, text) 
;Функция поиска в Notepad++ с помощью регулярного выражения
{
	SCI_SEARCHINTARGET := 2197
	firstMatchPos := -1
	WinGet, PID, PID, ahk_id %hScintilla%
	; size := StrPut(text, &quot;UTF-8&quot;) ;чтобы работал поиск кириллицы в файле с кодировкой UTF-8
	size := StrPut(text, &quot;CP1251&quot;) ;чтобы работал поиск кириллицы в файле с ANSI-кодировкой
	RB := new RemoteBuffer(PID, size) ;создаем новый RemoteBuffer
	VarSetCapacity(buf, size, 0)
	; StrPut(text, &amp;buf, &quot;UTF-8&quot;);чтобы работал поиск кириллицы в файле с кодировкой UTF-8
	StrPut(text, &amp;buf, &quot;CP1251&quot;) ;чтобы работал поиск кириллицы в файле с ANSI-кодировкой
	RB.Write(&amp;buf, size)
	SendMessage, SCI_SEARCHINTARGET, 10, RB.ptr,, ahk_id %hScintilla%
	firstMatchPos := ErrorLevel
	Return firstMatchPos
}


class RemoteBuffer
{
   __New(PID, size) {
      static flags := (PROCESS_VM_OPERATION := 0x8) | (PROCESS_VM_WRITE := 0x20) | (PROCESS_VM_READ := 0x10)
           , Params := [&quot;UInt&quot;, MEM_COMMIT := 0x1000, &quot;UInt&quot;, PAGE_READWRITE := 0x4, &quot;Ptr&quot;]
         
      if !this.hProc := DllCall(&quot;OpenProcess&quot;, &quot;UInt&quot;, flags, &quot;Int&quot;, 0, &quot;UInt&quot;, PID, &quot;Ptr&quot;)
         throw Exception(&quot;Can&#039;t open remote process PID = &quot; . PID . &quot;`nA_LastError: &quot; . A_LastError, &quot;RemoteBuffer.__New&quot;)
      
      if !this.ptr := DllCall(&quot;VirtualAllocEx&quot;, &quot;Ptr&quot;, this.hProc, &quot;Ptr&quot;, 0, &quot;Ptr&quot;, size, Params*) {
         DllCall(&quot;CloseHandle&quot;, &quot;Ptr&quot;, this.hProc)
         throw Exception(&quot;Can&#039;t allocate memory in remote process PID = &quot; . PID . &quot;`nA_LastError: &quot; . A_LastError, &quot;RemoteBuffer.__New&quot;)
      }
   }
   __Delete() {
      DllCall(&quot;VirtualFreeEx&quot;, &quot;Ptr&quot;, this.hProc, &quot;Ptr&quot;, this.ptr, &quot;UInt&quot;, 0, &quot;UInt&quot;, MEM_RELEASE := 0x8000)
      DllCall(&quot;CloseHandle&quot;, &quot;Ptr&quot;, this.hProc)
   }  
   Read(ByRef localBuff, size, offset = 0) {
      VarSetCapacity(localBuff, size, 0)
      if !DllCall(&quot;ReadProcessMemory&quot;, &quot;Ptr&quot;, this.hProc, &quot;Ptr&quot;, this.ptr + offset, &quot;Ptr&quot;, &amp;localBuff, &quot;Ptr&quot;, size, &quot;PtrP&quot;, bytesRead)
         throw Exception(&quot;Can&#039;t read data from remote buffer`nA_LastError: &quot; . A_LastError, &quot;RemoteBuffer.Read&quot;)
      Return bytesRead
   }
   Write(pData, size, offset = 0) {
      if !res := DllCall(&quot;WriteProcessMemory&quot;, &quot;Ptr&quot;, this.hProc, &quot;Ptr&quot;, this.ptr + offset, &quot;Ptr&quot;, pData, &quot;Ptr&quot;, size, &quot;PtrP&quot;, bytesWritten)
         throw Exception(&quot;Can&#039;t write data to remote buffer`nA_LastError: &quot; . A_LastError, &quot;RemoteBuffer.Write&quot;)
      Return bytesWritten
   }
}</code></pre></div>]]></content>
			<author>
				<name><![CDATA[Vadus]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=25975</uri>
			</author>
			<updated>2022-09-07T18:32:19Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=154687#p154687</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Поиск в Notepad++ с помощью Scintilla]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=154686#p154686" />
			<content type="html"><![CDATA[<p>Только точку верните.</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2022-09-07T13:22:23Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=154686#p154686</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Поиск в Notepad++ с помощью Scintilla]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=154685#p154685" />
			<content type="html"><![CDATA[<p>Спасибо, проверю.</p>]]></content>
			<author>
				<name><![CDATA[Vadus]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=25975</uri>
			</author>
			<updated>2022-09-07T13:18:40Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=154685#p154685</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Поиск в Notepad++ с помощью Scintilla]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=154684#p154684" />
			<content type="html"><![CDATA[<p>Не тестировал, но в функции SCI_SEARCHINTARGET не определено, и после Return знаки процента не нужны.</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2022-09-07T13:13:09Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=154684#p154684</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[AHK: Поиск в Notepad++ с помощью Scintilla]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=154683#p154683" />
			<content type="html"><![CDATA[<p>Добрый всем!<br />Пытаюсь запрограммировать поиск из AHK в тексте Notepad++ с помощью Scintilla-команды <strong>SCI_SEARCHINTARGET</strong>.<br />За образец взял <a href="https://www.autohotkey.com/boards/viewtopic.php?f=76&amp;t=62646&amp;hilit=Scintilla">https://www.autohotkey.com/boards/viewt … =Scintilla</a>. Там подсказали, как вставлять текст с помощью Scintilla-команды SCI_REPLACESEL, и это работает нормально.</p><p>Вот такой код для поиска получился:<br /></p><div class="codebox"><pre><code>   
SCI_SETSEARCHFLAGS := 2198
SCFIND_REGEXP := 0x00200000
SCI_SETTARGETSTART := 2190
SCI_SETTARGETEND := 2192
SCI_SEARCHINTARGET := 2197
SCI_GETTARGETSTART := 2191
SCI_GETTARGETEND := 2193   
SCI_GETSEARCHFLAGS := 2199

ControlGet, hScintilla, hwnd,, Scintilla1, ahk_class Notepad++
if !hScintilla {
   MsgBox, Scintilla not found
   ExitApp
}

;--- Устанавливаем флаги поиска SCI_SETSEARCHFLAGS
SendMessage, SCI_SETSEARCHFLAGS, SCFIND_REGEXP,,, ahk_id %hScintilla% ;опция поиска, когда строку поиска следует интерпретировать как регулярное выражение

	;--- Устанавливаем целевой диапазон поиска — от начала текста до 1000-й позиции
SendMessage, SCI_SETTARGETSTART, 0,,, ahk_id %hScintilla%
	SendMessage, SCI_SETTARGETEND, 1000,,, ahk_id %hScintilla%

;--- Производим поиск с помощью регулярных выражений. В данном случае ищем простой текст &quot;text&quot;
firstMatchPos := SCI_SEARCHINTARGET(hScintilla, &quot;text&quot;)
MsgBox firstMatchPos: &#039;%firstMatchPos%&#039; ;выводит 0

;--- Получаем позиции найденной фразы, помещенные в TARGET
SendMessage, SCI_GETTARGETSTART,,,, ahk_id %hScintilla%
foundStart := ErrorLevel
MsgBox foundStart: &#039;%foundStart%&#039; ;выводит 0

SendMessage, SCI_SETTARGETEND,,,, ahk_id %hScintilla%
foundEnd := ErrorLevel
MsgBox foundEnd: &#039;%foundEnd%&#039; ;выводит 0


SCI_SEARCHINTARGET(hScintilla, text) 
; Функция поиска по регулярному выражению в Notepad++. Возвращает позицию начала найденного текста или -1, если не нашли
{
	WinGet, PID, PID, ahk_id %hScintilla%
	size := StrPut(text, &quot;UTF-8&quot;)
	; size := StrPut(text, &quot;CP1251&quot;)
	RB := new RemoteBuffer(PID, size) ;создаем новый RemoteBuffer
	VarSetCapacity(buf, size, 0)
	StrPut(text, &amp;buf, &quot;UTF-8&quot;)
	; StrPut(text, &amp;buf, &quot;CP1251&quot;)
	RB.Write(&amp;buf, size)
	
	firstMatchPos := -1
	SendMessage, SCI_SEARCHINTARGET, 2, RB.ptr,, ahk_id %hScintilla% 	; Производим поиск с помощью регулярных выражений
	firstMatchPos := ErrorLevel
	Return %firstMatchPos% ; должен возвращать позицию начала найденного текста или -1, если не нашли
}


class RemoteBuffer
{
   __New(PID, size) {
      static flags := (PROCESS_VM_OPERATION := 0x8) | (PROCESS_VM_WRITE := 0x20) | (PROCESS_VM_READ := 0x10)
           , Params := [&quot;UInt&quot;, MEM_COMMIT := 0x1000, &quot;UInt&quot;, PAGE_READWRITE := 0x4, &quot;Ptr&quot;]
         
      if !this.hProc := DllCall(&quot;OpenProcess&quot;, &quot;UInt&quot;, flags, &quot;Int&quot;, 0, &quot;UInt&quot;, PID, &quot;Ptr&quot;)
         throw Exception(&quot;Can&#039;t open remote process PID = &quot; . PID . &quot;`nA_LastError: &quot; . A_LastError, &quot;RemoteBuffer.__New&quot;)
      
      if !this.ptr := DllCall(&quot;VirtualAllocEx&quot;, &quot;Ptr&quot;, this.hProc, &quot;Ptr&quot;, 0, &quot;Ptr&quot;, size, Params*) {
         DllCall(&quot;CloseHandle&quot;, &quot;Ptr&quot;, this.hProc)
         throw Exception(&quot;Can&#039;t allocate memory in remote process PID = &quot; . PID . &quot;`nA_LastError: &quot; . A_LastError, &quot;RemoteBuffer.__New&quot;)
      }
   }
   __Delete() {
      DllCall(&quot;VirtualFreeEx&quot;, &quot;Ptr&quot;, this.hProc, &quot;Ptr&quot;, this.ptr, &quot;UInt&quot;, 0, &quot;UInt&quot;, MEM_RELEASE := 0x8000)
      DllCall(&quot;CloseHandle&quot;, &quot;Ptr&quot;, this.hProc)
   }  
   Read(ByRef localBuff, size, offset = 0) {
      VarSetCapacity(localBuff, size, 0)
      if !DllCall(&quot;ReadProcessMemory&quot;, &quot;Ptr&quot;, this.hProc, &quot;Ptr&quot;, this.ptr + offset, &quot;Ptr&quot;, &amp;localBuff, &quot;Ptr&quot;, size, &quot;PtrP&quot;, bytesRead)
         throw Exception(&quot;Can&#039;t read data from remote buffer`nA_LastError: &quot; . A_LastError, &quot;RemoteBuffer.Read&quot;)
      Return bytesRead
   }
   Write(pData, size, offset = 0) {
      if !res := DllCall(&quot;WriteProcessMemory&quot;, &quot;Ptr&quot;, this.hProc, &quot;Ptr&quot;, this.ptr + offset, &quot;Ptr&quot;, pData, &quot;Ptr&quot;, size, &quot;PtrP&quot;, bytesWritten)
         throw Exception(&quot;Can&#039;t write data to remote buffer`nA_LastError: &quot; . A_LastError, &quot;RemoteBuffer.Write&quot;)
      Return bytesWritten
   }
}


</code></pre></div><p><strong>Но он всегда возвращает нули</strong>:<br />firstMatchPos=0, а должен возвращать позицию начала найденного текста или -1, если не нашли.<br />foundStart=0, а должен возвращать позицию начала найденного текста, то есть ту же, что firstMatchPos.<br />foundEnd=0, а должен возвращать позицию конца найденного текста.</p><p><strong>В чем может быть проблема, подскажите плиз</strong>. Может быть есть другой путь автоматизировать поиск в Notepad++?</p><p>На всякий случай: сам поиск я пытался строить, используя код на C++ для плагина Notepad++, который работает:<br /></p><div class="codebox"><pre><code>
    // Получаем текущий экземпляр scintilla. Get the current scintilla
    int which = -1;
    ::SendMessage(nppData._nppHandle, NPPM_GETCURRENTSCINTILLA, 0, (LPARAM)&amp;which);
    if (which == -1)
        return;
    HWND curScintilla = (which == 0)?nppData._scintillaMainHandle:nppData._scintillaSecondHandle;

//- Задаем опции поиска
::SendMessage(curScintilla, SCI_SETSEARCHFLAGS, SCFIND_REGEXP, 0); //опция поиска, когда строку поиска следует интерпретировать как регулярное выражение
LRESULT currentPosition = ::SendMessage(curScintilla, SCI_GETCURRENTPOS, 0, 0); // получает номер текущей позиции курсора во всем тексте

//--- Устанавливаем целевой диапазон поиска — от текущей позиции к началу текста — ищем назад по тексту
::SendMessage(curScintilla, SCI_SETTARGETSTART, 0, 0); //задаём область поиска от начала текста
::SendMessage(curScintilla, SCI_SETTARGETEND, 1000, 0); //задаём область поиска до 1000-й позиции 

string RegString = &quot;Probe&quot;; //текст (шаблон) для поиска
LRESULT firstMatchPos = -1; //создаем и задаем начальное значение переменной, в которой будет храниться найденное вхождение при поиске
firstMatchPos = ::SendMessage(curScintilla, SCI_SEARCHINTARGET, 2, (LPARAM)RegString.c_str()); // Ищем текст
//=== Если нашли, получаем найденный текст и установливаем на нем курсор
if (firstMatchPos == -1) //если не нашли — выходим
	return;
//--- После поиска получаем диапазон (начало и конец) найденной фразы
LRESULT foundStart;
foundStart = ::SendMessage(curScintilla, SCI_GETTARGETSTART, 0, 0); //получаем позицию начала найденной фразы, помещенное в TARGET

LRESULT foundEnd;
foundEnd = ::SendMessage(curScintilla, SCI_GETTARGETEND, 0, 0); //получаем позицию конца найденной фразы, помещенное в TARGET
LPSTR НайденныйТекст = (LPSTR)new char[foundEnd - foundStart]; //задаем текстовую переменную, в которую затем поместим текст диапазона
Sci_TextRange tr; //создаем объект TextRange — текстовый диапазон
tr.chrg.cpMin = (int)foundStart; //задаем начало диапазона — начало найденной фразы
tr.chrg.cpMax = (int)foundEnd; //задаем конец диапазона — конец найденной фразы
//Задаем начальный текст диапазона, пока пустую переменную
tr.lpstrText = НайденныйТекст;

::SendMessage(curScintilla, SCI_GETTEXTRANGE, 0, reinterpret_cast&lt;LPARAM&gt;(&amp;tr)); //получаем текст диапазона TARGET (найденную фразу) и помещаем его в переменную tr
MessageBoxA(NULL, tr.lpstrText, &quot;Текст диапазона tr.lpstrText&quot;, MB_OK); //Выводит сообщение — текст диапазона — найденную фразу

//Прокрутить экран до найденной фразы и установить на нее курсор
SendMessage(curScintilla, SCI_GOTOPOS, foundStart, NULL);

//--- Установить начало и конец выделения 
::SendMessage(curScintilla, SCI_SETSELECTIONSTART, foundStart, NULL); //задаём начало выделения — номер позиции курсора во всем тексте
::SendMessage(curScintilla, SCI_SETSELECTIONEND, foundEnd, NULL); //задаём конец выделения — номер позиции курсора во всем тексте

</code></pre></div>]]></content>
			<author>
				<name><![CDATA[Vadus]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=25975</uri>
			</author>
			<updated>2022-09-07T11:28:45Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=154683#p154683</id>
		</entry>
</feed>
