Написал я тестовый скрипт, который меня неприятно поразил, надо переписывать мою коротенькую винапи функцию, ибо она в скрипте проиграла PixelSearch аж в 10 раз. Видимо когда пикселсерчу подсовываешь диапазон значений - он работает более оптимально. Итак - на тест предлагаю скрипт поиска окна овервью.
Серв ушел в ДТ, я не успел сделать скринов, результаты на q8300 Asus Commando (выше писал конфиг уже) - Winapi - 2300-2600 мс, PixelSearch - 22-26мс.
Серв ушел в ДТ, я не успел сделать скринов, результаты на q8300 Asus Commando (выше писал конфиг уже) - Winapi - 2300-2600 мс, PixelSearch - 22-26мс.
Код:
#include <Winapi.au3>
Opt("PixelCoordMode", 2)
Opt("MouseCoordMode", 2)
Global $DLL
Global $White=0xd4d4d4
Global $cl=0x10
Search()
Func Search()
$hWnd=WinGetHandle("EVE")
if $hWnd <> 0 Then
WinActivate("EVE")
WinWaitActive("EVE")
$DLL=DllOpen("gdi32.dll")
Local $hDC = _WinAPI_GetDC($hWnd)
Local $timerDC=TimerInit()
Local $over=OverSearchWAPI($hDC)
DllClose($dll)
_WinAPI_ReleaseDC($hWnd, $hDC)
if IsArray($over) Then
$timerDC=TimerDiff($timerDC)
EndIf
Local $timerPS=TimerInit()
Local $over1=OverSearchPS()
if IsArray($over1) Then
$timerPS=TimerDiff($timerPS)
EndIf
MsgBox(0,"TimeDifference","The Winapi func="&$timerDC&@CR&"The Pixelsearch func="&$timerPS)
MsgBox(0,"Coordinate","X_API="&$over[0]&" Y_API="&$over[1]&@CR&"X_PS="&$over1[0]&" Y_PS="&$over1[1])
EndIf
EndFunc
Func _Pix($hDC,$x,$y,$PartofColor, $var)
Local $ColGet=DllCall($dll, 'dword', 'GetPixel', 'hwnd', $hDC, 'int', $x, 'int', $y)
Local $lay = BitAND($ColGet[0], 0x000000FF)
if Abs($lay-$PartofColor)<=$var Then
return 1
Else
SetError(1)
EndIf
EndFunc
func OverSearchWAPI($hDC)
#cs
Нам надо найти 4 полоски овервью, будем искать 0xd4d4d4, длина полоски 7 пх, высота 7пх
довольно очевидно, что проискав каждые 6 пикселей - мы ее не пропустим, а вот шаг по
вертикали чуть сложнее - шаг должен быть нечетным, чтобы не проскочить полоску по "пустым"
полосам, и не должен превышать половину полоски. 7пх/2=3.5, 3 нечетное, подходит. Значит
мы должны просканить каждый 6 пиксель через 3 ряда, найдя 0xd4d4d4 надо убедиться, что это
полоски и шаг2 - убедиться что это овервью (низ буквы V подойдет, советую не проверять с окном
Eve Mail).
#ce
$ClientSize=WinGetClientSize("EVE")
for $y=0 to $ClientSize[1] Step 3
for $x=0 to $ClientSize[0] Step 6
$p=_Pix($hDC,$x,$y, 0xd4,0x5)
if $p=1 Then ;встретили цвет
$coord=_Check($x,$y) ;проверили, не овервью ли
if $coord<>-1 Then
return $coord ;нашли? выходим из функции
EndIf
EndIf
Next
Next
SetError(1)
return -1
EndFunc
func OverSearchPS()
#cs
Все точно так же, только PS
#ce
$ClientSize=WinGetClientSize("EVE")
Local $x0=0
for $y=0 to $ClientSize[1] Step 3
$x=PixelSearch($x0,$y,$ClientSize[0],$y, $White,$cl,6)
if not @error Then
$coord=_Check($x[0],$x[1])
if $coord<>-1 Then
return $coord
Else
$x0=$x[0]+6
$y-=3
ContinueLoop
EndIf
EndIf
$x0=0
Next
SetError(1)
EndFunc
func _Check($x,$y)
#cs
-------
0000000
-------
0000000
-------
0000000
-------
Итак, мы наткнулись на неё, в любое место помеченное "-"
Что будем делать? проверим справа и слева, найдем длину, потом вверх и вниз, найдем координаты
лево-верхнего пикселя, проверим букву V. Если все условия соблюдены - вернем координаты.
#ce
Local $x1,$x2,$y1, $y2
For $x2=$x to $x+7
PixelSearch($x2,$y,$x2,$y,$White,$Cl)
if @error Then
$x2-=1
ExitLoop
EndIf
Next
For $x1=$x to $x-7 Step -1
PixelSearch($x1,$y,$x1,$y,$White,$Cl)
if @error Then
$x1+=1
ExitLoop
EndIf
Next
if ($x2-$x1)<>7 Then
Return -1
EndIf
For $y2=$y to $y+6 Step 2
PixelSearch($x1,$y2,$x1,$y2,$White,$Cl)
if @error Then
$y2-=2
ExitLoop
EndIf
Next
For $y1=$y to $y-6 Step -2
PixelSearch($x1,$y1,$x1,$y1,$White,$Cl)
if @error Then
$y1+=2
ExitLoop
EndIf
Next
if ($y2-$y1)<>6 Then
Return -1
Else
PixelSearch($x1,$y1+1,$x2,$y1+1,$White,$Cl)
If Not @error Then
Return -1
EndIf
EndIf
PixelSearch($x2+13,$y2,$x2+13,$y2,0x999999,0x20)
if @error Then
Return -1
EndIf
Local $ret[2]=[$x1,$y1]
Return $ret
EndFunc