Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Quadrat auswählen
Gehe zu Seite 1, 2, 3, 4, 5  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Westbeam



Anmeldungsdatum: 22.12.2009
Beiträge: 760

BeitragVerfasst am: 01.07.2011, 01:17    Titel: Quadrat auswählen Antworten mit Zitat

Okay, meine Frage lässt sich im Titel schlecht unterbringen ...

Es geht um Folgendes: Ich schreibe an meiner OpenWIZ-GUI Version 3. Unter Anderem habe ich aktive und inaktive Fenster realisiert, sodass das aktive Fenster immer als erstes gezeichnet wird. Ein Fenster aktiviert man, indem man in das Fenster klickt. Das klappt soweit auch ganz gut, allerdings kann man ein anderes Fenster auch aktivieren, wenn es sich unter dem gerade aktiven Fenster befindet. Wenn man nun in das aktive Fenster klickt, aktiviert man damit das Fenster, was sich unter diesem befindet. Das ist doof, aber ich weiß auch nicht, wie ich dies ändern soll. Das ist mein Code, um ein Fenster zu ändern:
Code:
If (mx>win(id).x And mx<win(id).w+win(id).x) And (my>win(id).y And my<win(id).h+win(id).y) And mb=1 Then
   For i As Integer=1 To anz_win
      win(i).active=0
   Next
   win(id).active=1
End If

"win(id)" ist ein Array, in dem die Fenster als ein UDT deklariert werden.
In dem IF-Zusammenhang wird überprüft, ob sich die Maus im Fenster befindet und ob die Maus gedrückt wurde. Ist dies der Fall, werden alle Fenster für inaktiv erklärt, bis auf das, welches angeklickt wurde.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1839
Wohnort: [JN58JR]

BeitragVerfasst am: 01.07.2011, 01:44    Titel: Antworten mit Zitat

Das ganze nennt sich Z-Array oder Z-Liste.

Um so etwas zu realisieren brauchst du eigetnlich nicht viel ändern.

Du besitzt ein array oder eine linked list, welche die Fenstereigeneschaften besitzt.
dieses array oder linkedlist ist linear nach seinem erzeugen hin geordnet. sprich, fenster 1 = 1. eintrag, fenster 2. 2ter eintrag, usw.

um nun die reihenfolge dieser fenster zu ändern kannst du entweder simpel die einträge in der reihenfolge abändern und das aktuell im fokus liegende fenster immer ans ende der liste stellen, oder du fügst (wenn du ein array nutzt) eine 2te liste hinzu (Z-List) welche die pointer auf die entsprchenden eigenschaftsfelder speichert.

damit kannst du dann die pointer immer entsprechend anpassen.

sinvoll ist hier auch eine double linked list, um bei den "checks" für maus und tastatur-abfragen immer rückwerts durch das array laufen zu können.

schliesslich ist das letzte fenster in der list, das, welches ganz oben zu finden ist ( je nach aufbau und deinem gut dünken)

folglich musst du bei einem mausklick erstmal schauen, ob die maus auf dem obersten fenster ist (letztes in der Z), und wenn nicht, ob es das 2th. tiefste, und dann das 3., 4. usw.

beim zeichnen hingegen ist es umgedreht.
hier zeichnest du natürlich das am hinten liegenste zuerst (1.) dann das 2te das darüber liegt, usw. .. solange bis das letzte gezeichnet wird, und damit das oberste fenster bildet.

Hier mal ein mini-beispiel:
TWM.bas
winman.bi

twm erzeugt 2 fenster (siehe code)
winman verwaltet die fenster und wertet die ereignisse aus.

dieses Beispiel arbeitet mit arrays und einer Z-List.

natürlich kannst du auch linkedlists's nutzen (was bei grösseren projekten zu emfpehlen ist). wie es dir beliebt.

In der F_Form_SetFocus() Funktion (Zeile 248) wird die "umstrukturierung" der Z-List vorgenommen. Dort wird die Fenster-ID Reihenfolge so abgeändert, das bei allen anderen aufrufen wie z.B. Draw und Mouse ereignisse, entsprechend die Z-Reihenfolge genutzt wird, um die liste abzuarbeiten.


