Jump to content

Recommended Posts

Posted

I had a quick search in the forums and checked out the Windows Management section of the Help file but I haven't found anything that will allow me to force a GUI to open on the Primary (or Secondary) monitor for those systems that run two or more monitors. Can anyone point me in the right direction or isn't AutoIt able to do this (yet)?

Posted

From the lack of responses, I'll assume AutoIt can't do it yet. Can any Devs give me an indication as to whether or not something like this will be included in a future release?

Posted (edited)

PartyPooper,

I'm not quite sure what you're looking for in the way of AutoIt support. There are WMI scripts on the forum that enable you to get the coordinates of all the monitors on your system. Your application could then open any of it's windows on any of the monitors simply by using the correct coordinates. I run multiple monitors and I have Windows set to extend the desktop to the second monitor. The first monitor's x position is 0, the second monitor's x position is 1281 (the first monitor's resolutin is 720 by 1280) and the second monitor is position to the left of the first (you tell Windows). It's been a while since I've looked at this to recall what the configuration looks like if the desktop is not extended. Of course, a simplistic way around it is to simply use the Nvidia graphics driver which allows you to define profiles for application, including what monitor an application's windows should open on (everyone one uses Nvidia, right?) or a package like UltraMon.

If I create a window using GUICREATE (400, 400, 1281, 0) it opens in the upper-left corner of the second monitor.

Do these comments help at all?

Sincerely,

Paul

Edited by pdaughe
Posted

2 monitors connected to the same machine? I think all you have to do is put it further on the x or y axis, depending on how the monitors are placed.

for example:

GUICreate(@desktopwidth + 50, 50, 500, 500)

would make it appear on the second monitor if the 2 monitors were placed next to each other.

P.S. that would only work if @desktopwidth returns the width of one of the monitors, and not both (im not sure), so you could use @desktopwidth/2 if it returns the width of both.

What goes around comes around... Payback's a bitch.

Posted

I run multiple (two) desktops with desktop spanning turned off (using the nVidia software). I tried the profiles and they work for AutoIt written apps, but not all apps, so I wanted to write an AutoIt one to force those apps that didn't work to open on a particular monitor. I might try desktop spanning to see if I get better results, In any case, you've given me an idea and a start - thanks.

Posted

2 monitors connected to the same machine? I think all you have to do is put it further on the x or y axis, depending on how the monitors are placed.

for example:

GUICreate(@desktopwidth + 50, 50, 500, 500)

would make it appear on the second monitor if the 2 monitors were placed next to each other.

P.S. that would only work if @desktopwidth returns the width of one of the monitors, and not both (im not sure), so you could use @desktopwidth/2 if it returns the width of both.

Yeah, how to use the @Desktop... macros is what is confusing me. Because I run different resolutions on both monitors, I'm not sure how to get the variables using @Desktop... I guess I may be able to use WMI, however, I was hoping that they (the Devs) would include addition functionality to these macros to make my life easier :)

Posted

Because I run different resolutions on both monitors

Where does that get you? I don't have more than one monitor, so I have no idea what that would do for you.

You could use WinSetPos() to put a GUI window on a different monitor... I wouldn't know how to go about making it open on that monitor though...

What goes around comes around... Payback's a bitch.

Posted

I have monitor 1 set up for 1280 x 1024 and monitor 2 set up for 1024 x 768. It's weird but the AU3Info tool reports:

Overall Size

x: -1280

y: 0

w: 2304

h: 768

With each monitor coordinates as follows:

Monitor 1

Upper Left: x: -1280 y: 0

Lower Right: x: -1 y: 1023

Monitor 2

Upper Left: x: 0 y: 0

Lower Right: x: 1023 y: 767

From this it isn't too hard to place items but if I was to change resolutions, I run into the problem of not being able to automatically detect the new resolutions on both monitors from within a program (I would have to manually put them in as variables).

Posted (edited)

Yeah, that one.

It's been so long since I have used window functions, sorry.

EDIT: just read your 2nd to last post...

WinMove($title, $text, $x / $CurrentxResolution * $NewxResolution, $y / $CurrentyResolution * $NewyResolution)?

Edited by Kickassjoe

What goes around comes around... Payback's a bitch.

  • 18 years later...
Posted (edited)

I know it's an ancient topic, but with many people working with multiple monitors a full answer was still sorely missing - every single answer here was manual.
Here's my fully automated UDF I came up with, which allows simply giving a monitor number and utilizing it via Windows API.
You can also use it for your default monitor but with a quick way to maximize or center it.

