MDI-ChildWindows - Größe managen

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
N00B
Beiträge: 122
Registriert: 11.07.2007 22:28

Re: MDI-ChildWindows - Größe managen

Beitrag von N00B »

ts-soft hat geschrieben: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 :wink:
Ich hab die neuere PB Version, allerdings hab ich grade PB 4.60 benutzt (hab für jede PB Version auf dem System, ein eigenes jaPBE laufen) da ich es sowieso grade auf hatte, und kurz zuvor noch an dem Prog das 10K Zeilen hat, und an dem ich schon 5 Jahre immer wieder mal schreibe, geschrieben hab, und das nicht mit PB 5.XX funzt weil die ja unbedingt gesammte Packer Lib umschreiben mussten, und mir das viel zu viel Arbeit ist das anzupassen.

Sprich ich hab kein Bock auf 5.XX und BindEvent()

Echt guckt euch die PB Anleitung an.

http://www.purearea.net/pb/german/manua ... event.html

da steht nichts davon, daß mann Events wie Size Change abfragen kann, im Gegensatz zu WindowEvent()

http://www.purearea.net/pb/german/manua ... event.html

Und warum sollte mich die Verarbeitung von weiteren Events bei 100ms stören ?
Ein normaler Mensch bewegt die Maus in nem Zeitraum von 100ms grade mal paar cm, und da soll irgendwas verloren gehen ?

Für mich ist das ein logischer Aufbau, die 100ms verzögern (ohne das, wird obwohl mann einmal F1 drückt, gleich ein mehrfaches F1 registriert) und erst dann läuft wird die Event Schleife weiterverarbeitet.

Echt wie soll die Event Schleife denn permanent um 100ms zerzögert werden, wenn dort

IF F1

steht ?

Ist doch völliger Quatsch, aber Hauptsache meckern, weil mein Code nicht irgendwelchen 0815 Normen entspricht.

Und hier der Beweis das mein Code funzt.

http://www12.zippyshare.com/v/77417850/file.html

Und ich weiss auch was ich sage und mache.
Wegen dem anderem Problem (GetAsyncKeyState), das ich noch garnicht angesprochen habe,
siehe hier: viewtopic.php?p=318047#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.
Mich interessiert die empfohlene Methode nicht.
Ich mache das seit 5 Jahren so, und hab keine Probleme damit, solange ich ClearKeyBuffers benutze.

Es funzt unter PB 4.60 auch ohne das übliche WindowCallback Zeugs der API.

Echt ihr seit doch die, die dem tagelang nicht geantwortet haben, ich hab mir wenigstens
die Mühe gemacht, und jetzt habt ihr nichts besseres zutun als an meinem Code rumzumeckern.

Dann schreibt ihr doch nenn netten & verständlichen Code für es_91

@RSBasic

Wieso ?

Guck dir einfach das Online Handbuch an, da steht nirgends was von, daß
mann mit WaitWindowEvent() irgendwas abfragen kann. Da ist nichts mit #PB_Event_SizeWindow usw usw

Und nein ich persönlich benutze kein EnableExplicit, daß macht mich tierisch Agro, ich brauch den
Käse nicht, nichts nervt mehr, als Beispiel Code erst mal nehmen zu müssen, und den ganzen Rotz zu modifizieren wegen diesem beknackten Explitit Zeug.

Ich schreib mein Zeug so, daß sich nicht Variablen in die Querre kommen, bin jaPBE Benutzer denen passiert sowas nicht !

EDIT: Ok anscheinend reicht die DirectDraw/Direct2D (was auch immer) Leistung unter Virtualbox aus, es liegt nicht daran, daß es dort flimmert.

Bei der XP Version unter Virtualbox hab ich diese ätzende nervige Fenster Maximier und Minimier Funktion von Windows noch an (so wie die meisten Leute, die auf den optischen Schnick Schnack stehen, statt auf maximale Leistung) und desshalb flimmert es dort, und bei anderen die Windows mit 0815 Settings laufen haben.

Hier wie mann die beknackten Minimier und Maximier Animationen abschaltet.

http://www.winfaq.de/faq_html/Content/t ... ip0025.htm
Zuletzt geändert von N00B am 10.02.2014 00:24, insgesamt 1-mal geändert.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: MDI-ChildWindows - Größe managen

Beitrag von ts-soft »

Hab Deinen Code nochmals getestet, er funktioniert nur unter 32-Bit, bei 64-Bit schaltet er ständig zwischen On und Off hin und her.
Das liegt wohl an dem GetAsyncKeystate.

Wenn ich das MDI an der Ecke anfasse und Resizen möchte gibts ein mächtiges Tooawohoo :mrgreen:

Ich würde ein sich so verhaltenes Fenster jedenfalls sofort in die Tonne treten.