MfG
TPM
_________________
[ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Westbeam



Anmeldungsdatum: 22.12.2009
Beiträge: 760

BeitragVerfasst am: 01.07.2011, 10:46    Titel: Antworten mit Zitat

Danke zwinkern

Das schaut doch schon sehr kompliziert aus, aber dass ich etwas Linked-List ähnliches nutzen kann dachte ich mir bereits.

Zitat:
Um so etwas zu realisieren brauchst du eigetnlich nicht viel ändern.

Oh doch. Meine 40 Zeilen Code, die ich habe, um Fenster zu zeichnen und zu verwalten kommen gegen deine 608(!!) Zeilen nicht an. lachen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1839
Wohnort: [JN58JR]

BeitragVerfasst am: 01.07.2011, 10:48    Titel: Antworten mit Zitat

naja... die verwaltugn is wirklich nicht grossartig kompliziert. die .bi umfasst einfach nur mehr funktionen, die eigetnlich nciht viel mit Z zutun haben, z.B. controls, oder move und resize, drag, usw. .. das baucht man aber alles nicht für Z ordnung

is wirklich nicht weiter wild. Hatte nur keine lust fix was zu schreiben, darum hab ich n altes projekt geupt.

wenn was unklar is, einfach nochma fragen.


MfG
TPM
_________________
[ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Westbeam



Anmeldungsdatum: 22.12.2009
Beiträge: 760

BeitragVerfasst am: 01.07.2011, 11:14    Titel: Antworten mit Zitat

Ich komme aber auch mit den vielen Variablen mit (für mich) teils unverständlichen Namen nicht ganz zurecht. Dann noch ein paar Fragen, welche ich vielleicht gleich an deine Funktion "F_Form_SetFocus" erkläre:
Code:
Function F_Form_SetFocus(V_FID As Uinteger) As Integer
Mutexlock(G_FormMutex)
Dim XSID As Uinteger = 0
Dim XFID As Uinteger = 0
For X As Uinteger = 1 To G_FormC
    If G_FormZ(X) > 0 Then
        If G_FormD(G_FormZ(X)).V_FID = V_FID Then XFID = X: Exit For
    Else: If XSID = 0 Then XSID = X
    End If
Next
If XFID = 0 Then XFID = XSID
If XFID = 0 Then Mutexunlock(G_FormMutex): Return 0
If XFID = 1 And G_FormC > 1 Then Mutexunlock(G_FormMutex): Return V_FID
For X As Uinteger = XFID - 1 To 1 Step -1
    G_FormZ(X + 1) = G_FormZ(X)
Next
G_FormZ(1) = V_FID
Mutexunlock(G_FormMutex)
F_Form_Redraw(V_FID)
Return V_FID
End Function

1. Benötige ich die Mutexen?
2. Wo genau wird einem Fenster der Zustand "aktiviert" gegeben?
3. Wo und wie wird das Z-Array deklariert?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1839
Wohnort: [JN58JR]

BeitragVerfasst am: 01.07.2011, 11:51    Titel: Antworten mit Zitat

ok

hier n besseres, beschriftetes, beispiel: http://ops.ath.cx/code?id=115
Dieses is mithilfe einer LinkedList (is schneller und praktischer) und wohl eher für dich geeigent. (darfst gerne weiterverwenden oder deinen bedürfnissen anpassen (lizens: Do what the fuck u want)

Mutexe: nein, nicht wenn du keine threads einsetzen willst. Mit Threads, wäre es sehr snivoll, kann aber problematisch werden im zusammenhang mit inkey und getmouse, da diese nicht threadsafe sind.


MfG
TPM
_________________
[ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Westbeam



Anmeldungsdatum: 22.12.2009
Beiträge: 760

BeitragVerfasst am: 01.07.2011, 12:46    Titel: Antworten mit Zitat

Danke. lächeln

Aber dennoch eine Frage, was macht in diesem Code die Variable "G_FormC" ? Der Variablenname gibt leider keinen Hinweis(Vielleicht änderst du mal die Art und Weise, wie du Variablen nennst, damit der Code besser lesbar ist. Nur ein Vorschlag zwinkern )


Zuletzt bearbeitet von Westbeam am 01.07.2011, 13:00, insgesamt 2-mal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1839
Wohnort: [JN58JR]

BeitragVerfasst am: 01.07.2011, 12:56    Titel: Antworten mit Zitat

C Variablen sind bei mir meist Counter ... hab vergessen sie zu nutzen durchgeknallt
Wollte die eigentlich als Form-Counter nutzen, um einfach zu ermitteln, wie viele Formen vorhanden sind, aber da ich keine Lösch und GetFormCount funktion hab, und das auch nur n beispiel is, macht es das eigentlich ziemlich überflüssig.

kannste getrost löschen und ignorieren. zwinkern


MfG
TPM
_________________
[ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Westbeam



Anmeldungsdatum: 22.12.2009
Beiträge: 760

BeitragVerfasst am: 01.07.2011, 13:08    Titel: Antworten mit Zitat

Okay.

Noch eine Frage...
Gibt es möglicherweise noch eine andere Möglichkeit? PuppetMasters Vorschlag ist zwar gut und funktioniert auch, allerdings müsste ich meinen eigenen ganzen Code so stark verändern, wenn nicht sogar durch PuppetMasters Code ersetzen, dass nichts mehr von meinem übrig bleibt. Es geht einfach nicht, seinen Code in meinen zu integrieren. Es ist schlichtweg unmöglich, meine Fenster im Programm so zu erstellen, wie ich es ursprünglich geplant habe.

Wenn es hilft, so sieht mein Code aus:

Code:
#Define Quit Inkey=CHR(255,107)
Dim Shared As Integer mx,my,mb,anz_win

Type WizWindow
   As Integer id
   As String title
   As Integer active
   As Integer x
   As Integer y
   As Integer w
   As Integer h
End Type

Dim Shared As WizWindow win(50000)

Declare Sub InitGUI()
Declare Sub DrawGadgets()
Declare Sub DrawWindow(id As Integer)

Screenres 640,480,32
InitGUI()

With win(1)
   .id=1
   .title="Testwindow"
   .active=1
   .x=100
   .y=50
   .w=400
   .h=300
End With
anz_win+=1

With win(2)
   .id=1
   .title="Testwindow2"
   .active=0
   .x=120
   .y=100
   .w=400
   .h=300
End With
anz_win+=1

Do
   Getmouse mx,my,,mb
   Sleep 10,1
   Screenlock
      Cls
      Line (0,0)-(640,480),&h376ea5,BF
      DrawGadgets()
   Screenunlock
Loop Until Quit
End

Sub InitGUI()
   With win(3)
      .id=0
      .title=""
      .active=0
      .x=0
      .y=0
      .w=0
      .h=0
   End With
   anz_win+=1
End Sub

Sub DrawGadgets()
   For i As Integer=1 To anz_win
      If win(i).id=1 Then DrawWindow(i)
      If win(i).active=1 Then
         win(3).id=1
         win(3).title=win(i).title
         win(3).active=1
         win(3).x=win(i).x
         win(3).y=win(i).y
         win(3).w=win(i).w
         win(3).h=win(i).h
      End If
      DrawWindow(3)
   Next
End Sub

Sub DrawWindow(id As Integer)
   If win(id).active=1 Then
      Line (win(id).x,win(id).y)-(win(id).w+win(id).x,win(id).h+win(id).y),&hFFFFFF,BF
      Line (win(id).x,win(id).y)-(win(id).w+win(id).x,win(id).h+win(id).y),&h000000,B
   Else
      Line (win(id).x,win(id).y)-(win(id).w+win(id).x,win(id).h+win(id).y),&hc0c0c0,BF
      Line (win(id).x,win(id).y)-(win(id).w+win(id).x,win(id).h+win(id).y),&h000000,B
   End If
   If (mx>win(id).x And mx<win(id).w+win(id).x) And (my>win(id).y And my<win(id).h+win(id).y) And mb=1 Then
      For i As Integer=1 To anz_win
         win(i).active=0
      Next
      win(id).active=1
   End If
End Sub
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1839
Wohnort: [JN58JR]

BeitragVerfasst am: 01.07.2011, 13:11    Titel: Antworten mit Zitat

sag doch das du array's nutzt ..

aber, dein Beispiel funzt doch?!? .. wo genau liegt denn dein Problem?

EDIT
Hat sich erledigt! habs gecheckt


MfG
TPM
_________________
[ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Westbeam



Anmeldungsdatum: 22.12.2009
Beiträge: 760

BeitragVerfasst am: 01.07.2011, 13:15    Titel: Antworten mit Zitat

In meinem ersten Post habe ich gesagt, dass ich Arrays nutze:
Ich hat Folgendes geschrieben:
"win(id)" ist ein Array, in dem die Fenster als ein UDT deklariert werden.

Sry verlegen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1839
Wohnort: [JN58JR]

BeitragVerfasst am: 01.07.2011, 13:31    Titel: Antworten mit Zitat

ups .. hab ich wohl übersehen. .. Sry!

so .. hier jetzt deinen code, etwas aufgemotzt:

einmal mit reinem select, und ohne focus: http://ops.ath.cx/code?id=116
und einmal mit select UND focus: http://ops.ath.cx/code?id=117


MfG
TPM
_________________
[ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Westbeam



Anmeldungsdatum: 22.12.2009
Beiträge: 760

BeitragVerfasst am: 01.07.2011, 13:38    Titel: Antworten mit Zitat

Ohohoh, du bist der Beste. happy
Ich wusste, dass es einfacher geht. Danke zwinkern
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1839
Wohnort: [JN58JR]

BeitragVerfasst am: 01.07.2011, 13:43    Titel: Antworten mit Zitat

naja.. einfacher schon ... aber, deine variante mit dem predef 50000 des array's is ganz schön speicherfressend.

du könntest hier, zum schonen, z.B. folgendes nutzen:

Code:
Dim Shared As WizWindow win()
Dim Shared As UInteger winZ()
'...
dim shared anz_alloc as uinteger
Sub WinAdd()
   anz_win+=1
   if anz_win > anz_alloc then
      anz_alloc += 25
      redim Preserve win(anz_alloc) as WizWindow
      redim Preserve winZ(anz_alloc) as UInteger
   end if
   With win(anz_win)
   .id=1
   .title="Testwindow-" & Str(anz_win)
'   .active=0               'brauchste nicht -> siehe: winActive
   .x=anz_win * 25
   .y=anz_win * 25
   .w=300
   .h=200
   End With
   winZ(anz_win) = anz_win
End Sub


damit erzeugst du, wenn der speicher zu gering ist, immer 25 neue einträge auf einmal.
das spart massig resourcen, und auch etwas zeit beim erzeugen. Beschleunigt das ganze, und nur alle jeweils 25 neuen fenstern kann es kurz stocken.


MfG
TPM
_________________
[ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Westbeam



Anmeldungsdatum: 22.12.2009
Beiträge: 760

BeitragVerfasst am: 01.07.2011, 13:56    Titel: Antworten mit Zitat

Dann bekomme ich folgenden Fehler:
Code:
Duplicated definition, win in 'redim Preserve win(anz_alloc) as WizWindow'
Duplicated definition, winZ in 'redim Preserve winZ(anz_alloc) as UInteger'
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1839
Wohnort: [JN58JR]

BeitragVerfasst am: 01.07.2011, 13:59    Titel: Antworten mit Zitat

du musst natürlich die zeilen
Code:

Dim Shared As WizWindow win(50000)
Dim Shared As UInteger winZ(50000)

durch diese hier ersetzten
Code:

Dim Shared As WizWindow win()
Dim Shared As UInteger winZ()


also .. die 50000 raus nehmen. sonst funzt es nicht.


MfG
TPM
_________________
[ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Westbeam



Anmeldungsdatum: 22.12.2009
Beiträge: 760

BeitragVerfasst am: 01.07.2011, 14:03    Titel: Antworten mit Zitat

Nun, dann bekomme ich immerhin schon einen "Segmentation fault". verwundert
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1839
Wohnort: [JN58JR]

BeitragVerfasst am: 01.07.2011, 14:06    Titel: Antworten mit Zitat

also .. bei mir funzt es ... http://ops.ath.cx/code?id=118


MfG
TPM
_________________
[ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Westbeam



Anmeldungsdatum: 22.12.2009
Beiträge: 760

BeitragVerfasst am: 01.07.2011, 14:08    Titel: Antworten mit Zitat

Ich bekomme auch bei deinem Code einen Segmentation fault. traurig
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1839
Wohnort: [JN58JR]

BeitragVerfasst am: 01.07.2011, 14:10    Titel: Antworten mit Zitat

ups .. falschen code geupt! verlegen

http://ops.ath.cx/code?id=119


MfG
TPM
_________________
[ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Gehe zu Seite 1, 2, 3, 4, 5  Weiter
Seite 1 von 5

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz