Jump to content

Recommended Posts

Posted

Hi, I have a monitor running at 1920x1080 (1080p) and another running at 3840x2160 (4K). I'm having real trouble obtaining the screen sizes and placing a multiwindow GUI.

I've tried a number of scripts available in the forums, but they all are reporting the same results. Here's the script that I'm currently using which I've gotten from the Internet

;author: ahha
;filename: determine screen sizes v1b.au3

;http://msdn.microsoft.com/en-us/library/ms724385%28VS.85%29.aspx

$VirtX = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 78)    ;SM_CXVIRTUALSCREEN 78
;The width of the virtual screen, in pixels. The virtual screen is the bounding rectangle of all display monitors.
;The SM_XVIRTUALSCREEN metric is the coordinates for the left side of the virtual screen.

$VirtY = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 79)    ;SM_CYVIRTUALSCREEN 79
;The height of the virtual screen, in pixels. The virtual screen is the bounding rectangle of all display monitors.
;The SM_YVIRTUALSCREEN metric is the coordinates for the top of the virtual screen.

$Mons = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 80) ;SM_CMONITORS 80
;The number of display monitors on a desktop. For more information, see the Remarks section in this topic.

;Remarks
;System metrics can vary from display to display.
;GetSystemMetrics(SM_CMONITORS) counts only visible display monitors. This is different from EnumDisplayMonitors, which enumerates both visible display monitors and invisible pseudo-monitors that are associated with mirroring drivers. An invisible pseudo-monitor is associated with a pseudo-device used to mirror application drawing for remoting or other purposes.


$LSVS = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 76)     ;SM_XVIRTUALSCREEN 76
;The coordinates for the left side of the virtual screen. The virtual screen is the bounding rectangle of all display monitors.
;The SM_CXVIRTUALSCREEN metric is the width of the virtual screen.

$TSVS = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 77)     ;SM_YVIRTUALSCREEN77
;The coordinates for the top of the virtual screen. The virtual screen is the bounding rectangle of all display monitors.
;The SM_CYVIRTUALSCREEN metric is the height of the virtual screen.

$PriDispX = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 0)  ;SM_CXSCREEN 0
;The width of the screen of the primary display monitor, in pixels.
;This is the same value obtained by calling GetDeviceCaps as follows: GetDeviceCaps( hdcPrimaryMonitor, HORZRES).

$PriDispY = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 1)  ;SM_CYSCREEN 1
;The height of the screen of the primary display monitor, in pixels.
;This is the same value obtained by calling GetDeviceCaps as follows: GetDeviceCaps( hdcPrimaryMonitor, VERTRES).


$mz = "SM_CXSCREEN = "&$PriDispX[0] &"   SM_CYSCREEN = "&$PriDispY[0]
$m0 = "@DesktopWidth = "&@DesktopWidth &"   @DesktopHeight = "&@DesktopHeight
$m1 = "Number of visible screen monitors: " & $Mons[0]
$m2 = "Maximum size of 'virtual screen' : " & $VirtX[0] &"x"& $VirtY[0]
$m3 = "Full 'virtual screen' coordinates: " & $LSVS[0] &"," & $TSVS[0] &" to "& $VirtX[0] &","& $VirtY[0]
MsgBox(0+262144, "Status of determine screen sizes", $mz &@CRLF& $m0 &@CRLF& $m1 &@CRLF& $m2 &@CRLF& $m3)

 

This reports a virtual screen of 3456x1719 (what???). What does the virtual screen mean, and why isn't it a combination of both screen. Also it reports DesktopWidth as 1920 and DesktopHeight as 1080, i.e. the smaller of two displays. I'm trying to create two GUIs that is maximised on each screen, but these numbers are wrong. Please help. Thanks.

Posted (edited)

Check my recent post from last 7 days.

Or ask me in next 2 days

Edited by mLipok

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

Posted

first use _WinAPI_EnumDisplayMonitors() example from HelpFIle:
 

#include <Array.au3>
#include <WinAPIGdi.au3>

Local $aPos, $aData = _WinAPI_EnumDisplayMonitors()

If IsArray($aData) Then
    ReDim $aData[$aData[0][0] + 1][5]
    For $i = 1 To $aData[0][0]
        $aPos = _WinAPI_GetPosFromRect($aData[$i][1])
        For $j = 0 To 3
            $aData[$i][$j + 1] = $aPos[$j]
        Next
    Next
EndIf

_ArrayDisplay($aData, '_WinAPI_EnumDisplayMonitors')

You will be able to get information about desktop on both monitors .

Then try to use this example:

#include <WinAPIGdi.au3>

