Eventschleifen, wie oft? [ERLEDIGT]

Grafische Primitive, XbaseParts und Darstellungsfragen allgemein.

Moderator: Moderatoren

Antworten
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Eventschleifen, wie oft? [ERLEDIGT]

Beitrag von Manfred »

Hi,

ich habe hier jetzt mehrfach gelesen (oder es so verstanden), das man pro Anwendung nur eine Eventschleife für die Abfrage benutzen soll.
Hm, ich merke ich denke immer noch in GET und READ unter Clipper. Es fehlt mir der nötige Hinweis dazu: Wie klappt das denn? Wenn ich jetzt in eine andere Funktion verzweige und dort eine Maske mit SLE aufbaue und danach ein Destroy(), dann wird doch alles druchlaufen und das Bild verschwindet sofort wieder. Woher weiß das Programm, dass es jetzt in der Eventschleife warten muß? Ich laufe jetzt hier im Kreis und der Fußboden sieht auch schon entsprechend abgewetzt aus.
Zuletzt geändert von Manfred am Di, 09. Jun 2009 12:56, insgesamt 1-mal geändert.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo Manfred,

nicht so kompliziert denken ;-)

Das die Events erfasst werden, darum kümmert sich Windows.
In der Eventschleife (1 x je GUI Thread) wird auf einen Event gewartet (nEvent := AppEvent ...) und danach wird mit oXbp:handleevent() darauf reagiert. Dieses kann dann z.B. ein neues Fenster aufbauen und SLE anzeigen (ohne destroy(), wir wollen ja was eingeben). Nach dem Anzeigen (INIT, CREATE ...) des neuen Dialoges ist der Code erstmal komplett durch und das Programm wartet wieder in der Eventloop in (nEvent := AppEvent ...).

Wenn nun bei HandleEvent() ein neuer Thread aufgemacht wird, der z.B. ein Fenster anzeigt, dann sollte (muss ?) dieser Thread auch eine Eventloop haben ... da ich aber nur Threads für lange Jobs (Durchsuchen, Ändern, Drucken etc. ohne Interaktion mit dem User) verwende habe ich mit 2 Loops keine Erfahrung.

Wenn man 2 Loops in einem Thread aufmacht, kann man nicht genau wissen in welchem Loop sich das Programm genau aufhält.
Gruß
Hubert
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Hubert,

stop, das war jetzt etwas falsch verstanden, oder falsch ausgedrückt von mir. Das Destroy() ist ja schon notwenig um alles nach der Benutzung wieder freizugeben. Meine Frage war jetzt nun, irgendwann muß ja das Destroy kommen und das Programm muß wissen: So, jetzt kommt die Eingabe, die Eingabe ist vorbei und jetzt gehe weiter und mache ein Destroy().

Ich baue die Maske auf mit Static
dann baue ich die Bezeichnungen mit Static
und dann die SLE dazu.

Ich kann im Moment nicht entdecken, wo und wie das Programm jetzt abwartet, bis die SLE benutzt und dann nicht mehr benutzt werden.

Ich weiß nicht wie ich mich hier und jetzt ausdrücken soll, ich weiß nur, dass ich es nicht so ganz verstehe.....

Oder muß ich erst irgendeinen Pushbutton einbauen, der das Programm dort stoppt? Kann doch auch nicht sein, oder?
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Manfred hat geschrieben:Ich baue die Maske auf mit Static
dann baue ich die Bezeichnungen mit Static
und dann die SLE dazu.

Ich kann im Moment nicht entdecken, wo und wie das Programm jetzt abwartet, bis die SLE benutzt und dann nicht mehr benutzt werden.
Schau dir doch mal den Code an.

Es gibt dort KEIN READ !

Das Fenster wird angezeigt (INIT, CREATE) und es gibt keinen Wartezustand außer AppEvent() in der Eventloop (darum heist die ja so).

Wenn du nun eine Taste drückst oder auf Close klickst gibt das einen Event der in der Eventloop über oXbp:handleevent(...) an das Control oder Fenster weitergereicht und dort bearbeitet wird, aber keinen Wartezustand ! Wenn du dort aber z.B. eine Endlosschleife oder eine sehr lange Schleife aufmachst, kommt der Computer nicht schnell genug in die Eventloop zurück und dein Programm ist 'eingefroren'.