Aber egal, Du denkst ja, ich will Dich nur ärgern oder denkst, alles was bei mir geht, funktioniert auch woander so.

Bin raus hier.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
N00B
Beiträge: 122
Registriert: 11.07.2007 22:28

Re: MDI-ChildWindows - Größe managen

Beitrag von N00B »

ts-soft hat geschrieben:Hab Deinen Code nochmals getestet, er funktioniert nur unter 32-Bit, bei 64-Bit schaltet er ständig zwischen On und Off hin und her.
Das liegt wohl an dem GetAsyncKeystate.

Wenn ich das MDI an der Ecke anfasse und Resizen möchte gibts ein mächtiges Tooawohoo :mrgreen:

Ich würde ein sich so verhaltenes Fenster jedenfalls sofort in die Tonne treten.

Aber egal, Du denkst ja, ich will Dich nur ärgern oder denkst, alles was bei mir geht, funktioniert auch woander so.

Bin raus hier.
Ok ich kann nichts für die Probleme von einem 64 Bit Windows, denn ich habe keines hier, mein Host System ist 32 Bit (und ich werde XP bis 2038 nicht aufgeben :D ) also kann ich kein 64 Bit System in Virtualbox laufen lassen.

Ja natürlich denk ich das, klar ich bin ein Noob im Vergleich zu euch, aber nach 7 Jahren sollte ich doch einen Code zusammenbringen von lächerlichen 148 Zeilen der auch funzt, und erst wenn ich persönlich geprüft habe das er funzt, ihn dann posten.

Es ist beleidigend für mich wenn mann animmt, daß ich hier was poste das nicht geprüft ist, und ich nach 7 Jahren keinen 148 Zeilen Basic Code zusammenkriege, der im grunde nur ein Gerüst ist, und der nicht abkackt nach paar Clicks.

Nur weil ich etwas durchgeknallt bin, bin ich nicht verantwortungsloss, ich hab hier versucht nach bestem Wissen & Gewissen zu helfen.

Anscheinend reicht die DirectDraw/Direct2D (was auch immer) Leistung unter Virtualbox aus, es liegt nicht daran, daß es dort flimmert.

Bei der XP Version unter Virtualbox hab ich diese ätzende nervige Fenster Maximier und Minimier Funktion von Windows noch an (so wie die meisten Leute, die auf den optischen Schnick Schnack stehen, statt auf maximale Leistung) und desshalb flimmert es dort, und bei anderen die Windows mit 0815 Settings laufen haben.

Hier wie mann die beknackten Minimier und Maximier Animationen abschaltet.

http://www.winfaq.de/faq_html/Content/t ... ip0025.htm
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: MDI-ChildWindows - Größe managen

Beitrag von RSBasic »

N00B hat geschrieben:Echt guckt euch die PB Anleitung an.

http://www.purearea.net/pb/german/manua ... event.html

da steht nichts davon, daß mann Events wie Size Change abfragen kann, im Gegensatz zu WindowEvent()

http://www.purearea.net/pb/german/manua ... event.html
Das mag zwar sein, dass bei WaitWindowEvent() die Auflistung der möglichen Events fehlt, aber du kannst alle Eventtypen abfragen, egal ob du WindowEvent() oder WaitWindowEvent() benutzt.
Das sollte eigentlich klar und logisch sein, wenn laut Hilfe ein Ereignis/Event zurückgegeben wird, dass du #PB_Event_* abfragen kannst.
Danke, dass Du dir die Mühe gemacht hast und das Video für uns erstellt hast. :D
N00B hat geschrieben:ich hab mir wenigstens die Mühe gemacht, und jetzt habt ihr nichts besseres zutun als an meinem Code rumzumeckern.
Es ist ja auch sehr nett von dir, aber wir wollen dir auch nur helfen. Ich finde, ein gegenseitiges Helfen ist nicht schlimm, etwa du? ;)
Und außerdem habe ich nicht gemeckert, sondern ich habe nur versucht, dir gute Tipps zu geben.
N00B hat geschrieben:Und nein ich persönlich benutze kein EnableExplicit, daß macht mich tierisch Agro, ich brauch den
Käse nicht, nichts nervt mehr, als Beispiel Code erst mal nehmen zu müssen, und den ganzen Rotz zu modifizieren wegen diesem beknackten Explitit Zeug.
Es nervt mehr, wenn du versehentlich Schreibfehler o.ä. machst und du dich wunderst, warum ein Teil deines Codes nicht ordnungsgemäß funktioniert, weil du beispielsweise eine ganz andere Variable benutzt. Außerdem ist es sauberer und lesbarer für andere, vorallem wenn du Beispielcodes teilen möchtest.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
N00B
Beiträge: 122
Registriert: 11.07.2007 22:28

Re: MDI-ChildWindows - Größe managen

Beitrag von N00B »

