Jump to content

Capturewnd command


Recommended Posts

Can capturewnd command be used to capture a screenshot or bmp of a window that is inactive or hidden?

this was my understanding

If so than I think my issue is with the  $hWnd  parameter

I had tried the direct window title and handle

 

#include <ScreenCapture.au3>


$test = WinGetTitle ("test")

_ScreenCapture_CaptureWnd("d:\test\test.bmp", "$test")


 

Link to comment
Share on other sites

_ScreenCapture won't capture hidden windows. You can use the _WinApi_PrintWindow function to do it

#include <GUIConstants.au3>
#include <ScreenCapture.au3>
#include <WinAPI.au3>

#RequireAdmin

AutoItSetOption("WinTitleMatchMode", -2)

Global $hMain = GUICreate("GDI+ example", 1280, 810)
Global $btnCapture = GUICtrlCreateButton("Capture", 10, 10, 100, 25)
Global $inpWindow = GUICtrlCreateInput("", 125, 10, 200, 25)
Global $picCapture = GUICtrlCreatePic("", 0, 40, 1280, 768)

GUISetState(@SW_SHOW)

While (True)
    Switch (GUIGetMsg())
        Case $GUI_EVENT_CLOSE
            Exit 0
        Case $btnCapture
            Local $hHBitmap = CaptureWindow(GUICtrlRead($inpWindow))
            If (Not @Error) Then
                _WinAPI_DeleteObject(GUICtrlSendMsg($picCapture, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap))
                _ScreenCapture_SaveImage(@ScriptDir & "\" & $inpWindow & ".png", $hHBitmap)
                _WinAPI_DeleteObject($hHBitmap)
            EndIf
    EndSwitch
WEnd

Func CaptureWindow($hWnd)
    If (Not IsHWnd($hWnd)) Then $hWnd = WinGetHandle($hWnd)
    If (@error) Then Return SetError(1, 0, False)
    Local $aWinPos = WinGetPos($hWnd)
    Local $hDC = _WinAPI_GetWindowDC($hWnd)
    Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC)
    Local $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $aWinPos[2], $aWinPos[3])
    Local $hObjectOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    _WinAPI_PrintWindow($hWnd, $hMemDC, True)

    _WinAPI_SelectObject($hMemDC, $hHBitmap)
    _WinAPI_BitBlt($hMemDC, 0, 0, $aWinPos[2], $aWinPos[3], $hDC, $aWinPos[0], $aWinPos[1], $SRCCOPY)

    _WinAPI_DeleteDC($hMemDC)
    _WinAPI_SelectObject($hMemDC, $hObjectOld)
    _WinAPI_ReleaseDC($hWnd, $hDC)

    Return $hHBitmap
EndFunc   ;==>CaptureWindow

This just captures the whole window. It will work if the window is in the background or off screen. Won't work if it's minimized, shouldn't work if the window is set set to hidden (not hidden behind another window but hidden as in the @SW_HIDDEN)

If you wanted to just capture a specific region you'll have to look at the BitBlt function. Which transfers the x, y, width, height from the x, y position of the $hSrcDc to the $hDestDc (Which is linked with the $hHBitmap variable).

Edit: After looking through some old scripts looks like I already did it to allow x, y, width, height

Edit2:

See the post below

Edited by InunoTaishou
Link to comment
Share on other sites

so my understanding is I can save this to my include folder and in my script stipulate this as well as its pre requisites as includes 

and than call apon the function whenever I want provided ie

#include <ScreenCapture.au3>
#include <GUIConstants.au3>
#include <ScreenCapture.au3>
#include <WinAPI.au3>
#include <findbmp.au3>

capturewindow(test)

 

 

 