GUICreateMonitor.au3

#include-once
#include <GUIConstantsEx.au3> ; for $GUI_EVENT_CLOSE
#include <WinAPIGdi.au3>

; #FUNCTION# ====================================================================================================================
; Description ...: Create a GUI on a specific monitor
; Parameters ....: $iMonitorNumber     - Monitor number (1-based index) or 0 for Primary or empty for Windows to decide
;                  $iCreate            - Actually create the GUI, otherwise just return an array of its potential values
;                  $sTitle             - Title to use for GUI
;                  $iWidth             - Width to use for GUI - can be number or "max"
;                  $iHeight            - Height to use for GUI - can be number or "max"
;                  $oLeft              - Left side to use for GUI - can be number or "center" or "max"
;                  $oTop               - Top side to use for GUI - can be number or "center" or "max"
;                  $iStyle             - Style to use for GUI
;                  $iExStyle           - Extended style to use for GUI
;                  $iParent            - Parent to use for GUI
; Return values .: See GUICreate
; Author ........: LWC <https://lior.weissbrod.com>
; Modified ......:
; ==================================================================================================================
Func GUICreateOnMonitor($iMonitorNumber, $iCreate, $sTitle, $iWidth = 0, $iHeight = 0, $oLeft = 0, $oTop = 0, $iStyle = "", $iExStyle = "", $iParent = "")
    if IsNumber($iMonitorNumber) then
        ; Get monitor information
        Local $aMonitorData = GetMonitorInfo()
        Local $aMonitors = $aMonitorData[0]
        Local $iPrimaryMonitorIndex = $aMonitorData[1]
        Local $iMonitorCount = UBound($aMonitors)
    EndIf

    ; Fallback for an non exising monitor
    If IsNumber($iMonitorNumber) and ($iMonitorNumber < 1 Or $iMonitorNumber > $iMonitorCount) Then
        If $iPrimaryMonitorIndex >= 0 Then
            $iMonitorNumber = $iPrimaryMonitorIndex + 1  ; Convert to 1-based index
        Else
            $iMonitorNumber = 1
        EndIf
    EndIf

    ; Get monitor position
    Local $iMonitorIndex = IsNumber($iMonitorNumber) ? $iMonitorNumber - 1 : ""  ; (1-based index to 0-based array)
    Local $iMonitorWidth = IsNumber($iMonitorNumber) ? $aMonitors[$iMonitorIndex][3] : @DesktopWidth
    Local $iMonitorHeight = IsNumber($iMonitorNumber) ? $aMonitors[$iMonitorIndex][4] : @DesktopHeight
    Local $iLeft = IsNumber($iMonitorNumber) ? $aMonitors[$iMonitorIndex][1] : 0
    Local $iTop = IsNumber($iMonitorNumber) ? $aMonitors[$iMonitorIndex][2] : 0

    ; Position window on monitor
    If $iWidth == "max" Then $iWidth = $iMonitorWidth
    If $iHeight == "max" Then $iHeight = $iMonitorHeight
    Local $iWindowLeft = $iLeft + (($oLeft == "max") ? $iMonitorWidth : (($oLeft == "center") ? ($iMonitorWidth - $iWidth) / 2 : $oLeft))
    Local $iWindowTop = $iTop + (($oTop == "max") ? $iMonitorHeight : (($oTop == "center") ? ($iMonitorHeight - $iHeight) / 2 : $oTop))

    Local $iSimulate = False
    If $iSimulate Then
        MsgBox($MB_ICONINFORMATION, "Simulation", "GUICreate(" & Chr(34) & $sTitle & Chr(34) & ", " & (($iWidth == "") ? "Default" : $iWidth) & ", " & (($iHeight == "") ? "Default" : $iHeight) & ", " & $iWindowLeft & ", " & $iWindowTop & " ," & (($iStyle == "") ? "Default" : $iStyle) & ", " & (($iExStyle == "") ? "Default" : $iExStyle) & ", " & (($iParent == "") ? "Default" : $iParent) & ")")
    EndIf
    Local $return = [IsNumber($iMonitorNumber) ? $iMonitorNumber : "", $iMonitorWidth, $iMonitorHeight, $iWindowLeft, $iWindowTop]
    Return $iCreate ? ($iSimulate ? 0 : GUICreate($sTitle, ($iWidth == "") ? Default : $iWidth, ($iHeight == "") ? Default : $iHeight, $iWindowLeft, $iWindowTop, ($iStyle == "") ? Default : $iStyle, ($iExStyle == "") ? Default : $iExStyle, ($iParent == "") ? Default : $iParent)) : $return
