1

Тема: AHK: Определение изменений в определенной области экрана.

Здравствуйте. В определенной области экрана находится картинка с цифрой белого цвета (0хFFFFFF). Периодически эта цифра меняется на другую цифру(тоже белого цвета), это и нужно определить. Нашел вот такой скрипт:

c:
coords := [[1033,23],[1044,23],[1032,36],[1044,36],[1038,35]
        ,[1038,23]] 
tooltip % res    
res := PixelChecksum(coords)

F::
Loop
{
    If (PixelChecksum(coords) != res)
	    { 
		    tooltip, изменилась
		    Sleep 5000
            goto c			
			return
        }        
            else
			tooltip, ne изменилась
		    return
            


    PixelChecksum(coords) {
    For k, v in coords
    {
        PixelGetColor, c, v[1], v[2]
        sum .= c "|"
    }
    Return sum
    }
}
return

Он работает, но не так быстро как нужно. Скрипт ниже через GDIP у меня отказывается работать, да и он не универсальный, как пишут (только на х32 работает). Нужно чтобы и на х64 и на х32 все работало.

; Example - Wait for a Screen Region to change
ChkSum := PixelChecksum( 0,0,10,10 )
While % ( ChkSum = PixelChecksum( 0,0,10,10 ) )
  Sleep, 100
MsgBox, Screen Region Change Detected!
Return

PixelCheckSum( X, Y, W, H, Title ) {
 hWn := WinExist( Title ), hDC := DllCall( "GetDC", UInt,hWn )
 mDC := DllCall( "CreateCompatibleDC", UInt,hDC )
 NumPut( VarSetCapacity(BI,40,0),BI ), NumPut( W,BI,4 ) , NumPut( H,BI,8 )
 NumPut( 32,NumPut( 1,BI,12,"UShort" ),0,"UShort" )     , NumPut( 0,BI,16 )
 hBM := DllCall( "CreateDIBSection", UInt,mDC, UInt,&BI , Int,0, UIntP,pB, Int,0,Int,0 )
 oBM := DllCall( "SelectObject", UInt,mDC, UInt,hBM )   , Rop := 0x40000000|0x00CC0020
 DllCall( "BitBlt", UInt,mDC, Int,0,Int,0, Int,W,Int,H, UInt,hDC, Int,X,Int,Y, UInt,Rop )
 DllCall( "shlwapi\HashData", UInt,pB, UInt,W*H*4, Int64P,Hash, UInt,8 )
 VarSetCapacity(HH,16,0), DllCall( "msvcrt\sprintf", Str,HH, Str,"%016I64X",UInt64,Hash )
 DllCall( "DeleteObject", UInt,hBM ), DllCall( "DeleteObject", UInt,oBM )
 DllCall( "DeleteDC", UInt,mDC ), DllCall( "ReleaseDC", UInt,hWn, UInt,hDC )
Return HH
}

Как еще можно определить изменение цифры? Нужно чтобы детект был практически мгновенным.

2

Re: AHK: Определение изменений в определенной области экрана.

Для обеих битностей.
У меня в своё время всё работало.

/*   __    __  __          __ __       __    __                 _       __                   
    / /_  / /_/ /_____  _ / // /____ _/ /_  / /________________(_)___  / /_ ____  _______
   / __ \/ __/ __/ __ \(_) // // __ '/ __ \/ //_/ ___/ ___/ __/ / __ \/ __// __ \/ __/ _ \
  / / / / /_/ /_/ /_/ / / // // /_/ / / / / ,< (__  ) /__/ / / / /_/ / /__/ /_/ / / / // / 
 /_/ /_/\__/\__/ .___(_) // / \__,_/_/ /_/_/|_/____/\___/_/ /_/ .___/\__(_)____/_/  \__ /  
              /_/     /_//_/                                 /_/                   (___/   
 
 http://ahkscript.org/boards/viewtopic.php?&t=4431
__________________________________________________________________________________________
*/

