Hallo in die Runde,
ich habe mir seinerzeit eine Routine gebastelt, die prüft, ob das Fenster im sichtbaren Bereich ist und ob man an die Fenstertitelzeile kommt. Offenbar funktioniert sie nicht, wenn zwei (oder mehr?) Monitore vorhanden sind. Insbesondere, wenn der Hauptmonitor rechts steht.
Hat hier jemand eine Routine, die solches erledigt oder gibt es dafür eine Funktion, die das übernimmt?
Oh wei, ich habe da Stunden herumgebastelt. Mit 2 Monitoren funktioniert mein Code. Soweit ich mich erinnere, macht aber der dritte Probleme. Es gibt für macOS ein Declare.
if ParentWindow = nil then return
dim isNewPrefs as Boolean = not Globals.thePrefs.IsPrefAvailable(WindowTitle + "_Top")
'get pref values
dim PrefValueTop as Integer = Globals.thePrefs.GetPrefNumber(WindowTitle + "_Top")
dim PrefValueLeft as Integer = Globals.thePrefs.GetPrefNumber(WindowTitle + "_Left")
dim PrefValueWidth as Integer = Globals.thePrefs.GetPrefNumber(WindowTitle + "_Width")
dim PrefValueHeight as Integer = Globals.thePrefs.GetPrefNumber(WindowTitle + "_Height")
if PrefValueWidth = 0 then PrefValueWidth = ParentWindow.Bounds.Width
if PrefValueHeight = 0 then PrefValueHeight = ParentWindow.Bounds.Height
if ParentWindow.MinimumWidth > PrefValueWidth then PrefValueWidth = ParentWindow.MinimumWidth
if ParentWindow.MinimumHeight > PrefValueHeight then PrefValueHeight = ParentWindow.MinimumHeight
'set the rect
dim theRect as REALbasic.Rect
if isNewPrefs then
theRect = new REALbasic.Rect(100, 100, ParentWindow.Width, ParentWindow.Height) 'dummy values
else
theRect = new REALbasic.Rect(PrefValueLeft, PrefValueTop, PrefValueWidth, PrefValueHeight)
end if
'Find screen.
Dim screenID as integer
For l as integer = 0 to screenCount - 1
if theRect.top >= screen(l).top and theRect.center.x > screen(l).left and theRect.center.x < (screen(l).left + screen(l).width) then screenID = l
next
lastScreen = screenID
Dim ShowOnScreen as screen = screen(screenID)
'for left and top we need to recalculate the values if the prefs are new, only for top if the prefs are not new
if isNewPrefs then
if ParentWindow.Width < 900 then PrefValueTop = (Screen(ShowOnScreen).Height - ParentWindow.Bounds.Height)/2
PrefValueLeft = (Screen(ShowOnScreen).Width - ParentWindow.Width)/2
theRect = new REALbasic.Rect(PrefValueLeft, PrefValueTop, PrefValueWidth, PrefValueHeight)
end if
dim ScreenHeight as Integer = ShowOnScreen.AvailableHeight
dim theTop as Integer
if ShowOnScreen.AvailableTop < 0 then
theTop = -min(-theRect.top, -ShowOnScreen.availabletop)
else
theTop = max(theRect.top, ShowOnScreen.availabletop)
end if
if ShowOnScreen.AvailableTop > 0 then
theRect.Top = Min(theTop - ShowOnScreen.AvailableTop, ScreenHeight) + ShowOnScreen.AvailableTop
else
theRect.Top = min(theTop, ScreenHeight)
end if
theRect.Left = min(max(theRect.left, ShowOnScreen.availableLeft), ShowOnScreen.availableLeft + (ShowOnScreen.availableWidth))
if ParentWindow.ToolbarVisibleMBS and theRect.Height <= ParentWindow.MinimumHeight + 78 then
theRect.Height = ParentWindow.MinimumHeight + 78
end if
theRect.Height = min(theRect.height, ShowOnScreen.AvailableHeight)
theRect.Width = min(theRect.Width, ShowOnScreen.AvailableWidth - 20)
ParentWindow.Bounds = theRect
Danke für die Tipps! Schau ich mir an.
…
Schade, dass die MBS Funktion nur für macOS funktioniert.
Zum Problem:
Mein Programm merkt sich die Fensterpositionen der verschiedenen Fenster auch für den nächsten Start. Nutzt jemand nun mehr als einen Monitor (Laptop und Zusatzbildschirm), ist es verständlich, wenn man einige Fenster auf dem externen Gerät anzeigen lässt. Wenn man nun den Laptop mobil nutzt und das Programm startet, wird das Fenster an einer Position geöffnet, die nicht im Sichtfeld des Laptops ist oder man nicht an die Titelzeile zum Verschieben kommt.
Das Problem kennen wir sehr gut. Im Office mit 2-4 Monitoren und dann im Home Office mit 1-2 Monitoren…
Unter Windows konnte ich es nie zu 100% lösen und habe es dann aufgegeben.
Ja, auch ich hatte mich mehrfach daran versucht. Zuletzt habe ich mich dann auf einen Monitor beschränkt. Ging lange gut. Jetzt hat sich jemand gemeldet und nachgefragt, ob ich hier nachbessern kann.
Ich habe die Routine von Beatrix mal an meinen Code angepasst und es sieht hier bei mir aus wie immer
Ich werde das mal zur Begutachtung an den Anwender weitergeben.
Ein anderes Problem ist, daß nicht mehr angeschlossene Monitore trotzdem in den System-Voreinstellungen noch vorhanden sind. Damit können Fenster, die an so einem Monitor waren, “verschwinden”. Dafür habe ich ein Menutiem im Windows-Menü “Fenster einsammeln”:
for currentWindow as Integer = 0 to App.WindowCount
dim ScreenID as Integer = getScreenID(App.Window(currentWindow))
if ScreenID = -1 then
Continue
ElseIf ScreenID > 0 then
'center window on middle of screen 1
App.Window(currentWindow).Left = (Screen(0).AvailableWidth - App.Window(currentWindow).Width) / 2
App.Window(currentWindow).Top = (Screen(0).AvailableHeight - App.Window(currentWindow).Height) / 2
end if
next
Private Function getScreenID(theWindow as Window) As Integer
'set the rect
if theWindow = Nil or not theWindow.Visible then Return -1
dim theRect as Realbasic.Rect
dim ToolbarHeight as Integer = theWindow.Bounds.Height - theWindow.height + 1
if ToolbarHeight = 1 then Return -1'going FullScreen
theRect = new REALbasic.Rect(theWindow.Left, theWindow.Top, theWindow.Width, theWindow.Height)
'Find screen.
Dim screenID as integer
For l as integer = 0 to screenCount - 1
if theRect.top >= screen(l).top and theRect.center.x > screen(l).left and theRect.center.x < (screen(l).left + screen(l).width) then screenID = l
next
Return screenID
End Function
Was helfen könnte wenn Du die Einstellungen je nach Monitor Anzahl speicherst und Geräte Name.
Oder auch die Monitor Auflösung dabei.
Einfach nur die Position reicht nicht wie Du gemerkt hast.
Windows mit Multi-Monitor und v.a. verschiedenen DPI ist mühsam. Xojo’s Methoden funktionieren da nur unzuverlässig.
Daher machen wir dies unter Windows mit Declares, um die Systemfunktionen zu nutzen.
Beispielprojekt: Monitors
Der Button ‘Fit on Monitor’ solle das Anliegen hier ermöglichen. Die anderen Buttons (rechts) helfen mit Positionierung von Fenstern und sollte mit MultiMonitor/DPI zurechtkommen.
Da sollte das Fenster auf keinem Screen zu finden sein. Dann müsste man ScreenID mit -1 vorbelegen und abschließend bei ScreenID=-1 die Fensterposition auf den Hauptbildschirm legen.
Muss ich mal testen.
…
ach, da brauche ich ja erst mal zwei Bildschirme
Muss ich mir mal Hardware ausleihen.
@Jürg_Otter:
An verschiedene DPI-Werte auf unterschiedlichen Monitoren hatte ich noch gar nicht gedacht
Ohne Zweitbildschirm macht das eigentlich keinen Spaß, dafür eine Lösung zu bauen.
So richtig Lust habe ich dazu nicht. Mal sehen, was die kommenden Tage noch so ansteht.