Hilfestellung beim Einstieg in GUI [erledigt]

Grafische Primitive, XbaseParts und Darstellungsfragen allgemein.

Moderator: Moderatoren

Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Re: Hilfestellung beim Einstieg in GUI

Beitrag von AUGE_OHR »

hi,

ich hab mir mal deinen Code angesehen ... ufff

Thema : MDI Fenster und Eventloop
suche mal im MDIDEMO Sample wie oft du

Code: Alles auswählen

nEvent := AppEvent( @mp1, @mp2, @oXbp )
findest.

in Main ist nun deine Eventloop und wenn du bei Ansicht/Browse oder Eingabe/Edit ein Fenster öffnest hast du jeweils eine Eventloop ... das gibt "so" Chaos [-X

wenn du weiter Eventloop verwenden willst dann nimm Thread() ... dann gibt es auch keine ALIAS() Probleme ;)


p.s. ich halte diesen Code für falsch

Code: Alles auswählen

   nEvent := AppEvent( @mp1, @mp2, @oXbp )
   oXbp:handleEvent( nEvent, mp1, mp2, oXbp )
   IF nEvent==xbeP_Keyboard
denn dieser Code würde dann knallen

Code: Alles auswählen

   nEvent := AppEvent( @mp1, @mp2, @oXbp ,100)
   oXbp:handleEvent( nEvent, mp1, mp2, oXbp )
es muss also IMHO vorher die Möglichkeit der Abfrage(n) vorhanden sein.

Code: Alles auswählen

   nEvent := AppEvent( @mp1, @mp2, @oXbp,100 )
   DO CASE
        CASE nEvent == xbe_None                   // nTimeout
        CASE nEvent == xbeP_Keyboard .AND. mp1 == xbeK_ESC
        CASE nEvent == xbeP_Keyboard .AND. mp1 == xbeK_ENTER

   OTHERWISE
       oXbp:handleEvent( nEvent, mp1, mp2, oXbp )
   ENDCASE
gruss by OHR
Jimmy
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Hilfestellung beim Einstieg in GUI

Beitrag von messing »

Hi Jimmy,
Danke für die Info.
Ich bin davon ausgegangen, das in jeder aufgerufenen Routine eine Eventloop sein muß?!? :?:
Habe beide Eventloop rausgenommen, nur noch die in der Main.
Trotzdem habe ich den Effekt, das wenn ich das Browse aufmache und dann die Eingabe, das bei erneutem Klick im Browse dieses mir das Browse
verhunzt. Kannst du mir sagen, wo ich da den Fehler habe? :banghead:
Gruß
Bruno
Messing
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14658
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Hilfestellung beim Einstieg in GUI

Beitrag von Jan »

Bruno,

je Thread normalerweise immer nur exakt eine Eventschleife. Da bin ich in meinen Anfangstagen mit Xbase++ und GUI auch reingelaufen ...

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
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:

Re: Hilfestellung beim Einstieg in GUI

Beitrag von brandelh »

Ich habe die Eventschleife in eine Funktion mit zeitlich befristetem Aufruf gepackt.
Diese wird ohne Begrenzung in MAIN aufgerufen, aber eventuell auch mit zeitlicher Begrenzung in längeren Schleifen.
Dennoch bleibt es eine Eventloop 8)

in Main.PRG am Ende die Eventloop gegen den Funktionsaufruf austauschen ...

Code: Alles auswählen

#include "common.ch"
procedure MAIN
    ...
    DoEventLoop()    // keine Zeitbegrenzung, MAIN steht hier bis zum Ende der Funktion