PixelCheckSum( X, Y, W, H, Title := "" ) { ;               By SKAN,   http://goo.gl/X5dfvn
;                                                          CD:08/Jun/2009 | MD:01/Sep/2014

  Static DIBSECTION, SRCCOPY := 0x00CC0020, CAPTUREBLT := 0x40000000, BPP := 32
  Local hWnd, hDC, mDC, hBM, oBM, nSize, pBITMAPINFOHEADER, ppvBits := 0
  
  If not VarSetCapacity( DIBSECTION )
         VarSetCapacity( DIBSECTION, 104, 0 ) 
  
  pBITMAPINFOHEADER := &DIBSECTION + ( A_PtrSize = 4 ? 24 : 32 )
  
  NumPut(  40, pBITMAPINFOHEADER +  0, "UInt"   ) 
  NumPut(   W, pBITMAPINFOHEADER +  4, "UInt"   )
  NumPut(   H, pBITMAPINFOHEADER +  8, "UInt"   )
  NumPut(   1, pBITMAPINFOHEADER + 12, "UShort" )
  NumPut( BPP, pBITMAPINFOHEADER + 14, "UShort" )

  hWnd  := WinExist( Title )
  hDC   := DllCall( "GetDC", "Ptr",hWnd, "UPtr" )
  mDC   := DllCall( "CreateCompatibleDC", UInt,hDC, "UPtr" )

  hBM   := DllCall( "CreateDIBSection", "Ptr", mDC, "Ptr", pBITMAPINFOHEADER, "Int",0
                                      , "PtrP",ppvBits, "Ptr",0, "Int",0, "UPtr" )
  
  oBM   := DllCall( "SelectObject", "Ptr",mDC, "Ptr",hBM, "UPtr" )
  
  DllCall( "BitBlt", "Ptr",mDC, "Int",0, "Int",0, "Int",W, "Int",H, "Ptr",hDC
                   , "Int",X, "Int",Y, "UInt",SRCCOPY | CAPTUREBLT )

  DllCall( "SelectObject", "Ptr",mDC, "Ptr",oBM )
  DllCall( "DeleteDC",  "Ptr",mDC )
  DllCall( "ReleaseDC", "Ptr",hWnd, "Ptr",hDC )

  DllCall( "GetObject", "Ptr",hBM, "Int",( A_PtrSize = 4 ? 84 : 104 ), "Ptr",&DIBSECTION )
  nSize := NumGet( pBITMAPINFOHEADER + 20, "UInt" ) 
  
Return DllCall( "NTDLL\RtlComputeCrc32", "UInt",0, "Ptr",ppvBits, "UInt",nSize, "UInt" )
     , DllCall( "DeleteObject", "Ptr",hBM )    
}

3

Re: AHK: Определение изменений в определенной области экрана.

Malcev, спасибо работает. Только вот я не понимаю, где у меня ошибка. Тултип изменяется, а msgbox 1 и sleep не хотят отзываться.

while GetKeyState(key,"P") 
{	
	ChkSum := PixelChecksum( 880,23,10,10 )
    tooltip % ChkSum
    DllCall("Sleep",UInt,0)
    if ( PixelChecksum( 880,23,10,10 ) = !ChkSum ) 
	    {
	        msgbox 1
	        Sleep 1000
	}
	smooth()
    DllCall("Sleep",UInt,delay)
}

4

Re: AHK: Определение изменений в определенной области экрана.

if ( PixelChecksum( 880,23,10,10 ) != ChkSum ) 
По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

5

Re: AHK: Определение изменений в определенной области экрана.

serzh82saratov работает, но срабатывает не всегда. Не успевает каким то образом.

6

Re: AHK: Определение изменений в определенной области экрана.

И не будет работать, так как каждый раз в начале цикла вы заново присваиваете ChkSum := PixelChecksum( 880,23,10,10 ).

7

Re: AHK: Определение изменений в определенной области экрана.

Точно.
Но всё же моя поправка имеет место быть?

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

8 (изменено: powercat, 2017-07-10 22:43:06)

Re: AHK: Определение изменений в определенной области экрана.

while GetKeyState(key,"P") 
{		
    ChkSum := PixelChecksum( 880,23,10,10 )  
	DllCall("Sleep",UInt,0)
	smooth()
    if (PixelChecksum( 880,23,10,10 ) != ChkSum) 
    {
	DllCall("Sleep",UInt,500)
    }
	DllCall("Sleep",UInt,0)
}

Все на что хватило ума. Работает, но опять же иногда Sleep 500 просто не применяется или применяется после того, как smooth() уже активна. Помогите довести до ума. В идеале нужно, чтобы после смены области ChkSum, smooth() выключался и вешался Sleep 500 только если зажата определенная клавиша, потом надо чтобы ChkSum запомнил новые пиксели в этих же координатах.

9 (изменено: serzh82saratov, 2017-07-11 20:33:05)

Re: AHK: Определение изменений в определенной области экрана.


ChkSum := PixelChecksum( 880,23,10,10 )  
while GetKeyState(key,"P") 
{		
    If ((T_ChkSum := PixelChecksum( 880,23,10,10 )) != ChkSum)  
		ChkSum := T_ChkSum, DllCall("Sleep",UInt,500)
	Else
		smooth(), DllCall("Sleep",UInt,0)
}
По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

10 (изменено: powercat, 2017-07-12 00:47:12)

Re: AHK: Определение изменений в определенной области экрана.

serzh82saratov достаточно хорошо работает, но smooth() успевает на какую-то долю секунды сработать перед задержкой. Я так понимаю мгновенно не получится из-за того, что ahk выполняется в одном потоке? Спасибо за помощь.

11

Re: AHK: Определение изменений в определенной области экрана.

Не нашёл описание "NTDLL\RtlComputeCrc32".

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

12

Re: AHK: Определение изменений в определенной области экрана.

Вот это нашел:
https://source.winehq.org/WineAPI/RtlComputeCrc32.html

13

Re: AHK: Определение изменений в определенной области экрана.

Спасибо, но я имею ввиду MSDN.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

14

Re: AHK: Определение изменений в определенной области экрана.

Она недокументирована.