 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 01.07.2011, 01:17 Titel: Quadrat auswählen |
|
|
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 |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 01.07.2011, 01:44 Titel: |
|
|
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 |
|
 |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 01.07.2011, 10:46 Titel: |
|
|
Danke
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.  |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 01.07.2011, 10:48 Titel: |
|
|
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 |
|
 |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 01.07.2011, 11:14 Titel: |
|
|
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 |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 01.07.2011, 11:51 Titel: |
|
|
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 |
|
 |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 01.07.2011, 12:46 Titel: |
|
|
Danke.
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 )
Zuletzt bearbeitet von Westbeam am 01.07.2011, 13:00, insgesamt 2-mal bearbeitet |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 01.07.2011, 12:56 Titel: |
|
|
C Variablen sind bei mir meist Counter ... hab vergessen sie zu nutzen
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.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 01.07.2011, 13:08 Titel: |
|
|
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 |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 01.07.2011, 13:11 Titel: |
|
|
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 |
|
 |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 01.07.2011, 13:15 Titel: |
|
|
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  |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
|
Nach oben |
|
 |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 01.07.2011, 13:38 Titel: |
|
|
Ohohoh, du bist der Beste.
Ich wusste, dass es einfacher geht. Danke  |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 01.07.2011, 13:43 Titel: |
|
|
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 |
|
 |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 01.07.2011, 13:56 Titel: |
|
|
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 |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 01.07.2011, 13:59 Titel: |
|
|
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 |
|
 |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 01.07.2011, 14:03 Titel: |
|
|
Nun, dann bekomme ich immerhin schon einen "Segmentation fault".  |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
|
Nach oben |
|
 |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 01.07.2011, 14:08 Titel: |
|
|
Ich bekomme auch bei deinem Code einen Segmentation fault.  |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
|
Nach oben |
|
 |
|
|
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.
|
|