RETURN
*-----------------------------------------------------------------------------
FUNCTION DoEventLoop(nSeconds)               // For Next Schleifen unterbrechen und Events verarbeiten !
   local nBisSeconds, nEvent, mp1:=nil, mp2:=nil, oXbp:=nil
   DEFAULT nSeconds to 0                     // Standard ist endlose Ausführung
   nBisSeconds := seconds() + nSeconds
   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 .and. HelpObject()==NIL
              * xbeP_HelpRequest erscheinen für jede Xbp Instanz, also zu oft !
              ShowNoHelp()  // in ANW_MENU.PRG
         otherwise
              oXbp:handleEvent( nEvent, mp1, mp2 )
      endcase
      if nSeconds > 0 .and. nBisSeconds < seconds() // nur wenn keine endlose Ausführung
         exit
      endif
   ENDDO
return nil
Wenn ich dann z.B. längere Schleifen habe die ich nicht in einen extra Thread auslagere (warum auch immer), dann mache ich sowas:

Code: Alles auswählen

nZeig := 0
do while ...
     ...
     nZeig++
     if nZeig > 100
        nZeig := 0
        DoEventLoop( 0.01 )
     endif
enddo
Gruß
Hubert
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Hilfestellung beim Einstieg in GUI

Beitrag von messing »

Jan hat geschrieben:Bruno,

je Thread normalerweise immer nur exakt eine Eventschleife. Da bin ich in meinen Anfangstagen mit Xbase++ und GUI auch reingelaufen ...

Jan
Ja, der Sturz war tief! :D
Gruß
Bruno
Messing
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Hilfestellung beim Einstieg in GUI

Beitrag von messing »

Eventloops entfernt, OK.
Nur warum spinnt das Browse, obwohl ich die DBF mit versch ALIAS öffne?
Gruß
Bruno
Messing
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Hilfestellung beim Einstieg in GUI

Beitrag von messing »

brandelh hat geschrieben:wie schließt du die Datei nach der Eingabe ?

Code: Alles auswählen

close alias   // immer genau angeben was geschlossen werden soll
2 mal die gleiche Datei offen, da gibt es Probleme mit dem Text Alias, ich nutze daher immer den numerischen Selectbereich ...

Code: Alles auswählen

use ...
if neterr()
   fehlermeldung()
else 
   ::nAlias := select()
endif 

im Closeevent des Fensters dann ...

if (::nAlias)->(used())
   (::nAlias)->(dbcloseArea())
endif
Hi Hubert,
Ich schließe die Datei nicht und mache auch noch keinen schreibvorgang in die Datei.
Ich öffne lediglich im Browse 2 DBF wovon vorerst eine im Browse ist. Ich öffne die Datei mit Text Alias. In der Eingabe öffne ich 7 DBF auch mit Text Alias, aber anderem als im Browse. Ich bin bis jetzt bei der Umstellung meines Prog. bis zu diesem Punkt gekommen. Bei der DevCon wurde mir gesagt, ich soll für Hintergrundarbeiten Threads nehmen, nicht für Dialoge. Ich öffne die DBF in der Eingabe mit

Code: Alles auswählen

DO WHILE .T.                  // EndlosschleIFe starten
   use dispo alias dispoeingabe shared new
                              // Datenbank öffnen
   IF Neterr() .AND. ;
      Alert( "Datei ist gesperrt!;ZugrIFf wiederholen?", ;
            {"Wiederholen","Abbrechen"} ) <> 2
                              // Netzfehler prüfen Abfrage
      LOOP              // ZugrIFf wiederholen
   ENDIF                // Abfrageabschluß
   EXIT                 // SchleIFe verlassen
ENDDO                   // SchleIFenabschluß
IF Used()               // Abfrage ob Datei geöffnet
   SET INDEX TO d_d_anf,d_z_anf,d_kd_bez,d_fah_nam,;
         d_kennz,d_kfzart,d_trart,d_such1
   set filter TO loeschm=.f.                        // Indexdateien öffnen
ENDIF                   // Abfrageabschluß

DO WHILE .T.                  // EndlosschleIFe starten
   use nachweis alias nachweiseingabe shared new
                              // Datenbank öffnen
   IF Neterr() .AND. ;
      Alert( "Datei ist gesperrt!;ZugrIFf wiederholen?", ;
            {"Wiederholen","Abbrechen"} ) <> 2
                              // Netzfehler prüfen Abfrage
      LOOP              // ZugrIFf wiederholen
   ENDIF                // Abfrageabschluß
   EXIT                 // SchleIFe verlassen