; To check how this work on "Dual Monitor" just move your mouse to second monitor and run this script again
_Example()

Func _Example()
    ; get mouse coordinates
    Local $tPos = _WinAPI_GetMousePos()
    ConsoleWrite('MouseX = ' & DllStructGetData($tPos, 1) & @CRLF)
    ConsoleWrite('MouseY = ' & DllStructGetData($tPos, 2) & @CRLF)

    ; get $hMonitor from previously defined Mouse coordinates
    Local $hMonitor = _WinAPI_MonitorFromPoint($tPos)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $hMonitor = ' & $hMonitor & @CRLF & '>Error code: ' & @error & '    Extended code: 0x' & Hex(@extended) & @CRLF) ;### Debug Console

    ; get monitor $aData appropriate for previously defined coordinates
    Local $aData = _WinAPI_GetMonitorInfo($hMonitor)
    If Not @error Then
        ConsoleWrite('Handle:      ' & $hMonitor & @CRLF)
        ConsoleWrite('Rectangle:   ' & DllStructGetData($aData[0], 1) & ', ' & DllStructGetData($aData[0], 2) & ', ' & DllStructGetData($aData[0], 3) & ', ' & DllStructGetData($aData[0], 4) & @CRLF)
        ConsoleWrite('Work area:   ' & DllStructGetData($aData[1], 1) & ', ' & DllStructGetData($aData[1], 2) & ', ' & DllStructGetData($aData[1], 3) & ', ' & DllStructGetData($aData[1], 4) & @CRLF)
        ConsoleWrite('Primary:     ' & $aData[2] & @CRLF)
        ConsoleWrite('Device name: ' & $aData[3] & @CRLF)
    EndIf
EndFunc   ;==>_Example

to get "Work area:" for  for each monitor.

 

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

Posted (edited)

Working example:

#include <GUIConstants.au3>
#include <WinAPIGdi.au3>

_Example()

Func _Example()
    ; taken from HelpFile Example for _WinAPI_EnumDisplayMonitors()
    Local $aMonitors_data = _WinAPI_EnumDisplayMonitors()
    If @error Then Return SetError(@error, @extended, 0)

    Local $hMonitor = $aMonitors_data[1][0] ; handle to first Monitor
    ConsoleWrite("! " & $hMonitor & @CRLF)

    Local Enum $MONITOR_X1 = 1, $MONITOR_Y1, $MONITOR_X2, $MONITOR_Y2

    Local $aMonitorInfo = _WinAPI_GetMonitorInfo($hMonitor)
    ConsoleWrite("! Primary=" & $aMonitorInfo[2] & '  MonitorName = ' & $aMonitorInfo[3] & @CRLF)
    ConsoleWrite("- X1 = " & DllStructGetData($aMonitorInfo[1], $MONITOR_X1) & @CRLF)
    ConsoleWrite("- Y1 = " & DllStructGetData($aMonitorInfo[1], $MONITOR_Y1) & @CRLF)
    ConsoleWrite("- X2 = " & DllStructGetData($aMonitorInfo[1], $MONITOR_X2) & @CRLF)
    ConsoleWrite("- Y2 = " & DllStructGetData($aMonitorInfo[1], $MONITOR_Y2) & @CRLF)

    ; Create a GUI_1 with various controls.
    Local $hGUI_1 = GUICreate("Example 1", _
            DllStructGetData($aMonitorInfo[1], $MONITOR_X2)-DllStructGetData($aMonitorInfo[1], $MONITOR_X1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_Y2)-DllStructGetData($aMonitorInfo[1], $MONITOR_Y1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_X1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_Y1) _
            )
    Local $idOK_1 = GUICtrlCreateButton("OK", 310, 370, 85, 25)
    ; Display the GUI_1
    GUISetState(@SW_SHOW, $hGUI_1)

    ; chceck if there was taken data for second monitor
    If UBound($aMonitors_data) = 3 Then
        $hMonitor = $aMonitors_data[2][0] ; handle to second Monitor
        ConsoleWrite("! " & $hMonitor & @CRLF)

        $aMonitorInfo = _WinAPI_GetMonitorInfo($hMonitor)
        ConsoleWrite("! Primary=" & $aMonitorInfo[2] & '  MonitorName = ' & $aMonitorInfo[3] & @CRLF)
        ConsoleWrite("- X1 = " & DllStructGetData($aMonitorInfo[1], $MONITOR_X1) & @CRLF)
        ConsoleWrite("- Y1 = " & DllStructGetData($aMonitorInfo[1], $MONITOR_Y1) & @CRLF)
        ConsoleWrite("- X2 = " & DllStructGetData($aMonitorInfo[1], $MONITOR_X2) & @CRLF)
        ConsoleWrite("- Y2 = " & DllStructGetData($aMonitorInfo[1], $MONITOR_Y2) & @CRLF)
    EndIf

    ; Create a GUI_2 with various controls.
    Local $hGUI_2 = GUICreate("Example 2", _
            DllStructGetData($aMonitorInfo[1], $MONITOR_X2)-DllStructGetData($aMonitorInfo[1], $MONITOR_X1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_Y2)-DllStructGetData($aMonitorInfo[1], $MONITOR_Y1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_X1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_Y1) _
            )
    Local $idOK_2 = GUICtrlCreateButton("OK", 310, 370, 85, 25)
    ; Display the GUI_2
    GUISetState(@SW_SHOW, $hGUI_2)

    ; Initialize a Local variable for GUIGetMsg($GUI_EVENT_ARRAY)
    Local $aMsg = 0

    ; Loop until the user Close both GUI_1 and GUI_2
    While IsHWnd($hGUI_1) Or IsHWnd($hGUI_2) ; check if any GUI exist
        ; Assign to $aMsg the advanced GUI messages.
        $aMsg = GUIGetMsg($GUI_EVENT_ARRAY)
        Switch $aMsg[1] ; Switch from GUIs
            Case $hGUI_1 ; The event comes from the GUI1
                Switch $aMsg[0] ; Switch from event ID
                    Case $GUI_EVENT_CLOSE
                        GUIDelete($hGUI_1)
                    Case $idOK_1
                        MsgBox($MB_SYSTEMMODAL, "", "Ok_1 clicked.")
                EndSwitch
            Case $hGUI_2  ; The event comes from the GUI2
                Switch $aMsg[0] ; Switch from event ID
                    Case $GUI_EVENT_CLOSE
                        GUIDelete($hGUI_2)
                    Case $idOK_2
                        MsgBox($MB_SYSTEMMODAL, "", "Ok_2 clicked.")
                EndSwitch
        EndSwitch
    WEnd

