Jump to content

Werty

Active Members
  • Posts

    1,182
  • Joined

  • Last visited

  • Days Won

    39

Werty last won the day on February 17

Werty had the most liked content!

Profile Information

  • Member Title
    ♥ 96.7k
  • Location
    Danmark

Recent Profile Visitors

2,348 profile views

Werty's Achievements

  1. Updated version, and a possible solution to get the faster version running with tool.exe. Arrays are slow in AutoIt, strings are fast, so got rid of the arrays... #include <GDIPlus.au3> #include <WinAPI.au3> HotKeySet("{ESC}", "_exit") ;Be sure $posx and $posy is pointing at the correct spot! Global $posx = 37+16, $posy = 38+16 , $result = "", $code1, $code2, $code3, $code4, $capture, $pixels = DllStructCreate('dword[2816]') ;Lookup table to avoid searching Global $lookup = "1000000000004000000000000000006000320000000000009000008000000000700000000000000000000000000000000000000000000000005" ;Test section ;-------------------------------------------------------------- $gui = GUICreate("Getnumber", 640, 480, 100, 100) GUISetState() WinWaitActive($gui); <--- necessary or screencapture fails _GDIPlus_Startup() $graphics = _GDIPlus_GraphicsCreateFromHWND($gui) $image = _GDIPlus_BitmapCreateFromFile("3.png") _GDIPlus_GraphicsDrawImageRect($graphics, $image, 16, 16, 176, 56) ;-------------------------------------------------------------- ;/Test section $hDDC = _WinAPI_GetWindowDC($gui) $hCDC = _WinAPI_CreateCompatibleDC($hDDC) $capture = _WinAPI_CreateCompatibleBitmap($hDDC, 88, 32) _WinAPI_SelectObject($hCDC, $capture) _WinAPI_BitBlt($hCDC, 0, 0, 88, 32, $hDDC, $posx, $posy, 0x00CC0020) _WinAPI_ReleaseDC($gui, $hDDC) ; <----NOTICE _WinAPI_DeleteDC($hCDC) $result = Getnumber($result) Consolewrite("Result: " & $result & @crlf) While 1 Sleep(10) WEnd Func Getnumber($result) Local $value = 64, $code1 = 0, $code2 = 0, $code3 = 0, $code4 = 0 DllCall('gdi32.dll', 'dword', 'GetBitmapBits', 'ptr', $capture, 'dword', DllStructGetSize($pixels), 'ptr', DllStructGetPtr($pixels)) For $loop = 1 To 2816 Step 440 $code1 += DllStructGetData($pixels, 1, $loop ) > 4278190080 ? $value:0 $code2 += DllStructGetData($pixels, 1, $loop+29) > 4278190080 ? $value:0 $code3 += DllStructGetData($pixels, 1, $loop+58) > 4278190080 ? $value:0 $code4 += DllStructGetData($pixels, 1, $loop+87) > 4278190080 ? $value:0 $value /= 2 Next Return StringMid($lookup, $code1+1, 1) & StringMid($lookup, $code2+1, 1) & StringMid($lookup, $code3+1, 1) & StringMid($lookup, $code4+1, 1) EndFunc Func _exit() _GDIPlus_Shutdown() Exit EndFunc As for the possible solution to get it to work with tool.exe, notice the "NOTICE" in above script, in the helpfile under GetWindowDC() it says... We may have been lucky that it worked at all with our gui as the gui is OWNED by us, so leaving out ReleaseDC() worked, but we dont OWN the tool.exe, so maybe try including the ReleaseDC(), you would have to put all the WinAPI stuff back into the loop, but as you said earlier, they are pretty fast as you saw no big changes in speed putting them outside the loop. it was the bitblt that required more time as we used the whole desktop that took time. Another solution could be to lower the resolution of your monitor to it's lowest possible, or get hold on an ancient 14"-17" lcd and hook that up, they can go low to 640x480.
  2. Try with _WinAPI_GetFileSizeEx(), maybe there's a difference.
  3. Have you tried using Opt("GUIOnEventMode", 1) ? Gui Reference in the helpfile, at the bottom "Gui Event Modes". https://www.autoitscript.com/autoit3/docs/guiref/GUIRef.htm
  4. Oh, didnt know my code was complicated, thanks for letting me know.
  5. @junkew, I fixed your script, I tried and tried with no result until I noticed you changed GetWindowDC() back to GetDC(), that doesnt work, it has to be GetWindowDC(). (though I have no idea why getdc($gui) doesnt work, I agree it should work somehow, I tried adding $CAPTUREBLT to the bitblt, with no result) #include <GDIPlus.au3> #include <WinAPI.au3> HotKeySet("{ESC}", "_exit") ;Be sure $posx and $posy is pointing at the correct spot! Global $posx = 37+16, $posy = 38+16 , $result = "", $code[4], $capture, $pixels = DllStructCreate('dword[2816]') ;Lookup table to avoid searching Global $digit[115] = [1,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0, _ 0,0,0,0,0,0,0,0,0,0,6,0,0,0,3,2,0,0,0,0, _ 0,0,0,0,0,0,0,0,9,0,0,0,0,0,8,0,0,0,0,0, _ 0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, _ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, _ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,5] ;Test section ;-------------------------------------------------------------- $gui = GUICreate("Getnumber", 640, 480, 100, 100) GUISetState() WinWaitActive($gui); <--- necessary or screencapture fails _GDIPlus_Startup() $graphics = _GDIPlus_GraphicsCreateFromHWND($gui) $image = _GDIPlus_BitmapCreateFromFile("3.png") _GDIPlus_GraphicsDrawImageRect($graphics, $image, 16, 16, 176, 56) Sleep(250); <------- necessary because drawimagerect() is too slow, script occasionally fails without ;-------------------------------------------------------------- ;/Test section ;~ $hDDC = _WinAPI_GetDC(0) ;should be $hDDC = _WinAPI_GetWindowDC($gui) ;~ $hDDC = _WinAPI_GetDC($gui) $hCDC = _WinAPI_CreateCompatibleDC($hDDC) $capture = _WinAPI_CreateCompatibleBitmap($hDDC, 88, 32) _WinAPI_SelectObject($hCDC, $capture) _WinAPI_BitBlt($hCDC, 0, 0, 88, 32, $hDDC, $posx, $posy, 0x00CC0020) _WinAPI_DeleteDC($hCDC) Sleep(250) local $t2 = TimerInit() $result = Getnumber($result) Consolewrite("Time: " & TimerDiff($t2) & @crlf) Consolewrite("Result: " & $result & @crlf) While 1 Sleep(10) WEnd Func Getnumber($result) Local $code[4] = [0,0,0,0], $value = 64 DllCall('gdi32.dll', 'dword', 'GetBitmapBits', 'ptr', $capture, 'dword', DllStructGetSize($pixels), 'ptr', DllStructGetPtr($pixels)) For $loop = 1 To 2816 Step 440 $code[0] += DllStructGetData($pixels, 1, $loop ) > 4278190080 ? $value:0 $code[1] += DllStructGetData($pixels, 1, $loop+29) > 4278190080 ? $value:0 $code[2] += DllStructGetData($pixels, 1, $loop+58) > 4278190080 ? $value:0 $code[3] += DllStructGetData($pixels, 1, $loop+87) > 4278190080 ? $value:0 $value /= 2 Next ;~ consolewrite($code[0] & $code[1] & $code[2] & $code[3]) Return String($digit[$code[0]]) & String($digit[$code[1]]) & String($digit[$code[2]]) & String($digit[$code[3]]) EndFunc Func _exit() _GDIPlus_Shutdown() Exit EndFunc
  6. @junkew, yes, the posx and posy must be EXACTLY on the correct spot (red pixel).
  7. Here's the pic from the first thread.... Imagine the first column of each number is a BYTE, with Most Significant Bit being 128, then 64, 32 16 8 4 2 1, we dont need the 128 as each number is only 7 imaginary bits tall, then the loop starts at the top left corner and reads the first bit, if it's lit it adds $value=64 to $code[0], if unlit nothing is added, then the next DllStructGetData reads the next number, and so on, when it gets to the end (last number) then $value is divided by 2 so it's 32 which is the next significant bit and the STEP in the loop goes to next line/bit, if it finds any lit bits it adds $value to $code, and so on.... The $code's now have values, which we then look up in the lookup table, like 114 is 5, the last in the lookup as it's the largest number, while 4 is located at 12'th place.
  8. It's actually including all four, the fourth is just only the first column of that number, as that is all we need. I'll see, as i promised in the other thread, about making a short tutorial/explanation of how it works, this time I promise I will get it done.....after dinner.
  9. Very sure If needed/wanted I can post one of my test examples later where you can see it works, right now I have to make dinner, so I'll be in and out for the next couple of hours.
  10. Hmm, the image you posted is one pixel off, should look like this... That said, I dont have much experience with automation, I use autoit for other things, so I might have assumed wrong that WinWaitActive should give the correct handle to the tools windows, try something like $tools = WinGetHandle(blablabla) or something, as the script should give you atleast other result than 1111 when you are so close. Test yourself how to get the correct handle to the tools windows, or have someone with more automation experience chime in. I get my handle to my test gui where it works like this.... $gui = GUICreate("Getnumber", 320, 240, -1, -1) Maybe something like this... $hTool = Run("tool.exe") ;and then change the GetWindowDC accordingly.
  11. HAHA, major speed increase, we've been doing it wrong, we've been using _WinAPI_GetDC(0) all the time which is the whole desktop, when we should have been using _WinAPI_GetWindowDC() instead, it's now like 5 times faster for me as it went from the whole desktop @3440x1440 to the test gui I've been using @640x480, and speed increased dramatically. Changes to make... $hDDC = _WinAPI_GetDC(0) ;should be $hDDC = _WinAPI_GetWindowDC($tool) ;Change $posx and $posy to point at the correct spot, this is now not from the desktop 0,0 but from the tools.exe windows start position. So speed increase depends on the size of the tools.exe window, maybe you can even resize it to be smaller. Times i get now for full cycle with bitblt and all... 0.5085 0.5136 1.3745 0.5044 0.4402 0.4155 0.9733 Try it and report back with times, it's awesome.
  12. I already tried that with my method, with no good result, to much information is lost no matter how i tried resizing it, tried all the filters and different sizes, but maybe it'll work using another method, like checksum as you mentioned earlier, and stuffed in a lookup table Though, my method already only reads 28 times, so it would have to be resized to something smaller than 28 pixels in a square to be faster. Putting a timer into my GetNumber() function i get insanely fast times like... Func Getnumber($result) $t2 = TimerInit() Local $code[4] = [0,0,0,0], $value = 64 DllCall('gdi32.dll', 'dword', 'GetBitmapBits', 'ptr', $capture, 'dword', DllStructGetSize($pixels), 'ptr', DllStructGetPtr($pixels)) For $loop = 1 To 2816 Step 440 $code[0] += DllStructGetData($pixels, 1, $loop ) > 4278190080 ? $value:0 $code[1] += DllStructGetData($pixels, 1, $loop+29) > 4278190080 ? $value:0 $code[2] += DllStructGetData($pixels, 1, $loop+58) > 4278190080 ? $value:0 $code[3] += DllStructGetData($pixels, 1, $loop+87) > 4278190080 ? $value:0 $value /= 2 Next Consolewrite("Time: " & TimerDiff($t2) & @crlf) Return String($digit[$code[0]]) & String($digit[$code[1]]) & String($digit[$code[2]]) & String($digit[$code[3]]) EndFunc Time: 0.0582 Time: 0.0583 Time: 0.0804 Time: 0.0641 Time: 0.0816 Time: 0.0582 Time: 0.0581 it's the other stuff that takes longer, here times I get for a full run. 6.0095 6.9233 6.9252 6.8122 7.2931 6.7959 6.9708 ..with the bitblt stuff. Maybe later I'll try making the getnumber() func into a C Dll, though with only 28 checks it's hardly gonna be worth it. 😛
  13. Come to think of it, if you used the loop you posted for the other tool with 3 digits from your first thread, then you might have gotten wrong results, as the "Do" in the Do-Until loop is placed wrong, if an error/false positive occur then it repeats and ControlClick's one more time, thereby changing the number it was supposed to be checking, so if you had gotten 37 false positives you would have ControlClicked 1000037 times instead of 1000000 times, missing out on some, causing the order of the results to be out of sync... For $loop = 0 To 999999 Do $serial = StringFormat('%06i', $loop) ControlClick($tool, "", "TTabSheet1", "primary", 1, 100, 100) $hDDC = _WinAPI_GetDC(0) $hCDC = _WinAPI_CreateCompatibleDC($hDDC) $hBmp = _WinAPI_CreateCompatibleBitmap($hDDC, 34, 20) _WinAPI_SelectObject($hCDC, $hBmp) ;Do should be here _WinAPI_BitBlt($hCDC, 0, 0, 34, 20, $hDDC, $posx, $posy, 0x00CC0020) _WinAPI_DeleteDC($hCDC) $result = GetNumber($result) Until ((StringLen($result) = 4) and StringIsDigit($result)) FileWrite($db, $serial & "," & $result & @LF) Next We have changed it in this new version, just concerned that you used it in your first thread about the tool with 3 digits, then you'd have a wrong list and have to redo it.
  14. Please also post an update on the "elapsed" time that you posted. 000000,17.3893 elapsed 000001,19.3955 elapsed 000002,4.952 elapsed 000003,5.7421 elapsed 000004,4.4015 elapsed 000005,4.6038 elapsed 000006,4.3785 elapsed 000007,4.8244 elapsed 000008,4.9788 elapsed 000009,5.0533 elapsed 000010,4.2012 elapsed 000011,4.3916 elapsed 000012,5.0254 elapsed 000013,5.2419 elapsed 000014,4.2951 elapsed 000015,4.4227 elapsed 000016,4.804 elapsed 000017,4.9286 elapsed 000018,3.9473 elapsed 000019,4.7 elapsed 000020,5.8118 elapsed 000021,19.3781 elapsed 000022,4.6165 elapsed 000023,4.7874 elapsed 000024,5.0672 elapsed 000025,4.9123 elapsed 000026,4.8596 elapsed 000027,5.0079 elapsed 000028,4.6646 elapsed 000029,5.0613 elapsed 000030,4.5557 elapsed It'll be interesting to see the change after we moved all that stuff out of the loop.
  15. Hmm, maybe check again if the result is 0000, if it returns 0000 again it must be correct, otherwise it will return the new correct result. Local $BigString = "" For $loop = 0 To 999999 ControlClick($tool, "", "TTabSheet1", "primary", 1, 100, 100) _WinAPI_BitBlt($hCDC, 0, 0, 88, 32, $hDDC, $posx, $posy, 0x00CC0020) $result = GetNumber($result) If $result = "0000" Then _WinAPI_BitBlt($hCDC, 0, 0, 88, 32, $hDDC, $posx, $posy, 0x00CC0020) $result = GetNumber($result) EndIf $BigString &= String(StringFormat('%06i', $loop)) & "," & String($result) & @LF Next _WinAPI_DeleteDC($hCDC) FileWrite($db, $BigString) It's not failproof, but you said the errors never (so far) occur the same place, so should be ok, else make it a triple check. But as you also mentioned, it could be hardware related, imagine the script being so fast that it runs faster than a 60hz monitor, then you would need a faster monitor. Or even a ram problem, that a computer with ECC ram would handle it better.
×
×
  • Create New...