Falls du aber einen MODALEN Dialog willst, also ein Fenster geht auf und soll den Rest des Programmes blockieren, dann braucht dieses - zumindest früher - eine eigene Eventloop(), heute kann man auch die Eigenschaft des Fensters auf Modal stellen ( oDlg:showModal() ), dann kümmert sich Xbase selbst darum.
Gruß
Hubert
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Hubert,

danke, ich bin ein Kotelett, total bekloppt. Ich erwähnte oben, ich denke noch zeilenweise. Ich Depp habe alles aufgebaut und dann dahinter ein Detroy() gemacht für den Fall der Fälle. Aber es läuft ja ganz anders. Mit dem X Button, oder anderen Pushbotten verlasse ich ja das Eingabefenster und rufe damit ein Destroy() oder sonstwas auf. Ich hatte jetzt im Kopf, dass es so läuft wie unter CLipper, nix tun und die Maske wird automatisch geschlossen.
tsetsetse.

Aber das mit dem Modal muß ich mir nochmal angucken.....
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14659
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Beitrag von Jan »

Hallo Manfred,

wie gut kann ich Deine Verwirrung vestehen! Ich hatte und habe immer noch damit auch massivst zu kämpfen. Daher vielleicht noch eine Bemerkung, damit Du Dir das nicht zu kompliziert machst: Da ja die GUI-Elemente (Statics, SLEs, Browses, etc.) den oDlg:drawingarea als Parent haben, brauchst Du auch nur den zu destroyen. Der nimmt dann den ganzen Rest mit. Zusätzlich manuell destroyen musst Du nur Sachen, die eben nicht diesen Parent haben, wie etwa Presentation-Spaces zum Drucken.

Du kannst übrigens recht gut kontrollieren, ob Du sauber destroyd hast. Binde mal die memwatch.dll ein. Die gibt Dir dann automatisch genau an, ob Du nach dem verlassen eines Dialoges wieder genau so wenig Elemente hast wie vorher.

Und eine Weiterführung einer kurzen Bemerkung von Hubert: Er schrieb "je GUI-Thread". Wenn Du also Threads programmierst, dann bekommt jeder diser Threads doch noch seine eigene Event-Schleife.

Jan
Benutzeravatar
Rolf Ramacher
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1931
Registriert: Do, 09. Nov 2006 10:33
Wohnort: Bergheim
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Rolf Ramacher »

Hi Manfred,

ich gebe dir mal einen Code von mir:

Code: Alles auswählen

#include "Gra.ch"
#include "Xbp.ch"
#include "Appevent.ch"
#include "Font.ch"
#include "Set.Ch"
#include "Inkey.Ch"
 
#Define CRLF Chr(13)+Chr(10)

PROCEDURE Main
   LOCAL nEvent, mp1, mp2, nKey, oStatic, aSpwatch
   LOCAL oDlg, oXbp, drawingArea, aEditControls := {}
	Local aFelder:={}, aDb:={}
	
		
	AAdd(aDb,"spkonst")

	// Aktualisierung Spwatch.Dbf
 	aSpwatch:={"Konstanten","Untern.Anschrift","E","",0}
	AnhangSpwatch(aSpwatch)

	use Spkonst New
	AAdd(aFelder,{"firma",Spkonst->Firma})
	AAdd(aFelder,{"str",Spkonst->Str})
	AAdd(aFelder,{"ort",Spkonst->Ort})
	AAdd(aFelder,{"plz",Strzero(Spkonst->Plz,5)})
	AAdd(aFelder,{"tel",Spkonst->Telefon})
	AAdd(aFelder,{"fax",Spkonst->Fax})
	AAdd(aFelder,{"ustid",Spkonst->UstId})
	Close Spkonst

   oDlg := XbpDialog():new( AppDesktop(), , {50,150}, {700,300}, , .F.)
   oDlg:taskList := .T.
   oDlg:title :="Eingabe Unternehmen Anschrift"
	oDlg:sysmenu:=.f.
   oDlg:create()

   drawingArea := oDlg:drawingArea
   drawingArea:setFontCompoundName( "9.Arial" )

	oStatic := XbpStatic():new( drawingArea,, {10, 230},  {50, 20} ) 
	oStatic:options := XBPSTATIC_TEXT_LEFT 
	oStatic:caption := "Name"
	oStatic:Create()

	oXbp := XbpSLE():new( drawingArea, , {80,230}, {200,20}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } } )
	oXbp:tabStop := .T.
	oXbp:dataLink := {|x| IIf( x==NIL, aFelder[1][2], aFelder[1][2] := x ) } 
	oXbp:create()
	oXbp:SetData()
	oXbp:killInputFocus:={ |x,y,oSLE| oSLE:getData()  } 

	oStatic := XbpStatic():new( drawingArea,, {320, 230},  {50, 20} ) 
	oStatic:options := XBPSTATIC_TEXT_LEFT 
	oStatic:caption := "Strasse"
	oStatic:Create()

	oXbp := XbpSLE():new( drawingArea, , {390,230}, {200,20}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } } )
	oXbp:tabStop := .T.
	oXbp:dataLink := {|x| IIf( x==NIL, aFelder[2][2], aFelder[2][2] := x ) } 
	oXbp:create()
	oXbp:SetData()
	oXbp:killInputFocus:={ |x,y,oSLE| oSLE:getData()  } 

	oStatic := XbpStatic():new( drawingArea,, {10, 200},  {50, 20} ) 
	oStatic:options := XBPSTATIC_TEXT_LEFT
	oStatic:caption := "Ort"
	oStatic:Create()

	oXbp := XbpSLE():new( drawingArea, , {80,200}, {200,20}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } } )
	oXbp:tabStop := .T.
	oXbp:dataLink := {|x| IIf( x==NIL, aFelder[3][2],aFelder[3][2] := x ) } 
	oXbp:create()
	oXbp:SetData()
	oXbp:killInputFocus:={ |x,y,oSLE| oSLE:getData()  } 

	oStatic := XbpStatic():new( drawingArea,, {10, 140},  {50, 20} ) 
	oStatic:options := XBPSTATIC_TEXT_LEFT
	oStatic:caption := "Telefon"
	oStatic:Create()

	oXbp := XbpSLE():new( drawingArea, , {80,140}, {200,20}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } } )
	oXbp:tabStop := .T.
	oXbp:dataLink := {|x| IIf( x==NIL, aFelder[5][2],aFelder[5][2] := x ) } 
	oXbp:create()
	oXbp:SetData()
	oXbp:killInputFocus:={ |x,y,oSLE| oSLE:getData()  } 

	oStatic := XbpStatic():new( drawingArea,, {10, 170},  {50, 20} ) 
	oStatic:options := XBPSTATIC_TEXT_LEFT
	oStatic:caption := "Telefax"
	oStatic:Create()

	oXbp := XbpSLE():new( drawingArea, , {80,170}, {200,20}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } } )
	oXbp:tabStop := .T.
	oXbp:dataLink := {|x| IIf( x==NIL, aFelder[6][2],aFelder[6][2] := x ) } 
	oXbp:create()
	oXbp:SetData()
	oXbp:killInputFocus:={ |x,y,oSLE| oSLE:getData()  } 

	oStatic := XbpStatic():new( drawingArea,, {320, 200},  {50, 20} ) 
	oStatic:options := XBPSTATIC_TEXT_LEFT
	oStatic:caption := "Plz"
	oStatic:Create()

	oXbp := XbpSLE():new( drawingArea, , {390,200}, {50,20}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } } )
	oXbp:tabStop := .T.
	oXbp:bufferLength:=5 
	oXbp:dataLink := {|x| IIf( x==NIL, aFelder[4][2],aFelder[4][2] := x ) } 
	oXbp:create()
	oXbp:SetData()
	oXbp:killInputFocus:={ |x,y,oSLE| oSLE:getData()  } 

	oStatic := XbpStatic():new( drawingArea,, {320, 170},  {60, 20} ) 
	oStatic:options := XBPSTATIC_TEXT_LEFT
	oStatic:caption := "UST-IDNR"
	oStatic:Create()

	oXbp := XbpSLE():new( drawingArea, , {390,170}, {120,20}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } } )
	oXbp:tabStop := .T.
	oXbp:dataLink := {|x| IIf( x==NIL, aFelder[7][2],aFelder[7][2] := x ) } 
	oXbp:create()
	oXbp:SetData()
	oXbp:killInputFocus:={ |x,y,oSLE| oSLE:getData()  } 

   oXbp := XbpPushButton():new( drawingArea, , {350,20}, {100,20}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } } )
   oXbp:caption := "Abbruch"
   oXbp:tabStop := .T.
	oXbp:default:=.t.
   oXbp:create()
   oXbp:activate := {|| Freigabe(aDb),oDlg:destroy(),PostAppEvent( xbeP_Close )  }

   oXbp := XbpPushButton():new( drawingArea, , {470,20}, {100,20}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } } )
   oXbp:caption := "Speichern"
   oXbp:tabStop := .T.
	oXbp:default:=.t.
   oXbp:create()
   oXbp:activate := {||  Freigabe(aDb),Speichern(aFelder,"untanschrift",aSpwatch),oDlg:destroy(),PostAppEvent( xbeP_Close ) }
 
   oDlg:show()
   SetAppFocus(oDlg)

   nEvent := xbe_None
   DO WHILE nEvent <> xbeP_Close
      nEvent := AppEvent( @mp1, @mp2, @oXbp )
      oXbp:handleEvent( nEvent, mp1, mp2 )
   ENDDO
RETURN
Wie du siehst wird zuerst das Array mit entsprechenden Daten befüllt und danach alle Datenbanken geschlossen. Danach erfolgt der Maskenaufbau mit den SLE-Feldern und den STatics.

Der "event-Handle" zum schluss sorgt für die Anzeige auf dem Bildschirm.
Bei den Pushbuttons erfolgt die Aktion, daß der Dialog geschlossen wird.

Bei weiteren Untermenüs habe ich noch den "alten"-Dialog - also oParent
den ich dann enable() wieder freigebe und mit SetAppFocus(oParent) wieder den aktuellen Focus gebe.

Ist es jetzt etwas klarer ? Am Dienstag kann ich es dir nochmals zeigen.
Gruß Rolf

Mitglied der Gruppe XUG-Cologne
www.xug-cologne.de
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hm,

ein weiteres Problem. (Für mich jedenfalls)

Ich habe einen Hauptdialog, in dem oben ein Menue vorhanden ist, über das ich dann eine Maske aufrufe, die in dem Hauptdialog erscheint.

So weit so gut.

In der Maske sind Pushbutton, die ich gerade versuche über den SCManage mit Hot Keys zu steuern. Wenn ich jetzt aber die Alt Taste drücke, dann werden die Menues im Hauptdialog aktiviert. Das wollte ich aber eigentlich nicht haben. Es sollten die Hotkeys in der neuen Maske aktiv werden.

Wo liegt hier mal wieder mein Denkfehler?
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14659
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Beitrag von Jan »

Hallo Manfred,

das erinnert mich ganz enorm an ein Problem, mit dem ich zu kämpfen hatte :? .

Du musst die ALT-Taste umbiegen. Das machst Du in der Event-Schleife. Du musst den Standard-Event abfangen und das von Dir gewünschte Ereignis reinpacken.

Das hier ist meine Hauptschleife:

Code: Alles auswählen

DO WHILE .T.
   nEvent := AppEvent(@mp1, @mp2, @oEventXbp)

   // Für einige XBase-Parts ein anderes Tastaturverhalten einsetzen
   IF nEvent == xbeP_Keyboard //Ist das überhaupt ein Tastaturevent? Ansonsten aus Performancegründen die ganze Schleife überspringen
      IF mp1 = xbeK_ENTER                                     // Ist das ein Enter? Darum geht es schließlich.
         IF oEventXbp:isDerivedFrom("XBPPUSHBUTTON")          // Ist das ein Pushbutton?
            PostAppEvent(xbeP_Activate, NIL, NIL, oEventXbp)  // Dann auslösen, wie mit Leertaste
          ELSEIF oEventXbp:isDerivedFrom("XbpBrowse")         // Ist das eine Browse-Spalte?
            PostAppEvent(xbeK_RIGHT, NIL, NIL, oEventXbp)     // Dann in die nächste Spalte springen, wie mit PfeilRechts
         ENDIF
       ELSEIF mp1 = xbeK_ALT_F4                               // Möchte jemand das Programm mit Alt F4 beenden?
         mp1 := xbeK_ALT                                      // Das Menü aktivieren
      ENDIF
   ENDIF

   oEventXbp:handleEvent(nEvent, mp1, mp2)
ENDDO
Und so sieht das in jedem Thread aus, jeder Thread hat eine andere Tastenbelegung bei mir, hier für F2 - F12.

Code: Alles auswählen

DO WHILE .T.
   nEvent := AppEvent(@mp1, @mp2, @oXbp)
   DO CASE
      CASE nEvent = xbe_None
      CASE nEvent = xbeP_Keyboard .AND. ;
                    (mp1 == xbeK_F2 .OR. mp1 == xbeK_F3 .OR. mp1 == xbeK_F4 .OR. mp1 == xbeK_F5 .OR. mp1 == xbeK_F6 .OR. ;
                     mp1 == xbeK_F7 .OR. mp1 == xbeK_F8 .OR. mp1 == xbeK_F9 .OR. mp1 == xbeK_F10 .OR. mp1 == xbeK_F11 .OR. mp1 == xbeK_F12)
           Checkkeys(mp1, aoBut, oXbp)
      OTHERWISE
           oXbp:handleEvent(nEvent, mp1, mp2)
      END
ENDDO
Dazu gehört noch die Funktion Checkkeys, die dann die Tastaturkürzel-Funktionen ausführt.

Du musst das natürlich an Deine Gegebenheiten anpassen, das soll nur ein Beispiel sein.

Jan
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

so wie es aussieht, klappt es auch so. Mal testen, welche Probleme auf mich warten könnten.

Das Menue wird zwar aktiviert, aber dann muß ich halt sehen, dass ich mit den HotKeys entsprechend aufpasse.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo Manfred,

ich kenne jetzt dein Programm nicht, aber eigentlich ist es normal, dass das Hauptmenü aufgerufen wird, wenn man in einem MDI Child die ALT Taste drückt, da MDI childs keine eigenen Menüs haben sondern nur das Hauptmenü.
Gruß
Hubert
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Hubert,

für Dich ist das normal, ich wandere hier immer noch auf Entdeckerpfaden und muß mehr oder weniger "learning by burning" anwenden...

Jetzt muß ich einmal austesten, was passiert, wen mehrere Unterfenster mit den Hotkeys offen sind. Wer weiß was mich da jetzt erwartet.

Ist allerdings ein wenig blöde sowas. Wenn ich da an andere Programme denke, die scheinen das wohl alles von Hause aus zu können.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Gerd König
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 193
Registriert: Fr, 09. Jun 2006 7:52
Wohnort: Nähe Sömmerda

Beitrag von Gerd König »

Hallo Manfred,

in meinem Programm kann es eine zweite Eventschleife geben, dann wird allerdings die Schleife in der Main-Prozedur nicht verwendet.

Beispiel:

Ich habe eine eigene Messagebox programmiert, wo der Meldungstext in einem MLE angezeigt wird und damit teilweise oder vollständig in die Zwischenablage kopert werden kann und die Größe der Messagebox unabhängig von der Textlänge an den Parent bzw den Desktop angepaßt werden kann.

Dieses Messagefenster hat eine eigene Schleife, die verlassen wird, wenn die Taste <OK> des Messagefensters oder die Eingabetaste (oder falls gewünscht irgendeine Taste) gedrückt wird.

Das gleiche Konzept habe ich auch z.B. für folgende Funktionalitäten verwendet:
Confirmbox mit "Ja", "Nein"

Confirmbox mit den Tasten <cText1>, <cText2> und "Abbrechen"

Fenster für bisher noch nicht in den Datenbanken enthaltene Werte von Feldern, wenn diese an einer Programmstelle zwingend erforderlich sind, z.B. Gewicht (das beim Anlegen der Stammdaten eventuell noch nicht bekannt war)

Es ist aber immer nur ein Event-Loop wirksam, nach dem :destroy() eines solchen Fensters kehrt das Programm immer in den Event-Loop der Main-Prozedur zurück.

Hoffentlich habe ich Dich nicht jetzt vollkommen verwirrt!

Herzlichst
Gerd
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Gerd König hat geschrieben:Hallo Manfred,


Hoffentlich habe ich Dich nicht jetzt vollkommen verwirrt!

Herzlichst
Gerd
:drunken:

Doch, ich habe kein Wort verstanden. :-k
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Gerd König
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 193
Registriert: Fr, 09. Jun 2006 7:52
Wohnort: Nähe Sömmerda

Beitrag von Gerd König »

Hi Manfred,

gar nichts ... das tut mir leid

Also:
Die XBase-Messagebox ist mir zu unflexibel.

Außer einer ausgegebenen Nachricht, die ich lesen kann (oder auch nicht) und bestätigen muß habe ich keine weiteren Möglichkeiten. Und wenn der Text z.B. 100 Zeilen lang ist, sehe ich nur einen Bruchteil

Deshalb habe ich ein eigenes Meldungsfenster entwickelt.

Das Programm darf wie bei einer Standard-Messagebox erst fortgesetzt werden, wenn diese geschlossen (:destroy()-Methode) wird. Die Taste <ok> setzt über den activate-Codeblock eine logische Variable, das gleiche geschieht, wenn die Eingabetaste betätigt wird.

Bis dahin dreht sich das Programm in der Eventschleife des Meldungsfensters. Diese wird wie gesagt erst bei gesetzter Varriablen verlassen.

Code: Alles auswählen

   
lExit:=.F.
//......
DO WHILE ! lExit
   nEvent:=AppEvent(@mp1,@mp2,@oXbp,1)
   IF ValType(oXbp)="O"
       oXbp:handleEvent(nEvent,mp1,mp2)
   ENDIF
   IF nEvent=xbeP_Keyboard
       IIf(((lAcceptAllKeys .OR. mp1=xbeK_RETURN), lExit:=.T., NIL)
   ENDIF
   IF nEvent=xbeP_Close
       lExit:=.T.
   ENDIF
ENDDO
IF XBP_STAT_CREATE=oDlg:status()
    oDlg:setModalState(XBP_DISP_MODELESS)
    oDlg:destroy()
ENDIF

oDlg ist das Meldungsfenster
lAcceptAllKeys entscheidet ob ich irgendeine Taste drücken kann

Vielleicht löst dieses Programmschnipsel das Verständnisproblem

Gruß
Gerd
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14659
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Beitrag von Jan »

Moin Manfred,

(wer hat eigentlich die Uhr auf dem Server gestellt?)

Ich denke gerd möchte damit ausdrücken, daß bestimmte Fenster eine eigene Event-Schleife haben. In der dann auch eigene Tastaturauswertungen abgefragt werden. Und sobald diese Fenster wieder geschlossen werden, wird die Haupt-Event-Schleife wieder aktiv.

Das ist etwas, was ich auhc mache. Allerdings eher notgedrungen, da ich mit Multithreading arbeite: Jedes Fenster ist ein eigener Thread. Was aber wiederum den Vorteil hat, daß ich für jedes Fenster auch eine eigene Tastatur-Auswertung einbauen kann.

Wir hatten ja schon mal irgendwann gesagt, daß ein normales 1-threadiges Programm nur 1 Event-Schleife hat. in Deinem Fall mit individuellen Auswertungen wirst Du aber nicht umhin kommen, diese Dialog mit einer eigenen Eventschleife auszustatten

Jan
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Jan,
Jan hat geschrieben:(wer hat eigentlich die Uhr auf dem Server gestellt?)
wieso? Ich habe nach der Umstellung auf Winterzeit die allgemeine Zeitanzeige (die man sieht, wenn man sich nicht einloggt) angepasst - Deine eigene musst Du (wie bei jeder Zeitumstellung) in Deinem Profil anpassen...

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14659
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Beitrag von Jan »

Moin Martin,

ja, hab ich mir nach edm Absenden des Beitrages auch schon gedacht, und hab das auch schon umgestellt. Passiert das nach dem Update dann automatisch?

Jan
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Jan,
:dontknow:

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Antworten