XbpStatic aendern (Newbie)

Grafische Primitive, XbaseParts und Darstellungsfragen allgemein.

Moderator: Moderatoren

Antworten
Wonderer
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 107
Registriert: Do, 06. Jul 2006 13:24

XbpStatic aendern (Newbie)

Beitrag von Wonderer »

Hallo,

ich hab wieder ein mal das Vergnügen mich in XBase einzuarbeiten und versuche gerade eine simple GUI-Anwendung mit XbpDialog zum Testen zu erstellen.
Das Fenster geht auf und reagiert auf das Close-Ereignis. Jetzt wollte ich eigentlich, dass in nem StaticText-Object andere Events angezeigt werden ( Str( nEvent ) ).
Nachdem das nicht funktionierte habe ich das Event noch etwas eingegrenzt aber es funktioniert dennoch nicht.

Code: Alles auswählen

#include "Appevent.ch"
#include "Xbp.ch"

PROCEDURE Main

 LOCAL nPara, nIter, cParas
 LOCAL nEvent, mp1, mp2, oXbp
 LOCAL oTxtCapt, cTxtCapt

  AppSys()

  DO WHILE nEvent <> xbeP_Close
   nEvent := AppEvent( @mp1, @mp2, @oXbp )
   oStat := SetAppWindow():childFromName( 1001 )
   IF nEvent == xbeK_ESC
    oStat:setCaption( "Esc pressed" )
   ENDIF
   oXbp:HandleEvent( nEvent, mp1,mp2 )
  ENDDO

RETURN

PROCEDURE AppSys

 LOCAL aSize, oDlg

 aSize := {500,500} // SetAppWindow():currentSize()

 oDlg := XbpDialog():new()
 oDlg:title := "Test-Application"
 oDlg:create( nil,nil, {100,100},{200,100},nil, .t. )

 oTxtCapt := XbpStatic():new()
 oTxtCapt:setName( 1001 )
 oTxtCapt:type := XBPSTATIC_TYPE_TEXT
 oTxtCapt:autoSize := .t.
 oTxtCapt:caption := "Event: "
 oTxtCapt:create( oDlg:drawingArea, , {50,50},{200,100},, .t. )

 oDlg:show()

 SetAppWindow( oDlg )
 SetAppFocus( oDlg )

RETURN
Als Alternative falls das so nicht geht hab ich da für den Zugriff schon das Ableiten einer eigenen Klasse im Kopf, aber so wärs ja auch ganz Ok. :D

Danke schon mal für nen Hinweis der mich in die richtige Richtung weiterführt. :)
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: XbpStatic aendern (Newbie)

Beitrag von brandelh »

Der Event heißt "Keyboard" und die Taste ist ein Parameter ...
Einige Tasten wie die oder ENTER haben eigene Events. Ich sehe mal nach ...

Ich verwende eine Funktion für den Eventloop, der man auch angeben kann wie lange man darin bleiben will.
Z.B. wenn man KEINE Threads verwendet und eine Schleife durchläuft macht es sinn, alle 1000 Durchläufe die Eventloop für <= 1 Sekunde aufzurufen.

Code: Alles auswählen

*-----------------------------------------------------------------------------
FUNCTION DoEventLoop(nSeconds)               // For Next Schleifen unterbrechen und Events verarbeiten !
   local nBisSeconds, nEvent, mp1:=nil, mp2:=nil, oXbp:=nil, dBis

   DEFAULT nSeconds to 0

   dBis := date()
   nBisSeconds := seconds() + nSeconds

   if nBisSeconds >= 86400                   // Endlosschleife um Mitternacht verhindern
      dBis++
      nBisSeconds := nBisSeconds % 86400
   endif

   DO WHILE .T.
      nEvent := AppEvent( @mp1, @mp2, @oXbp, nSeconds)
      do case
         case nEvent = xbe_None
            * nichts tun ist hier Standard
         case nEvent = xbeP_Keyboard .and. mp1 == xbeK_F1
            * xbeP_HelpRequest erscheinen für jede Xbp Instanz, also zu oft !
            ShowNoHelp()  // in ANW_MENU.PRG

         case nEvent = xbeP_Keyboard .and. mp1 == xbeK_ESC
                *** was soll geschehen ?
                
         otherwise
              oXbp:handleEvent( nEvent, mp1, mp2 )
      endcase
      if nSeconds > 0
         if date() = dBis .and. nBisSeconds < seconds()
            exit
         endif
      endif
   ENDDO