EndFunc

; #FUNCTION# ====================================================================================================================
; Description ...: Get monitor information (filtered for physical monitors)
; Parameters ....: None
; Return values .: Array (empty if no info)
; Author ........: LWC <https://lior.weissbrod.com>
; Modified ......:
; ==================================================================================================================
Func GetMonitorInfo()
    Local $aMonitors[0][5] ; [index][0=handle, 1=left, 2=top, 3=width, 4=height]
    Local $iMonitorCount = 0

    Local $aResult = _WinAPI_EnumDisplayMonitors()

    If @error Or Not IsArray($aResult) Then
        Return $aMonitors
    EndIf

    $iMonitorCount = UBound($aResult)

    ; Filter out virtual monitors (those with very small dimensions or zero dimensions)
    Local $aFilteredMonitors[0][5]
    Local $iFilteredCount = 0
    Local $iPrimaryMonitorIndex = -1  ; Track which monitor is primary

    For $i = 0 To $iMonitorCount - 1
        ; Get monitor handle from the enumeration result
        Local $hMonitor = $aResult[$i][0]

        ; Skip null/invalid handles
        If $hMonitor = 0 Then
            ContinueLoop
        EndIf

        Local $aMonitorInfo = _WinAPI_GetMonitorInfo($hMonitor)

        If @error Then
            ContinueLoop
        EndIf

        ; Extract rectangle data from the monitor info
        ; $aMonitorInfo[0] = $tagRECT structure for monitor rectangle
        Local $tRect = $aMonitorInfo[0]
        Local $iLeft = DllStructGetData($tRect, 1)
        Local $iTop = DllStructGetData($tRect, 2)
        Local $iRight = DllStructGetData($tRect, 3)
        Local $iBottom = DllStructGetData($tRect, 4)
        Local $iWidth = $iRight - $iLeft
        Local $iHeight = $iBottom - $iTop

        ; Filter out monitors with dimensions less than 100x100 (likely virtual)
        If $iWidth >= 100 And $iHeight >= 100 Then
            ReDim $aFilteredMonitors[$iFilteredCount + 1][5]
            $aFilteredMonitors[$iFilteredCount][0] = $hMonitor        ; handle
            $aFilteredMonitors[$iFilteredCount][1] = $iLeft           ; left
            $aFilteredMonitors[$iFilteredCount][2] = $iTop            ; top
            $aFilteredMonitors[$iFilteredCount][3] = $iWidth          ; width
            $aFilteredMonitors[$iFilteredCount][4] = $iHeight         ; height

            ; Check if this is the primary monitor
            If $aMonitorInfo[2] = 1 Then  ; Primary flag
                $iPrimaryMonitorIndex = $iFilteredCount
            EndIf

            $iFilteredCount += 1
        EndIf
    Next

    ; Store primary monitor index in the first element for easy access
    Local $aResult[2]
    $aResult[0] = $aFilteredMonitors
    $aResult[1] = $iPrimaryMonitorIndex
    Return $aResult
EndFunc

; #FUNCTION# ====================================================================================================================
; Description ...: Create a sample GUI on a specific monitor
; Parameters ....: See CreateGUIOnMonitor
; Return values .: None
; Author ........: LWC <https://lior.weissbrod.com>
; Modified ......:
; ==================================================================================================================
Func sampleGUICreateOnMonitor($iMonitorNumber, $iCreate, $sTitle, $iWidth = 0, $iHeight = 0, $oLeft = 0, $oTop = 0, $iStyle = "", $iExStyle = "", $iParent = "")
    Local $hGUI = GUICreateOnMonitor($iMonitorNumber, $iCreate, $sTitle, $iWidth, $iHeight, $oLeft, $oTop, $iStyle, $iExStyle, $iParent)
    if $hGUI <> 0 then
        GUISetState(@SW_SHOW, $hGUI)

        While 1
            Local $nMsg = GUIGetMsg()
            Switch $nMsg
                Case $GUI_EVENT_CLOSE
                    GUIDelete($hGUI)
                    ExitLoop
            EndSwitch
        WEnd
    EndIf
EndFunc

; sampleGUICreateOnMonitor(1, True, "Sample GUI", 400, 300, "center", "center")
; sampleGUICreateOnMonitor(1, True, "Sample GUI", "max", "max")

 

Edited by LWC

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...