ENDDO                   // SchleIFenabschluß
IF Used()               // Abfrage ob Datei geöffnet
   SET INDEX TO n_d_anf,n_z_anf,n_kd_bez,n_fah_nam,;
         n_kennz,n_kfzart,n_trart,n_such1
   set filter TO loeschm=.f.                     // Indexdateien öffnen
ENDIF                   // Abfrageabschluß

set DEFAULT TO (lw_array[4])
set DEFAULT TO (lw_array[1])

DO WHILE .T.               // EndlosschleIFe starten
   use kunden alias kundeneingabe shared new
                              // Datenbank öffnen
   IF Neterr() .AND. ;
      Alert( "Datei ist gesperrt!;ZugrIFf wiederholen?", ;
                   {"Wiederholen","Abbrechen"} ) <> 2
                              // Netzfehler prüfen Abfrage
      LOOP              // ZugrIFf wiederholen
   ENDIF                // Abfrageabschluß
   EXIT                 // SchleIFe verlassen
ENDDO                   // SchleIFenabschluß
IF Used()               // Abfrage ob Datei geöffnet
   SET INDEX TO kdbez,kdnam,kdplz
                              // Indexdateien öffnen
ENDIF                   // Abfargeabschluß

DO WHILE .T.                  // EndlosschleIFe starten
   use fahrer alias fahrereingabe shared new
                              // Datenbank öffnen
   IF Neterr() .AND. ;
      Alert( "Datei ist gesperrt!;ZugrIFf wiederholen?", ;
                   {"Wiederholen","Abbrechen"} ) <> 2
                              // Netzfehler prüfen Abfrage
      LOOP              // ZugrIFf wiederholen
   ENDIF                // Abfrageabschluß
   EXIT                 // SchleIFe verlassen
ENDDO                   // SchleIFenabschluß
IF Used()               // Abfrage ob Datei geöffnet
   SET INDEX TO fah_nam // Indexdatei öffnen
ENDIF                   // Abfrageabschluß

DO WHILE .T.
   use kfz01 alias kfzeingabe shared new// Datenbank öffnen
   IF Neterr() .AND. ;
      Alert( "Datei ist gesperrt!;ZugrIFf wiederholen?", ;
                   {"Wiederholen","Abbrechen"} ) <> 2
                              // Netzfehler prüfen Abfrage
      LOOP              // ZugrIFf wiederholen
   ENDIF                // Abfrageabschluß
   EXIT                 // SchleIFe verlassen
ENDDO                   // SchleIFenabschluß
IF Used()               // Abfrage ob Datei geöffnet
   SET INDEX TO kfz_nr  // Indexdatei öffnen
   set filter TO kfz_typ = "L"   // Filterbedingung festlegen
ENDIF                   // Abfrageabschluß

DO WHILE .T.                // EndlosschleIFe starten
   use transp alias transeingabe shared new
                              // Datenbank öffnen
   IF Neterr() .AND. ;
      Alert( "Datei ist gesperrt!;ZugrIFf wiederholen?", ;
                   {"Wiederholen","Abbrechen"} ) <> 2
                              // Netzfehler prüfen Abfrage
      LOOP              // ZugrIFf wiederholen
   ENDIF                // Abfrageabschluß
   EXIT                 // SchleIFe verlassen
ENDDO                   // SchleIFenabschluß
IF Used()               // Abfrage ob Datei geöffnet
   SET INDEX TO t_art   // Indexdatei öffnen
ENDIF                   // Abfrageabschluß