return nil
die Abfrage nach deiner ESC Taste habe ich mal schnell eingebaut ;-)

Sollte man viele solcher "Sondertasten" verarbeiten wollen, macht es Sinn die Abfrage zu optimieren

Code: Alles auswählen

   DO WHILE .T.
      nEvent := AppEvent( @mp1, @mp2, @oXbp, nSeconds)
      do case
         case nEvent = xbe_None
            * nichts tun ist hier Standard
         case nEvent = xbeP_Keyboard
                do case
                    case mp1 == xbeK_F1
                    case mp1 == xbeK_ESC
 ...
                
         otherwise
              oXbp:handleEvent( nEvent, mp1, mp2 )
      endcase
Achtung, die Schleife darf nicht blockiert werden !
In einer Sekunde werden viele 1000 Durchläufe verarbeitet, wenn du eine Funktion aufrufst die 5 Sekunden braucht,
wird dein Programm nicht mehr reagieren für 5 Sekunden !

Je nach Aufgabe also besser an Threads denken :-)
Gruß
Hubert
Wonderer
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 107
Registriert: Do, 06. Jul 2006 13:24

Re: XbpStatic aendern (Newbie)

Beitrag von Wonderer »

Danke, funktioniert leider immer noch nicht.
Der Aufruf von 'childFromName' von SetAppWindow, und auch der Aufruf über das oXbp-Objekt scheint zu funktionieren - es kommt keine Fehlermeldung.
Aber 'setCaption' bewirkt keine Änderung - angenommen die Methode wird aufgerufen.

Mein geänderter Code zur Schleife sieht jetzt so aus:

Code: Alles auswählen

 LOCAL nLastEvent, nLastSec

  AppSys()

  nLastEvent := xbe_None
  nLastSec := seconds()

  DO WHILE nEvent <> xbeP_Close
   nSec := seconds()
   nEvent := AppEvent( @mp1, @mp2, @oXbp )
   DO CASE
    CASE nEvent == xbeP_Keyboard .and. mp1 == xbeK_ESC
     oStat := oXbp:childFromName( 1001 )
     oStat:setCaption( "Esc pressed" )
     nLastSec := nSec
     nLastEvent := nEvent
    CASE nEvent == xbeP_Keyboard .and. mp1 <> xbeK_ESC
     oStat := SetAppWindow():childFromName( 1001 )
     oStat:setCaption( "key pressed" )
     nLastSec := nSec
     nLastEvent := nEvent
    CASE nLastEvent <> xbe_None .and. nSec > (nLastSec+3)
      oStat := oXbp:childFromName( 1001 )
      oStat:setCaption( "wait for event" )
      nLastEvent := xbe_None
   ENDCASE
   //IF nEvent == xbeP_Keyboard .and. mp1 == xbeK_ESC
    //oStat:setCaption( "Esc pressed" )
   //ENDIF
   oXbp:HandleEvent( nEvent, mp1,mp2 )
  ENDDO
und danke für den Hinweis mit den Threads, werde ich mir dann später mal anschauen...

EDIT: Alt+F4 und Klick auf FensterX-Schließen funktioniert
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14651
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: XbpStatic aendern (Newbie)

Beitrag von Jan »

Du solltest die Schleife so schreiben, wie Hubert es dargestellt hat. Also erst die Abfrage auf nEvent == xbeP_Keyboard, und nur im zutreffenden Fall de Abfrage auf Escape. Ansonsten läufts Du extrem häufig durch all die If-Abfragen.