is this the line I would adjust for the save location?

                _ScreenCapture_SaveImage(@ScriptDir & "\" & $inpWindow & ".png", $hHBitmap)
Edited by beelzeboul
clarifying
Link to comment
Share on other sites

I'm confused. The

Func CaptureWindow($sFileName = "", $iLeft = -1, $iTop = -1, $iWidth = -1, $iHeight = -1, $hWnd = WinGetHandle("[Active]"))

function in the post I linked will capture the window of the hWnd you give it (The $test) and save it if you supply a file name in the first parameter. If you don't give it a file name then it returns the windows HBitmap object.

The PrintWindow function I posted in this topic just takes a hWnd (the $test) and returns a windows HBitmap, which I saved using _ScreenCapture_SaveImage in the current script directory as the search criteria from the input (as a png file)

Edited by InunoTaishou
Link to comment
Share on other sites

#include <ScreenCapture.au3>
#include <GUIConstants.au3>
#include <WinAPI.au3>
#include <findbmp.au3>
#include <capturewindow.au3>


Func CaptureWindow($sFileName = "D:\test\test.bmp", $iLeft = -1, $iTop = -1, $iWidth = -1, $iHeight = -1, $hWnd = WinGetHandle("[test]"))

 

is this correct than?

 

this doesnt shoot me any errors but doesnt have the desired effect either

 

 

 

Edited by beelzeboul
Link to comment
Share on other sites

Try it like this (make sure to change the name of the window where I put the comment)

 

#include <GDIPlus.au3>
#include <WinApi.au3>
#include <WindowsConstants.au3>


$hWindow = WinGetHandle("Name of your window here") ; <-- Change this!
CaptureWindow("D:\test\test.bmp", Default, Default, Default, Default, $hWindow)


Func CaptureWindow($sFileName = "", $iLeft = -1, $iTop = -1, $iWidth = -1, $iHeight = -1, $hWnd = WinGetHandle("[Active]"))
    If (Not IsHWnd($hWnd)) Then $hWnd = WinGetHandle($hWnd)
    If (@error) Then Return SetError(1, 0, 0)
    Local $tDesktop = GetDesktopMetrics()
    Local $tRectFWindow = _WinAPI_GetWindowRect($hWnd)

    If ($iLeft = -1 Or $iLeft = Default) Then $iLeft = DllStructGetData($tDesktop, 1)
    If ($iTop = -1 Or $iLeft = Default) Then $iLeft = DllStructGetData($tDesktop, 2)
    If ($iWidth = -1 Or $iWidth = 0 Or $iWidth = Default) Then
        If ($hWnd = _WinAPI_GetDesktopWindow()) Then
            $iWidth = DllStructGetData($tDesktop, 3)
        Else
            $iWidth = DllStructGetData($tRectFWindow, 3) - DllStructGetData($tRectFWindow, 1)
        EndIf
    EndIf
    If ($iHeight = -1 Or $iHeight = 0 Or $iHeight = Default) Then
        If ($hWnd = _WinAPI_GetDesktopWindow()) Then
            $iHeight = DllStructGetData($tDesktop, 4)
        Else
            $iHeight = DllStructGetData($tRectFWindow, 4) - DllStructGetData($tRectFWindow, 2)
        EndIf
    EndIf
    Local $iWidth2 = $iWidth
    Local $iHeight2 = $iHeight
    If ($iLeft) Then $iWidth = Abs($iWidth - $iLeft)
    If ($iTop) Then $iHeight = Abs($iHeight - $iTop)
    Local $hDC = _WinAPI_GetWindowDC($hWnd)
    Local $hDestDC = _WinAPI_CreateCompatibleDC($hDC)
    Local $hDestBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iWidth, $iHeight)
    Local $hDestSv = _WinAPI_SelectObject($hDestDC, $hDestBitmap)
    Local $hSrcDC = _WinAPI_CreateCompatibleDC($hDC)
    Local $hBmp = _WinAPI_CreateCompatibleBitmap($hDC, $iWidth2, $iHeight2)
    Local $hSrcSv = _WinAPI_SelectObject($hSrcDC, $hBmp)
    Local $tPoint = _WinAPI_CreatePoint($iLeft, $iTop)

    _WinAPI_PrintWindow($hWnd, $hSrcDC, True)

    _WinAPI_ScreenToClient($hWnd, $tPoint)

    _WinAPI_BitBlt($hDestDC, 0, 0, $iWidth, $iHeight, $hSrcDC, $iLeft, $iTop, $MERGECOPY)

    _WinAPI_SelectObject($hDestDC, $hDestSv)
    _WinAPI_SelectObject($hSrcDC, $hSrcSv)
    _WinAPI_ReleaseDC($hWnd, $hDC)
    _WinAPI_DeleteDC($hDestDC)
    _WinAPI_DeleteDC($hSrcDC)
    _WinAPI_DeleteObject($hBmp)
    $tPoint = 0
    $tRectFWindow = 0
    $tDesktop = 0

    If ($sFileName = "") Then Return $hDestBitmap

    _GDIPlus_Startup()
    Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hDestBitmap)
    _WinAPI_DeleteObject($hDestBitmap)
    _GDIPlus_ImageSaveToFile($hBitmap, $sFileName)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()
    Return True
EndFunc   ;==>CaptureWindow


Func GetDesktopMetrics()
    Return _GDIPlus_RectFCreate(_WinAPI_GetSystemMetrics($SM_XVIRTUALSCREEN), _WinAPI_GetSystemMetrics($SM_YVIRTUALSCREEN), _
            _WinAPI_GetSystemMetrics($SM_CXVIRTUALSCREEN), _WinAPI_GetSystemMetrics($SM_CYFULLSCREEN))
EndFunc   ;==>GetDesktopMetrics

 

Edited by Floops
Link to comment
Share on other sites

Ya it's throwing me off too, because it's not in either of my examples lol

Just a forewarning, looks like i never finished the complete function in my topic. It will work if you try and capture the whole window but if the $iLeft or $iTop positions are > 0, it just comes out black. Don't have time to fix it right now but I'll look at it later.

Edit: Fixed, this should be good and show you how to use it

#include <GUIConstants.au3>
#include <WinAPIsysinfoConstants.au3>
#include <WinAPI.au3>
#include <GDIPlus.au3>

; Required for applications that are ran in admin mode
;~ #RequireAdmin

AutoItSetOption("WinTitleMatchMode", -2)

Global $hMain = GUICreate("GDI+ example", 1280, 810)
GUICtrlCreateLabel("X: ", 10, 13, 30, 20)
Global $inpLeft = GUICtrlCreateInput("-1", 25, 10, 50, 20)
GUICtrlCreateLabel("Y: ", 85, 13, 30, 20)
Global $inpTop = GUICtrlCreateInput("-1", 100, 10, 50, 20)
GUICtrlCreateLabel("Width: ", 160, 13, 30, 20)
Global $inpWidth = GUICtrlCreateInput("-1", 195, 10, 50, 20)
GUICtrlCreateLabel("Height: ", 255, 13, 30, 20)
Global $inpHeight = GUICtrlCreateInput("-1", 295, 10, 50, 20)
GUICtrlCreateLabel("Title: ", 355, 13, 25, 20)
Global $inpWindow = GUICtrlCreateInput("Program Manager", 385, 10, 100, 20)
GUICtrlCreateLabel("Save As: ", 495, 13, 50, 20)
Global $inpSaveAs = GUICtrlCreateInput(@ScriptDir & "\Desktop.png", 545, 10, 200, 20)
Global $btnCapture = GUICtrlCreateButton("Capture", 750, 10, 100, 20)
Global $picCapture = GUICtrlCreatePic("", 0, 40, 1280, 768)

GUISetState(@SW_SHOW)

While (True)
    Switch (GUIGetMsg())
        Case $GUI_EVENT_CLOSE
            Exit 0
        Case $btnCapture
            Local $hHBitmap = CaptureWindow(GUICtrlRead($inpSaveAs), GUICtrlRead($inpLeft), GUICtrlRead($inpTop), GUICtrlRead($inpWidth), GUICtrlRead($inpHeight), GUICtrlRead($inpWindow))
            If (Not @error) Then
                _WinAPI_DeleteObject(GUICtrlSendMsg($picCapture, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap))
                _WinAPI_DeleteObject($hHBitmap)
            EndIf
    EndSwitch
WEnd

Func CaptureWindow($sFileName = "", $iLeft = -1, $iTop = -1, $iWidth = -1, $iHeight = -1, $hWnd = WinGetHandle("[Active]"), $bClientArea = True)
    If (Not IsHWnd($hWnd)) Then $hWnd = WinGetHandle($hWnd)
    If (@error) Then Return SetError(1, 0, False)
    If (BitAND(WinGetState($hWnd), 16) = 16) Then Return SetError(2, 0, False)
    Local $iSrcWidth = 0
    Local $iSrcHeight = 0

    If ($hWnd = _WinAPI_GetDesktopWindow() Or $hWnd = WinGetHandle("Program Manager")) Then
        Local $tDesktop = GetDesktopMetrics()
        If ($iWidth = -1 Or $iWidth = 0 Or $iWidth = Default Or $iWidth > DllStructGetData($tDesktop, 3)) Then $iWidth = DllStructGetData($tDesktop, 3)
        If ($iHeight = -1 Or $iHeight = 0 Or $iHeight = Default Or $iWidth > DllStructGetData($tDesktop, 4)) Then $iHeight = DllStructGetData($tDesktop, 4)
        $iSrcWidth = DllStructGetData($tDesktop, 3)
        $iSrcHeight = DllStructGetData($tDesktop, 4)
    Else
        Local $tRectWindow = _WinAPI_GetWindowRect($hWnd)
        ; Get the absolute width, using Abs on all of the memembers because the [1] index of the struct may be negative, supports multiple monitors
        Local $iAbsWidth = Abs(Abs(DllStructGetData($tRectWindow, 3)) - Abs(DllStructGetData($tRectWindow, 1)))
        ; Get the absolute height, using Abs on all of the memembers because the [1] index of the struct may be negative, supports multiple monitors
        ; Subtracts the caption bar if $bClientArea only
        Local $iAbsHeight = Abs(Abs(DllStructGetData($tRectWindow, 4)) - Abs(DllStructGetData($tRectWindow, 2))) - ($bClientArea ? _WinAPI_GetSystemMetrics($SM_CYCAPTION) : 0)
        If ($iWidth = -1 Or $iWidth = 0 Or $iWidth = Default Or $iWidth > $iAbsWidth) Then $iWidth = $iAbsWidth
        If ($iHeight = -1 Or $iHeight = 0 Or $iHeight = Default Or $iHeight > $iAbsHeight) Then $iHeight = $iAbsHeight
        $iSrcWidth = $iAbsWidth
        $iSrcHeight = $iAbsHeight
    EndIf

    If ($iLeft = -1 Or $iLeft = Default) Then $iLeft = 0
    If ($iTop = -1 Or $iTop = Default) Then $iTop = 0

    Local $hDC = _WinAPI_GetWindowDC($hWnd)
    Local $hDestDC = _WinAPI_CreateCompatibleDC($hDC)
    Local $hDestBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iWidth, $iHeight)
    Local $hDestSv = _WinAPI_SelectObject($hDestDC, $hDestBitmap)
    Local $hSrcDC = _WinAPI_CreateCompatibleDC($hDC)
    Local $hBmp = _WinAPI_CreateCompatibleBitmap($hDC, $iSrcWidth, $iSrcHeight)
    Local $hSrcSv = _WinAPI_SelectObject($hSrcDC, $hBmp)

    _WinAPI_PrintWindow($hWnd, $hSrcDC, True)

    _WinAPI_BitBlt($hDestDC, 0, 0, $iWidth, $iHeight, $hSrcDC, $iLeft, $iTop, $MERGECOPY)

    _WinAPI_SelectObject($hDestDC, $hDestSv)
    _WinAPI_SelectObject($hSrcDC, $hSrcSv)
    _WinAPI_ReleaseDC($hWnd, $hDC)
    _WinAPI_DeleteDC($hDestDC)
    _WinAPI_DeleteDC($hSrcDC)
    _WinAPI_DeleteObject($hBmp)
    $tPoint = 0
    $tRectWindow = 0
    $tDesktop = 0

    If ($sFileName) Then
        _GDIPlus_Startup()
        Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hDestBitmap)
        _GDIPlus_ImageSaveToFile($hBitmap, $sFileName)
        _GDIPlus_BitmapDispose($hBitmap)
        _GDIPlus_Shutdown()
    EndIf
    Return $hDestBitmap
EndFunc   ;==>CaptureWindow

Func GetDesktopMetrics()
    Return _GDIPlus_RectFCreate(_WinAPI_GetSystemMetrics($SM_XVIRTUALSCREEN), _WinAPI_GetSystemMetrics($SM_YVIRTUALSCREEN), _
            _WinAPI_GetSystemMetrics($SM_CXVIRTUALSCREEN), _WinAPI_GetSystemMetrics($SM_CYVIRTUALSCREEN))
EndFunc   ;==>GetDesktopMetrics

 

Edited by InunoTaishou
Link to comment
Share on other sites

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
 Share

  • Recently Browsing   0 members

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