Jump to content

ScreenCapture automatization function (Need HELP)


Errious
 Share

Recommended Posts

Hello,

i am searching for a function that allows me some very specific functions for Screen Captures.

 

  • First should be the possibillity to create a Screenshot from a specific window and this is possibly under another window but has to stay there and not getting forced to be in the first - layer position if this is clear enough :-)
  • The other thing should be the ability to create a Screen Capture every couple minutes or a specific period.

 

I tried a lot of Screen Capture tools but neither can do both together.

Also my try to create my own script with AutoIT failed, because of missing knoweledge about how to use it for this specific reasons, would be very kind if someone can tell me in the first place if this is possible at all and maybe someone has allready an idea about how to realize it?

 

best regards

 

 

 

 

Edited by Errious
Link to comment
Share on other sites

After reading and looking around to find something that works for me i found this:

Spoiler
#include <GDIPlus.au3>

_GDIPlus_Startup()
Global $handle = WinGetHandle("[HANDLE:0x0000000000061034]") ; This is the Handle from the window to capture found manual under WindowInfo! ;
Global $hBitmap = Capture_Window($handle, _WinAPI_GetWindowWidth($handle), _WinAPI_GetWindowHeight($handle)) ; This function is creating a picture from the window with the given HANDLE. ;
_GDIPlus_ImageSaveToFile($hBitmap, @ScriptDir & "\test.jpg") ; This is to give it a name and save the picture. ;
_GDIPlus_Shutdown() ; Shuts down the process. ;

ShellExecute(@ScriptDir & "\test.jpg") ; Is opening the picture with the given name.;

Func Capture_Window($hWnd, $w, $h)
    If Not IsHWnd($hWnd) Then Return SetError(1, 0, 0)
    If Int($w) < 1 Then Return SetError(2, 0, 0)
    If Int($h) < 1 Then Return SetError(3, 0, 0)
    Local Const $hDC_Capture = _WinAPI_GetDC(HWnd($hWnd))
    Local Const $hMemDC = _WinAPI_CreateCompatibleDC($hDC_Capture)
    Local Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC_Capture, $w, $h)
    Local Const $hObjectOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    DllCall("gdi32.dll", "int", "SetStretchBltMode", "hwnd", $hDC_Capture, "uint", 4)
    DllCall("user32.dll", "int", "PrintWindow", "hwnd", $hWnd, "handle", $hMemDC, "int", 0)

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

    Local Const $hFullScreen = WinGetHandle("[TITLE:Program Manager;CLASS:Progman]")
    Local Const $aFullScreen = WinGetPos($hFullScreen)
    Local Const $c1 = $aFullScreen[2] - @DesktopWidth, $c2 = $aFullScreen[3] - @DesktopHeight
    Local Const $wc1 = $w - $c1, $hc2 = $h - $c2

    If (($wc1 > 1 And $wc1 < $w) Or ($w - @DesktopWidth > 1) Or ($hc2 > 7 And $hc2 < $h) Or ($h - @DesktopHeight > 1)) And (BitAND(WinGetState(HWnd($hWnd)), 32) = 32) Then
        Local $hBmp_t = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
        $hBmp = _GDIPlus_BitmapCloneArea($hBmp_t, 8, 8, $w - 16, $h - 16)
        _GDIPlus_BitmapDispose($hBmp_t)
    Else
        $hBmp = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
    EndIf
    _WinAPI_DeleteObject($hHBitmap)
    Return $hBmp
EndFunc   ;==>Capture_Window

 

This was working till i updated to the newest version from autoIT and now i get Errors :mad::

  • Global $hBitmap = Capture_Window($handle, _WinAPI_GetWindowWidth($handle)
  • Global $hBitmap = Capture_Window($handle, _WinAPI_GetWindowWidth($handle), _WinAPI_GetWindowHeight($handle)

This script was doing what i need for what i want in the first place, it creates a screen shot from a specific window even behind another window.

Maybe someone can tell me what is wrong now, when it worked fine before?

 

 

Edited by Errious
Link to comment
Share on other sites

Did you mean this:

Quote

This was working till i updated to the newest version from autoIT and now i get Errors :mad::

  • Global $hBitmap = Capture_Window($handle, _WinAPI_GetWindowWidth($handle)
  • Global $hBitmap = Capture_Window($handle, _WinAPI_GetWindowWidth($handle), _WinAPI_GetWindowHeight($handle)

This script was doing what i need for what i want in the first place, it creates a screen shot from a specific window even behind another window.

Maybe someone can tell me what is wrong now, when it worked fine before?

To be in the hidden part of your post?

I'll assume not... you can post your code nicely and visibly using the <> code tags.

If this has just broken in the latest version, you should check these fixes and let Melba know if you have found another problem.

 

 

Problem solving step 1: Write a simple, self-contained, running, replicator of your problem.

Link to comment
Share on other sites

Thank you SlackerAI for your post.

 

Because i have no clue where i find fixes i can tell after uninstalling 3.3.14.3 and install 3.3.14.0 that script works again.

 

At least i can now try to put something together that works i hope, im still searching for some help on my project.

Still missing is the part to realize the automatic capture every 60s or so.

Also i came up with the idea to create some kind of GUI but have some problems i need to solve before.

For example, when using HANDLE process for the window it gets a new ID when launching again, so i can not stay with the one i can manual identify, any way to have some kind of lookup function to identify the window i want to capture autamicly?

Also i need to change the format from Jpg to Png because of non compressed files.

Link to comment
Share on other sites

Made some changes today and this is what i came up with:

 

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

_GDIPlus_Startup()
Global $handle = WinGetHandle("[HANDLE:Notepad]") ; This is the Handle from the window to capture found manual under WindowInfo! ;
_GDIPlus_Shutdown() ; Shuts down the process. ;

_ScreenCapture_SetJPGQuality(100);max image quality
$scrFile = @ScriptDir & "\screenshot - " & @MDAY & @MON & @YEAR & '-' & @HOUR &@MIN& @SEC & ".png"
_ScreenCapture_CaptureWnd($scrFile, "[ACTIVE]", -1, -1, -1, -1, 0)

Func Capture_Window($hWnd, $w, $h)
    If Not IsHWnd($hWnd) Then Return SetError(1, 0, 0)
    If Int($w) < 1 Then Return SetError(2, 0, 0)
    If Int($h) < 1 Then Return SetError(3, 0, 0)
    Local Const $hDC_Capture = _WinAPI_GetDC(HWnd($hWnd))
    Local Const $hMemDC = _WinAPI_CreateCompatibleDC($hDC_Capture)
    Local Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC_Capture, $w, $h)
    Local Const $hObjectOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    DllCall("gdi32.dll", "int", "SetStretchBltMode", "hwnd", $hDC_Capture, "uint", 4)
    DllCall("user32.dll", "int", "PrintWindow", "hwnd", $hWnd, "handle", $hMemDC, "int", 0)

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

    Local Const $hFullScreen = WinGetHandle("[TITLE:Program Manager;CLASS:Progman]")
    Local Const $aFullScreen = WinGetPos($hFullScreen)
    Local Const $c1 = $aFullScreen[2] - @DesktopWidth, $c2 = $aFullScreen[3] - @DesktopHeight
    Local Const $wc1 = $w - $c1, $hc2 = $h - $c2
 EndFunc   ;==>Capture_Window

Short right :) Does what it should do, create screenshot from specific HANDLE even behind a window and save file with different times as name.

One thing i need still help on is the automatic function to run the script every 60s for example.

Was trying to use loop and while but no progress forward so far, maybe someone can help me with knowledge, would be kind :)

Best Regards

Edited by Errious
Link to comment
Share on other sites

#include <GDIPlus.au3>
#include <WindowsConstants.au3>
#include <ScreenCapture.au3>
#include <MsgBoxConstants.au3>
#include <AutoItConstants.au3>

; Press ESC to exit script
HotKeySet("{ESC}", "On_Exit")

Global $Paused, $Runner
Global $fNot_1_Vis = True, $iBegin = 0
Global $sAutoIt_Path = StringRegExpReplace(@AutoItExe, "(^.*\\)(.*)", "\1")
_GDIPlus_Startup()
Global $handle = WinGetHandle("[HANDLE:NOTEPAD]") ; This is the Handle from the window to capture found manual under WindowInfo! ;
_GDIPlus_Shutdown() ; Shuts down the process. ;
_ScreenCapture_SetJPGQuality(100);max image quality
$scrFile = @ScriptDir & "\screenshot - " & @MDAY & @MON & @YEAR & '-' & @HOUR &@MIN& @SEC & ".png" ;save file with name format;
_ScreenCapture_CaptureWnd($scrFile, "[ACTIVE]", -1, -1, -1, -1, 0)

Opt("TrayAutoPause", 0)

HotKeySet("{PAUSE}", "TogglePause")
HotKeySet("{ESC}", "Terminate")
HotKeySet("{F9}", "Capture_Window")

Func On_Exit()
    Exit
EndFunc

While 1
    Sleep(100)
WEnd
;;;;;;;;

Func TogglePause()
    $Paused = Not $Paused
    While $Paused
        Sleep(100)
        ToolTip('Script is "Paused"', 0, 0)
    WEnd
    ToolTip("")
EndFunc   ;==>TogglePause

Func Terminate()
    Exit 0
EndFunc   ;==>Terminate


Func Capture_Window($hWnd, $w, $h)
    $Runner = Not $Runner
    While $Runner
 Sleep(3000)
    If Int($w) < 1 Then Return SetError(2, 0, 0)
    If Int($h) < 1 Then Return SetError(3, 0, 0)
    Local Const $hDC_Capture = _WinAPI_GetDC(HWnd($hWnd))
    Local Const $hMemDC = _WinAPI_CreateCompatibleDC($hDC_Capture)
    Local Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC_Capture, $w, $h)
    Local Const $hObjectOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    DllCall("gdi32.dll", "int", "SetStretchBltMode", "hwnd", $hDC_Capture, "uint", 4)
    DllCall("user32.dll", "int", "PrintWindow", "hwnd", $hWnd, "handle", $hMemDC, "int", 0)
    _WinAPI_DeleteDC($hMemDC)
    _WinAPI_SelectObject($hMemDC, $hObjectOld)
    _WinAPI_ReleaseDC($hWnd, $hDC_Capture)
    Local Const $hFullScreen = WinGetHandle("[TITLE:Program Manager;CLASS:Progman]")
    Local Const $aFullScreen = WinGetPos($hFullScreen)
    Local Const $c1 = $aFullScreen[2] - @DesktopWidth, $c2 = $aFullScreen[3] - @DesktopHeight
    Local Const $wc1 = $w - $c1, $hc2 = $h - $c2
    WEnd
 EndFunc

In this code i impemented some hotkey functions to create pause and terminate but problem is if i define f9 for Capture_Window() i allways get an Error, im sure its just a logic problem cause i miss to whrite it in the correct way?

Edited by Errious
Link to comment
Share on other sites

To add a little... you are calling the function Capture_Window with the HotKeySet command, if you check that command in the help you will see it says "The called function can not be given parameters. They will be ignored." But you have coded your function to expect 3 parameters, you need to re-write your function so it is not expecting to receive $w, $h and $hWnd as parameters.

Problem solving step 1: Write a simple, self-contained, running, replicator of your problem.

Link to comment
Share on other sites

Thank you, my mistake, magically some parts of the script were lost during my work with it.
This is the Script with the Function to create a screenshot itself.

#include <std\GDIPlus.au3>
#include <std\ScreenCapture.au3>
#include <std\WindowsConstants.au3>

_GDIPlus_Startup()
Global $handle = WinGetHandle("[HANDLE:NOTEPAD]")
Global $hBitmap = Capture_Window($handle, _WinAPI_GetWindowWidth($handle), _WinAPI_GetWindowHeight($handle))
_GDIPlus_ImageSaveToFile($hBitmap, "C:\Users\Eric\Desktop\Picrunner\screenshot\" & "screenshot - " & @MDAY & @MON & @YEAR & '-' & @HOUR &@MIN& @SEC & ".png")
_GDIPlus_Shutdown()

Func Capture_Window($hWnd, $w, $h)
    If Not IsHWnd($hWnd) Then Return SetError(1, 0, 0)
    If Int($w) < 1 Then Return SetError(2, 0, 0)
    If Int($h) < 1 Then Return SetError(3, 0, 0)
    Local Const $hDC_Capture = _WinAPI_GetDC(HWnd($hWnd))
    Local Const $hMemDC = _WinAPI_CreateCompatibleDC($hDC_Capture)
    Local Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC_Capture, $w, $h)
    Local Const $hObjectOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    DllCall("gdi32.dll", "int", "SetStretchBltMode", "hwnd", $hDC_Capture, "uint", 4)
    DllCall("user32.dll", "int", "PrintWindow", "hwnd", $hWnd, "handle", $hMemDC, "int", 0)

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

    Local Const $hFullScreen = WinGetHandle("[TITLE:Program Manager;CLASS:Progman]")
    Local Const $aFullScreen = WinGetPos($hFullScreen)
    Local Const $c1 = $aFullScreen[2] - @DesktopWidth, $c2 = $aFullScreen[3] - @DesktopHeight
    Local Const $wc1 = $w - $c1, $hc2 = $h - $c2

    If (($wc1 > 1 And $wc1 < $w) Or ($w - @DesktopWidth > 1) Or ($hc2 > 7 And $hc2 < $h) Or ($h - @DesktopHeight > 1)) And (BitAND(WinGetState(HWnd($hWnd)), 32) = 32) Then
        Local $hBmp_t = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
        $hBmp = _GDIPlus_BitmapCloneArea($hBmp_t, 8, 8, $w - 16, $h - 16)
        _GDIPlus_BitmapDispose($hBmp_t)
    Else
        $hBmp = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
     EndIf

    _WinAPI_DeleteObject($hHBitmap)
    Return $hBmp

 EndFunc

My problem is still to have a loop running, i tried different attempts to solve this but unfortunately i can not bring it to run,

HotKeySet("{ESC}", "_Exit")

Func Capture_Window($hWnd, $w, $h)
 While
      Sleep(3000)
  WEnd

when trying this for example, the script returns error, i have read a lot but can not find a solution how i have to do this, even the helpfile is leading me to not working results, any help would be much appreciated.

At least i try but my head hurts...

Link to comment
Share on other sites

And they say I'm just a grumpy old man.....

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

_GDIPlus_Startup()

HotKeySet("{ESC}", "_Exit")

While 1
  Capture_Window()
  Sleep(5000)
WEnd

Func _Exit()
  _GDIPlus_Shutdown()
  Exit
EndFunc


Func Capture_Window()

    Local $hWnd = WinGetHandle("[CLASS:Notepad]")
    Local $w =  _WinAPI_GetWindowWidth($hWnd)
    Local $h = _WinAPI_GetWindowHeight($hWnd)
    Local Const $hDC_Capture = _WinAPI_GetDC(HWnd($hWnd))
    Local Const $hMemDC = _WinAPI_CreateCompatibleDC($hDC_Capture)
    Local Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC_Capture, $w, $h)
    Local Const $hObjectOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    DllCall("gdi32.dll", "int", "SetStretchBltMode", "hwnd", $hDC_Capture, "uint", 4)
    DllCall("user32.dll", "int", "PrintWindow", "hwnd", $hWnd, "handle", $hMemDC, "int", 0)

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

    Local Const $hFullScreen = WinGetHandle("[TITLE:Program Manager;CLASS:Progman]")
    Local Const $aFullScreen = WinGetPos($hFullScreen)
    Local Const $c1 = $aFullScreen[2] - @DesktopWidth, $c2 = $aFullScreen[3] - @DesktopHeight
    Local Const $wc1 = $w - $c1, $hc2 = $h - $c2

    If (($wc1 > 1 And $wc1 < $w) Or ($w - @DesktopWidth > 1) Or ($hc2 > 7 And $hc2 < $h) Or ($h - @DesktopHeight > 1)) And (BitAND(WinGetState(HWnd($hWnd)), 32) = 32) Then
        Local $hBmp_t = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
        $hBmp = _GDIPlus_BitmapCloneArea($hBmp_t, 8, 8, $w - 16, $h - 16)
        _GDIPlus_BitmapDispose($hBmp_t)
    Else
        $hBmp = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
     EndIf

    _WinAPI_DeleteObject($hHBitmap)
    
    Local $sSaveFileName = @ScriptDir & "\screenshot - " & @MDAY & @MON & @YEAR & '-' & @HOUR &@MIN& @SEC & ".png"
    _GDIPlus_ImageSaveToFile($hBmp, $sSaveFileName)
    
 EndFunc

I've made some essential changes and some just to make it more portable for me... I'm sure you'll figure out what is what (note the save path change).

Edited by SlackerAl

Problem solving step 1: Write a simple, self-contained, running, replicator of your problem.

Link to comment
Share on other sites

"And they say I'm just a grumpy old man..... "

If so then you are a very kind old man :)
Thank you for this, it makes so much more sense now if i read the construct of the code ;)

TBH i understand this forum has his own rules, because many guys ask questions like i did and also many guys ask questions before reading the forum rules and get punished more or less for this.

I tried to learn about AutoIT but for someone who is not familiar with programming it is hard.

With your help and look into your changes it was like turning a litght on :)

Many thanks for this!

 

 

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

×
×
  • Create New...