RSBasic hat geschrieben:
N00B hat geschrieben:Echt guckt euch die PB Anleitung an.

http://www.purearea.net/pb/german/manua ... event.html

da steht nichts davon, daß mann Events wie Size Change abfragen kann, im Gegensatz zu WindowEvent()

http://www.purearea.net/pb/german/manua ... event.html
Das mag zwar sein, dass bei WaitWindowEvent() die Auflistung der möglichen Events fehlt, aber du kannst alle Eventtypen abfragen, egal ob du WindowEvent() oder WaitWindowEvent() benutzt.
Das sollte eigentlich klar und logisch sein, wenn laut Hilfe ein Ereignis/Event zurückgegeben wird, dass du #PB_Event_* abfragen kannst.
Ich halte mich strikt an die Anleitung :D ich hab nur nach Anleitung gelernt, und bis auf EnableExplicit (schon das Explicit zu schreiben ist voll die Tortur für mich 7 Finger System Tipper :lol: ) halte ich mich eigentlich immer an das was dort steht, desshalb bin ich nicht von ausgegangen das ich auch Events von WaitWindowEvent abfangen kann.

Dann verbessere ich mal den Code, nach diesem Post.
RSBasic hat geschrieben:
Danke, dass Du dir die Mühe gemacht hast und das Video für uns erstellt hast. :D
Nichts zu danken :D ging nicht anders, ich musste beweisen das die Aussage das mein Code nach paar Klicks abkackt, nicht sein kann. Das hat mich rasend gemacht, daß wirkt ja als währe ich nach 7 Jahren Coden noch ein absoluter Anfänger (das bin ich wenn es um Bits und Bytes geht :lol: )
RSBasic hat geschrieben:
N00B hat geschrieben:ich hab mir wenigstens die Mühe gemacht, und jetzt habt ihr nichts besseres zutun als an meinem Code rumzumeckern.
Es ist ja auch sehr nett von dir, aber wir wollen dir auch nur helfen. Ich finde, ein gegenseitiges Helfen ist nicht schlimm, etwa du? ;)
Und außerdem habe ich nicht gemeckert, sondern ich habe nur versucht, dir gute Tipps zu geben.
Ne finde das auch gut :allright: nur habt ihr erst geholfen, als ich vermeintlich schlechten Code geposted habe, ihr hattet ja viel länger schon Zeit es_91 (wars glaub ich) zu helfen, aber erst bei vermeintlich schlechtem Code, kamm was.
RSBasic hat geschrieben:
N00B hat geschrieben:Und nein ich persönlich benutze kein EnableExplicit, daß macht mich tierisch Agro, ich brauch den
Käse nicht, nichts nervt mehr, als Beispiel Code erst mal nehmen zu müssen, und den ganzen Rotz zu modifizieren wegen diesem beknackten Explitit Zeug.
Es nervt mehr, wenn du versehentlich Schreibfehler o.ä. machst und du dich wunderst, warum ein Teil deines Codes nicht ordnungsgemäß funktioniert, weil du beispielsweise eine ganz andere Variable benutzt. Außerdem ist es sauberer und lesbarer für andere, vorallem wenn du Beispielcodes teilen möchtest.
Die mach ich nicht :D (ich prüfe wirklich alles, wie ein paranoider auf Funktionalität) ja in den Kommentaren mach ich die, da die ja nichts kaputtmachen.

Sauberer und lesbarer ?

Ich finde EnableExplicit ist ne einzige Katastrophe wenn es um Lesbarkeit geht.

Viel mehr Zeilen, daß sieht schrecklich aus :D

Es bremst enorm aus.

Mann muss sich Jahre zuvor schon nenn Kopf machen, über Variablen die mann noch gar nicht benutzt, und ständig wieder an den Anfang vom Code springen.

Wenn mann

-keine Globalen Variablen benutzt
-alles was möglich ist in Proceduren auslagert

und ein gutes System für Variablen Bennenung hat, kann doch gar nichts mehr schief gehen :)

EDIT: So hab im Code das WindowEvent durch WaitWindowEvent ersetzt, und das Delay(1) rausgenommen, und ne Warnung in den Kommentaren zwecks 64 Bit Windows und GetAsyncKeyState_() reingemacht.

Auf Enable Explicit umzuschreiben, ist mir zu viel Aufwand, muss bald pennen gehen, und der Bart muss auch noch runter. Seh schon aus wie Chewbacca :lol:

EDIT2: Ok hab mal Enable Explicit in den Code reingemacht, daß hat mich 5 Minuten Schlaf gekostet.

EDIT3: Ok wieder editiert, hab jetzt GetAsyncKeyState_() komplett ausgebaut, und durch
AddKeyboardShortcut() ersetzt (natürlich hab ich die Option für HideMenu eingebaut, den Menüs sind hässlich und klauen nur Platz :D )somit sollte es auch unter 64Bit und jeglicher Windows Version ab NT4 problemlos laufen.