DO WHILE .T.                 // EndlosschleIFe starten
   use selbst alias selbsteingabe shared new
                              // Datenbank öffnen
   IF Neterr() .AND. ;
      Alert( "Datei ist gesperrt!;ZugrIFf wiederholen?", ;
                   {"Wiederholen","Abbrechen"} ) <> 2
                              // Netzfehler prüfen Abfrage
      LOOP              // ZugrIFf wiederholen
   ENDIF                // Abfrageabschluß
   EXIT                 // SchleIFe verlassen
ENDDO                   // SchleIFenabschluß
und im Browse mit

Code: Alles auswählen

do while .T.                  // EndlosschleIFe starten
   use dispo alias dislist shared new
                              // Datenbank öffnen
   IF Neterr() .AND. ;
         Alert( "Datei ist gesperrt!;ZugrIFf wiederholen?", ;
            {"Wiederholen","Abbrechen"} ) <> 2
                              // Netzfehler prüfen Abfrage
      LOOP              // ZugrIFf wiederholen
   ENDIF                // Abfrageabschluß
   EXIT                 // SchleIFe verlassen
ENDDO                   // SchleIFenabschluß
IF Used()               // Abfrage ob Datei geöffnet
   SET INDEX TO d_d_anf,d_z_anf,d_kd_bez,d_fah_nam,;
      d_kennz,d_kfzart,d_trart,d_such1
   set filter TO loeschm=.f.                        // Indexdateien öffnen
ENDIF                   // Abfrageabschluß
//dislistindex:=ordlist()
do while .T.                  // EndlosschleIFe starten
   use nachweis alias nachweislist shared new
                              // Datenbank öffnen
   IF Neterr() .AND. ;
         Alert( "Datei ist gesperrt!;ZugrIFf wiederholen?", ;
            {"Wiederholen","Abbrechen"} ) <> 2
                              // Netzfehler prüfen Abfrage
      LOOP              // ZugrIFf wiederholen
   ENDIF                // Abfrageabschluß
   EXIT                 // SchleIFe verlassen
ENDDO                   // SchleIFenabschluß
IF Used()               // Abfrage ob Datei geöffnet
   SET INDEX TO n_d_anf,n_z_anf,n_kd_bez,n_fah_nam,;
      n_kennz,n_kfzart,n_trart,n_such1
   set filter TO loeschm=.f.                     // Indexdateien öffnen
ENDIF                   // Abfrageabschluß
:banghead: :banghead: :banghead: ich versteh es nicht.
Gruß
Bruno
Messing
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:

Re: Hilfestellung beim Einstieg in GUI

Beitrag von brandelh »

Was für eine Menge Zeilen, die eigentlich immer das Gleiche machen ...
aber ich sehe weder ein browse noch etwas das ein zweites Fenster aufmacht.

Was ich sehe sind FIXE Aliasnamen. Somit kannst du kein MDI GUI (2 Fenster mit gleicher Datei z.B. 2 Kunden gleichzeitig) bauen
und wenn das nicht gewünscht ist, würde ich zuerst alle nötigen Dateien öffnen, und danach die Browse und Edit Aufrufe setzen.

Ich würde eine Funktion machen die die Dateien öffnet, wobei der jeweilige Name entweder als Parameter oder falls das zu umständlich ist per do case Abfrage gesetzt wird.
Das würde den Code wesentlich kürzer und damit lesbarer machen ... Beispiel:

Code: Alles auswählen

#define DISPO  1
#define NACHW 2
...
if DatOpen(DISPO)    .and. ;
   DatOpen(NACHW) ...
   * alle Dateien offen, keine Fehler
else
   * Eine Datei konnte nicht geöffnet werden ...
