Eventschleifen, wie oft? [ERLEDIGT]
Moderator: Moderatoren
- Manfred
- 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]
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.
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!!
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!!
- brandelh
- Foren-Moderator
- Beiträge: 15697
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
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.
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
Hubert
- Manfred
- Foren-Administrator
- Beiträge: 21200
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
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?
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!!
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!!
- brandelh
- Foren-Moderator
- Beiträge: 15697
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Schau dir doch mal den Code an.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.
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
Hubert
- Manfred
- Foren-Administrator
- Beiträge: 21200
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
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.....
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!!
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!!
- Jan
- Marvin
- Beiträge: 14659
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 88 Mal
- Kontaktdaten:
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
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
- Rolf Ramacher
- Der Entwickler von "Deep Thought"
- Beiträge: 1931
- Registriert: Do, 09. Nov 2006 10:33
- Wohnort: Bergheim
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
Hi Manfred,
ich gebe dir mal einen Code von mir:
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.
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
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.
- Manfred
- Foren-Administrator
- Beiträge: 21200
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
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?
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!!
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!!
- Jan
- Marvin
- Beiträge: 14659
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 88 Mal
- Kontaktdaten:
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:
Und so sieht das in jedem Thread aus, jeder Thread hat eine andere Tastenbelegung bei mir, hier für F2 - F12.
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
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
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
Du musst das natürlich an Deine Gegebenheiten anpassen, das soll nur ein Beispiel sein.
Jan
- Manfred
- Foren-Administrator
- Beiträge: 21200
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
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.
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!!
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!!
- Manfred
- Foren-Administrator
- Beiträge: 21200
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
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.
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!!
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!!
-
- Rekursionen-Architekt
- Beiträge: 193
- Registriert: Fr, 09. Jun 2006 7:52
- Wohnort: Nähe Sömmerda
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
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
- Manfred
- Foren-Administrator
- Beiträge: 21200
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
Gerd König hat geschrieben:Hallo Manfred,
Hoffentlich habe ich Dich nicht jetzt vollkommen verwirrt!
Herzlichst
Gerd
Doch, ich habe kein Wort verstanden.
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!!
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!!
-
- Rekursionen-Architekt
- Beiträge: 193
- Registriert: Fr, 09. Jun 2006 7:52
- Wohnort: Nähe Sömmerda
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.
oDlg ist das Meldungsfenster
lAcceptAllKeys entscheidet ob ich irgendeine Taste drücken kann
Vielleicht löst dieses Programmschnipsel das Verständnisproblem
Gruß
Gerd
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
- Jan
- Marvin
- Beiträge: 14659
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 88 Mal
- Kontaktdaten:
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
(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
- Martin Altmann
- Foren-Administrator
- Beiträge: 16517
- Registriert: Fr, 23. Sep 2005 4:58
- Wohnort: Berlin
- Hat sich bedankt: 111 Mal
- Danksagung erhalten: 48 Mal
- Kontaktdaten:
Hallo Jan,
Viele Grüße,
Martin
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...Jan hat geschrieben:(wer hat eigentlich die Uhr auf dem Server gestellt?)
Viele Grüße,
Martin
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.
- Martin Altmann
- Foren-Administrator
- Beiträge: 16517
- Registriert: Fr, 23. Sep 2005 4:58
- Wohnort: Berlin
- Hat sich bedankt: 111 Mal
- Danksagung erhalten: 48 Mal
- Kontaktdaten:
Hallo Jan,
Viele Grüße,
Martin
Viele Grüße,
Martin
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.