Es wird ja an keiner Stelle WinAPI Code benutzt.
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: MDI-ChildWindows - Größe managen

Beitrag von RSBasic »

N00B hat geschrieben:(schon das Explicit zu schreiben ist voll die Tortur für mich 7 Finger System Tipper :lol: )
Es gibt da so eine sehr hilfreiche Funktion, die sich Autovervollständigung nennt. ;)
N00B hat geschrieben:nur habt ihr erst geholfen, als ich vermeintlich schlechten Code geposted habe, ihr hattet ja viel länger schon Zeit es_91 (wars glaub ich) zu helfen, aber erst bei vermeintlich schlechtem Code, kamm was.
Ich wollte ja auch helfen, aber der Threadersteller wollte explizit nicht, dass man einen Beispielcode posten soll, sondern entweder Pseudocode oder Erklärung. Und da ich keine Zeit für große Erklärung hatte, gabs von mir auch keine Hilfe.
Wie ich jetzt sehe, hat es_91 seine Threadbeschreibung nachträglich geändert, aber vorher gab es noch folgende Bemerkung. Zitat aus dem Google Cache:
es_91 hat geschrieben:Bitte keinen Code! Wenn, dann Pseudocode, aber lieber Lösungsansätze. Geht schneller und spart euch Mühe.
N00B hat geschrieben:Viel mehr Zeilen, daß sieht schrecklich aus :D
Der Programmierer sieht aber nicht, was du für Variablen du definiert und initialisiert hast.
Was ist, wenn er eine vorhandene Variable wiederverwenden möchte? Muss er deinen ganzen Code durchsuchen, um eine bestimmte Variable finden zu können, die er vielleicht weiterverwenden kann?
Außerdem kannst du die Variablendefinition in eine separaten Include-Datei auslagern oder benutzerdefinierte Faltmarken anlegen.
N00B hat geschrieben:Es bremst enorm aus.
Was genau wird ausgebremst? Die Entwicklungszeit?
N00B hat geschrieben:Mann muss sich Jahre zuvor schon nenn Kopf machen, über Variablen die mann noch gar nicht benutzt, und ständig wieder an den Anfang vom Code springen.
Wenn du stets globale Variablen nutzt, dann ja, aber globale Variablen sollte man sowieso möglichst vermeiden.
N00B hat geschrieben:Auf Enable Explicit umzuschreiben, ist mir zu viel Aufwand
Wenn du EnableExplicit für deine Anwendungen nicht nutzt, dann ist es deine Sache und du kannst natürlich machen, was du willst, aber wenn man Codes veröffentlichen möchte, dann sollte man schon auf die Lesbarkeit, Wartbarkeit, Strukturierung und Sauberkeit des Codes achten.
Was ist aufwändiger? Wenn du einmal für alle User* EnableExplicit einbaust, damit jeder User deinen Code problemlos ohne Zusatzaufwand wiederverwenden kann, oder ist es insgesamt aufwändiger, wenn jeder einzelne User im Forum selber EnableExplicit einbauen muss, weil er selber EnableExplicit nutzt und alle Variablen einzeln und korrekt definieren muss?
*: Ja es kann möglich sein, dass jemand die gleiche Frage hat, die Forensuche nutzt und den geposteten Beispielcode verwendet.
N00B hat geschrieben:EDIT2: Ok hab mal Enable Explicit in den Code reingemacht, daß hat mich 5 Minuten Schlaf gekostet.
Danke für die nachträgliche Anpassung. So ist es schon besser. ;)
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
Bisonte
Beiträge: 2468
Registriert: 01.04.2007 20:18

Re: MDI-ChildWindows - Größe managen

Beitrag von Bisonte »

NOOB's Beispiel mal etwas anders und ohne flackern inkl. 64Bit Test ;)

Ich weiss : Bei 5.21 gehts doch mit Bind.... , bewusst drauf verzichtet, damit NOOB es auch testen kann 8)

Code: Alles auswählen

;:- Da kein OS genannt wurde, auf dem es lauffähig sein sollte,
;:- und N00B ein Beispiel gepostet hat, das eigentlich nur auf 
;:- Windows läuft, hier eine Windows Variante, die nicht flackert.

;:- PB Version : 5.21 (sollte aber auch mit 4.6 funktionieren)

EnableExplicit

;:- Die Variable, die das ganze steuert

Global AutoSize = #True

