26 (изменено: KusochekDobra, 2018-04-17 21:36:56)

Re: AHK: ImageSearch без файла картинки

Вам бы следовало почитать справку и запомнить это простое, как вызывать функции, раз после моего комментария в 22 сообщении ответили, что поняли свою ошибку и следом, совершаете её же.

"haystack" - второй параметр функции G_Search(), следовательно, HWND окна нужно передать ей вторым параметром. Первым передаёте "ЧТО ищете", вторым "ГДЕ ищете". В случае с окном, координаты передавать не нужно, оставьте пустое место после запятых вместо значений. Поиск производится во всём окне. Окно может быть не активно и скрыто другими окнами, но не свёрнуто. Так же, существуют известные проблемы, связанные с получением изображения таким образом.

Наглядно проверить, корректное ли получается изображение окна, можно, например, так:


#SingleInstance, Force
#NoEnv
SetTitleMatchMode, 2

#Include Gdip.ahk

if (hwnd := WinExist("ahk_class ClassName")) {
	wToken := Gdip_Startup()
	pWin := Gdip_BitmapFromHWND(hwnd)
	Gui,1: Add, Picture,,% "HBITMAP:*" (hPic := Gdip_CreateHBITMAPFromBitmap(pWin))
	Gui,1: Show,,MyWindow
} else {
	MsgBox,,Title,Окно не найдено
	ExitApp
}
return
Escape::
GuiClose:
	DeleteObject(hPic)
	Gdip_DisposeImage(pWin)
	Gdip_Shutdown(wToken)
	ExitApp

27

Re: AHK: ImageSearch без файла картинки

KusochekDobra, забыли объект удалить Gdip_CreateHBITMAPFromBitmap(pWin).

28

Re: AHK: ImageSearch без файла картинки

Решил все же делать снимок всего экрана, а не отдельного окна. Так, как проблемы с черным окном появляются часто.
Составил код и вроде как я начал получать то, что хочу.

Сам код:

#NoEnv
#SingleInstance, Force
#Include Gdip.ahk
#Include Gdip_ImageSearch.ahk
#Include G_Search.ahk
#Include Retrieve.ahk

CoordMode, Pixel
CoordMode, Mouse
CoordMode, ToolTip
SetWorkingDir, A_ScriptDir
SetTitleMatchMode, 2
SetBatchLines, -1
xx := 0, yy := 0
ww := 2500, hh := 2500

loop, 6
{
   LIST := ""
   result := []
   needle := Retrieve_%A_Index%_png()
   count := G_Search(needle, "screen", result, xx, yy, ww, hh, 15,,, 100)
   i := 1
   LIST := result[i++]","result[i++]
   Loop, Parse, LIST, `n
   {
      StringSplit, Coord, A_LoopField, `,
      MouseClick, , %Coord1%, %Coord2%, 1 , 0.5
   }
}

Но возникает две проблемы:
1. Скрипт в упор не хочет искать картинки не по порядку. У меня пронумерованы картинки от 1 до 6. Если сначала появится картинка 1, то скрипт будет и дальше все искать как нужно и спокойно найдет и 5 и 6 и 3, но если появится сначала картинка например 2 и выше, то скрипт ничего не ищет дальше. Просто делает 6 попыток и стоит.
2. Скрипт всегда при каждой попытке по новому делает снимок экрана, так как писалось в примере от KusochekDobra, что сначала передаем, что ищем, а потом передаем где ищем. А можно использовать один снимок для всех шести попыток поиска?

29

Re: AHK: ImageSearch без файла картинки


#NoEnv
#SingleInstance, Force
#Include Gdip.ahk
#Include Gdip_ImageSearch.ahk
#Include G_Search.ahk
#Include Retrieve.ahk

CoordMode, Pixel
CoordMode, Mouse
CoordMode, ToolTip
SetWorkingDir, A_ScriptDir
SetTitleMatchMode, 2
SetBatchLines, -1