Hast Du im Debugger mal geprüft, was oStat für einen Status hat?

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Wonderer
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 107
Registriert: Do, 06. Jul 2006 13:24

Re: XbpStatic aendern (Newbie)

Beitrag von Wonderer »

Jan hat geschrieben:Du solltest die Schleife so schreiben, wie Hubert es dargestellt hat. Also erst die Abfrage auf nEvent == xbeP_Keyboard, und nur im zutreffenden Fall de Abfrage auf Escape.
Danke, mein Code sieht jetzt so aus:

Code: Alles auswählen

  AppSys()

  nLastEvent := xbe_None
  nLastSec := seconds()

  DO WHILE nEvent <> xbeP_Close
   nSec := seconds()
   nEvent := AppEvent( @mp1, @mp2, @oXbp )
   oStat := oXbp:childFromName( 1001 )
   oStat2 := SetAppWindow():childFromName( 1001 )
   DO CASE
    CASE nEvent == xbeP_Keyboard 
     DO CASE
       CASE mp1 == xbeK_ESC
        oStat:setCaption( "Esc pressed" )
        nLastSec := nSec
        nLastEvent := nEvent
      OTHERWISE
        oStat2:setCaption( "key pressed" )
        nLastSec := nSec
        nLastEvent := nEvent
     ENDCASE
    CASE nLastEvent <> xbe_None .and. nSec > (nLastSec+3)
      oStat:setCaption( "wait for event" )
      nLastEvent := xbe_None
   ENDCASE
   //IF nEvent == xbeP_Keyboard .and. mp1 == xbeK_ESC
    //oStat:setCaption( "Esc pressed" )
   //ENDIF
   oXbp:HandleEvent( nEvent, mp1,mp2 )
  ENDDO
Hast Du im Debugger mal geprüft, was oStat für einen Status hat?
oStat und oStat2 von dem hier geposteten Code enthalten das XbpStatic-Objekt...

Auch beim Debuggen wird Caption nicht geändert :(

EDIT: Mit Debugger läuft der Code in die CASE Abschnitte und setzt auch die Caption - ohne Debugger bleibt die Caption gleich!?
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14651
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: XbpStatic aendern (Newbie)

Beitrag von Jan »

Auch die Caption von oStat wird nicht geändert?

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Wonderer
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 107
Registriert: Do, 06. Jul 2006 13:24

Re: XbpStatic aendern (Newbie)

Beitrag von Wonderer »

Mit Debugger läuft der Code in die CASE Abschnitte und setzt auch die Caption - ohne Debugger bleibt die Caption gleich!?
Wonderer
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 107
Registriert: Do, 06. Jul 2006 13:24

Re: XbpStatic aendern (Newbie)

Beitrag von Wonderer »

Ich poste noch einmal den gesamten Quellcode - wie schon beschrieben - im Debugger wird der Inhalt des Static-Feldes gesetzt ( habe 2 Breakpoints - einen beim CASE xbeP_Keyboard und einen innerhalb nLastEvent <> xbe_None ) aber wenn ich das Programm einfach so ohne Debugger starte dann werden die Codezeilen in den Case-Blöcken nicht ausgeführt -> keine Änderung des Textfeldes.

Code: Alles auswählen

// test program

#include "Appevent.ch"
#include "Xbp.ch"

PROCEDURE Main

 LOCAL nPara, nIter, cParas
 LOCAL nEvent, mp1, mp2, oXbp
 LOCAL oTxtCapt, cTxtCapt, oStat, oStat2
 LOCAL nLastEvent, nLastSec

  AppSys()

  nLastEvent := xbe_None
  nLastSec := seconds()

  DO WHILE nEvent <> xbeP_Close
   nSec := seconds()
   nEvent := AppEvent( @mp1, @mp2, @oXbp )
   oStat := oXbp:childFromName( 1001 )
   oStat2 := SetAppWindow():childFromName( 1001 )
   DO CASE
    CASE nEvent == xbeP_Keyboard
     DO CASE
      CASE mp1 == xbeK_ESC
       oStat:setCaption( "Esc pressed" )
       nLastSec := nSec
       nLastEvent := nEvent
      OTHERWISE
       oStat:setCaption( "key pressed" )
       nLastSec := nSec
       nLastEvent := nEvent
     ENDCASE
    CASE nLastEvent <> xbe_None .and. nSec > (nLastSec+15)
      oStat := oXbp:childFromName( 1001 )
      oStat:setCaption( "wait for event" )
      nLastEvent := xbe_None
      nLastSec := nSec
   ENDCASE
   //IF nEvent == xbeP_Keyboard .and. mp1 == xbeK_ESC
    //oStat:setCaption( "Esc pressed" )
   //ENDIF
   oXbp:HandleEvent( nEvent, mp1,mp2 )
  ENDDO

RETURN

PROCEDURE AppSys

 LOCAL aSize, oDlg

 aSize := {500,500} // SetAppWindow():currentSize()

 oDlg := XbpDialog():new()
 oDlg:title := "Test-Application"
 oDlg:create( nil,nil, {100,100},{200,100},nil, .t. )

 oTxtCapt := XbpStatic():new()
 oTxtCapt:setName( 1001 )
 oTxtCapt:type := XBPSTATIC_TYPE_TEXT
 oTxtCapt:autoSize := .t.
 oTxtCapt:caption := "wait for event"
 oTxtCapt:create( oDlg:drawingArea, , {50,50},{200,100},, .t. )

 oDlg:show()

 SetAppWindow( oDlg )
 SetAppFocus( oDlg )

RETURN
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: XbpStatic aendern (Newbie)

Beitrag von brandelh »

Code: Alles auswählen

 oXbp:childFromName( 1001 )
dies ist eine Falle ...

oXbp enthält das Control, das den Event bemerkt hat.
Das KANN das Fenster sein, es muss aber nicht !

Wenn du sehen willst, welche Events kommen, ist meine DebugPrint() Klasse geeignet, oder ein CRT Fenster das ? Meldung druckt.

ALLE Controlls die du setzt im Programm, können erst dann reagieren, wenn sie selbst Zeit (oXbp:handleevent()) dafür hatten (die Anwendung steht ja an deiner Programmstelle) ...
Solche Experimente in der Eventloop, die ja genau die Anzeige erzeugen soll, sind sehr gefährlich.

:arrow: => http://www.xbaseforum.de/viewtopic.php?f=16&t=3121
Gruß
Hubert
Wonderer
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 107
Registriert: Do, 06. Jul 2006 13:24

Re: XbpStatic aendern (Newbie)

Beitrag von Wonderer »

brandelh hat geschrieben:

Code: Alles auswählen

 oXbp:childFromName( 1001 )
dies ist eine Falle ...

oXbp enthält das Control, das den Event bemerkt hat.
Das KANN das Fenster sein, es muss aber nicht !
Danke, ich habe jetzt alle 'setCaption' Aufrufe über das oStat2 realisiert. Ohne Debugger wird die Caption aber immer noch nicht geändert!? :?:
Solche Experimente in der Eventloop, die ja genau die Anzeige erzeugen soll, sind sehr gefährlich.
Im Moment kenne ich keine andere Methode - also ohne Eventloop - um ein Fenster zu öffnen und auf Ereignisse zu reagieren.
Habe mir das mit den Threads angeschaut, aber da sehe ich keinen Unterschied ob die DO WHILE .T: - nEvent := AppEvent( ... ) in einem separaten Thread abläuft oder direkt in der MAIN Procedure.

Hast du den Code von mir mal getestet mit und ohne Debugger?
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: XbpStatic aendern (Newbie)

Beitrag von brandelh »

Die Eventloop ist nötig, da habe ich nicht widersprochen.

Ich sagte, dass du in der Eventloop solche Aktionen nicht machen sollst ...
das Control braucht für die Änderung wohl auch das nächste handleevent() ... bin mir nicht sicher.

Die Threads sind z.B. für umfangreiche Suchen oder Drucken etc. gedacht.

Wozu dient die Anzeige ?
Willst du sehen welche Events ankommen ?

Dann nimm DebugPrint()
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: XbpStatic aendern (Newbie)

Beitrag von brandelh »

vielleicht deutlicher, die Eventloop verarbeitet die aufgetretenen Events und reicht sie an handleevent weiter.
Dazwischen kann man etwas manipulieren, z.B. auch Events unterdrücken, aber alles was länger dauert ist nicht erlaubt.
Änderungen an Controls als solches löst meist wieder Events aus, wie jede kleine Mausbewegung ...
Gruß
Hubert
Wonderer
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 107
Registriert: Do, 06. Jul 2006 13:24

Re: XbpStatic aendern (Newbie)

Beitrag von Wonderer »

brandelh hat geschrieben:vielleicht deutlicher, die Eventloop verarbeitet die aufgetretenen Events und reicht sie an handleevent weiter.
Dazwischen kann man etwas manipulieren, z.B. auch Events unterdrücken, aber alles was länger dauert ist nicht erlaubt.
Das heißt in XBase kann ich mir in dem Hauptfenster in einem TextStatic-Feld nicht anzeigen lassen welche Events vom Hauptfenster auftreten?
Oder hab ich das immer noch nicht verstanden?

sorry falls ich da gerade total auf dem Schlauch stehe...
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: XbpStatic aendern (Newbie)

Beitrag von brandelh »

Alle Beispiele die sowas machen sind XbpCRT() Fenster, dort kann man immer mit ? " " alles anzeigen lassen und mit GUI=YES compiliert auch die Events die auftreten.
Was du willst habe ich noch nie versucht, ich nutze bei DebugPrint() ein eigenes Fenster, daher kann ich das nicht mit Bestimmtheit sagen, aber die Zeit das gehend zu machen hab ich auch nicht.

Normal wir die Caption oder der Inhalt von Controls im normalen Code des Fensters oder anderer Fenster generiert ...

Vielleicht wird das Beispiel es deutlicher machen !
Statt in der Eventloop etwas zu tun, wird ein Event erzeugt, der danach etwas auslöst ... aber XbpCrt() ;-)

..\XPPW32\source\samples\basics\VIOEvent\Event.prg
Gruß
Hubert
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: XbpStatic aendern (Newbie)

Beitrag von AUGE_OHR »

Wonderer hat geschrieben:Ich poste noch einmal den gesamten Quellcode
für das was du da vorhast gibt es von Alaska ein fertiges Tool : MEMWATCH.zip
The Alaska Memory Watcher is intended to provide a tool
which allows you to monitor the activities in an application
while it is running. It shows and maintains GDI/USER heap
as well as open GUI objects.
The functionalities in this tool allow you to locate
memory leaks, unused variables, unused GUI objects etc.
was die Eventloop angeht : wie schon gesagt ist es NICHT gut solchen Code "in" einer Eventloop auszuführen !
im optimalen Fall hast du eine Eventloop für das gesamte Programm !
gruss by OHR
Jimmy
Wonderer
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 107
Registriert: Do, 06. Jul 2006 13:24

Re: XbpStatic aendern (Newbie)

Beitrag von Wonderer »

danke nochmal, ich hab jetzt den angefangenen Quellcode davon beiseite gelegt und das Beispiel SdiDemo abgeändert zum besseren Verständnis.

falls ich doch noch mal an diesem Test-Code bastle melde ich mich wieder hier.. :)
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: XbpStatic aendern (Newbie)

Beitrag von brandelh »

SDI Demo oder MdI Demo (das habe ich für mein Framework verwendet) sind gute Beispiele, heute wird SDI wohl der Vorzug gegeben.
Gruß
Hubert
Antworten