Jump to content

Recommended Posts

Posted
On 1/15/2019 at 11:48 PM, Bilgus said:

why not copy the dc of the window and search that instead using a similar method or bitblit

 can you please guide me as to where I can find information on how to use this method. I am open to anything else that works faster. My experience in programming is only a one semester high school class. I can do things with guidance but don't know a lot of intricacies. Thanks

Posted

This should give you a place to start from

#cs ----------------------------------------------------------------------------

    AutoIt Version: 3.3.14.5

#ce ----------------------------------------------------------------------------

#include <APIGdiConstants.au3>
#include <GUIConstantsEx.au3>
#include <SendMessage.au3>
#include <StaticConstants.au3>
#include <WinAPIGdi.au3>
#include <WinAPIHObj.au3>

#include <Timers.au3>

$G_iPID = RunProgram()
$G_hWND = _GetHwndFromPID($G_iPID)
ConsoleWrite("PID: " & $G_iPID & " hWNd: " & $G_hWND & @CRLF)
Example($G_hWND)



Func RunProgram()
    ; Run Notepad with the window maximized.
    Local $iPID = Run("notepad.exe", "", @SW_SHOW)

    ; Wait 10 seconds for the Notepad window to appear.
    WinWait("[CLASS:Notepad]", "", 10)

    Return $iPID
EndFunc   ;==>RunProgram

;Function for getting HWND from PID
;www.autoitscript.com/wiki/FAQ#How_can_I_get_a_window_handle_when_all_I_have_is_a_PID.3F
Func _GetHwndFromPID($iPID)
    $hWND = 0
    $winlist = WinList()
    Do
        For $i = 1 To $winlist[0][0]
            If $winlist[$i][0] <> "" Then
                $iPID2 = WinGetProcess($winlist[$i][1])
                If $iPID2 = $iPID Then
                    $hWND = $winlist[$i][1]
                    ExitLoop
                EndIf
            EndIf
        Next
    Until $hWND <> 0
    Return $hWND
EndFunc   ;==>_GetHwndFromPID



Func Example($hWND) ;helpfile _WinAPI_CreateDIBSection
    Local $hStarttime = _Timer_Init()

    Local $iWidth = 0, $iHeight = 0

    Local $aWinsz = WinGetPos($hWND)
    If IsArray($aWinsz) Then
        $iWidth = $aWinsz[2]
        $iHeight = $aWinsz[3]
    EndIf

    Local $hWndDC = _WinAPI_GetDC($hWND)
    Local $hCompDC = _WinAPI_CreateCompatibleDC(0)

    ; Create 32 (ARGB) bits-per-pixel device-independent bitmap (DIB) that use a mask
    Local $tBIV5HDR = DllStructCreate($tagBITMAPV5HEADER)

    DllStructSetData($tBIV5HDR, 'bV5Size', DllStructGetSize($tBIV5HDR))
    DllStructSetData($tBIV5HDR, 'bV5Width', $iWidth)
    DllStructSetData($tBIV5HDR, 'bV5Height', $iHeight)
    DllStructSetData($tBIV5HDR, 'bV5Planes', 1)
    DllStructSetData($tBIV5HDR, 'bV5BitCount', 32)
    DllStructSetData($tBIV5HDR, 'biCompression', $BI_BITFIELDS)
    DllStructSetData($tBIV5HDR, 'bV5SizeImage', 0)
    DllStructSetData($tBIV5HDR, 'bV5XPelsPerMeter', 0)
    DllStructSetData($tBIV5HDR, 'bV5YPelsPerMeter', 0)
    DllStructSetData($tBIV5HDR, 'bV5ClrUsed', 0)
    DllStructSetData($tBIV5HDR, 'bV5ClrImportant', 0)
    DllStructSetData($tBIV5HDR, 'bV5RedMask', 0x00FF0000)
    DllStructSetData($tBIV5HDR, 'bV5GreenMask', 0x0000FF00)
    DllStructSetData($tBIV5HDR, 'bV5BlueMask', 0x000000FF)
    DllStructSetData($tBIV5HDR, 'bV5AlphaMask', 0xFF000000)
    DllStructSetData($tBIV5HDR, 'bV5CSType', 0)
    DllStructSetData($tBIV5HDR, 'bV5Endpoints', 0, 1)
    DllStructSetData($tBIV5HDR, 'bV5Endpoints', 0, 2)
    DllStructSetData($tBIV5HDR, 'bV5Endpoints', 0, 3)
    DllStructSetData($tBIV5HDR, 'bV5GammaRed', 0)
    DllStructSetData($tBIV5HDR, 'bV5GammaGreen', 0)
    DllStructSetData($tBIV5HDR, 'bV5GammaBlue', 0)
    DllStructSetData($tBIV5HDR, 'bV5Intent', 0)
    DllStructSetData($tBIV5HDR, 'bV5ProfileData', 0)
    DllStructSetData($tBIV5HDR, 'bV5ProfileSize', 0)
    DllStructSetData($tBIV5HDR, 'bV5Reserved', 0)

    Local $pBits
    Local $hBmp = _WinAPI_CreateDIBSection(0, $tBIV5HDR, $DIB_RGB_COLORS, $pBits)
    Local $hBmpOld = _WinAPI_SelectObject($hCompDC, $hBmp)
    Local $tPixels = DllStructCreate("dword[" & $iWidth * $iHeight & "]", $pBits) ;DWORD is 32 bits


    _WinAPI_PrintWindow($hWND, $hCompDC) ;copy hWND into the compatible dc we created
    WinSetState($hWND, "", @SW_MINIMIZE)

    _WinAPI_SelectObject($hCompDC, $hBmpOld) ;deselect hbmp from dc and restore hBmpOld so we can play with it

    ConsoleWrite("Setup: " & _Timer_Diff($hStarttime) & " Ms" & @CRLF)
    $hStarttime = _Timer_Init()

    For $iY = 0 To $iHeight - 1
        For $iX = 1 To $iWidth
            Local $iColorIdx = ($iY * $iWidth) + $iX ;;Calculate position in array based on image stride
            $iColor = DllStructGetData($tPixels, 1, $iColorIdx)
            ;;alternatively you could search for a specific color...
            If BitAND($iColor, 0x0000FF00) > 0xB0 And BitAND($iColor, 0x0000FF) < 0x3F And BitAND($iColor, 0x000000FF) < 0x3F Then
                DllStructSetData($tPixels, 1, 0xFF00FF00, $iColorIdx) ;Don't Forget Alpha Channel
            EndIf
        Next
    Next

    ConsoleWrite("Search: " & _Timer_Diff($hStarttime) & " Ms" & @CRLF)

    ;copy hbmp into picture control to view results
    Local $hForm = GUICreate('Test ' & StringReplace(@ScriptName, '.au3', '()'), $iWidth, $iHeight)
    Local $idPic = GUICtrlCreatePic('', 0, 0, $iWidth, $iHeight)
    Local $hPic = GUICtrlGetHandle($idPic)

    ; Set bitmap to control
    _SendMessage($hPic, $STM_SETIMAGE, 0, $hBmp)
    Local $hObj = _SendMessage($hPic, $STM_GETIMAGE)
    If $hObj <> $hBmp Then
        _WinAPI_DeleteObject($hBmp)
    EndIf

    GUISetState(@SW_SHOW)

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    ;release objects
    _WinAPI_DeleteObject($hBmp)
    _WinAPI_ReleaseDC(0, $hCompDC)
    _WinAPI_ReleaseDC($hWND, $hWndDC)

EndFunc   ;==>Example

Things to remember:

This is a bit slower than what is possible since we go over the whole image and are searching for a range of colors and then show the results

You can save some time by storing the $tagBITMAPV5HEADER structure rather than re-creating it each time

same goes for hCompDC and hWndDC but this is just an example to get you started....

 

Ideally the client area should be excluded _WinAPI_PrintWindow($hWND, $hCompDC, true)

Store the handle from _WinAPI_SelectObject() you need to put it back when finished (see $hBmpOld = _WinAPI_SelectObject($hCompDC, $hBmp))

You need to free/delete handles/objects you create when you finish with them (see release objects comment...)

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...