therks

Capturing fullscreen (directx) window

30 posts in this topic

#1 ·  Posted (edited)

Hi there, been out of the AutoIt game for a while but I'm tinkering with a screenshot manager of sorts, and I'm hoping to use AutoIt to do some screen capturing in a fullscreen application.

I messed about with the _ScreenCapture_Capture() function and pared it down to what seems to be the necessary bits:

#include <ScreenCapture.au3>

HotKeySet('#g', '_Test')
HotKeySet('{esc}', '_Exit')

ProcessWaitClose(@AutoItPID)

Func _Exit()
    Exit
EndFunc

Func _Test()
    Local $sFileName = 'C:\Test.jpg'
    Local $hWnd = WinGetHandle('[active]')
    Local $hDDC = _WinAPI_GetDC($hWnd)
    Local $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    Local $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, @DesktopWidth, @DesktopHeight)
    _WinAPI_SelectObject($hCDC, $hBMP)
    _WinAPI_BitBlt($hCDC, 0, 0, @DesktopWidth, @DesktopHeight, $hDDC, 0, 0, $__SCREENCAPTURECONSTANT_SRCCOPY)

    _WinAPI_ReleaseDC($hWnd, $hDDC)
    _WinAPI_DeleteDC($hCDC)

    _ScreenCapture_SaveImage($sFileName, $hBMP, True)
EndFunc

Unfortunately, all I get are full black images. I'm not well versed with this stuff, so I'm hoping maybe there's some API magic that can help, but I'm getting the feeling that what I want is just not possible with AutoIt alone.

Thanks for reading.

*Edit: I've also tried Irfanview's screen capture ability and it only returns a black image as well, but it will capture the cursor. I don't know if that helps or means anything.

Edited by therks
Title update/clarification

Share this post


Link to post
Share on other sites



Why not using _ScreenCapture_Capture? This script works for me:

#include <ScreenCapture.au3>

HotKeySet('!g', '_Test')
HotKeySet('{esc}', '_Exit')

ProcessWaitClose(@AutoItPID)

While 1
    Sleep(1000)
WEnd

Func _Exit()
    Exit
EndFunc

Func _Test()
    Local $sFileName = 'Test.jpg'
    Local $hWnd = WinGetHandle('[active]')
    $aPos=WinGetPos($hWnd)
    If _ScreenCapture_Capture($sFileName,0,0,$aPos[2],$aPos[3],False) Then ShellExecute($sFileName)
EndFunc

 

Share this post


Link to post
Share on other sites

That's what I tried first of course, but it just gave me a black image. Looking at the source for  _ScreenCapture_Capture I saw it was using _WinAPI_GetDesktopWindow() for the device context so I was hoping if I forced it to grab the current active window instead I might get better results. Alas no luck, hence why I am here.

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Have a look at _WinAPI_SetWindowDisplayAffinity and this modified example:

#include <APIGdiConstants.au3>
#include <APISysConstants.au3>
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <ScreenCapture.au3>
#include <StaticConstants.au3>
#include <WinAPIGdi.au3>
#include <WinAPISys.au3>
#include <WindowsConstants.au3>

#cs
If (_WinAPI_GetVersion() < '6.1') Or (Not _WinAPI_DwmIsCompositionEnabled()) Then
    MsgBox(BitOR($MB_ICONERROR, $MB_SYSTEMMODAL), 'Error', 'Require Windows 7 or later with enabled Aero theme.')
    Exit
EndIf
#ce

Global $g_iWidth = @DesktopWidth / 2, $g_iHeight = @DesktopHeight / 2

Local $hForm = GUICreate('Test ' & StringReplace(@ScriptName, '.au3', '()'), $g_iWidth + 116, $g_iHeight + 51)
GUICtrlCreatePic('', 14, 14, $g_iWidth + 2, $g_iHeight + 2, -1, $WS_EX_STATICEDGE)
GUICtrlSetState(-1, $GUI_DISABLE)
Global $g_hPic = GUICtrlGetHandle(-1)
Local $idCheck = GUICtrlCreateCheckbox('Protect against capture of window', 14, $g_iHeight + 23, 182, 21)
Local $idButton = GUICtrlCreateButton('Capture', $g_iWidth + 29, 13, 74, 25)
GUICtrlSetState(-1, BitOR($GUI_DEFBUTTON, $GUI_FOCUS))
Local $idMyCapture = GUICtrlCreateButton('MyCapture', $g_iWidth + 29, 43, 74, 25)
GUISetState(@SW_SHOW)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop
        Case $idButton
            _Capture()
        Case $idMyCapture
            _MyCapture()
        Case $idCheck
            If GUICtrlRead($idCheck) = $GUI_CHECKED Then
                _WinAPI_SetWindowDisplayAffinity($hForm, $WDA_MONITOR)
            Else
                _WinAPI_SetWindowDisplayAffinity($hForm, 0)
            EndIf
    EndSwitch
WEnd

Func _Capture()
    Local $hObj = _SendMessage($g_hPic, $STM_SETIMAGE, 0, 0)
    If $hObj Then
        _WinAPI_DeleteObject($hObj)
    EndIf
    Local $hDC = _WinAPI_GetDC($g_hPic)
    Local $hDestDC = _WinAPI_CreateCompatibleDC($hDC)
    Local $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $g_iWidth, $g_iHeight)
    Local $hDestSv = _WinAPI_SelectObject($hDestDC, $hBitmap)
    Local $hSrcDC = _WinAPI_CreateCompatibleDC($hDC)
    $hObj = _ScreenCapture_Capture('', 0, 0, -1, -1, 0)
    Local $hSrcSv = _WinAPI_SelectObject($hSrcDC, $hObj)
    _WinAPI_SetStretchBltMode($hDestDC, $HALFTONE)
    _WinAPI_StretchBlt($hDestDC, 0, 0, $g_iWidth, $g_iHeight, $hSrcDC, 0, 0, @DesktopWidth, @DesktopHeight, $SRCCOPY)
    _WinAPI_ReleaseDC($g_hPic, $hDC)
    _WinAPI_SelectObject($hDestDC, $hDestSv)
    _WinAPI_DeleteDC($hDestDC)
    _WinAPI_SelectObject($hSrcDC, $hSrcSv)
    _WinAPI_DeleteObject($hObj)
    _WinAPI_DeleteDC($hSrcDC)
    _SendMessage($g_hPic, $STM_SETIMAGE, 0, $hBitmap)
    $hObj = _SendMessage($g_hPic, $STM_GETIMAGE)
    If $hObj <> $hBitmap Then
        _WinAPI_DeleteObject($hBitmap)
    EndIf
EndFunc   ;==>_Capture

Func _MyCapture()
    Local $iOldAffinity=_WinAPI_GetWindowDisplayAffinity($hForm)
                _WinAPI_SetWindowDisplayAffinity($hForm, 0)
Local $hObj = _SendMessage($g_hPic, $STM_SETIMAGE, 0, 0)
    If $hObj Then
        _WinAPI_DeleteObject($hObj)
    EndIf
    Local $hDC = _WinAPI_GetDC($g_hPic)
    Local $hDestDC = _WinAPI_CreateCompatibleDC($hDC)
    Local $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $g_iWidth, $g_iHeight)
    Local $hDestSv = _WinAPI_SelectObject($hDestDC, $hBitmap)
    Local $hSrcDC = _WinAPI_CreateCompatibleDC($hDC)
    $hObj = _ScreenCapture_Capture('', 0, 0, -1, -1, 0)
    Local $hSrcSv = _WinAPI_SelectObject($hSrcDC, $hObj)
    _WinAPI_SetStretchBltMode($hDestDC, $HALFTONE)
    _WinAPI_StretchBlt($hDestDC, 0, 0, $g_iWidth, $g_iHeight, $hSrcDC, 0, 0, @DesktopWidth, @DesktopHeight, $SRCCOPY)
    _WinAPI_ReleaseDC($g_hPic, $hDC)
    _WinAPI_SelectObject($hDestDC, $hDestSv)
    _WinAPI_DeleteDC($hDestDC)
    _WinAPI_SelectObject($hSrcDC, $hSrcSv)
    _WinAPI_DeleteObject($hObj)
    _WinAPI_DeleteDC($hSrcDC)
    _SendMessage($g_hPic, $STM_SETIMAGE, 0, $hBitmap)
    $hObj = _SendMessage($g_hPic, $STM_GETIMAGE)
    If $hObj <> $hBitmap Then
        _WinAPI_DeleteObject($hBitmap)
    EndIf
    _WinAPI_SetWindowDisplayAffinity($hForm, $iOldAffinity)
EndFunc   ;==>_Capture

 

Edited by AutoBert

Share this post


Link to post
Share on other sites

Still no dice unfortunately. Just more blackness. :(

Share this post


Link to post
Share on other sites

Does running as admin work?

Share this post


Link to post
Share on other sites
5 hours ago, therks said:

Still no dice unfortunately. Just more blackness. :(

The script example run: If 'Protect against capture of window'-checkbox is unchecked both capture routines are showing captured in the piccontrol. If this checkboxis checked, the 'Capture'-button can't capture (black square) but the 'MyCapture'-button shows the captured in the piccontrol.

Are you sure you are trying to capture output of a windows-app?

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

On Sonntag, 31. Juli 2016 at 7:03 PM, therks said:

I'm hoping to use AutoIt to do some screen capturing in a fullscreen application.

..

Unfortunately, all I get are full black images.

Have you tried to do your screenshots with some other program, e.g. irfanview ?

That might be a simpler solution.

Also, what resolution & screenmode is that "fullscreen application" using ?

Edited by hajo4

-HaJo

Share this post


Link to post
Share on other sites
15 hours ago, hajo4 said:

Have you tried to do your screenshots with some other program, e.g. irfanview ?

That might be a simpler solution.

Also, what resolution & screenmode is that "fullscreen application" using ?

Irfanview was actually my first stop when I couldn't get the AutoIt functions to work, it also gives me a black image.

Resolution is the same as the desktop resolution, 1366x768 I believe (it's a laptop at work I can't check at the moment). Not sure what you mean by screenmode though.

Share this post


Link to post
Share on other sites

Check out my topic from a while back, the capture window function should do what you want

 

Share this post


Link to post
Share on other sites
On 1.8.2016 at 9:06 AM, AutoBert said:

Are you sure you are trying to capture output of a windows-app?

what's the name of your fullscreen app?

Share this post


Link to post
Share on other sites

Does the Printscreen key work ?

Share this post


Link to post
Share on other sites
19 hours ago, therks said:

Irfanview was actually my first stop when I couldn't get the AutoIt functions to work,

it also gives me a black image.

Well, there are more Screenshoters out there...


-HaJo

Share this post


Link to post
Share on other sites
8 hours ago, AutoBert said:

what's the name of your fullscreen app?

It's software from work that displays a feed from the security cameras around the site. I wanted to have images to add to my reports if need be but it's just a display. I asked the boss if I could write some software to take screencaps every couple minutes and he said that was fine as long as I showed him how it worked after. So far I haven't been able to show him anything though because I can't get any images to appear.

54 minutes ago, hajo4 said:

Well, there are more Screenshoters out there...

Ideally I wanted to do it all myself, to introduce less extraneous software, but for what it's worth I tried that too and still the same results.

I appreciate all the help guys but I'm thinking this is just beyond AutoIt's capability. It seems to be like a directx window (like most games) and I never had any luck getting screen caps from those either (short of using something like Fraps).

Share this post


Link to post
Share on other sites
30 minutes ago, therks said:

 I'm thinking this is just beyond AutoIt's capability.

It's relative. If the Printscreen key on your keyboard can't provide a screenshot then probably no software will work

Share this post


Link to post
Share on other sites
1 hour ago, therks said:

It's software from work that displays a feed from the security cameras around the site.

I wanted to have images to add to my reports if need be but it's just a display.

How about recording those video-streams directly ?

What would be the plan to show evidence in case of a break-in to police etc. ?

I would think that's a pretty basic requirement for security --> read manual, faq, ask manufacturer, etc.


-HaJo

Share this post


Link to post
Share on other sites
On 1.8.2016 at 9:06 AM, AutoBert said:

Are you sure you are trying to capture output of a windows-app?

You have meanwhile editet  the title, and i think meanwhile it will not be possible with AutoIt because the (none Windows-App) is bypassing windows at draw directly to the monitors. The developer of the solution surely will have tools (he want to sell) to capture screen.

Share this post


Link to post
Share on other sites

Have you tried the game bar?  Just one more great Win10 feature :)

http://www.howtogeek.com/219947/how-to-record-pc-gameplay-with-windows-10’s-game-dvr-and-game-bar/


,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites
15 minutes ago, hajo4 said:

How about recording those video-streams directly ?

What would be the plan to show evidence in case of a break-in to police etc. ?

I would think that's a pretty basic requirement for security --> read manual, faq, ask manufacturer, etc.

I think it is being recorded somewhere off site. Or maybe my boss just didn't know what he was talking about. ;) My idea was just to have local screen caps for ease of reference, I would actually be deleting them at the end of every shift if nothing pertinent happened.

1 minute ago, iamtheky said:

Have you tried the game bar?  Just one more great Win10 feature :)

http://www.howtogeek.com/219947/how-to-record-pc-gameplay-with-windows-10’s-game-dvr-and-game-bar/

No Windows 10 here. It's a few years old with Windows 7.

7 minutes ago, AutoBert said:

You have meanwhile editet  the title, and i think meanwhile it will not be possible with AutoIt because the (none Windows-App) is bypassing windows at draw directly to the monitors. The developer of the solution surely will have tools (he want to sell) to capture screen.

Yeah I edited the title when I realized it probably should be mentioned. I'm on the same thought as you, it probably can't be done with AutoIt and would need something more robust (or way beyond my abilities at least). I did some Googling and ended up here but it was all Greek to me.

It's no big deal, it was just a fun little thing to tinker with while I was at work.

Share this post


Link to post
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