xx := 0, yy := 0
ww := 2500, hh := 2500
images := [Retrieve_1_png(), Retrieve_2_png(), Retrieve_3_png(), Retrieve_4_png(), Retrieve_5_png(), Retrieve_6_png()]

F1::	; F1
	SetSquare(xx, yy, ww, hh)
	if (count := G_Search(images, "screen", result, xx, yy, ww, hh, 15,,, 100)) {
		SetSquare()
		MsgBox,,Результат,% "Всего = " count
		i := 1
		Loop,% count {
			ToMove(result[i++], result[i++])
			Sleep, 500
		}
	} else
		MsgBox,,Title,Ничего не найдено.
return

G_Search(images,haystack,ByRef outResult,x:=0,y:=0,w:=0,h:=0,vari:=0,trans:="",direction:=1,count:=1) {
    token := Gdip_Startup(), outResult := [], total := 0
	if haystack is number
		haystackPointer := Gdip_BitmapFromHWND(haystack)
	else if (haystack == "screen")
		haystackPointer := Gdip_Bitmapfromscreen(Format("{1}|{2}|{3}|{4}",x,y,w,h))
	else
		haystackPointer := Gdip_CreateBitmapFromFile(haystack)
	
	for item, needle in images
	{
		if needle is number
			needlePointer := Gdip_CreateBitmapFromHBITMAP(needle)
		else
			needlePointer := Gdip_CreateBitmapFromFile(needle)
		if (found := Gdip_ImageSearch(haystackPointer,needlePointer,result,0,0,0,0,vari,trans,direction,count,x,y)) {
			total += found
			outResult.Push(result*)
		} Gdip_DisposeImage(needlePointer)
	}
   
    Gdip_DisposeImage(haystackPointer)
    Gdip_Shutdown(token)
    return total
}
ToMove(xx, yy) {
	Send {Click,%xx%,%yy%,0}
}
SetSquare(x := "", y := "", w := "", h := "", boldLine := 1, clr := "FF0000") {
	if (x == "") {
		SplashImage 1:, Hide
		SplashImage 2:, Hide
		SplashImage 3:, Hide
		SplashImage 4:, Hide
	} else {
		width := w - x, heigth := h - y, workArr := []
		SplashImage 1:, % "CW" clr " B x" x " y" y " w" width + boldLine " h" boldLine
		SplashImage 2:, % "CW" clr " B x" x " y" h " w" width + boldLine " h" boldLine
		SplashImage 3:, % "CW" clr " B x" x " y" y " w" boldLine " h" heigth
		SplashImage 4:, % "CW" clr " B x" w " y" y + 1 " w" boldLine " h" heigth
		return workArr := [x, y, w, h]
	}
}
Escape::
	ExitApp

30

Re: AHK: ImageSearch без файла картинки

KusochekDobra Находит, но координаты не определяет. Ответ пуст. Заменил ToMove(result[i++], result[i++]) как было у меня кодом на LIST := result[i++]","result[i++], тоже пусто. Как получить результат с ToMove? Пробовал через MsgBox, тоже пусто. Везде пусто.

31

Re: AHK: ImageSearch без файла картинки

Прошу прощения. Моя вина.
Для возврата по ссылке результата, переменную, которая используется при вызове, нужно инициализировать пустым массивом. Чтобы этого не делать постоянно, я добавил это в тело функции Gdip_ImageSearch() в 18 сообщении, но забыл об этом упомянуть. Обновите пожалуйста код своей Gdip_ImageSearch(), кодом из того примера. Заработает.

32

Re: AHK: ImageSearch без файла картинки

Тоже самое: картинку находит, но в координатах пусто.

33

Re: AHK: ImageSearch без файла картинки

У меня такой результат только в том случае, если возвращающая по ссылке переменная не была инициализирована пустым массивом, о чём говорил выше. Если это сделать, работает как часы. Проверял: два графических элемента, которые в совокупности повторяются 32 раза. Пример выше показывает сообщение с этим количеством и возит курсором по всем 32-м точкам.
Посмотрите внимательно, есть ли в Вашей Gdip_ImageSearch(), в 76 строке, следующее:

OutputList := []

34

Re: AHK: ImageSearch без файла картинки

KusochekDobra Использую Ваш Gdip_ImageSearch() с поста 18 http://forum.script-coding.com/viewtopi … 52#p124752 Прошелся поиском и там нет сочетания OutputList := [].

35

Re: AHK: ImageSearch без файла картинки

При всём желании, я бы не смог удалить эту строку из Вашего файла. Означать это может только то, что после упоминания мной о сделанных изменениях в 18 сообщении, Вы не скопировали содержимое кода из того примера.

Чтобы убедиться в том, что обсуждаемая правка в нём действительно есть, перейдите на страницу с этим сообщением и выполните поиск в браузере используя сочетание "Ctrl+F", после чего, в поле поиска вставьте "OutputList := []".

Последняя правка сообщения №18 с добавлением искомой строки была 16 числа. Обсуждалось это изменение лишь начиная с 19.

36

Re: AHK: ImageSearch без файла картинки

Прошу прощенья. В творческом беспорядке действительно использовал не тот файл. Копировать то копировал, но не в ту папку. Проверил теперь, все отлично работает. Спасибо.

37 (изменено: Vicoriyan, 2018-04-27 23:05:06)

Re: AHK: ImageSearch без файла картинки

Вставил рабочий код в свой проект и получаю это: https://ibb.co/eyj9wx. Отдельно работает, а если вставить, получаю ошибку. Что может повлиять? Или с чем может быть конфликт?

38

Re: AHK: ImageSearch без файла картинки

Не сочтите за грубость, но, пожалуй, в качестве тренинга на таком примитивном уровне, дам последние рекомендации и потом перестану реагировать на сообщения в этой теме, суть которых описана в справочных материалах и прочих, легко доступных примерах, которые обычно следует освоить перед тем, как приходить к их применению.

Первая строка на скрине, по мнению гугл-переводчика, говорит, что: -"Слишком много параметров передано функции"-. Ниже представляется строкой запись в Вашем коде, поясняющая детали, вызов какой именно функции привёл к этому, а ещё ниже, стрелочкой (--->) указан номер строки в Вашем коде, где эта функция вызывается.

Пример, Вашего кода, который отказывается работать со вполне рабочим результатом наших с Вами изысканий, Вы, не приводите. Поэтому, из описания Вашей проблемы и с учётом того, что уже сказано, могу предположить, что не сошлись звёзды, но в программировании это применимо едва ли. Значит, эту версию можно однозначно отвергнуть.

39

Re: AHK: ImageSearch без файла картинки

Malcev пишет:

KusochekDobra, забыли объект удалить Gdip_CreateHBITMAPFromBitmap(pWin).

Оказывается, просто так удалить этот объект нельзя, если он побывал в употреблении GUI:


#NoEnv
#SingleInstance, Force

tst_b := "iVBORw0KGgoAAAANSUhEUgAAABcAAAAKCAYAAABfYsXlAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4yMfEgaZUAAADQSURBVDhPjZFLDsIwDETLpyAhJH73PxgSB2DVLRtEmHE8wQ2JYKTnesZJIO2QUuoitWb/kAseHRbga1MP37PRntYQrfWmal5U5/5kKX+oXsSC1npqCWhe4ArWgOIBthY8GEDyhp3BIuLA/Q3s2UBbMNXrpJAfi2cRPkQ78xN4em8hxBsxp7fX4KL//c6DN4VMOgDe6g52DCAu4A3zWm3yjSxoZ360xn3IpROIOX9oNM8ifIjWekofVEhnEPMLoFaAPn8bHVwjtTIq5nH2ydLwBmR0cKR+ONfmAAAAAElFTkSuQmCC"

