Fenstergröße und -position prüfen

Hallo in die Runde.
Ich sichere für meine Programmfenster die Position und Größe, um sie beim nächsten Öffnen wieder einstellen zu können. Dazu ist es aber erforderlich, dass beim Öffnen geprüft wird, ob diese Werte sinnvoll sind (Titelzeile nicht erreichbar, Fenster außerhalb des sichtbaren Bereiches (z. B. zweiter Monitor entfernt), Fenstergröße=0, etc.).

Hat jemand dafür schon eine passende Funktion, die auch Unterschiede der verschiedenen Systeme berücksichtigt (Dock, Menüzeile, Taskleiste am Rand, etc.)?
Schön wäre auch, wenn eine Mindesfenstergröße mitgegeben werden könnte.

Gruß, Stefan Mettenbrink.

Eine Mindestfenstergröße kannst Du doch in der IDE einstellen für das Haptfenster mit Min Width und Min Height

In OSX kannst Du das Speichern der Fenstergröße und Position auch vom System machen lassen.

in Window.Open

  #if TargetCocoa then
    Declare function setFrameAutosaveName lib "cocoa" selector _
    "setFrameAutosaveName:" ( NSWindowHandle as integer, AutosaveName as _
    CFStringRef ) as boolean
    call setFrameAutosaveName( me.Handle, App.ExecutableFile.Name)
  #endif

MinWidth und MaxWidth werden aber von den gesicherten Werten im Open-Event überschrieben:
me.top=fenstertop(43)
me.left=fensterleft(43)
me.width=fensterwidth(43)
me.height=fensterheight(43)

Ich benötige eine Lösung für Mac OS, Linux und Windows.

Das kannst Du probieren, die Werte bei width height und left mit deinen Werten ersetzen.

   Dim myBounds As New Realbasic.Rect
  myBounds.Width = 400
  myBounds.Height = 300
  myBounds.Left = 0
  myBounds.Top = 0 + Screen(0).AvailableTop
  me.Bounds = myBounds

man kann mit Realbasic.Rect z.B. auch ein Fenster mittig anordnen.

  myBounds.HorizontalCenter = Screen(0).AvailableWidth
  myBounds.VerticalCenter = Screen(0).AvailableHeight

Du missverstehst mich.
Ich kann die Fensterwerte einstellen. Das mache ich auch schon. Ich möchte nur nicht, dass die Fensterwerte so blöd eingestellt werden, dass die Fenster nicht zu sehen sind.
Sie einfach immer beim Öffnen zu Zentrieren ist wenig hilfreich, weil das nur selten die Letzte Position war.

Gruß, Stefan Mettenbrink.

Dann musst du im window.open Event schauen wie die Werte sind und ggf. anpassen.

ich habe im App.open diesen code um die Anzahl der Fenster und ihre Größen zu ermitteln.
for i=0 to anzahlscreen-1
if screen(i).left<min_Screen_width then min_Screen_width=screen(i).left
if screen(i).Width+screen(i).Left>max_screen_width then max_screen_width=screen(i).Width+screen(i).Left
if screen(i).Height>max_Screen_height then max_Screen_height=screen(i).Height

next

in jedem window.open steht dann dieser code, wenn es da nicht rein passt öffnet sich das fenster mit den Werten, die ich in der IDE fest eingegeben habe. Das Dock berücksichtige ich hier nicht, aber alles andere passt!

if rpx >=min_Screen_width and rpx<max_screen_width and rpy >=36 then
rechnungen.left=rpx
rechnungen.top=rpy
rechnungen.width=rgx
rechnungen.height=rgy
end if

[quote=161734:@Stefan Mettenbrink]Du missverstehst mich.
Ich kann die Fensterwerte einstellen. Das mache ich auch schon. Ich möchte nur nicht, dass die Fensterwerte so blöd eingestellt werden, dass die Fenster nicht zu sehen sind.
Sie einfach immer beim Öffnen zu Zentrieren ist wenig hilfreich, weil das nur selten die Letzte Position war.[/quote]
Da die Fensterposition zu deinem Dokument gehört solltest du sie auch im Dokument speichern. Hat dein Dokument ein geeignetes Speicherformat dafür?

Wenn ja, dann lad das Dokument, prüf ob es auf den Bildschirm passt, wenn ja zeig es, wenn nein nimm einen Default Wert.

Wenn nein … hmmm, ungünstig, aber machbar. Mußt du dann für jedes Dokument in deinen Einstellungen (Preferences) speichern mit Dateiname. Du speicherst doch deine Einstellungen, oder?

[quote]Dann musst du im window.open Event schauen wie die Werte sind und ggf. anpassen.

ich habe im App.open diesen code um die Anzahl der Fenster und ihre Größen zu ermitteln.
for i=0 to anzahlscreen-1
if screen(i).left<min_Screen_width then min_Screen_width=screen(i).left
if screen(i).Width+screen(i).Left>max_screen_width then max_screen_width=screen(i).Width+screen(i).Left
if screen(i).Height>max_Screen_height then max_Screen_height=screen(i).Height

next
[/quote]

Ja, so in etwa habe ich das auch gedacht. Allerdings mit einer Methode, die aufgerufen wird und der das Fenster als Parameter mitgegeben wird.

[quote]
in jedem window.open steht dann dieser code, wenn es da nicht rein passt öffnet sich das fenster mit den Werten, die ich in der IDE fest eingegeben habe. Das Dock berücksichtige ich hier nicht, aber alles andere passt!

if rpx >=min_Screen_width and rpx<max_screen_width and rpy >=36 then
rechnungen.left=rpx
rechnungen.top=rpy
rechnungen.width=rgx
rechnungen.height=rgy
end if[/quote]

Zumindest sollte unter Mac OS das Menü berücksichtigt werden. Wäre blöd, wenn man wegen des Menüs die Fenstertitelzeile nicht erreichen kann.

Gruß, Stefan Mettenbrink.

Das halte ich für ungeschickt. Es gibt in meinem Programm nicht nur ein Fenster. Es gibt den Einstellungsdialog, ein Suchfenster, eine Toolbox, etc.
Alle diese Fenster haben ihre Position, die natürlich gesichert werden (wie die diversen Einstellungsparameter ebenso). Diese Daten gehören nicht zu den Anwenderdaten und werden deshalb in den Preferences gesichert.

Gruß, Stefan Mettenbrink.

[quote=165008:@Stefan Mettenbrink]Das halte ich für ungeschickt. Es gibt in meinem Programm nicht nur ein Fenster. Es gibt den Einstellungsdialog, ein Suchfenster, eine Toolbox, etc.
Alle diese Fenster haben ihre Position, die natürlich gesichert werden (wie die diversen Einstellungsparameter ebenso). Diese Daten gehören nicht zu den Anwenderdaten und werden deshalb in den Preferences gesichert…[/quote]
Eben. App-Daten (wie Toolbox) werden app-weit gesichert (in den Preferences), Document-spezifische Daten im Dokument :wink: und das hat nichts mit der Anzahl der Fenster zu tun.

Z.B. enthält ein Word-Dokument weit mehr als den Text den du siehst, und die Dokumentation des .doc Formats ist über 600 Seiten groß (siehe https://msdn.microsoft.com/en-us/library/office/cc313153(v=office.12).aspx)

Dokumentenspezifische Daten nicht im Dokument selbst zu speichern ist machbar aber unelegant (und nicht sehr OOP)… Das Dokument sollte selbst wissen wo es hin muß wenn es aufgeht, und was es macht wenn es dort nicht hin kann.

P.S. Kann sein daß ich deine Frage falsch verstanden hab. Ich dachte es geht um Dokumentenfenster.

Hallo zusammen,
in 64Bit funktioniert dies nicht mehr.

#if TargetCocoa then
Declare function setFrameAutosaveName lib “cocoa” selector _
“setFrameAutosaveName:” ( NSWindowHandle as integer, AutosaveName as _
CFStringRef ) as boolean
call setFrameAutosaveName( me.Handle, App.ExecutableFile.Name)
#endif

Hat jemand eine Lösung dafür?

[quote=270056:@Horst Jehle]Hallo zusammen,
in 64Bit funktioniert dies nicht mehr.

#if TargetCocoa then
Declare function setFrameAutosaveName lib “cocoa” selector _
“setFrameAutosaveName:” ( NSWindowHandle as integer, AutosaveName as _
CFStringRef ) as boolean
call setFrameAutosaveName( me.Handle, App.ExecutableFile.Name)
#endif

Hat jemand eine Lösung dafür?[/quote]

Ah! Danke für den Hinweis. Ich war schon am verzweifeln weil ich nicht herausfinden konnte warum die Daten plötzlich nicht mehr geladen wurden…

Wäre auch an einer Lösung interessiert.

setFrameAutosaveName: ist keine Methode von NSWindow, sondern von NSWindowController (war es immer schon, das hat nichts mit 64bit zu tun).

EDIT: Sorry, habe setFrameAutosaveName mit setWindowFrameAutosaveName verwechselt.

Im Bezug auf die Fensterposition ist das falsch. Die Fensterposition eines Dokuments wird auf dem Computer gespeichert und nicht im Dokument.

Und warum funktioniert dies in 32Bit ohne Probleme?

Hier der Link zum Developer Dokument: Saving a Window’s Position into the User’s Defaults

Keine Ahnung. Interessanterweise (vorausgesetzt ich habe keinen Fehler im Code) ist WindowController nil:

[code]Declare Function windowController Lib “Cocoa” Selector “windowController” (NSWindow As Ptr) As Ptr

Dim win As Ptr = Ptr(Self.Handle)
Dim controller As Ptr = windowController(win) // controller ist Nil[/code]
… und der Aufruf von NSWindow.setFrameAutosaveName wurde schon immer umgeleitet auf NSWindowController.setWindowFrameAutosaveName. Wenn aber controller Nil ist, dann passiert einfach nichts (eine Message an ein Objekt das Nil ist zu senden in Objective C ist erlaubt).