;:- Der WindowCallBack des MDI Fensters. Hier wird auf
;:- #WM_EXITSIZEMOVE reagiert. Solange die Variable AutoSize
;:- wahr ist (#TRUE) wird das Fenster wieder verändert.
;:- Und nebenbei noch #WM_DESTROY, um angehängte Daten zu löschen.

Procedure MDI_WindowCallback(hWnd, uMsg, wParam, lParam)
  
  ;:- da fragt sich manch einer, warum ein CallBack ? 
  ;:- In der EventLoop kann ich das doch auch...
  ;:- Das mag zwar jetzt funktionieren, aber 
  ;:- Sicherheit gibt es nicht, dass diese Events
  ;:- in der nächsten PB Version "durchgereicht"
  ;:- werden ! Im CallBack klappt das immer.
  
  Protected Result = #PB_ProcessPureBasicEvents
  Protected Window = GetProp_(hWnd, "PB_WINDOWID") - 1 ; Ermittelt die PB Window Nr. (Für ResizeWindow())
                                                       ; Wird von PB selbst erstellt 
  Protected MDIGadget = GetProp_(hWnd, "PB_MDIGADGET") ; Dieses haben wir selbst angehängt !
  
  Select uMSG
      
    Case #WM_DESTROY ; Fenster wird geschlossen, Beendet, oder sonstwie zerstört
      RemoveProp_(hWnd, "PB_MDIGADGET") ; Da wir das selbst reingeklebt haben, müssen wir das wieder selbst abkratzen.
      
    Case #WM_EXITSIZEMOVE ; Das Ereignis tritt erst auf, wenn der User die Maustaste loslässt
      If AutoSize = #True
        If IsWindow(Window) And IsGadget(MDIGadget)
          ResizeWindow(Window, 20, 20, GadgetWidth(MDIGadget) - 60, GadgetHeight(MDIGadget) - 80)
        EndIf
      EndIf
      
  EndSelect
  
  ProcedureReturn Result
  
EndProcedure

;:- Hiermit sollte man nun das MDI ChildWindow erstellen.
;:- Diese Prozedur hängt Daten an das ChildWindow, setzt
;:- den CallBack und wechselt die GadgetListe wieder zum
;:- Fenster auf dem das MDI Gadget erstellt wurde.

Procedure CreateMDIWindow(MDIGadget, ChildWindow, Title.s)
  
  Protected Result = #False
  Protected OldGadgetList = UseGadgetList(0)
  
  If IsGadget(MDIGadget)
    If GadgetType(MDIGadget) = #PB_GadgetType_MDI                  ; Ist das MDIGadget überhaupt ein solches ?
      Result = AddGadgetItem(MDIGadget, ChildWindow, Title)        ; weil sonst der Rückgabewert nicht funktioniert !
      If ChildWindow = #PB_Any : ChildWindow = Result : EndIf
      If IsWindow(ChildWindow)
        SetProp_(WindowID(ChildWindow), "PB_MDIGADGET", MDIGadget) ; Daten anhängen
        SetWindowCallback(@MDI_WindowCallback(), ChildWindow)      ; CallBack setzen
        UseGadgetList(OldGadgetList)                               ; Vorherige Gadgetliste setzen
      EndIf
    EndIf
  EndIf
  
  ProcedureReturn Result
  
EndProcedure

;:- Und nun geht das ganze in die Erprobung

Define Window, Event
Define Btn1, Btn2, MDI, ChildMDI

Window = OpenWindow(#PB_Any, 0, 0, 800, 600, "Autosize = On", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)

;:- Menu erstellen

If CreateMenu(0, WindowID(Window))
  MenuTitle("AutoSize (INDEX 0)")
  MenuItem(1,"Autosize = ON")
  MenuItem(2,"Autosize = OFF")
  MenuTitle("MDI ChildWindows (INDEX 1)")
  SetMenuItemState(0, 0, #True)
  SetMenuItemState(0, 1, #False)
EndIf
  
Btn1      = ButtonGadget(#PB_Any, 10, 10, 100, 20, "Test1")   ; Einfach nur ein Gadget
MDI       = MDIGadget(#PB_Any, 10, 40, 780, 520, 1, 70)       ; Das MDI Gadget
ChildMDI  = CreateMDIWindow(MDI, #PB_Any, "Child")            ; Das erste ChildWindow
Btn2      = ButtonGadget(#PB_Any, 300, 10, 100, 20, "Test2")  ; Hier der Test, auf welchem Fenster neue Gadgets landen

AddKeyboardShortcut(Window, #PB_Shortcut_F1, 0)

Repeat
  
  Event = WaitWindowEvent()
  
  Select Event
      
    Case #PB_Event_CloseWindow
      Select EventWindow()
        Case Window
          Break
        Case ChildMDI
          SetWindowState(ChildMDI, #PB_Window_Minimize) 
      EndSelect
      
    Case #PB_Event_Gadget
      If EventGadget() = Btn1 Or EventGadget() = Btn2
        Debug "Button :" + GetGadgetText(EventGadget())
        If EventWindow() <> Window
          Debug "Oh Falsches Fenster"
        EndIf
      EndIf
      
    Case #PB_Event_Menu 
      Select EventMenu()
        Case 0 ; Die F1 Taste wurde gedrückt
          If AutoSize = #False
            AutoSize = #True  
            SetMenuItemState(0, 1, #True)
            SetMenuItemState(0, 2, #False)
            SetWindowTitle(Window, "Autosize = ON")
          Else
            AutoSize = #False
            SetMenuItemState(0, 1, #False)
            SetMenuItemState(0, 2, #True)
            SetWindowTitle(Window, "Autosize = OFF")
          EndIf
          
        Case 1
          SetMenuItemState(0, 1, #True)
          SetMenuItemState(0, 2, #False)
          AutoSize = #True
          
        Case 2    
          SetMenuItemState(0, 1, #False)
          SetMenuItemState(0, 2, #True)
          AutoSize = #False
          
      EndSelect
      
  EndSelect
  
ForEver
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: MDI-ChildWindows - Größe managen

Beitrag von RSBasic »

Allgemein bezüglich des Vorhabens: Ich würds grundsätzlich ganz anders machen. Ich würde nicht ständig das Fenster resizen, wenn die Größe verändert wurde, sondern einfach die Möglichkeit entfernen, damit man die Größe überhaupt nicht mehr verändern kann. Erstens sieht der Benutzer dann, dass er die Größe nicht verändern kann/darf und zweitens gibt es kein Flackern, aber andauernd die Größe beim Resizen wiederherzustellen nach dem Motto "ich will das nicht, ich will meine Ursprungsgröße wieder haben, bitte bitte", finde ich, das sieht komisch aus, wenn die Anwendung dagegen ankämpft, die Größe zurückzusetzen.
N00B hat geschrieben:Es wird ja an keiner Stelle WinAPI Code benutzt.
Was aber nicht schlimm ist, weil MDIGadget() sowieso nur für Windows gibt.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
N00B
Beiträge: 122
Registriert: 11.07.2007 22:28

Re: MDI-ChildWindows - Größe managen

Beitrag von N00B »

Bisonte hat geschrieben:NOOB's Beispiel mal etwas anders und ohne flackern inkl. 64Bit Test ;)

Ich weiss : Bei 5.21 gehts doch mit Bind.... , bewusst drauf verzichtet, damit NOOB es auch testen kann 8)

Code: Alles auswählen

;:- Da kein OS genannt wurde, auf dem es lauffähig sein sollte,
;:- und N00B ein Beispiel gepostet hat, das eigentlich nur auf 
;:- Windows läuft, hier eine Windows Variante, die nicht flackert.

;:- PB Version : 5.21 (sollte aber auch mit 4.6 funktionieren)

EnableExplicit

;:- Die Variable, die das ganze steuert

Global AutoSize = #True

;:- Der WindowCallBack des MDI Fensters. Hier wird auf
;:- #WM_EXITSIZEMOVE reagiert. Solange die Variable AutoSize
;:- wahr ist (#TRUE) wird das Fenster wieder verändert.
;:- Und nebenbei noch #WM_DESTROY, um angehängte Daten zu löschen.

Procedure MDI_WindowCallback(hWnd, uMsg, wParam, lParam)
  
  ;:- da fragt sich manch einer, warum ein CallBack ? 
  ;:- In der EventLoop kann ich das doch auch...
  ;:- Das mag zwar jetzt funktionieren, aber 
  ;:- Sicherheit gibt es nicht, dass diese Events
  ;:- in der nächsten PB Version "durchgereicht"
  ;:- werden ! Im CallBack klappt das immer.
  
  Protected Result = #PB_ProcessPureBasicEvents
  Protected Window = GetProp_(hWnd, "PB_WINDOWID") - 1 ; Ermittelt die PB Window Nr. (Für ResizeWindow())
                                                       ; Wird von PB selbst erstellt 
  Protected MDIGadget = GetProp_(hWnd, "PB_MDIGADGET") ; Dieses haben wir selbst angehängt !
  
  Select uMSG
      
    Case #WM_DESTROY ; Fenster wird geschlossen, Beendet, oder sonstwie zerstört
      RemoveProp_(hWnd, "PB_MDIGADGET") ; Da wir das selbst reingeklebt haben, müssen wir das wieder selbst abkratzen.
      
    Case #WM_EXITSIZEMOVE ; Das Ereignis tritt erst auf, wenn der User die Maustaste loslässt
      If AutoSize = #True
        If IsWindow(Window) And IsGadget(MDIGadget)
          ResizeWindow(Window, 20, 20, GadgetWidth(MDIGadget) - 60, GadgetHeight(MDIGadget) - 80)
        EndIf
      EndIf
      
  EndSelect
  
  ProcedureReturn Result
  
EndProcedure

;:- Hiermit sollte man nun das MDI ChildWindow erstellen.
;:- Diese Prozedur hängt Daten an das ChildWindow, setzt
;:- den CallBack und wechselt die GadgetListe wieder zum
;:- Fenster auf dem das MDI Gadget erstellt wurde.

Procedure CreateMDIWindow(MDIGadget, ChildWindow, Title.s)
  
  Protected Result = #False
  Protected OldGadgetList = UseGadgetList(0)
  
  If IsGadget(MDIGadget)
    If GadgetType(MDIGadget) = #PB_GadgetType_MDI                  ; Ist das MDIGadget überhaupt ein solches ?
      Result = AddGadgetItem(MDIGadget, ChildWindow, Title)        ; weil sonst der Rückgabewert nicht funktioniert !
      If ChildWindow = #PB_Any : ChildWindow = Result : EndIf
      If IsWindow(ChildWindow)
        SetProp_(WindowID(ChildWindow), "PB_MDIGADGET", MDIGadget) ; Daten anhängen
        SetWindowCallback(@MDI_WindowCallback(), ChildWindow)      ; CallBack setzen
        UseGadgetList(OldGadgetList)                               ; Vorherige Gadgetliste setzen
      EndIf
    EndIf
  EndIf
  
  ProcedureReturn Result
  
EndProcedure

;:- Und nun geht das ganze in die Erprobung

Define Window, Event
Define Btn1, Btn2, MDI, ChildMDI

Window = OpenWindow(#PB_Any, 0, 0, 800, 600, "Autosize = On", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)

;:- Menu erstellen

If CreateMenu(0, WindowID(Window))
  MenuTitle("AutoSize (INDEX 0)")
  MenuItem(1,"Autosize = ON")
  MenuItem(2,"Autosize = OFF")
  MenuTitle("MDI ChildWindows (INDEX 1)")
  SetMenuItemState(0, 0, #True)
  SetMenuItemState(0, 1, #False)
EndIf
  
Btn1      = ButtonGadget(#PB_Any, 10, 10, 100, 20, "Test1")   ; Einfach nur ein Gadget
MDI       = MDIGadget(#PB_Any, 10, 40, 780, 520, 1, 70)       ; Das MDI Gadget
ChildMDI  = CreateMDIWindow(MDI, #PB_Any, "Child")            ; Das erste ChildWindow
Btn2      = ButtonGadget(#PB_Any, 300, 10, 100, 20, "Test2")  ; Hier der Test, auf welchem Fenster neue Gadgets landen

AddKeyboardShortcut(Window, #PB_Shortcut_F1, 0)

Repeat
  
  Event = WaitWindowEvent()
  
  Select Event
      
    Case #PB_Event_CloseWindow
      Select EventWindow()
        Case Window
          Break
        Case ChildMDI
          SetWindowState(ChildMDI, #PB_Window_Minimize) 
      EndSelect
      
    Case #PB_Event_Gadget
      If EventGadget() = Btn1 Or EventGadget() = Btn2
        Debug "Button :" + GetGadgetText(EventGadget())
        If EventWindow() <> Window
          Debug "Oh Falsches Fenster"
        EndIf
      EndIf
      
    Case #PB_Event_Menu 
      Select EventMenu()
        Case 0 ; Die F1 Taste wurde gedrückt
          If AutoSize = #False
            AutoSize = #True  
            SetMenuItemState(0, 1, #True)
            SetMenuItemState(0, 2, #False)
            SetWindowTitle(Window, "Autosize = ON")
          Else
            AutoSize = #False
            SetMenuItemState(0, 1, #False)
            SetMenuItemState(0, 2, #True)
            SetWindowTitle(Window, "Autosize = OFF")
          EndIf
          
        Case 1
          SetMenuItemState(0, 1, #True)
          SetMenuItemState(0, 2, #False)
          AutoSize = #True
          
        Case 2    
          SetMenuItemState(0, 1, #False)
          SetMenuItemState(0, 2, #True)
          AutoSize = #False
          
      EndSelect
      
  EndSelect
  
ForEver
Ja aber dein vermeintlicher Super Code der besser als meiner laufen soll, verwendet WinAPI Zeug, und da redest du von das sie besser auf jeder Variante laufen soll ?

So ein Schwachsinn !

1. Mein Code ist viiiiiiiiiiiiiiiiiiel kompakter und verständlicher, und sieht 100000 x besser aus, wenn ich das Case Zeugs schon sehe wird mir ganz schlecht.
2. Mein Code braucht keine WinAPI, versuch mal nenn Prozess per API ab Vista so zu beenden wie unter XP, geht nicht mehr, da braucht mann Code der für beides geht. (kann es bei Gelegenheit rauskrammen)
3. Mein Code funzt, und macht genau das was er machen soll, und flackern tut es nur deswegen, weil der 0815 User nicht diese dämmlichen Animationen beim Maximieren & Minimieren abstellt.

So und jetzt muss ich los in meine Spätschicht.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: MDI-ChildWindows - Größe managen

Beitrag von ts-soft »

Hier das ganze mit WindowsBounds-API :wink:
http://msdn.microsoft.com/en-us/library ... 85%29.aspx
Die Werte im MDI_WindowCallback bitte auf die Bedürfnisse anpassen.

Code: Alles auswählen

EnableExplicit

Global AutoSize = #True

Procedure MDI_WindowCallback(hWnd, uMsg, wParam, lParam)

  Protected Result = #PB_ProcessPureBasicEvents
  Protected mm.MINMAXINFO
 
  Select uMsg
    Case #WM_GETMINMAXINFO
      If AutoSize
        mm\ptMinTrackSize\x = 200
        mm\ptMinTrackSize\y = 200
        mm\ptMaxTrackSize\x = 720
        mm\ptMaxTrackSize\y = 500
        CopyMemory(@mm, lParam, SizeOf(MINMAXINFO))
        Result = 0
      EndIf
  EndSelect
 
  ProcedureReturn Result
EndProcedure

Procedure CreateMDIWindow(MDIGadget, ChildWindow, Title.s)
 
  Protected Result = #False
  Protected OldGadgetList = UseGadgetList(0)
 
  If IsGadget(MDIGadget)
    If GadgetType(MDIGadget) = #PB_GadgetType_MDI
      Result = AddGadgetItem(MDIGadget, ChildWindow, Title)
      If ChildWindow = #PB_Any : ChildWindow = Result : EndIf
      If IsWindow(ChildWindow)
        SetWindowCallback(@MDI_WindowCallback(), ChildWindow)
        UseGadgetList(OldGadgetList)
      EndIf
    EndIf
  EndIf
 
  ProcedureReturn Result
 
EndProcedure

;:- Und nun geht das ganze in die Erprobung

Define Window, Event
Define Btn1, Btn2, MDI, ChildMDI

Window = OpenWindow(#PB_Any, 0, 0, 800, 600, "Autosize = On", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)

;:- Menu erstellen

If CreateMenu(0, WindowID(Window))
  MenuTitle("AutoSize (INDEX 0)")
  MenuItem(1,"Autosize = ON")
  MenuItem(2,"Autosize = OFF")
  MenuTitle("MDI ChildWindows (INDEX 1)")
  SetMenuItemState(0, 0, #True)
  SetMenuItemState(0, 1, #False)
EndIf
 
Btn1      = ButtonGadget(#PB_Any, 10, 10, 100, 20, "Test1")   ; Einfach nur ein Gadget
MDI       = MDIGadget(#PB_Any, 10, 40, 780, 520, 1, 70)       ; Das MDI Gadget
ChildMDI  = CreateMDIWindow(MDI, #PB_Any, "Child")            ; Das erste ChildWindow
Btn2      = ButtonGadget(#PB_Any, 300, 10, 100, 20, "Test2")  ; Hier der Test, auf welchem Fenster neue Gadgets landen

AddKeyboardShortcut(Window, #PB_Shortcut_F1, 0)

Repeat
 
  Event = WaitWindowEvent()
 
  Select Event
     
    Case #PB_Event_CloseWindow
      Select EventWindow()
        Case Window
          Break
        Case ChildMDI
          SetWindowState(ChildMDI, #PB_Window_Minimize)
      EndSelect
     
    Case #PB_Event_Gadget
      If EventGadget() = Btn1 Or EventGadget() = Btn2
        Debug "Button :" + GetGadgetText(EventGadget())
        If EventWindow() <> Window
          Debug "Oh Falsches Fenster"
        EndIf
      EndIf
     
    Case #PB_Event_Menu
      Select EventMenu()
        Case 0 ; Die F1 Taste wurde gedrückt
          If AutoSize = #False
            AutoSize = #True 
            SetMenuItemState(0, 1, #True)
            SetMenuItemState(0, 2, #False)
            SetWindowTitle(Window, "Autosize = ON")
          Else
            AutoSize = #False
            SetMenuItemState(0, 1, #False)
            SetMenuItemState(0, 2, #True)
            SetWindowTitle(Window, "Autosize = OFF")
          EndIf
         
        Case 1
          SetMenuItemState(0, 1, #True)
          SetMenuItemState(0, 2, #False)
          AutoSize = #True
         
        Case 2   
          SetMenuItemState(0, 1, #False)
          SetMenuItemState(0, 2, #True)
          AutoSize = #False
         
      EndSelect
     
  EndSelect
 
ForEver
Dieses Beispiel ist für den Threadersteller, blafassel von NOOB unerwünscht.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Gesperrt