...
function DatOpen(nArt)
   DO WHILE .T.                  // EndlosschleIFe starten
      do case
         case nArt = 1
            use dispo alias dispoeingabe shared new // Datenbank öffnen
         case nArt = 2
            use nachweis alias nachweiseingabe shared new
      end // CASE ist einfacher zu verstehen als Array und man hat keine Probleme mit local Variablen 
      IF Neterr() 
         if Alert( "Datei ist gesperrt!;Zugriff wiederholen?", {"Wiederholen","Abbrechen"} ) <> 2
            LOOP              // ZugrIFf wiederholen
         else
            return .f.
         endif
      ELSE
         EXIT                 // SchleIFe verlassen
      ENDIF                // Abfrageabschluß
   ENDDO                   // SchleIFenabschluß
   IF Used()               // Abfrage ob Datei geöffnet
      do case
         case nArt = 1
            SET INDEX TO d_d_anf,d_z_anf,d_kd_bez,d_fah_nam, d_kennz,d_kfzart,d_trart,d_such1
            set filter TO loeschm=.f.                        // Indexdateien öffnen
         case nArt = 2      
            SET INDEX TO n_d_anf,n_z_anf,n_kd_bez,n_fah_nam,n_kennz,n_kfzart,n_trart,n_such1
            set filter TO loeschm=.f.                     // Indexdateien öffnen
      end
   ENDIF                   // Abfrageabschluß
return .t.
Sobald die Funktion mit dem DatOpen() getestet ist, kann man sich dann dem eigentlichen Problem zuwenden ;-)
Je einfacher und klarer der Quellcode gehalten ist, umso leichter fällt die Fehlersuche.
Gruß
Hubert
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Re: Hilfestellung beim Einstieg in GUI

Beitrag von AUGE_OHR »

messing hat geschrieben:Bei der DevCon wurde mir gesagt, ich soll für Hintergrundarbeiten Threads nehmen, nicht für Dialoge.
wenn du Hintergrundarbeiten hast die keinen User Eingriff benötigen -> keine Eventloop nötig.

es ist also nicht "Thread / Eventloop" sondern "Dialog / User Aktion / Eventloop" was man in einem Thread laufen lassen könnte.
ein Thread hat ja eine eigene WorkSpaceList() sodas ein ALIAS() Problem dann nicht auftreten kann.

ich habe nun auch nichts auffälliges bei der ersten Durchsicht gefunden ... aber aufgefallen sind mir die Combobox(en).

das o:itemselect ruft ja die Function ComboAction() auf.
dann holst du dir mit o:XbpSLE:getdata() deinen String den du mit SUBSTR() bearbeitest.
das ist IMHO bei XBPCOMBO_DROPDOWNLIST falsch den du kann ja keine Eingabe machen.

btw. sieht optisch nicht schön aus wenn man mit " " ( Space() ) in der Listbox arbeitet

wenn du aber das Element aus der Listbox nimmst

Code: Alles auswählen

? ValType( oCombobox:GetData() ) // -> "A"
erhält du ja ein Array mit der "Nummer" des Elements welche übereinstimmen mit der Reihenfolge wie du sie per o:additem() hinzugefügt hast.
auch der 2nd Teil der Angaben in der Listbox kannst mit der "Nummer" identifizieren und musst es nicht aus einem String "raus-holen"

tja und dann kommt

Code: Alles auswählen

IF(ndata=0,dbgotop(),dbgoto(ndata))
die ja verschiedenen DBF bedienen soll. hier würde ich den ALIAS() als Parameter mit übergeben und überprüfen

btw. ndata=0 tritt bei dir auch bei K_DOWN / K_UP ein d.h. man kann nicht mit der Tastatur arbeiten !

Frage : warum übernimmst du z.b. bei den Fahrern nicht alles "einmal" in ein Array auf ?

so nun nochmal zurück zu Thread wie du das testen könntest. es geht um die Proceduren "Ansicht" und "Eingabe".

füge in die beiden PRG so was ein

Code: Alles auswählen

STATIC isRunning := .F.
STATIC oThread := NIL

FUNCTION Start_Thread()
   IF isRunning = .T.
      //
      // aWindow[5] := oDlg
      //
      SetAppWindow( aWindow[5] )
      SetAppFocus( oLastFocus )
      RETURN oThread
   ELSE
      oThread := Thread() :new()
      oThread:start( "Ansicht")     // Procedure Name. Parameter per Komma dahinter
   ENDIF
RETURN oThread

PROCEDURE Ansicht
...
   isRunning := .T.
...
  // hier der Code 
...
   isRunning := .F.
   oThread := NIL
RETURN
gruss by OHR
Jimmy
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Hilfestellung beim Einstieg in GUI

Beitrag von messing »

Hi Jimmy,
bei uns ist das so ein Kapitel mit der Ordnung.
Ich habe die Combo so aufgebaut, weil hier wahllos gelöscht wird. Ein Fahrer der aufhört, wird sofort gelöscht. Hat einen, sorry für die Bezeichnung, GEILEN Effekt. In der Dispo stehen die Daten, wann, wer, wo. Wenn der Fahrer gelöscht wurde, ist er in der Dispo immer noch drin. Also habe ich aus dem löschen eine Markierung gemacht in der Farerdatenbank. Da gelöschte Sätze nicht angezeigt werden stimmt somit nicht der Index der Combo mit der Recno des Fahrers. Deswegen hab ich die Recno mit in die Combo genommen, um auf dessen Daten zugreifen zu können. Ich hab früher gelöscht und gepackt, doch nachdem mehrfach der böse GOTT ( Chef ) geflucht hat, weil er noch an alte Daten ran müßte, wurde das physikalische löschen von mir abgeschaft. Ja wenn der HERR so will, dann soll er es auch so bekommen :( . Hoffe auf Verständnis fur einen (Sklaven-) Programmschreiber :D . Das Löschen bezieht sich traurigerweise auch auf KFZ und Kunden. Stell dir vor, Du hast einen Kunden, der 6 Wochen keinen Auftrag erteilt. Hier wird dieser sofort gelöscht! Meldet sich der Kunde wieder, wird er neu angelegt ( ohje ). Genauso mit KFZ, zeitweise Stillegung bedeutet sofortiges löschen. Wieder im Betrieb, neu anlegen. Hier die Begründung meines Oberhauptes " ICH WILL NICHT EWIG DURCH DIE FAHRER BLÄTTER, BIS ICH DEN RICHTIGEN GEFUNDEN HABE. AUßERDEM, EIN FAHRER DER NICHT FÄHRT, BRAUCHT AUCH NICHT ERFASST ZU SEIN". Selbe Begründung für alles andere auch. Ich habe hier schon Wochen verbracht damit, Daten wieder herzustellen, weil ein Kunde sich nach 3 Monaten mit einer Reklamation gemeldet hat, und er diesen nach Beendigung der Zusammenarbeit sofort aus der Dispo gelöscht hat. Also muß ich "für mich" gewisse Absicherungen einbauen, damit es dem Chef passt, ich aber trotzdem noch an die Daten rankomme.
Gruß
Bruno
Messing
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Hilfestellung beim Einstieg in GUI

Beitrag von messing »

Servus,
Formdesigner ?
Der Formdesigner erstellt CLASS Code. Ich hab mal getestet
Das Formular welches der FD erstellt beinhaltet alle Objekte welche ich mit FD gemacht hab.

Code: Alles auswählen

NewForm():New():Create()
erstellt ein Dialogfenster mit allen Objekten.
Wie kann ich auf diese Objekte zugreifen? Verstehe ich dies richtig, wenn ich sage das alle Objekte im Dialogobjekt enthalten sind?
Ich hab mit

Code: Alles auswählen

abc:=NewForm():New():Create()
das Testprogr. laufen lassen und im Debugger gesehen, alles in einem.
Frage: Wie spricht man ein Objekt im Objekt an?
Gruß
Bruno
Messing
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14658
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Hilfestellung beim Einstieg in GUI

Beitrag von Jan »

messing hat geschrieben:Servus,
Formdesigner ?
Der Formdesigner erstellt CLASS Code. Ich hab mal getestet
Dann hast Du nicht genug getestet :wink: Da ich, wie allgemein bekannt, keinen Klassen-Code mag, speichere ich mir die Ergebnisse des Formdesigners als Funktions-Code ab. Sofern ich den Formdesigner überhaupt benutze, was extrem selten der Fall ist.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
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:

Re: Hilfestellung beim Einstieg in GUI

Beitrag von Martin Altmann »

Konstantin,
der Classcode, den Du bekommst, ist durchaus verbesserungswürdig.
Zum Beispiel solltest Du für jedes Objekt (SLE/MLE/Button/...) eine eigene Variable nehmen - am besten Klassenvariable. Dann kannst Du die entsprechenden Objekte recht einfach über ihren Namen ansprechen - also z.B.:

Code: Alles auswählen

	::Tierarzt   := XbpSLE():new( ::drawingArea, , {132,nY}, {468,20} )
	::Tierarzt:bufferLength := 57
	::Tierarzt:clipSiblings := .T.
	::Tierarzt:tabStop := .T.
	::Tierarzt:autoTab := .T.
	::Tierarzt:Tooltip := "Geben Sie den Tierarzt an!" 
	::Tierarzt:dataLink := {|x| IIf( PCOUNT()==0, (::dbSelect)->TIERARZT, (::dbSelect)->TIERARZT := alltrim( x ) ) }
	AAdd( ::editControls, ::Tierarzt )
Und später könntest Du dann z.B. mit ::Tierarzt:EditBuffer() auf den Inhalt des Eingabefeldes zugreifen.

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
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:

Re: Hilfestellung beim Einstieg in GUI

Beitrag von brandelh »

Martin Altmann hat geschrieben:der Classcode, den Du bekommst, ist durchaus verbesserungswürdig.
im Function code stimme ich dir zu, da dort standardmäßig alle Controls mit oXbp erstellt werden und weiter untern in der Funktion dann nicht direkt zugreifbar sind.
Beim Class-Code bekommst du aber genau das was du vorher eingegeben hast ;-)

Edit -> Symbols for iVar oder in den Properties iVarName ...
Der IVarName des Fensters wird später übrigens zur Basisklasse dieses Fensters.
Gruß
Hubert
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:

Re: Hilfestellung beim Einstieg in GUI

Beitrag von Martin Altmann »

Echt?
Das war aber früher nicht so - meiner Meinung nach. Das letzte Mal habe ich den FD vor etlichen Jahren genutzt.

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
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Hilfestellung beim Einstieg in GUI

Beitrag von messing »

Danke an Euch beide :D
Gruß
Bruno
Messing
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Re: Hilfestellung beim Einstieg in GUI

Beitrag von AUGE_OHR »

messing hat geschrieben:bei uns ist das so ein Kapitel mit der Ordnung.
Ich habe die Combo so aufgebaut, weil hier wahllos gelöscht wird...
ok das mit dem löschen ist noch ein anderes Thema. ich wollte auf ein "grosses" Array hinaus.

um die Combobox zu "füllen" musst du ja eh einmal durch die DBF.
nun nimmst 2 Felder als 1 Item als Eintrag per o:additem()
später "zerteilst" du den String dann wieder mit SUBSTR()

mein Vorschlag : alles in ein Array

also DBF -> Array // pro FELD eine Column
o:addItem( aArray [1] ) // erste Column -> Anzeige
o:itemselect -> oCombobox:getData() -> Array -> Element -> i
result -> aArray [2] ... // 2nd Column result ... usw

ICH WILL NICHT EWIG DURCH DIE FAHRER BLÄTTER, BIS ICH DEN RICHTIGEN GEFUNDEN HABE
wie wäre "inkrementelles" suchen ?

ich sagt ja schon das sich deine Combobox mit dem Keyboard nicht so richtig arbeitet. wenn ich einen Buchstaben eingebe, nach dem ich mit F4 eine Combobox geöffnet habe, springt er auf das Item aber "löst" auch sofort aus. Ich kann dann nicht per K_UP / K_DOWN navigieren.

