Seite 1 von 3
MDI-ChildWindows - Größe managen
Verfasst: 04.02.2014 19:54
von es_91
Hallo.
Ich habe folgenden Fall: Ich möchte die Fenstergröße meiner MDI-ChildWindows so managen, dass sie sich an die Größe des MDIGadgets (= Größe des Mutterfensters) anpassen, das auch, wenn sie minimiert oder maximiert sind, allerdings NUR DANN wenn der Anwender keine eigene Größe per Mausklick festgelegt hat.
Hoffe das beschreibt es eindeutig. Ich versuche es nochmal anders:
Wenn der Anwender sich entschließt, die Größe seiner ChildWindows selbst zu verwalten, soll nicht mehr automatisch in die Fenstergröße der MDI-ChildWindows eingegriffen werden, tut er das aber nicht sollen sie automatisch einen festen "Abstand" zu beiden vertikalen Seitenrändern des MDIGadgets haben.
Schönen Abend,
es_91.
Re: MDI-ChildWindows - Größe managen
Verfasst: 09.02.2014 21:59
von N00B
OK unter PB 4.60 und meinem Windows XP mit 32 Bit funzt der Code einwandfrei, mangels anderer Versionen (insbesondere 64 Bit Versionen) kann ich nur für 32 Bit Win2000/XP garantieren das der Code geht
Sollte es zu Flimmern kommen, liegt das daran das die Animationen
beim maximieren und minimieren von Fenstern unter Windows an sind ! (die sind bei mir generell
aus, der Schnick Schnack bremst mich nur aus)
Hier wie mann es abschaltet.
http://www.winfaq.de/faq_html/Content/t ... ip0025.htm
EDIT: So der aktuellste Code, ohne Geflimmer, keine WinAPI Befehle, keine Befehle wurden verwendet bei denen in der Anleitung steht. blabla geht erst ab Windows Version so und so.
Also sollte der ab jeder Windows Version ab Windows NT4 völlig ohne Probleme funzen.
Code: Alles auswählen
EnableExplicit
Define MainWinH, MainWinW, Event, Menu, MenuEntry
Global AutoSize
; WIN
Enumeration
#MainWin
#MDI_Win
EndEnumeration
; GADGET
Enumeration
#Button
#MDI_GD
EndEnumeration
; MENU
Enumeration
#GDI_MENU
EndEnumeration
Procedure GetAndRunMenuEvents(Menu,MenuEntry)
; Menüs in der Titelleiste starten immer bei MenuEntry 0 das ist ganz normal
; Bei Kontextmenüs hingegen bei Menuentry 1
If Menu = #GDI_MENU
If MenuEntry = 1 : Debug "MenuEntry=1"
;KEINE AHNUNG WARUM ABER GetMenuItemState & SetMenuItemState brauchen
;MenuEntry=0 zum funzen, obwohl MenuEntry=1 abgefangen und an diese Procedure übergeben wird
If GetMenuItemState(#GDI_MENU,0)
Debug "DISABLE"
AutoSize = 0
SetMenuItemState(#GDI_MENU,0,0)
SetWindowTitle(#MainWin,"Autosize = OFF")
Else
Debug "ENABLE"
AutoSize = 1
SetMenuItemState(#GDI_MENU,0,1)
SetWindowTitle(#MainWin,"Autosize = ON")
EndIf
EndIf
EndIf
EndProcedure
MainWinW=600 : MainWinH=470
#FirstIDForGDI_Entry=70
OpenWindow(#MainWin,0,0,MainWinW,MainWinH,"Autosize = On",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ButtonGadget(#Button,10,10,100,20,"Bla")
If CreateMenu(#MainWin,WindowID(#MainWin))
MenuTitle("Menu index 0")
MenuTitle("MDI windows menu")
MenuItem(0,"Autosize")
MDIGadget(#MDI_GD,10,40, MainWinW - 20, MainWinH - 70,1,#FirstIDForGDI_Entry)
AddGadgetItem(#MDI_GD,#MDI_Win,"child window")
UseGadgetList(WindowID(#MainWin))
EndIf
AddKeyboardShortcut(#MainWin,#PB_Shortcut_F1,1)
Menu = #GDI_MENU
SetMenuItemState(#GDI_MENU,0,1)
AutoSize = 1
; HideMenu(0,1) ; Würde ich benutzen, da Fenster Menüs hässlich sind :D
; Falls das Child Win Maximiert wird, landen die Buttons zum Minimieren,Maximieren & Schliessen
; auf die Titelleiste vom MainWindow, daß ist anscheinend normal.
; Macht nichts, denn durch Doppelklick auf die Fensterleiste vom MDI Window wird das MDI Fenster wieder
; auf seine normale Größe gebracht (oder halt maximiert je nachdem was gerade aktiv ist)
; und die Minimieren,Maximieren & Schliessen Buttons sind wieder beim MDI Window
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_SizeWindow
If AutoSize = 1
Debug "AUTOSIZE"
DisableWindow(#MDI_Win,1) : ResizeWindow(#MDI_Win,2,0,MainWinW - 37, MainWinH - 110) : DisableWindow(#MDI_Win,0)
EndIf
EndIf
If Event = #PB_Event_Gadget
Event = EventGadget()
If Event = #Button
Debug "Button"
EndIf
EndIf
If Event = #PB_Event_Menu
Debug "" : Debug "Menu ID="+Str(Menu)
MenuEntry = EventMenu()
Debug "Menu Entry="+Str(MenuEntry) : Debug "--------"
GetAndRunMenuEvents(Menu,MenuEntry)
Menu = #GDI_MENU ; Muss danach auf die ID des Titelleisten Menus vom jeweiligen Fenster (in diesem Fall ID1)
; zurückgestellt werden sonst wird permanent (aber nur für Menu Keyboard Events) die letzte benutze
; Menu ID eines Kontext Menü Events ausgegeben und der jeweilige
; Keyboard Shortcut führt das falsche Menü aus ! Da die Menu ID nicht stimmt.
EndIf
If Event = #PB_Event_CloseWindow
Break
EndIf
ForEver
Hoffe ich konnte helfen.
Re: MDI-ChildWindows - Größe managen
Verfasst: 09.02.2014 22:31
von ts-soft
@N00B
Jetzt wäre noch interessant, unter welcher Windows Version dieser Code funktioniert
Fenstertitel wackelt zwischen On und Off hin und her, ansonsten ist das Fenster nicht bedienbar und
nach ein paar klicks ist es dann auch tod.
Ist ja nett, das Du helfen willst, aber Dein Code verstößt gegen alle Regeln der Eventbearbeitung und
funktioniert auch nicht, jedenfalls auf meinem System ist das Ergebnis unbenutzbar.
Gruß
Thomas
Re: MDI-ChildWindows - Größe managen
Verfasst: 09.02.2014 22:49
von N00B
PB 4.60 Windows XP 32 Bit Version.
Wo verstösst der gegen die Event Verarbeitung ?
Nur weil ich nicht dieses potthässliche Case für Menu Events benutze ?

sondern
ne viel schönere Methode die ich mir hier irgendwo mal abgeschaut hab ?
Ich hasse Select und Case, es ist potthässlich, und wenn ich if benutzen kann, tu ich das auch

Re: MDI-ChildWindows - Größe managen
Verfasst: 09.02.2014 23:05
von ts-soft
Naja, aller Code im EventLoop hat aufgrund eines Ereignisses zu geschehen. Code Ausserhalb von (Wait)WindowEvent() hat dort
nichts zu suchen. Dann noch die Delays und schon kommt nur noch ein Teil der Events überhaupt noch an.
Statt WindowEvent besser WaitWindowEvent(timeout) benutzen, dabei geht nichts flötten und den Code ausserhalb der
Events in eine TimerProc packen und in gewissen Abständen (TimerEvent) aufrufen.
Hab gerade keine Lust unter XP zu testen, aber kann mir auch nicht denken, das der Code dort viel besser läuft.
Gruß
Thomas
Re: MDI-ChildWindows - Größe managen
Verfasst: 09.02.2014 23:19
von N00B
ts-soft hat geschrieben:Naja, aller Code im EventLoop hat aufgrund eines Ereignisses zu geschehen. Code Ausserhalb von (Wait)WindowEvent() hat dort
nichts zu suchen. Dann noch die Delays und schon kommt nur noch ein Teil der Events überhaupt noch an.
Statt WindowEvent besser WaitWindowEvent(timeout) benutzen, dabei geht nichts flötten und den Code ausserhalb der
Events in eine TimerProc packen und in gewissen Abständen (TimerEvent) aufrufen.
Hab gerade keine Lust unter XP zu testen, aber kann mir auch nicht denken, das der Code dort viel besser läuft.
Gruß
Thomas
Sorry Ts aber da muss ich dir gewaltig wiedersprechhen :p
Bei WaitWindowEvent kann ich nicht prüfen ob sich die Fenstergröße geändert hat ! Und das ist nur einer der Nachteile, mit WindowEvent() kann mann einfach viel mehr Events Abfragen, und hier ist Window Event einfach besser geeignet, braucht mann viel weniger Code.
Und bei einem Delay von 1ms geht nichts flöten, echt warum gibt es die WindowEvent() Funktion sonst in PB, wenn sie soooooooo schlecht ist ?
Mir sind noch nie Events flöten gegangen (nur bei Kontextmenü Events, über die beknackte API (und das egal ob WaitWindowEvents oder WindowEvent) wenn ich Kontext Events nicht auf einem Editor Gadget angewendet hab, sondern auf Listen, ich konnte mir Jahrelang nicht erklären, warum das öfter mal passiert ist, aber mit der Kontext Menü Methode aus dem Code geht es jetzt endlich nach 5 Jahren rätseln völlig fehlerfrei)
und ich hab mein TV Out aktiviert + 4 einzelne Desktops gleichzeitig laufen.
Was redest du da ? Natürlich läuft der Code unter XP völlig ohne Probleme, echt das nervt, ich nehme das jetzt mit meinem Smartphone auf, damit du es siehst.
Und dann lass ich extra nochmal XP unter Virtualbox mit dem Code laufen, und nehme das auch noch auf !
Re: MDI-ChildWindows - Größe managen
Verfasst: 09.02.2014 23:24
von ts-soft
Unterschied zwischen WindowEvent() : Delay(100) und WaitWindowEvent(100)
Bei der WindowEvent() Variante werden Events, die während des Delay() auftreten, erst nach dem Delay()
bearbeitet, was eine verzögernde Reaktion der GUI nach sich zieht.
Bei WaitWindowEvent(100) gibts kein Delay(), sondern es wird per Timer autom. eine Unterbrechung durchgeführt.
Auf Ereignisse wird ohne Verzögerung reagiert.
Änderungen der Fenstergrösse werden doch auch im Eventloop korrekt verarbeitet, ausser wenn das Fenster
gerade verschoben wird. Hierfür kann man dann BindEvent() nutzen, dafür müßtest Du dann natürlich updaten,
was sowieso ratsam wäre.
Falls Du mir immer noch wiedersprichst, soll es mir egal sein, ich weiß was ich sage und mache

Re: MDI-ChildWindows - Größe managen
Verfasst: 09.02.2014 23:26
von RSBasic
N00B hat geschrieben:Bei WaitWindowEvent kann ich nicht prüfen ob sich die Fenstergröße geändert hat ! Und das ist nur einer der Nachteile, mit WindowEvent() kann mann einfach viel mehr Events Abfragen, und hier ist Window Event einfach besser geeignet, braucht mann viel weniger Code.

Kannst du vielleicht Beispielcodes posten? Ich glaube, du hast da einfach was falsches gemacht und du glaubst, das Problem liegt bei WaitWindowEvent().
N00B hat geschrieben:warum gibt es die WindowEvent() Funktion sonst in PB, wenn sie soooooooo schlecht ist ?
Es gibt z.B. auch Goto, was man auch nicht nutzen sollte, wenn man einen sauberen Code schreiben möchte, aber es ist trotzdem vorhanden.

Re: MDI-ChildWindows - Größe managen
Verfasst: 09.02.2014 23:40
von ts-soft
Wegen dem anderem Problem (GetAsyncKeyState), das ich noch garnicht angesprochen habe,
siehe hier:
http://www.purebasic.fr/german/viewtopi ... 47#p318047
wird nicht empfohlen, ist falsch wie Du es benutzt.
Mit einem Windows-Callback (MDIGadget ist sowieso Windows Only), kann man alle Probleme auch
unter PB4.60 lösen, so das es auch funktioniert.
Re: MDI-ChildWindows - Größe managen
Verfasst: 09.02.2014 23:47
von RSBasic
Und es wäre vorteilhaft, wenn du grundsätzlich EnableExplicit benutzt.