Jump to content

Multi-Monitor GUI tracking and keeping it visible using ini


Recommended Posts

#include <WinAPISys.au3> ; _WinAPI_GetSystemMetrics
#include <WinAPIGdi.au3> ; _WinAPI_MonitorFromWindow

Opt("MustDeclareVars", 1)

Global $Ini = @AppDataCommonDir & '\position.ini'
If Not FileExists($Ini) Then
    Local $aiSection[3][2] = [[2, ""], ["X", -1], ["Y", -1]]
    IniWriteSection($Ini, "Current", $aiSection) ; create the ini file to use for tracking the gui
EndIf

Global $MyApp = GUICreate('MyApp', 500, 300, IniRead($Ini, 'Current', "X", "-1"), IniRead($Ini, 'Current', "Y", "-1")) ; the GUI

Global $isMonitor = _WinAPI_MonitorFromWindow($MyApp, 0) ; if a previously used monitor is not available, center the GUI on the Primary Monitor
If $isMonitor = 0 Then
    IniWrite($Ini, 'Current', 'X', -1)
    IniWrite($Ini, 'Current', 'Y', -1)
EndIf

GUIRegisterMsg(0x0003, "tracking") ; allows tracking the gui position
    
Func tracking() ; track gui position and maintain visibility
    Local $aPos = WinGetPos($MyApp) ; -32000 = minimized (AutoIt)
    If $aPos[0] = -32000 Then $aPos[0] = -1
    If $aPos[1] = -32000 Then $aPos[1] = -1
    Local $tWorkArea = DllStructCreate($tagRECT)
    _WinAPI_SystemParametersInfo(0x0030, 0, $tWorkArea)
    Local $aReturn = [DllStructGetData($tWorkArea, 'Bottom') - DllStructGetData($tWorkArea, 'Top')] ; screen heighth without the taskbar
    Local $taskbar = _WinAPI_GetSystemMetrics(1) - $aReturn[0]  ; full screen - the above = taskbar height
    If $aPos[0] < _WinAPI_GetSystemMetrics(76) - 1 Then $aPos[0] = _WinAPI_GetSystemMetrics(76) ;keep gui onscreen left
    If $aPos[1] < _WinAPI_GetSystemMetrics(77) - 1 Then $aPos[1] = _WinAPI_GetSystemMetrics(77) ;keep gui onscreen top
    If $aPos[0] > _WinAPI_GetSystemMetrics(76) + _WinAPI_GetSystemMetrics(78) - $aPos[2] Then _ ; line wrapped to next line
            $aPos[0] = _WinAPI_GetSystemMetrics(76) + _WinAPI_GetSystemMetrics(78) - $aPos[2]     ;keep gui onscreen right
    If $aPos[1] > _WinAPI_GetSystemMetrics(77) + _WinAPI_GetSystemMetrics(79) - $taskbar - $aPos[3] Then _ ; line wrapped to next line
            $aPos[1] = _WinAPI_GetSystemMetrics(77) + _WinAPI_GetSystemMetrics(79) - $taskbar - $aPos[3]     ;bottom and above the taskbar
    IniWrite($Ini, 'Current', 'X', $aPos[0]) ; Write the X position to the Ini.
    IniWrite($Ini, 'Current', 'Y', $aPos[1])
EndFunc   ;==>tracking

GUISetState(@SW_SHOW)

While 1
    Switch GUIGetMsg()
        Case -3
            If MsgBox(36, 'Delete the ini file?', 'Do you want to delete the ini file?') = 6 Then FileDelete($Ini)
            Exit
    EndSwitch
WEnd

If, while testing, the gui is lost in space; do one of the following
close the app and restart it OR
hover the taskbar icon and choose to minimize, then restart it.

It also works on single monitor systems.

Edited by Shark007
update to a functioning example with more comments
Link to post
Share on other sites

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