ein "inkrementelles" suchen würde ja über den oCombobox:keyboard Slot erfolgen ... du darfst aber nicht sofort ein o:itemselect auslösen d.h. xbeLB_ItemSelected "abfangen"

wenn ich mir das ganze so ansehe frage ich mich ob man statt der 4 x Combobox lieber 4 x Browse mit 1 Column nehmen sollte ...
gruss by OHR
Jimmy
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Hilfestellung beim Einstieg in GUI

Beitrag von messing »

AUGE_OHR hat geschrieben: mein Vorschlag : alles in ein Array
Hi Jimmy, hab alles mal überarbeitet, habe das ganze als ZIP beigefügt. Wie müßte ich jetzt weitermachen, um in den Comboboxen den ersten Listeneintrag zu haben, und zugleich der Wert im Eingabearray abgelegt wird?

An alle, der Aufruf war Hilfestellung beim Einstieg in GUI :D
Durch die DevCon angetrieben solltet ihr auch mal reinschauen. Ich bin über jeden Komentar erfreut.
Dateianhänge
TEST.ZIP
Bitte nicht zurückhalten mit INFOs
(420.91 KiB) 194-mal heruntergeladen
Gruß
Bruno
Messing
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Hilfestellung beim Einstieg in GUI

Beitrag von messing »

Biite an ALLE,
Was muß ich machen, das mir bei 2 offenen Fenstern, 1. Eingabe, 2. Browse, das Browse nicht jedesmal Salat zuückgibt. Wenn ich erst das Browse öffne und dann das Eingabe Fenster werden mir jedesmal wenn ich wieder ins Browse gehe dort die Daten verhunzt. Ich hab noch keine Eingabe gemacht, sondern nur das Fenster nach dem Browse geöffnet und dann wieder ins Browse geklickt. Noch etwas: CUSTOMER->NAME im Xbpbrowse funktioniert nicht von einer anderen Workarea aus. Gibts da einen Trick?
Gruß
Bruno
Messing
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Re: Hilfestellung beim Einstieg in GUI

Beitrag von AUGE_OHR »

messing hat geschrieben:Wie müßte ich jetzt weitermachen, um in den Comboboxen den ersten Listeneintrag zu haben, und zugleich der Wert im Eingabearray abgelegt wird?

Code: Alles auswählen

   ::KundenCombo:setdata({1})
   ::TransCombo:setdata({1})
   ::KfzCombo:setdata({1})
   ::FahrerCombo:setdata({1})
wenn du nun einen "bestimmten" Kunden haben willst kannst du mit

Code: Alles auswählen

   nPosi := ASCAN(::KUNDENARRAY,{ |e| e[ KUNDEN_NAME ] = cKD_Name } )
   IF nPosi > 0
       ::KundenCombo:setdata({nPosi})
   ELSE
       ::KundenCombo:setdata({1})
   ENDIF
messing hat geschrieben:Was muß ich machen, das mir bei 2 offenen Fenstern, 1. Eingabe, 2. Browse, das Browse nicht jedesmal Salat zuückgibt.
hast du es mit meinem "Thread():NEW()" Vorschlag versucht ?
messing hat geschrieben:Noch etwas: CUSTOMER->NAME im Xbpbrowse funktioniert nicht von einer anderen Workarea aus. Gibts da einen Trick?
meinst du nun WorkArea (???) oder WorkSpaceList() ?
gruss by OHR
Jimmy
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Hilfestellung beim Einstieg in GUI

Beitrag von messing »

Ich öffne die DBF im Browse und nochmal in der Eingabe. Kein zweiter Thread. Selbe DBF. Wenn ich von Workarea Parts aus versuche ein Browse von Customer zu machen CUSTOMER->NAME, nur ein und derselbe Satz im Browse. Befinde ich mich in der Workarea CUSTOMER, dann macht er das Browse richtig.
Gruß
Bruno
Messing
Antworten