1

Тема: AHK: Переполнение Rum, Bitmap

Пытаюсь разобратся с AHK.
Есть задача получать цвет пикселей в определенных координатах клиентского окна, сравнивать их с уже известными цветами.  процесс цикличный.
PixelGetColor слишком медленный для моих задач.
Порывшись на форуме, нашел подходящие под мою задачу функции.
Все прекрасно работает, но очень быстро заканчивается оперативная память. Такое ощущение что в приведенном ниже скрипте функция WindowBitmap_Delete(hWnd, hDC, hBitmap) не чистит память. В чем может быть проблема ?

SetBatchLines -1
WinTitle = Безымянный – Блокнот
WinGet, hwnd, ID, %WinTitle%
x = 879
y = 153

loop 500
{
	hMemDC := WindowBitmap_Capture(hwnd, hDC, hBitmap) ; делаем снимок
	loop, 12
	{
		
		GetPixel(x, y)
		y += 72		
		; msgbox %Color%
	}
	WindowBitmap_Delete(hWnd, hDC, hBitmap) ; очищаем память
	sleep 10
}

WindowBitmap_PixelGetColor(hMemDC, x, y) {
	Return DllCall("GetPixel", Ptr, hMemDC, UInt, x, UInt, y)
}
WindowBitmap_Capture(hWnd, ByRef hDC, ByRef hBitmap) {
	WinGetPos,,, Width, Height, ahk_id %hWnd%
	hDC := DllCall("GetDC", Ptr, hWnd, Ptr)
	hMemDC := DllCall("CreateCompatibleDC", Ptr, hDC)
	hBitmap := DllCall("CreateCompatibleBitmap", Ptr, hDC, Int, Width, Int, Height, Ptr)
	DllCall("SelectObject", Ptr, hMemDC, Ptr, hBitmap)
	DllCall("PrintWindow", Ptr, hWnd, Ptr, hMemDC, UInt, 0) ; 0-50 ms depend on window size; GetPixel - 0.004 ms on each ( > 8sec on FullHD display capture)
	Return hMemDC
}
WindowBitmap_Delete(hWnd, ByRef hDC, ByRef hBitmap) {
	DllCall("DeleteObject", Ptr, hBitmap)
	DllCall("DeleteDC", Ptr, hMemDC)
	DllCall("ReleaseDC", Ptr, hWnd, Ptr, hDC)
}
GetPixel(x, y) {
	global
	col := WindowBitmap_PixelGetColor(hMemDC, x, y)
	Color := (col = -1) ? "Error" : Format("{:#08x}",col)	
	Return Color
}

F8::Pause

2

Re: AHK: Переполнение Rum, Bitmap

Попробуйте.

3

Re: AHK: Переполнение Rum, Bitmap

stealzy
Попробовал.
Прекрасно работает память не засоряется.
Огромное спасибо.

4

Re: AHK: Переполнение Rum, Bitmap

stealzy
Не помню почему я не отписался, но рас зашел сюда считаю должным. В моем примере функций была ошибка, правильный код я приведу ниже, этот код был взят из поиска и он кстати твой и был приведен примером  для кого то, это метод в моем примере(взятый из твоего поста) работает быстро и быстрее чем, то что ты дальше привел в пример. Ты просто забыл параметр 1 добавить, но было сложно разобраться когда ты только знакомишься с АХК. Исправь, это где то у себя в посте чтоб не травмировать людей ).

Было так:

WindowBitmap_Delete(hWnd, ByRef hDC, ByRef hBitmap) {
	DllCall("DeleteObject", Ptr, hBitmap)
	DllCall("DeleteDC", Ptr, hMemDC)
	DllCall("ReleaseDC", Ptr, hWnd, Ptr, hDC)
}
}

Нужно так:

WindowBitmap_Delete(hWnd, ByRef hDC, ByRef hBitmap, hMemDC) {
	DllCall("DeleteObject", Ptr, hBitmap)
	DllCall("DeleteDC", Ptr, hMemDC)
	DllCall("ReleaseDC", Ptr, hWnd, Ptr, hDC)
}