EndFunc   ;==>_Example

 

Edited by mLipok
fixed: first screen width and height

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

  • 3 weeks later...
Posted (edited)

Better example:

;~ https://www.autoitscript.com/forum/topic/196126-problem-detecting-screen-size/?tab=comments#comment-1406593

#include <GUIConstants.au3>
#include <WinAPIGdi.au3>

_Example()

Func _Example()
    Local $aMonitors_data = _WinAPI_EnumDisplayMonitors()
    If @error Then Return SetError(@error, @extended, 0)

    Local $hMonitor = $aMonitors_data[1][0] ; handle to first Monitor
    ConsoleWrite("! " & $hMonitor & @CRLF)

    Local Enum $MONITOR_X1 = 1, $MONITOR_Y1, $MONITOR_X2, $MONITOR_Y2

    Local $aMonitorInfo = _WinAPI_GetMonitorInfo($hMonitor)
    ConsoleWrite("! Primary=" & $aMonitorInfo[2] & '  MonitorName = ' & $aMonitorInfo[3] & @CRLF)
    ConsoleWrite("- X1 = " & DllStructGetData($aMonitorInfo[1], $MONITOR_X1) & @CRLF)
    ConsoleWrite("- Y1 = " & DllStructGetData($aMonitorInfo[1], $MONITOR_Y1) & @CRLF)
    ConsoleWrite("- X2 = " & DllStructGetData($aMonitorInfo[1], $MONITOR_X2) & @CRLF)
    ConsoleWrite("- Y2 = " & DllStructGetData($aMonitorInfo[1], $MONITOR_Y2) & @CRLF)

    ; Create a GUI_1 with ClientWidth and ClientHeight
    Local $hGUI_1 = GUICreate("Example 1", _
            DllStructGetData($aMonitorInfo[1], $MONITOR_X2) - DllStructGetData($aMonitorInfo[1], $MONITOR_X1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_Y2) - DllStructGetData($aMonitorInfo[1], $MONITOR_Y1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_X1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_Y1) _
            )

    ; change size of window using: WindowWidth and WindowHeight
    WinMove($hGUI_1, "", _
            DllStructGetData($aMonitorInfo[1], $MONITOR_X1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_Y1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_X2) - DllStructGetData($aMonitorInfo[1], $MONITOR_X1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_Y2) - DllStructGetData($aMonitorInfo[1], $MONITOR_Y1) _
            )
    Local $idOK_1 = GUICtrlCreateButton("OK", 310, 370, 85, 25)
    ; Display the GUI_1
    GUISetState(@SW_SHOW, $hGUI_1)

    ; chceck if there was taken data for second monitor
    If UBound($aMonitors_data) = 3 Then
        $hMonitor = $aMonitors_data[2][0] ; handle to second Monitor
        ConsoleWrite("! " & $hMonitor & @CRLF)

        $aMonitorInfo = _WinAPI_GetMonitorInfo($hMonitor)
        ConsoleWrite("! Primary=" & $aMonitorInfo[2] & '  MonitorName = ' & $aMonitorInfo[3] & @CRLF)
        ConsoleWrite("- X1 = " & DllStructGetData($aMonitorInfo[1], $MONITOR_X1) & @CRLF)
        ConsoleWrite("- Y1 = " & DllStructGetData($aMonitorInfo[1], $MONITOR_Y1) & @CRLF)
        ConsoleWrite("- X2 = " & DllStructGetData($aMonitorInfo[1], $MONITOR_X2) & @CRLF)
        ConsoleWrite("- Y2 = " & DllStructGetData($aMonitorInfo[1], $MONITOR_Y2) & @CRLF)
    EndIf

    ; Create a GUI_2 with ClientWidth and ClientHeight
    Local $hGUI_2 = GUICreate("Example 2", _
            DllStructGetData($aMonitorInfo[1], $MONITOR_X2) - DllStructGetData($aMonitorInfo[1], $MONITOR_X1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_Y2) - DllStructGetData($aMonitorInfo[1], $MONITOR_Y1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_X1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_Y1) _
            )

    ; change size of window using: WindowWidth and WindowHeight
    WinMove($hGUI_2, "", _
            DllStructGetData($aMonitorInfo[1], $MONITOR_X1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_Y1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_X2) - DllStructGetData($aMonitorInfo[1], $MONITOR_X1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_Y2) - DllStructGetData($aMonitorInfo[1], $MONITOR_Y1) _
            )
    Local $idOK_2 = GUICtrlCreateButton("OK", 310, 370, 85, 25)
    ; Display the GUI_2
    GUISetState(@SW_SHOW, $hGUI_2)

    ; Initialize a Local variable for GUIGetMsg($GUI_EVENT_ARRAY)
    Local $aMsg = 0

    ; Loop until the user Close both GUI_1 and GUI_2
    While IsHWnd($hGUI_1) Or IsHWnd($hGUI_2) ; check if any GUI exist
        ; Assign to $aMsg the advanced GUI messages.
        $aMsg = GUIGetMsg($GUI_EVENT_ARRAY)
        Switch $aMsg[1] ; Switch from GUIs
            Case $hGUI_1 ; The event comes from the GUI1
                Switch $aMsg[0] ; Switch from event ID
                    Case $GUI_EVENT_CLOSE
                        GUIDelete($hGUI_1)
                    Case $idOK_1
                        MsgBox($MB_SYSTEMMODAL, "", "Ok_1 clicked.")
                EndSwitch
            Case $hGUI_2  ; The event comes from the GUI2
                Switch $aMsg[0] ; Switch from event ID
                    Case $GUI_EVENT_CLOSE
                        GUIDelete($hGUI_2)
                    Case $idOK_2
                        MsgBox($MB_SYSTEMMODAL, "", "Ok_2 clicked.")
                EndSwitch
        EndSwitch
    WEnd

EndFunc   ;==>_Example

 

Remarks:

HelpFile for:

GUICreate

says:

  Quote

The size specified is the size of the client area of the window. The border and title bar will make the window slightly larger than specified. Using menu controls will also change the windows height.

Expand  

So it is enought to use:
 

; Create a GUI_1 with ClientWidth and ClientHeight
    Local $hGUI_1 = GUICreate("Example 1", _
            DllStructGetData($aMonitorInfo[1], $MONITOR_X2) - DllStructGetData($aMonitorInfo[1], $MONITOR_X1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_Y2) - DllStructGetData($aMonitorInfo[1], $MONITOR_Y1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_X1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_Y1) _
            )

    ; change size of window using: WindowWidth and WindowHeight
    WinMove($hGUI_1, "", _
            DllStructGetData($aMonitorInfo[1], $MONITOR_X1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_Y1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_X2) - DllStructGetData($aMonitorInfo[1], $MONITOR_X1), _
            DllStructGetData($aMonitorInfo[1], $MONITOR_Y2) - DllStructGetData($aMonitorInfo[1], $MONITOR_Y1) _
            )

 

and finally the each window is better fixed to WorkArea.

 

Edited by mLipok

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

  Reveal hidden contents

Signature last update: 2023-04-24

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...