SkinnyWhiteGuy Posted November 25, 2009 Posted November 25, 2009 I was in need of this the other day, and researched out how to detect all displays. This should work with any number of monitors, and only generate one picture with all displays in it. It should also try to avoid taking screen shots from virtual displays used by some remote tools. expandcollapse popup#NoTrayIcon #include <ScreenCapture.au3> Global $tag_DISPLAY_DEVICE = "dword cb;char DeviceName[32];char DeviceString[128];dword StateFlags;char DeviceID[128];char DeviceKey[128]" Global Const $DISPLAY_DEVICE_MIRRORING_DRIVER = 0x00000008 Global Const $DISPLAY_DEVICE_PRIMARY_DEVICE = 0x00000004 Global $tag_POINTL = "long x;long y" Global $tag_DEVMOD = "char dmDeviceName[32];ushort dmSpecVersion;ushort dmDriverVersion;short dmSize;" & _ "ushort dmDriverExtra;dword dmFields;" & $tag_POINTL & ";dword dmDisplayOrientation;dword dmDisplayFixedOutput;" & _ "short dmColor;short dmDuplex;short dmYResolution;short dmTTOption;short dmCollate;" & _ "byte dmFormName[32];ushort LogPixels;dword dmBitsPerPel;int dmPelsWidth;dword dmPelsHeight;" & _ "dword dmDisplayFlags;dword dmDisplayFrequency" Global Const $ENUM_CURRENT_SETTINGS = -1 Global $Left, $Top, $Right, $Bottom Global $i = 0 While 1 $struct = DllStructCreate($tag_DISPLAY_DEVICE) DllStructSetData($struct, "cb", DllStructGetSize($struct)) $aRetrun = DllCall("user32.dll", "int", "EnumDisplayDevices", "ptr", 0, "dword", $i, "ptr", DllStructGetPtr($struct), "dword", 0) If Not $aRetrun[0] Then ExitLoop If Not BitAND(DllStructGetData($struct, "StateFlags"), $DISPLAY_DEVICE_MIRRORING_DRIVER) Then ; Avoid Virtual Displays ;~ ConsoleWrite(DllStructGetData($struct, "DeviceName") & @TAB & "Primary: " & (BitAND(DllStructGetData($struct, "StateFlags"), $DISPLAY_DEVICE_PRIMARY_DEVICE) > 0) & @CRLF) $dev = DllStructCreate($tag_DEVMOD) DllStructSetData($dev, "dmSize", DllStructGetSize($dev)) $aRetrun = DllCall("user32.dll", "int", "EnumDisplaySettings", "str", DllStructGetData($struct, "DeviceName"), "dword", $ENUM_CURRENT_SETTINGS, "ptr", DllStructGetPtr($dev)) If Not IsNumber($Left) Or $Left > DllStructGetData($dev, "x") Then $Left = DllStructGetData($dev, "x") If Not IsNumber($Top) Or $Top > DllStructGetData($dev, "y") Then $Top = DllStructGetData($dev, "y") If Not IsNumber($Right) Or $Right < DllStructGetData($dev, "x") + DllStructGetData($dev, "dmPelsWidth") Then $Right = DllStructGetData($dev, "x") + DllStructGetData($dev, "dmPelsWidth") If Not IsNumber($Bottom) Or $Bottom < DllStructGetData($dev, "y") + DllStructGetData($dev, "dmPelsHeight") Then $Bottom = DllStructGetData($dev, "y") + DllStructGetData($dev, "dmPelsHeight") EndIf $i += 1 WEnd If $CmdLine[0] = 1 Then _ScreenCapture_Capture($CmdLine[1], $Left, $Top, $Right, $Bottom) Else _ScreenCapture_Capture(@ScriptDir & "\screenshot.jpg", $Left, $Top, $Right, $Bottom) EndIf Tested on Windows 7 (64-bit) & XP (32-bit). The commented line shows how to detect which of the displays is the Primary display.
water Posted November 25, 2009 Posted November 25, 2009 Great script! Tested on Windows XP SP 3 with 2 monitors. My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki
Alek Posted November 26, 2009 Posted November 26, 2009 wouldn't#NoTrayIcon #include <ScreenCapture.au3> $Pos = WinGetPos("Program Manager") If $CmdLine[0] = 1 Then _ScreenCapture_Capture($CmdLine[1], $Pos[0], $Pos[1], $Pos[0] + $Pos[2], $Pos[1] + $Pos[3]) Else _ScreenCapture_Capture(@ScriptDir & "\screenshot.jpg", $Pos[0], $Pos[1], $Pos[0] + $Pos[2], $Pos[1] + $Pos[3]) EndIfwork just as well? [font="Impact"]Never fear, I is here.[/font]
fp001 Posted December 11, 2009 Posted December 11, 2009 SkinnyWhiteGuy, thanks a lot for your code . It made creating the following UDF, which can be used to retrieve all current, non-virtual displays' positions, a doddle: expandcollapse popup#cs author: "SkinnyWhiteGuy" on http://www.autoitscript.com/forum/index.php?showtopic=105921 #ce #include-once ;out: [n][0:x 1:y 2:width 3:height 4:is primary] Func _displayGetPos() Local $returnArray[1][5] Local $tag_DISPLAY_DEVICE = "dword cb;char DeviceName[32];char DeviceString[128];dword StateFlags;char DeviceID[128];char DeviceKey[128]" Local $DISPLAY_DEVICE_MIRRORING_DRIVER = 0x00000008 Local $DISPLAY_DEVICE_PRIMARY_DEVICE = 0x00000004 Local $tag_POINTL = "long x;long y" Local $tag_DEVMOD = "char dmDeviceName[32];ushort dmSpecVersion;ushort dmDriverVersion;short dmSize;" & _ "ushort dmDriverExtra;dword dmFields;" & $tag_POINTL & ";dword dmDisplayOrientation;dword dmDisplayFixedOutput;" & _ "short dmColor;short dmDuplex;short dmYResolution;short dmTTOption;short dmCollate;" & _ "byte dmFormName[32];ushort LogPixels;dword dmBitsPerPel;int dmPelsWidth;dword dmPelsHeight;" & _ "dword dmDisplayFlags;dword dmDisplayFrequency" Local Const $ENUM_CURRENT_SETTINGS = -1 Local $i = 0 While 1 $struct = DllStructCreate($tag_DISPLAY_DEVICE) DllStructSetData($struct, "cb", DllStructGetSize($struct)) Local $aRetrun = DllCall("user32.dll", "int", "EnumDisplayDevices", "ptr", 0, "dword", $i, "ptr", DllStructGetPtr($struct), "dword", 0) If Not $aRetrun[0] Then ExitLoop If Not BitAND(DllStructGetData($struct, "StateFlags"), $DISPLAY_DEVICE_MIRRORING_DRIVER) Then ; Avoid Virtual Displays ConsoleWrite(DllStructGetData($struct, "DeviceName") & @TAB & "Primary: " & (BitAND(DllStructGetData($struct, "StateFlags"), $DISPLAY_DEVICE_PRIMARY_DEVICE) > 0) & @CRLF) $dev = DllStructCreate($tag_DEVMOD) DllStructSetData($dev, "dmSize", DllStructGetSize($dev)) $aRetrun = DllCall("user32.dll", "int", "EnumDisplaySettings", "str", DllStructGetData($struct, "DeviceName"), "dword", $ENUM_CURRENT_SETTINGS, "ptr", DllStructGetPtr($dev)) If IsNumber($returnArray[0][0]) Then ReDim $returnArray[UBound($returnArray)+1][5] ;if not first fill in, upsize $returnArray[UBound($returnArray)-1][0]=DllStructGetData($dev,"x") $returnArray[UBound($returnArray)-1][1]=DllStructGetData($dev,"y") $returnArray[UBound($returnArray)-1][2]=DllStructGetData($dev,"dmPelsWidth") $returnArray[UBound($returnArray)-1][3]=DllStructGetData($dev,"dmPelsHeight") $returnArray[UBound($returnArray)-1][4]=(BitAND(DllStructGetData($struct, "StateFlags"), $DISPLAY_DEVICE_PRIMARY_DEVICE) > 0) ;is primary? EndIf $i += 1 WEnd Return $returnArray EndFunc
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