tst_r := "iVBORw0KGgoAAAANSUhEUgAAABcAAAAKCAYAAABfYsXlAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMjHxIGmVAAAAlUlEQVQ4T7WQ0QpCMQxDgy/iD/j//+iDoMJMtrWrYQ9ewcLpbZqsiGit/Y0x6LOD/RD2Zhni16PB4ePAnTzIy/bsE9dzp74oRmgAV6I6p+e5wHbLEP4odEV74Tp2RS9D+APO81evjGP5nEkOHUkL8+4pj4dXMqwL+9P33auiSwvkbqJrrPH/D267fE99GF8QtfMqAPAGCQVH5DPl+gUAAAAASUVORK5CYII="

b := H_Func(tst_b)
r := H_Func(tst_r)
Gui,1: Add, Picture,, HBITMAP:%r%
Gui,1: Show,w150 h50
return

H_Func(B64,ico:=0) {
	If !DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &B64, "UInt", 0, "UInt", 0x01, "Ptr", 0, "UIntP", DecLen, "Ptr", 0, "Ptr", 0)
		Return False
	VarSetCapacity(Dec, DecLen, 0)
	If !DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &B64, "UInt", 0, "UInt", 0x01, "Ptr", &Dec, "UIntP", DecLen, "Ptr", 0, "Ptr", 0)
		Return False
	hData := DllCall("Kernel32.dll\GlobalAlloc", "UInt", 2, "UPtr", DecLen, "UPtr")
	pData := DllCall("Kernel32.dll\GlobalLock", "Ptr", hData, "UPtr")
	DllCall("Kernel32.dll\RtlMoveMemory", "Ptr", pData, "Ptr", &Dec, "UPtr", DecLen)
	DllCall("Kernel32.dll\GlobalUnlock", "Ptr", hData)
	DllCall("Ole32.dll\CreateStreamOnHGlobal", "Ptr", hData, "Int", True, "PtrP", pStream)
	hGdip := DllCall("Kernel32.dll\LoadLibrary", "Str", "Gdiplus.dll", "UPtr")
	VarSetCapacity(SI, 16, 0), NumPut(1, SI, 0, "UChar")
	DllCall("Gdiplus.dll\GdiplusStartup", "PtrP", pToken, "Ptr", &SI, "Ptr", 0)
	DllCall("Gdiplus.dll\GdipCreateBitmapFromStream",  "Ptr", pStream, "PtrP", pBitmap)
	if (ico)
		DllCall("Gdiplus.dll\GdipCreateHICONFromBitmap", "Ptr", pBitmap, "PtrP", hBitmap, "UInt", 0)
	else
		DllCall("Gdiplus.dll\GdipCreateHBITMAPFromBitmap", "Ptr", pBitmap, "PtrP", hBitmap, "UInt", 0)
	DllCall("Gdiplus.dll\GdipDisposeImage", "Ptr", pBitmap)
	DllCall("Gdiplus.dll\GdiplusShutdown", "Ptr", pToken)
	DllCall("Kernel32.dll\FreeLibrary", "Ptr", hGdip)
	DllCall(NumGet(NumGet(pStream + 0, 0, "UPtr") + (A_PtrSize * 2), 0, "UPtr"), "Ptr", pStream)
	Return hBitmap
}
DeleteObject(hObject) {
   return DllCall("DeleteObject", A_PtrSize ? "UPtr" : "UInt", hObject)
}

GuiClose:
GuiEscape:
	result_b := DeleteObject(b)
	result_r := DeleteObject(r)
	MsgBox,,Title,% "result_b = " result_b "`nresult_r = " result_r
	ExitApp

Это вызывает вопросы: удаляется ли потом объект вместе с завершением сценария и если нет, то как его удалить?

40

Re: AHK: ImageSearch без файла картинки

Этот хендл удаляется автоматически при закрытии окна:

a bitmap used on a Picture control is deleted when the GUI is destroyed, and an image will generally be deleted immediately if it needs to be resized. To avoid this, put an asterisk between the colon and handle. For example: hbitmap:*%handle% (or "hbitmap:*" handle in an expression). With the exception of ImageSearch, this forces the command to take a copy of the image.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg