Errious Posted February 14, 2018 Posted February 14, 2018 (edited) 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 February 17, 2018 by Errious
Errious Posted February 15, 2018 Author Posted February 15, 2018 (edited) After reading and looking around to find something that works for me i found this: Spoiler expandcollapse popup#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 : 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 February 15, 2018 by Errious
SlackerAl Posted February 16, 2018 Posted February 16, 2018 Did you mean this: Quote This was working till i updated to the newest version from autoIT and now i get Errors : 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.
Errious Posted February 16, 2018 Author Posted February 16, 2018 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.
Errious Posted February 16, 2018 Author Posted February 16, 2018 (edited) 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 February 16, 2018 by Errious
Errious Posted February 17, 2018 Author Posted February 17, 2018 (edited) expandcollapse popup#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 February 17, 2018 by Errious
SlackerAl Posted February 20, 2018 Posted February 20, 2018 (edited) You never define $w, $h or $hWnd. It does actually say this as the error message too... Edited February 20, 2018 by SlackerAl Problem solving step 1: Write a simple, self-contained, running, replicator of your problem.
SlackerAl Posted February 20, 2018 Posted February 20, 2018 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.
Errious Posted February 20, 2018 Author Posted February 20, 2018 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. expandcollapse popup#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...
SlackerAl Posted February 20, 2018 Posted February 20, 2018 (edited) And they say I'm just a grumpy old man..... expandcollapse popup#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 February 20, 2018 by SlackerAl Errious 1 Problem solving step 1: Write a simple, self-contained, running, replicator of your problem.
Errious Posted February 20, 2018 Author Posted February 20, 2018 "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!
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now