Hi,
wenn unter Win 10 das Tool "Ausschneiden und Skizzieren" verwendet wird, wird der Bildschirminhalt eingefroren (auch wenn ein Video abgespielt wird).
Wie macht man das mit AutoIt?
Hi,
wenn unter Win 10 das Tool "Ausschneiden und Skizzieren" verwendet wird, wird der Bildschirminhalt eingefroren (auch wenn ein Video abgespielt wird).
Wie macht man das mit AutoIt?
Da gibt es sicher mehrere Möglichkeiten... z.B. die Taskleiste ausblenden und mit BlockInput bzw. BlockInputEx die Eingaben (Tastatur und/oder Maus) des Users blockieren. Dann kanst du eine Kopie des Desktops erstellen und diese dann anzeigen... sieht ja 100% echt aus... aber da tut sich dann absolut nichts, wenn du es nicht willst. Habe das vor ewigen Jahren mal mit einem Freund auf dem AMIGA gemacht... der wollte mich dafür killen.
Ne es soll nur das Bild eingeforen werden.
An eine Kopie des Desktops habe ich auch schon gedacht. Hoffe aber, dass es für das einfrieren einen eigenen Befehl gibt.
So was vielleicht?
#include <GUIConstantsEx.au3>
#include <ScreenCapture.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
; enum _PROCESS_DPI_AWARENESS -> https://msdn.microsoft.com/en-us/library/windows/desktop/dn280512(v=vs.85).aspx
Global Enum $DPI_AWARENESS_INVALID = -1, $PROCESS_DPI_UNAWARE = 0, $PROCESS_SYSTEM_DPI_AWARE, $PROCESS_PER_MONITOR_DPI_AWARE
Global Enum $Context_UnawareGdiScaled = -5, $Context_PerMonitorAwareV2, $Context_PerMonitorAware, $Context_SystemAware, $Context_Unaware
Global Const $WM_DPICHANGED = 0x02E0, $WM_GETDPISCALEDSIZE = 0x02E4
_WinAPI_SetDPIAwareness()
Local Const $hBitmap = _ScreenCapture_Capture("", 0, 0, @DesktopWidth - 1, @DesktopHeight - 1, False)
Local Const $hGUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOPMOST)
Local Const $iPic = GUICtrlCreatePic("", 0, 0, @DesktopWidth - 1, @DesktopHeight - 1)
_WinAPI_DeleteObject(GUICtrlSendMsg($iPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hBitmap))
GUISetState()
Do
If GUIGetMsg() = $GUI_EVENT_CLOSE Then
_WinAPI_DeleteObject($hBitmap)
GUIDelete($hGUI)
Exit
EndIf
Until False
Func _WinAPI_SetDPIAwareness($hGUI = 0)
Switch @OSBuild
Case 6000 To 9199
If Not DllCall("user32.dll", "bool", "SetProcessDPIAware") Then Return SetError(1, 0, 0) ;requires Vista+ / Server 2008+
Return 1
Case 9200 To 13999
_WinAPI_SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE) ;requires Win 8.1+ / Server 2012 R2+
If @error Then Return SetError(2, 0, 0)
Return 1
Case @OSBuild > 13999
#cs
Context_Unaware = ((DPI_AWARENESS_CONTEXT)(-1)),
Context_SystemAware = ((DPI_AWARENESS_CONTEXT)(-2)),
Context_PerMonitorAware = ((DPI_AWARENESS_CONTEXT)(-3)),
Context_PerMonitorAwareV2 = ((DPI_AWARENESS_CONTEXT)(-4)),
Context_UnawareGdiScaled = ((DPI_AWARENESS_CONTEXT)(-5))
#ce
_WinAPI_SetProcessDpiAwarenessContext($Context_PerMonitorAwareV2, $hGUI, 1)
If @error Then Return SetError(3, @error, 0)
Return 1
EndSwitch
Return -1
EndFunc ;==>_WinAPI_SetDPIAwareness
Func _WinAPI_SetProcessDpiAwareness($DPIAware) ;https://docs.microsoft.com/en-us/windows/desktop/api/shellscalingapi/nf-shellscalingapi-setprocessdpiawareness
Local $aResult = DllCall("Shcore.dll", "long", "SetProcessDpiAwareness", "int", $DPIAware) ;requires Win 8.1+ / Server 2012 R2+
If @error Then Return SetError(1, 0, 0)
Return 1
EndFunc ;==>_WinAPI_SetProcessDpiAwareness
Func _WinAPI_SetProcessDpiAwarenessContext($DPIAwareContext = $Context_PerMonitorAware, $hGUI = 0, $iMode = 1)
$DPIAwareContext = ($DPIAwareContext < -5) ? -5 : ($DPIAwareContext > -1) ? -1 : $DPIAwareContext
$iMode = ($iMode < 1) ? 1 : ($iMode > 3) ? 3 : $iMode
Switch $iMode
Case 1
Local $hDC = _WinAPI_GetDC($hGUI)
Local $aResult1 = DllCall("user32.dll", "int", "GetDpiFromDpiAwarenessContext", "ptr", $hDC) ;requires Win10 v1803+ / Server 2016+
If @error Or Not IsArray($aResult1) Then Return SetError(11, 0, 0)
_WinAPI_ReleaseDC(0, $hDC)
;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext
Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult1[0] + $DPIAwareContext) ;requires Win10 v1703+ / Server 2016+
If @error Or Not IsArray($aResult) Then Return SetError(12, 0, 0)
Case 2
;~ If Not $hGUI Then $hGUI = WinGetHandle(AutoItWinGetTitle())
Local $aResult2 = DllCall("user32.dll", "int", "GetWindowDpiAwarenessContext", "ptr", $hGUI) ;requires Win10 v1607+ / no server support
If @error Or Not IsArray($aResult2) Then Return SetError(21, 0, 0)
Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult2[0] + $DPIAwareContext) ;requires Win10 v1703+ / Server 2016+
If @error Or Not IsArray($aResult) Then Return SetError(22, 0, 0)
Case 3
Local $aResult31 = DllCall("user32.dll", "ptr", "GetThreadDpiAwarenessContext") ;requires Win10 v1607+ / no server support
If @error Or Not IsArray($aResult31) Then Return SetError(31, 0, 0)
Local $aResult32 = DllCall("user32.dll", "int", "GetAwarenessFromDpiAwarenessContext", "ptr", $aResult31[0]) ;requires Win10 v1607+ / no server support
If @error Or Not IsArray($aResult32) Then Return SetError(32, 0, 0)
Local $aResult = DllCall("user32.dll", "Bool", "SetThreadDpiAwarenessContext", "int", $aResult32[0] + $DPIAwareContext) ;requires Win10 v1607+ / no server support
If @error Or Not IsArray($aResult) Then Return SetError(33, 0, 0)
EndSwitch
Return 1
EndFunc ;==>_WinAPI_SetProcessDpiAwarenessContext
Alles anzeigen
Wow perfekt
Edit
Trotzdem habe ich noch eine Frage dazu.
Ich habe das ganze mal auf mehrere Monitore erweitert. Außerdem wird danach noch ein Screenshot als Datei abgelegt.
Wenn ich nun die DPI auf meinem 2. Bildschirm größer wie 100% einstellt, dann wird das eingefrorene Bild korrekt angezeigt.
Allerdings ist die abgelegte Datei nicht korrekt.
Weißt du warum sich dies unterschiedlich verhält?
Wenn ich die DPI des 1. Bildschirms ändere sieht beides gleich aus
#Region ;************ Includes ************
#Include <WinAPISysWin.au3>
#include <GUIConstantsEx.au3>
#include <ScreenCapture.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#EndRegion ;************ Includes ************
; enum _PROCESS_DPI_AWARENESS -> https://msdn.microsoft.com/en-us/library/windows/desktop/dn280512(v=vs.85).aspx
Global Enum $DPI_AWARENESS_INVALID = -1, $PROCESS_DPI_UNAWARE = 0, $PROCESS_SYSTEM_DPI_AWARE, $PROCESS_PER_MONITOR_DPI_AWARE
Global Enum $Context_UnawareGdiScaled = -5, $Context_PerMonitorAwareV2, $Context_PerMonitorAware, $Context_SystemAware, $Context_Unaware
Global Const $WM_DPICHANGED = 0x02E0, $WM_GETDPISCALEDSIZE = 0x02E4
$aAufloesung = _GetGlobalResolution()
_WinAPI_SetDPIAwareness()
Local Const $hBitmap = _ScreenCapture_Capture("", 0, 0, $aAufloesung[2] - 1, $aAufloesung[3] - 1, False)
Local Const $hGUI = GUICreate("", $aAufloesung[2], $aAufloesung[3], 0, 0, $WS_POPUP, $WS_EX_TOPMOST)
Local Const $iPic = GUICtrlCreatePic("", 0, 0, $aAufloesung[2] - 1, $aAufloesung[3] - 1)
_WinAPI_DeleteObject(GUICtrlSendMsg($iPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hBitmap))
GUISetState()
_ScreenCapture_Capture("D:\test.jpg", 0, 0, $aAufloesung[2] - 1, $aAufloesung[3] - 1, False) ;Bild wird erstellt
Do
If GUIGetMsg() = $GUI_EVENT_CLOSE Then
_WinAPI_DeleteObject($hBitmap)
GUIDelete($hGUI)
Exit
EndIf
Until False
Func _WinAPI_SetDPIAwareness($hGUI = 0)
Switch @OSBuild
Case 6000 To 9199
If Not DllCall("user32.dll", "bool", "SetProcessDPIAware") Then Return SetError(1, 0, 0) ;requires Vista+ / Server 2008+
Return 1
Case 9200 To 13999
_WinAPI_SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE) ;requires Win 8.1+ / Server 2012 R2+
If @error Then Return SetError(2, 0, 0)
Return 1
Case @OSBuild > 13999
#cs
Context_Unaware = ((DPI_AWARENESS_CONTEXT)(-1)),
Context_SystemAware = ((DPI_AWARENESS_CONTEXT)(-2)),
Context_PerMonitorAware = ((DPI_AWARENESS_CONTEXT)(-3)),
Context_PerMonitorAwareV2 = ((DPI_AWARENESS_CONTEXT)(-4)),
Context_UnawareGdiScaled = ((DPI_AWARENESS_CONTEXT)(-5))
#ce
_WinAPI_SetProcessDpiAwarenessContext($Context_PerMonitorAwareV2, $hGUI, 1)
If @error Then Return SetError(3, @error, 0)
Return 1
EndSwitch
Return -1
EndFunc ;==>_WinAPI_SetDPIAwareness
Func _WinAPI_SetProcessDpiAwareness($DPIAware) ;https://docs.microsoft.com/en-us/windows/desktop/api/shellscalingapi/nf-shellscalingapi-setprocessdpiawareness
Local $aResult = DllCall("Shcore.dll", "long", "SetProcessDpiAwareness", "int", $DPIAware) ;requires Win 8.1+ / Server 2012 R2+
If @error Then Return SetError(1, 0, 0)
Return 1
EndFunc ;==>_WinAPI_SetProcessDpiAwareness
Func _WinAPI_SetProcessDpiAwarenessContext($DPIAwareContext = $Context_PerMonitorAware, $hGUI = 0, $iMode = 1)
$DPIAwareContext = ($DPIAwareContext < -5) ? -5 : ($DPIAwareContext > -1) ? -1 : $DPIAwareContext
$iMode = ($iMode < 1) ? 1 : ($iMode > 3) ? 3 : $iMode
Switch $iMode
Case 1
Local $hDC = _WinAPI_GetDC($hGUI)
Local $aResult1 = DllCall("user32.dll", "int", "GetDpiFromDpiAwarenessContext", "ptr", $hDC) ;requires Win10 v1803+ / Server 2016+
If @error Or Not IsArray($aResult1) Then Return SetError(11, 0, 0)
_WinAPI_ReleaseDC(0, $hDC)
;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext
Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult1[0] + $DPIAwareContext) ;requires Win10 v1703+ / Server 2016+
If @error Or Not IsArray($aResult) Then Return SetError(12, 0, 0)
Case 2
;~ If Not $hGUI Then $hGUI = WinGetHandle(AutoItWinGetTitle())
Local $aResult2 = DllCall("user32.dll", "int", "GetWindowDpiAwarenessContext", "ptr", $hGUI) ;requires Win10 v1607+ / no server support
If @error Or Not IsArray($aResult2) Then Return SetError(21, 0, 0)
Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult2[0] + $DPIAwareContext) ;requires Win10 v1703+ / Server 2016+
If @error Or Not IsArray($aResult) Then Return SetError(22, 0, 0)
Case 3
Local $aResult31 = DllCall("user32.dll", "ptr", "GetThreadDpiAwarenessContext") ;requires Win10 v1607+ / no server support
If @error Or Not IsArray($aResult31) Then Return SetError(31, 0, 0)
Local $aResult32 = DllCall("user32.dll", "int", "GetAwarenessFromDpiAwarenessContext", "ptr", $aResult31[0]) ;requires Win10 v1607+ / no server support
If @error Or Not IsArray($aResult32) Then Return SetError(32, 0, 0)
Local $aResult = DllCall("user32.dll", "Bool", "SetThreadDpiAwarenessContext", "int", $aResult32[0] + $DPIAwareContext) ;requires Win10 v1607+ / no server support
If @error Or Not IsArray($aResult) Then Return SetError(33, 0, 0)
EndSwitch
Return 1
EndFunc ;==>_WinAPI_SetProcessDpiAwarenessContext
Func _GetGlobalResolution()
Local $aRes[4], $hWindow, $stRET
$hWindow = _WinAPI_GetDesktopWindow()
$stRET = _WinAPI_GetWindowPlacement($hWindow)
If Not @error Then
$aRes[0] = DllStructGetData($stRET, 'rcNormalPosition', 1) ; left
$aRes[1] = DllStructGetData($stRET, 'rcNormalPosition', 2) ; top
$aRes[2] = DllStructGetData($stRET, 'rcNormalPosition', 3) ; right
$aRes[3] = DllStructGetData($stRET, 'rcNormalPosition', 4) ; bottom
Return $aRes
Else
Return SetError(1, 0, 0)
EndIf
EndFunc ;==>_GetGlobalResolution
Alles anzeigen
Probiere es mal damit:
...
_WinAPI_SetDPIAwareness()
Local Const $hFullScreen = WinGetHandle("[TITLE:Program Manager;CLASS:Progman]")
Local Const $aFullScreen = WinGetPos($hFullScreen), $iPosMainScreen = Abs($aFullScreen[0])
Local Const $iW = $aFullScreen[2], $iH = $aFullScreen[3]
Local Const $hBitmap = _ScreenCapture_Capture("", $aFullScreen[0], $aFullScreen[1], $iW - 1, $iH - 1, False)
Local Const $hGUI = GUICreate("", $iW, $iH, $aFullScreen[0], $aFullScreen[1], $WS_POPUP, $WS_EX_TOPMOST)
Local Const $iPic = GUICtrlCreatePic("", 0, 0, $iW, $iH)
_WinAPI_DeleteObject(GUICtrlSendMsg($iPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hBitmap))
GUISetState()
...
Alles anzeigen
Danke UEZ, aber damit besteht das Problem auch
Und so:
;-- TIME_STAMP 2020-09-17 16:30:18 v 0.1
#Region ;************ Includes ************
#include <GUIConstantsEx.au3>
#include <ScreenCapture.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#Include <Array.au3>
#Include <WinAPISysWin.au3>
#include <WinAPIGdi.au3>
#include <WinAPIGdiDC.au3>
#EndRegion ;************ Includes ************
Opt('MustDeclareVars', 1)
;~ Global $sScreenCapture = "M:\DPIAwareness.jpg"
Global $sScreenCapture = "D:\DPIAwareness.jpg"
; enum _PROCESS_DPI_AWARENESS -> https://msdn.microsoft.com/en-us/library/windows/desktop/dn280512(v=vs.85).aspx
Global Enum $DPI_AWARENESS_INVALID = -1, $PROCESS_DPI_UNAWARE = 0, $PROCESS_SYSTEM_DPI_AWARE, $PROCESS_PER_MONITOR_DPI_AWARE
Global Enum $Context_UnawareGdiScaled = -5, $Context_PerMonitorAwareV2, $Context_PerMonitorAware, $Context_SystemAware, $Context_Unaware
Global Const $WM_DPICHANGED = 0x02E0, $WM_GETDPISCALEDSIZE = 0x02E4
Global $aAufloesung = _GetGlobalResolution()
If @error Then Exit @error
Global $aRec = $aAufloesung[0]
Global $aPos = $aAufloesung[1]
ConsoleWrite('@Desktop = ' & @DesktopWidth & ',' & @DesktopHeight & @CRLF)
ConsoleWrite('$aRec = ' & _ArrayToString($aRec, ', ') & @CRLF)
ConsoleWrite('$aPos = ' & _ArrayToString($aPos, ', ') & @CRLF)
_WinAPI_SetDPIAwareness()
Local Const $hBitmap = _ScreenCapture_Capture("", $aRec[0], $aRec[1], $aRec[2] -1, $aRec[3] -1, False)
Local Const $hGUI = GUICreate("", $aPos[2], $aPos[3], $aPos[0], $aPos[1], $WS_POPUP, $WS_EX_TOPMOST)
Local Const $iPic = GUICtrlCreatePic("", 0, 0, $aPos[2], $aPos[3])
_WinAPI_DeleteObject(GUICtrlSendMsg($iPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hBitmap))
GUISetState()
_ScreenCapture_Capture($sScreenCapture, $aRec[0], $aRec[1], $aRec[2] -1, $aRec[3] -1, False) ; Bild speichern
Do
If GUIGetMsg() = $GUI_EVENT_CLOSE Then
_WinAPI_DeleteObject($hBitmap)
GUIDelete($hGUI)
ShellExecute($sScreenCapture)
Exit
EndIf
Until False
Func _WinAPI_SetDPIAwareness($hGUI = 0)
Switch @OSBuild
Case 6000 To 9199
If Not DllCall("user32.dll", "bool", "SetProcessDPIAware") Then Return SetError(1, 0, 0) ;requires Vista+ / Server 2008+
Return 1
Case 9200 To 13999
_WinAPI_SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE) ;requires Win 8.1+ / Server 2012 R2+
If @error Then Return SetError(2, 0, 0)
Return 1
Case @OSBuild > 13999
#cs
Context_Unaware = ((DPI_AWARENESS_CONTEXT)(-1)),
Context_SystemAware = ((DPI_AWARENESS_CONTEXT)(-2)),
Context_PerMonitorAware = ((DPI_AWARENESS_CONTEXT)(-3)),
Context_PerMonitorAwareV2 = ((DPI_AWARENESS_CONTEXT)(-4)),
Context_UnawareGdiScaled = ((DPI_AWARENESS_CONTEXT)(-5))
#ce
_WinAPI_SetProcessDpiAwarenessContext($Context_PerMonitorAwareV2, $hGUI, 1)
If @error Then Return SetError(3, @error, 0)
Return 1
EndSwitch
Return -1
EndFunc ;==>_WinAPI_SetDPIAwareness
Func _WinAPI_SetProcessDpiAwareness($DPIAware) ;https://docs.microsoft.com/en-us/windows/desktop/api/shellscalingapi/nf-shellscalingapi-setprocessdpiawareness
Local $aResult = DllCall("Shcore.dll", "long", "SetProcessDpiAwareness", "int", $DPIAware) ;requires Win 8.1+ / Server 2012 R2+
If @error Then Return SetError(1, 0, 0)
Return 1
EndFunc ;==>_WinAPI_SetProcessDpiAwareness
Func _WinAPI_SetProcessDpiAwarenessContext($DPIAwareContext = $Context_PerMonitorAware, $hGUI = 0, $iMode = 1)
$DPIAwareContext = ($DPIAwareContext < -5) ? -5 : ($DPIAwareContext > -1) ? -1 : $DPIAwareContext
$iMode = ($iMode < 1) ? 1 : ($iMode > 3) ? 3 : $iMode
Switch $iMode
Case 1
Local $hDC = _WinAPI_GetDC($hGUI)
Local $aResult1 = DllCall("user32.dll", "int", "GetDpiFromDpiAwarenessContext", "ptr", $hDC) ;requires Win10 v1803+ / Server 2016+
If @error Or Not IsArray($aResult1) Then Return SetError(11, 0, 0)
_WinAPI_ReleaseDC(0, $hDC)
;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext
Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult1[0] + $DPIAwareContext) ;requires Win10 v1703+ / Server 2016+
If @error Or Not IsArray($aResult) Then Return SetError(12, 0, 0)
Case 2
;~ If Not $hGUI Then $hGUI = WinGetHandle(AutoItWinGetTitle())
Local $aResult2 = DllCall("user32.dll", "int", "GetWindowDpiAwarenessContext", "ptr", $hGUI) ;requires Win10 v1607+ / no server support
If @error Or Not IsArray($aResult2) Then Return SetError(21, 0, 0)
Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult2[0] + $DPIAwareContext) ;requires Win10 v1703+ / Server 2016+
If @error Or Not IsArray($aResult) Then Return SetError(22, 0, 0)
Case 3
Local $aResult31 = DllCall("user32.dll", "ptr", "GetThreadDpiAwarenessContext") ;requires Win10 v1607+ / no server support
If @error Or Not IsArray($aResult31) Then Return SetError(31, 0, 0)
Local $aResult32 = DllCall("user32.dll", "int", "GetAwarenessFromDpiAwarenessContext", "ptr", $aResult31[0]) ;requires Win10 v1607+ / no server support
If @error Or Not IsArray($aResult32) Then Return SetError(32, 0, 0)
Local $aResult = DllCall("user32.dll", "Bool", "SetThreadDpiAwarenessContext", "int", $aResult32[0] + $DPIAwareContext) ;requires Win10 v1607+ / no server support
If @error Or Not IsArray($aResult) Then Return SetError(33, 0, 0)
EndSwitch
Return 1
EndFunc ;==>_WinAPI_SetProcessDpiAwarenessContext
Func _GetGlobalResolution()
Local $aRect[4], $aRes[2], $hWindow, $tWINDOWPLACEMENT, $tRECT
$hWindow = _WinAPI_GetDesktopWindow()
$tWINDOWPLACEMENT = _WinAPI_GetWindowPlacement($hWindow)
If Not @error Then
$tRECT = DllStructCreate($tagRECT, DllStructGetPtr($tWINDOWPLACEMENT, 'rcNormalPosition'))
$aRect[0] = DllStructGetData($tRECT, 'left')
$aRect[1] = DllStructGetData($tRECT, 'top')
$aRect[2] = DllStructGetData($tRECT, 'right')
$aRect[3] = DllStructGetData($tRECT, 'bottom')
$aRes[0] = $aRect
$aRes[1] = _WinAPI_GetPosFromRect($tRECT)
Return $aRes
Else
Return SetError(1, 0, 0)
EndIf
EndFunc ;==>_GetGlobalResolution
Alles anzeigen
Danke Bitnugger, aber damit besteht das Problem auch