Xbase für Anfänger

Konzeptionelles, Technisches, Termine, Fragen zum Hersteller usw.

Moderator: Moderatoren

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: Xbase für Anfänger

Beitrag von brandelh »

GANZ WICHTIG ist es am Anfang neben den Grundlagenkapiteln im Handbauch auch die Beispiele anzusehen.
Am schnellsten geht es mit den "Application Part"s, wie z.B. APPEDIT, aber die Ergebnisse haben mich damals nicht überzeugt,
ist aber schon ne Weile her, vielleicht sind die besser geworden ;-)
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: Xbase für Anfänger

Beitrag von AUGE_OHR »

Benz hat geschrieben:Ja hab den FormDesigner schon versucht, allerdings funktioniert der nicht richtig. ich kann keine aktion machen, ich kann ihn wenn ich ihn geöffnet habe nicht mal mehr ohne taskmanager schließen.
hm ... welche Xbase++ Version hast du ? welches OS() ?
Benz hat geschrieben:Es ist auch so, dass ich nicht unbedingt mit dem FormDesigner programmieren will, da es mir ziemlich wichtig ist, das ganze von Grund auf zu verstehen.
"programmieren" ist hier das falsche Wort. Vielmehr "generiert" der FormDesigner dir Source Code aus dem was du "zusammen-geclicked" hast. "mehr" kann der (jetzige) Xbase++ FormDesigner nicht aber du kannst dir dann den Source Code ansehen wie er z.b. die o:datalink "geschrieben" hat.

p.s. lass dir dann "Class Code" ausgeben statt "Function Code"
gruss by OHR
Jimmy
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: Xbase für Anfänger

Beitrag von brandelh »

Hi,

auch ich nutze den Formdesigner um die nötigen Controls mit einigen Grundeinstellung in etwa zu positionieren. MIT CLASS-Code wie Jimmy schrieb !
Ganz wichtig ist es, unter "Bearbeiten \ Symbole für iVar" allen Controls und dem Fenster (das wird der ClassName !) ordentliche Namen zu geben.
Diese werden dann später verwendet um ein Control zu steuern.
oftName und osleName sind einfach sprechender als oft1 und osle1 ;-)
Die "Bearbeiten \ Reihenfolge" (Tab-Reihenfolge) kann man sich sparen, bei jeder Änderung wird die wieder umgestellt :-( ( zumindest bis 1.90.335)
Die Tab-Reihenfolge kann man einfach durch die Reihenfolge er Controls in der Create() Methode einstellen. Wer zuerst steht, bekommt TAB zuerst ;-)
Das genaue Ausrichten kann man sich genauso sparen, dazu ist der XppFD einfach zu schlecht (wird sich ja in Xbase VX 3.0 ändern, versprochen :D hat man sich schnell :badgrin: ).
Das mache ich im Programm über Variablen.
nSpaFt1, nSpaSle1 etc. und tausche die fixen Zahlen gegen diese Variablen aus.
nPosY z.B. zähle ich hoch, so kann man auch ganz einfach mit einer kleinen Änderung eine ganze Spalte verschieben oder durch einfaches Einfügen einer Zeile mit neuem Code ein
eine neue Control-Zeile einfügen und alles passt dennoch.
Ich mache das in Create, andere im resize(), was immer dann besser ist, wenn ein Dialog in der Größe geändert werden kann. Schlechter ist es NIE ! ;-)

Ich nutze den XppFD in einem Unterverzeichnis nur das erste mal für den gesamten PRG code, danach hole ich nur die Änderungen in das richtige Programmverzeichnis.
Klingt umständlich, aber so habe ich die volle Kontrolle und mein Texteditor ist sehr gut ;-)

Wichtig ist auch, dass man eine PRG nur für die GUI nutzt, und die andere für die Implementation von der Logik, die GUI Datei wird so schon groß genug.
xppFD benennt die GUI Datei mit _X.PRG wenn die andere X.PRG heist, das ist schon OK, aber nicht optimal ;-)
ich nenne dlgNameGUI.PRG und dlgNameCode.PRG, die werden zusammen einsortiert. Die MAIN und die #include "_..." Anweisungen muss man dann noch löschen und statt beidem eine normale Funktion() schreiben, die ein solches Fenster aufbaut.
Gruß
Hubert
Benz
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 440
Registriert: Mo, 30. Mai 2011 15:06
Danksagung erhalten: 1 Mal

Re: Xbase für Anfänger

Beitrag von Benz »

brandelh hat geschrieben:Hi,

ja man kann den Ursprung als PresentationParameter nach oben links verlegen, so mache ich das ...
Allerdings ist das noch nicht dokumentiert.

So sieht das bei mir aus:

Code: Alles auswählen

*---------------------------------------------------------------------------
METHOD HB_Dialog:init( oParent, oOwner, aPos, aSize, aPP, lVisible )
   local x
   DEFAULT aPP TO { { XBP_PP_ORIGIN , XBP_ORIGIN_TOPLEFT } }
   x := aScan(aPP, {|aP| aP[1]=XBP_PP_ORIGIN } )
   if x > 0
      aPP[x] := { XBP_PP_ORIGIN , XBP_ORIGIN_TOPLEFT }
   else
      aadd( aPP, { XBP_PP_ORIGIN , XBP_ORIGIN_TOPLEFT } )
   endif
   DEFAULT lVisible TO .F.
   DEFAULT oParent  TO SetAppWindow()

   ::XbpDialog:init( oParent, oOwner, aPos, aSize, aPP, lVisible )

Kannst du mir vielleicht sagen wie ich das einbinde ? :?: :?: :?: :?: :oops: :oops:
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: Xbase für Anfänger

Beitrag von brandelh »

Hi,

bei einem Fenster aPP mit dem obigen DEFAULT Wert vorbelegen (plus eventuell anderen Sachen) ist am einfachsten.
Ich habe mir den XbpDialog() erweitert, daher oben auch HB_Dialog(), aber mein ganzes Framework ist nicht ganz einfach zu verstehen ;-)
Gruß
Hubert
Benz
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 440
Registriert: Mo, 30. Mai 2011 15:06
Danksagung erhalten: 1 Mal

Re: Xbase für Anfänger

Beitrag von Benz »

ok :-) hat jetzt geklappt, glaub ich zumindest :D. Danke
Benz
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 440
Registriert: Mo, 30. Mai 2011 15:06
Danksagung erhalten: 1 Mal

Re: Xbase für Anfänger

Beitrag von Benz »

Wie kann man denn Sonderzeichen richtig darstellen lassen ?

Außerdem würde ich gerne 2 Childfenster öffnen, das habe ich soweit, in dem einen steht dann ein Formular und im anderen steht ein Browse-Objekt, mit dem ich auf eine Datenbank zugreife.
Könnte mir jemand sagen, wie ich es mache, dass bei Klick auf das Browse-Objekt in irgendeine Zeile, diese Zeile in das Formular übergeben wird und verändert werden kann ?!

Gruß
Zuletzt geändert von Benz am Mo, 20. Jun 2011 7:48, insgesamt 1-mal geändert.
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: Xbase für Anfänger

Beitrag von AUGE_OHR »

Benz hat geschrieben:Wie kann man denn Sonderzeichen richtig darstellen lassen ?
meinst du das € Zeichen ?
mit /PM:PM linken

SETLOCALE( NLS_ICURRENCYEURO, "1" )
SETLOCALE( NLS_SCURRENCY, CHR( 213 ) ) // bei OEM
SETLOCALE( NLS_SCURRENCY, CHR( 128 ) ) // bei ANSI
und natürlich muss der gewählte Font das € Zeichen auch haben.
gruss by OHR
Jimmy
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: Xbase für Anfänger

Beitrag von brandelh »

Ansonsten kann man viele aus der Zeichentabelle entnehmen und direkt im Quellcode einfügen, wenn man auf ANSI Quellcode geschaltet hat.
Wenn nicht, braucht man eine Zeichenliste von dem PC Zeichensatz (meist PC850) und kann dann einige nur über den Zahlencode eingeben.
So mache ich z.B. chr(34) wenn ich " Zeichen im String anhängen will, da sonst mein Editor mit der Einfärbung Probleme bekommt.
Notfalls kann man sich eine drucken bzw. besser in eine Datei ausgeben, wobei Zeichen unter chr(32) nicht (alle) druckbar sind.

Code: Alles auswählen

set alternate to DOS-Zeichen.TXT
set alternate on 
? "DOS Zeichensatz: "
? str(32,3),"Blank"
for x := 33 to 255
   ? str(x,3),chr(x)
next
set alternate to 
Gruß
Hubert
Benz
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 440
Registriert: Mo, 30. Mai 2011 15:06
Danksagung erhalten: 1 Mal

Re: Xbase für Anfänger

Beitrag von Benz »

ok.
Und hat vielleicht auch jemand eine Lösung für meine zweite Frage ? :-)
Benz hat geschrieben: Außerdem würde ich gerne 2 Childfenster öffnen, das habe ich soweit, in dem einen steht dann ein Formular und im anderen steht ein Browse-Objekt, mit dem ich auf eine Datenbank zugreife.
Könnte mir jemand sagen, wie ich es mache, dass bei Klick auf das Browse-Objekt in irgendeine Zeile, diese Zeile in das Formular übergeben wird und verändert werden kann ?!

Gruß
Benutzeravatar
Bertram Hansen
Foren-Moderator
Foren-Moderator
Beiträge: 1015
Registriert: Di, 27. Sep 2005 8:55
Wohnort: 51379 Leverkusen
Hat sich bedankt: 28 Mal
Danksagung erhalten: 20 Mal
Kontaktdaten:

Re: Xbase für Anfänger

Beitrag von Bertram Hansen »

Hallo Benz,

das geht über den Callback Slot beim XbpBrowse()

Auszug aus der Doku:

Code: Alles auswählen

Klasse 
XbpBrowse()

   Slot:	:itemMarked := {| aRowCol, uNIL2, self | ... }
Methode:	:itemMarked ( <RowCol> ) --> self

Parameter 
<aRowCol>

<aRowCol> ist ein Array mit zwei Elementen { nRowPos, nColPos }. Es gibt die Zeilen- und Spaltenposition der Zelle im Browser an, in der die linke Maustaste gedrückt wurde. 

Rückgabe 
Die Methode gibt das Objekt zurück, das die Methode ausgeführt hat. 

Beschreibung 
Das Ereignis xbeBRW_ItemMarked wird erzeugt, wenn eine Zeile oder eine Zelle im Browser hervorgehoben ist. 
Du musst dort eine Funktion/Prozedure aufrufen, die dann die Daten im Formular aktualisiert bzw. zum editieren frei gibt. Suche mal nach itemMarked hier im Forum.
:wave:
Gruß Bertram
http://www.tobax.de
Mitglied der XUG Cologne
Mitglied der XUG Osnabrück
Beisitzer des Deutschsprachige Xbase-Entwickler e.V.

Solange Kakaobohnen an Bäumen wachsen ist Schokolade Obst!
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: Xbase für Anfänger

Beitrag von AUGE_OHR »

Benz hat geschrieben:Und hat vielleicht auch jemand eine Lösung für meine zweite Frage ? :-)
das "auslösen" hat dir ja Bertram erklärt. aber wie "synchronisiert" man die Maske mit dem Browse ?

wenn du die Maske mit dem FormDesigner ( XPPFD.EXE ) erstellt hat und "Class Code" generiert hast dann gibt es die iVar "editcontrol".
"editcontrol" hat per AADD() alle XbpSLE Objecte in ein Array aufgenommen.

ein XbpSLE hat ja nun einen o:Datalink, in dem ein Codeblock steht, der für da "lesen"/"schreiben" zuständig ist.

Code: Alles auswählen

AEVAL( oMaske:editcontrol, { | oXbp | oXbp:SetData() } )
damit werden ja die "Werte in Editcontrols übertragen" so das du sie anzeigen/editieren kannst.

nun gibt es es bei XbpBrowse() den Slot "o:stableBlock" den man mit einem Codeblock "bestücken" kann.

Code: Alles auswählen

 ::oBrowse:stableblock := {|| Ref2Gets(::editControls)}

FUNCTION Ref2Gets(editcontrols,oBrowse)
LOCAL oCol
LOCAL i
LOCAL n
LOCAL LenGets := LEN(editcontrols)

   FOR n := 1 TO LenGets
      editcontrols[n]:setdata() // lese DBF und fülle SLE
      editcontrols[n]:show()    // anzeigen
   NEXT
RETURN NIL
damit bekommst du nun bei einer "Bewegung" im Browse die "passenden" Daten in der Maske.

In meine Beispiel gehe ich davon aus das "im Fenster" der Maske auch das Browse ist.
wenn es 2 "Fenster" sind müsstest du das oMaske:editcontrols in den oBrowse:stableblock bekommen
... aber das ist noch ein ganz anderes Thema mit mehreren "Fenstern"
gruss by OHR
Jimmy
Benz
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 440
Registriert: Mo, 30. Mai 2011 15:06
Danksagung erhalten: 1 Mal

Re: Xbase für Anfänger

Beitrag von Benz »

ok sehr gut danke euch allen :-)

Kann mir dann noch jemand sagen, wie das Ereignis heißt, das ausgelöst wird, wenn ich ein SLE verlasse, also entweder durch Mausklick auf ein anderes SLE oder durch den Tabulator oder sonst irgendwie. ?! Danke schonmal im voraus : -)


ganz nebenbei noch :D : wie kommt der "spitzname" rechts eigentlich zustande ? ;) Hat mich jemand so genannt oder ist das abhängig von der Anzahl meiner Beiträge :-D
Zuletzt geändert von Benz am Di, 21. Jun 2011 10:51, insgesamt 1-mal geändert.
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

Re: Xbase für Anfänger

Beitrag von Manfred »

Hi,

wenn Du in der Hilfe zu XbpSle mal auf Klassenbaum klickst, dann bekommst Du alle wichtigen Dinge angezeigt.

Dein Spitz-Name wird vom Forum vorgegeben, je nachdem wieviele Beiträge Du bisher hattest. Da kommen noch bessere Namen, warte es nur ab. :badgrin:
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
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

Re: Xbase für Anfänger

Beitrag von Markus Walter »

Benz hat geschrieben:ok sehr gut danke euch allen :-)

Kann mir dann noch jemand sagen, wie das Ereignis heißt, das ausgelöst wird, wenn ich ein SLE verlasse, also entweder durch Mausklick auf ein anderes SLE oder durch den Tabulator oder sonst irgendwie. ?! Danke schonmal im voraus : -)
Die Ereignisreihenfolge für den Dialog ist in der Online-Hilfe bei der Funktion SetAppFocus() dokumentiert. Für die SLE-Klasse siehst Du alle Ereignisse in der Doku bei XbpWindow (von der die XbpSLE ja abgeleitet ist). Da findest Du xbeP_KillInputFocus. Das ist das Ereignis, das Du suchst
Benz hat geschrieben: ganz nebenbei noch :D : wie kommt der "spitzname" rechts eigentlich zustande ? ;) Hat mich jemand so genannt oder ist das abhängig von der Anzahl meiner Beiträge :-D
Dieser Name hängt in der Tat von der Anzahl der Beiträge ab (ausser bei Administratoren und Moderatoren).
Gruß
Markus

Mitglied der XUG Saarland-Pfalz
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

Re: Xbase für Anfänger

Beitrag von Manfred »

Markus,

Danke für die Bestätigung meiner Aussage =D> :lol:
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!!
Benz
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 440
Registriert: Mo, 30. Mai 2011 15:06
Danksagung erhalten: 1 Mal

Re: Xbase für Anfänger

Beitrag von Benz »

ok, und nochmals danke.
Ich habe auch schon in der Hilfe geschaut, nur dass keine Missverständnisse auftreten :-P ich schaue schon vorher, aber wenn ich nichts finde schreibe ich hier hinein.

Für mich als Anfänger ist es erst einmal ziemlich schwierig mich in der OnlineHilfe zurecht zu finden.
Für euch wird das bestimmt eine Kleinigkeit sein so etwas herauszufinden :-D.
Ich muss mich erst mal zurecht finden dann klappt das denke ich :-)
Benz
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 440
Registriert: Mo, 30. Mai 2011 15:06
Danksagung erhalten: 1 Mal

Re: Xbase für Anfänger

Beitrag von Benz »

Jetzt habe ich ein Problem mit dem Ereignis:

Ich habe diesen Code für 2 SLEs.

Code: Alles auswählen

  
  sle_mnummer := XbpSLE():New(grp1,, {116, 36}, {100, 22})
  sle_mnummer:TabStop := .T.
  sle_mnummer:dataLink := {|x| IIf( x==NIL, cVarB, cVarB := x ) }
  sle_mnummer:LayoutAlign := 1
  sle_mnummer:setData()
  sle_mnummer:killInputFocus := ;
          { |x,y,oSLE2| oSLE2:getData(), ConfirmBox ( , "TEst: ", cVarB)  }

  sle_passwort := XbpSLE():New(grp1,, {316, 40}, {100, 22})
  sle_passwort:TabStop := .T.
  sle_passwort:dataLink := {|x| IIf( x==NIL, cVarC, cVarC := x ) }
  sle_passwort:LayoutAlign := 2
  sle_passwort:setData()
  sle_passwort:killInputFocus := ;
          { |x,y,oSLE3| oSLE3:getData(), ConfirmBox ( , "TEst: ", cVarC)  }
Das Beispiel, das bei xbpsle() dabei stand funktioniert problemlos.
Mein Problem ist jetzt, wenn ich beispielsweise aus dem sle_mnummer herausgehe bekomme ich die richtig Confirmbox.
Nur wenn ich sie wegklicken will dann kommt eine falsche, die immer wieder eine neue falsche aufruft, wenn ich sie wegklicke.

An was kann das liegen ? Habe ich etwas vergessen ?

Hier das Beispiel aus xbpsle():

Code: Alles auswählen

// In the example, two XbpSLE objects are created in an XbpCrt
// window with edit buffers limited to 20 and 15 characters,
// respectively. Both XbpSLE objects use data code blocks
// to access LOCAL variables. These code blocks are evaluated
// when the XbpSLE object loses the input focus. In the callback
// slot :killInputFocus, :getData() is called to read the edit
// buffer and assign the values to LOCAL variables via :dataLink.

   #include "Appevent.ch"

   PROCEDURE Main
      LOCAL nEvent, mp1, mp2, oXbp
      LOCAL cVarA := "Test A", cVarB := "Test B"
      SetColor("N/W")
      CLS

      // Create first SLE, specify position using :create()
      // On :typeOut set the focus to the second SLE
      oXbp              := XbpSLE():new()
      oXbp:autoTab      := .T.
      oXbp:bufferLength := 20

      // Data code block containing assignment to LOCAL variable
      oXbp:dataLink := {|x| IIf( x==NIL, cVarA, cVarA := x ) }

      oXbp:create( , , {100,200}, {100,30} )

      oXbp:setData()

      // Assign the value of the edit buffer to a LOCAL variable
      // when the input focus is lost
      oXbp:killInputFocus := ;
          { |x,y,oSLE| oSLE:getData(), QOut( "cVarA =", cVarA ) }

      // Create second SLE, specify position using :new()
      oXbp              := XbpSLE():new( , , {100,150}, {100,30} )
      oXbp:tabStop      := .T.
      oXbp:bufferLength := 15
      oXbp:dataLink := {|x| IIf( x==NIL, cVarB, cVarB := x ) }
      oXbp:create()

      oXbp:setData()
      oXbp:killInputFocus := ;
          { |x,y,oSLE| oSLE:getData(), QOut( "cVarB =", cVarB ) }

      // Event loop
      nEvent := 0
      DO WHILE nEvent <> xbeP_Close
         nEvent := AppEvent( @mp1, @mp2, @oXbp )
         oXbp:handleEvent( nEvent, mp1, mp2 )
      ENDDO
   RETURN

Benutzeravatar
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

Re: Xbase für Anfänger

Beitrag von Markus Walter »

Manfred hat geschrieben:Markus,

Danke für die Bestätigung meiner Aussage =D> :lol:
Du warst halt - mal wieder - zu schnell für mich... :D
Gruß
Markus

Mitglied der XUG Saarland-Pfalz
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: Xbase für Anfänger

Beitrag von brandelh »

Hi,

auf deine konkrete Frage fällt mir zwar jetzt nichts ein, aber in deinem Code sind mir zwei Sachen aufgefallen,
die verbessert - besser verstanden werden sollten ;-)

Code: Alles auswählen

sle_passwort := XbpSle():new(...
...
sle_passwort:setData()
sle_passwort:killInputFocus := ;
          { |x,y,oSLE3| oSLE3:getData(), ConfirmBox ( , "TEst: ", cVarC)  }
Zunächst darf man eine Methode (bis auf wenige Ausnahmen) erst nach den Create() ausführen,
der Code sieht aus als ob er in der INIT() Methode steht, somit darf sle_passwort:setData() hier nicht stehen.

dann verwendest du als 3. Parameter durchnummerierte Variablen, das läßt mich darauf schließen, das du nicht weißt,
dass es sich um lokale Variablen ausschließlich INNERHALB des Codeblocks handelt:

Code: Alles auswählen

x1:killInputFocus := { |x,y,oSLE1| oSLE1:getData()...
x2:killInputFocus := { |x,y,oSLE2| oSLE2:getData()...
x3:killInputFocus := { |x,y,oSLE3| oSLE3:getData()...
es ist nicht falsch es so zu schreiben, aber oSLE1 wird von killinputfocus gefüllt, mit dem Objekt das diesen aufgerufen hat.
Hier wird also x1 als 3. Parameter an oSLE1 übergeben, sobald x1 den input focus verliert.
Hier wird also x2 als 3. Parameter an oSLE2 übergeben, sobald x2 den input focus verliert.
...
Falsch ist es nicht, aber verwirrend und wenn du mit Cut&Paste Programmteile wiederverwendest, könntest du eine Variable versehentlich nicht umändern.

In den Beispielen im Handbuch wird oft diese Syntax verwendet:

Code: Alles auswählen

x1:killInputFocus := { |x,y,SELF| SELF:getData() ...
Dies führt aber dazu, dass in diesem Codeblock die Variable SELF (das aufrufende Control, hier x1) die Systemvariable SELF des Fensters überschreibt.
Ein ::MeineFensterMethode() wird dann statt auf das Fenster auf x1 zugreifen und logischerweise mit dem Fehler "unbekannte Methode" abbrechen.
Bis man so einen Fehler gefunden hat !

Ich empfehle daher immer diese Namensgebung, einfach, verständlich und treffsicher:

Code: Alles auswählen

x1:killInputFocus := { |p1,p2,oXbp|   oXbp:....
Gruß
Hubert
Benz
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 440
Registriert: Mo, 30. Mai 2011 15:06
Danksagung erhalten: 1 Mal

Re: Xbase für Anfänger

Beitrag von Benz »

Hallo Hubert,

ich habe setdata() auch zuerst weggelassen, dann hat es auch funktioniert.

Ich habe es nur hinzugefügt um zu testen, ob das vielleicht fehlt, aber das Programm zeigt keine Reaktion daruf.
Das gleiche bei den Variablen:

Ich wollte testen, ob es möglicherweise etwas mit der gleichen Namensgebung zu tun hat. Wie man sehen kann: Fehlanzeige.

Naja. Kann es vielleicht daran liegen, dass das Beispiel ein Hybridprogramm ist und mein Programm nicht ?!
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: Xbase für Anfänger

Beitrag von brandelh »

Hallo,

Die Hybrid Programme verhalten sich in einigen Dingen anders, hier z.b. wird im Beispiel auf der Console mit qout() die Info nur angezeigt.
Dadurch wird aber keinesfalls ein Event erzeugt. Das Original-Beispiel wird in den nächsten SLE wechseln und auf Eingaben warten.

In deinem Beispiel verwendest du eine confirmbox() diese wird auf jeden Fall zunächst den Focus vom Fenster wegnehmen und selbst übernehmen.
Beim Schließen muss nun das Fenster wieder reagieren und sollte selbst den DisplayFocus übernehmen (das Fenster wird angezeigt), wenn du allerdings zuvor
in ein SLE geklickt hast, müsste dieses nun den InputFocus Event auslösen.
:idea: Aber da haben wir das Problem doch schon, lies mal inder Hilfe zu killInputFocus nach !
Wenn der Codeblock ausgeführt wird, hat er das alte SLE schon verlassen und ist schon im neuen !
Noch bevor der Befehl confirmbox erreicht wird, hängt er bereits in dem angeklickten oder nächsten SLE ... die 1. Confirmbox übernimmt nun den Focus,
was zu einem erneuten auslösen von KillInputFocus, diesmal aber vom SLE2 etc. führt. Bevor dieses nun die 2. Confirmbox starten kann,
ist der Focus schon wieder in der Ersten und so weiter und so fort.

Aus genau diesem Grunde ist ein Debugger bei Windows GUI Problemen (wer hat Focus, welcher Event etc.) kaum zu gebrauchen.
Darum ist in dem Beispiel ein XbpCRT und QOUT() verwendet worden.

Ich habe in der Wissensdatenbank eine Funktin DebugPrint() veröffentlicht. An diese kann man solche Meldungen senden, ohne das Events ausgelöst werden.
Ein neues Fenster zeigt diese dann an. Eine andere Möglichkeit ist SET ALTERNATE TO ... (SET CONSOLE OFF nicht vergessen) und ? DebugText in eine Textdatei.
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: Xbase für Anfänger

Beitrag von AUGE_OHR »

hi,
Benz hat geschrieben:

Code: Alles auswählen

    sle_mnummer:killInputFocus := ;
          { |x,y,oSLE2| oSLE2:getData(), ConfirmBox ( , "TEst: ", cVarB)  }
zur Ergänzung von Huberts Aussagen das o:getData() ja schon den o:datalink ausgeführt hat kommt hinzu das mit einer DBF ein "sperren" notwendig ist.

das o:killInputFocus entspricht einem VALID ( o:SetInputFocus wäre das WHEN ) und das REPLACE wäre das o:getData().
du würdest aber auch nicht jedes mal ein REPLACE machen sondern alle zusammenfassen so wie mit

Code: Alles auswählen

IF RLOCK()
   AEval ( ::EditControls, { | oXbp | oXbp:GetData() } )
   UNLOCK
ENDIF
zu VALID : wie unter Clipper würde ich alles in eine Function schreiben und mit o:EditBuffer() abfragen.

Code: Alles auswählen

   oSLE:killInputFocus := {|x,y,oSelf| MyValid(oSelf,"Text_welches_SLE"} 

FUNCTION MyValid(oSelf,cName)
LOCAL cInhalt := oSelf:Editbuffer()
LOCAL lRet  := .T.
LOCAL nButton

DO CASE
     CASE cName = "SLE001"
       IF EMPYT(cInhalt)
           ...
           nButton := Confirmbox(,"blabla","Title",XBPMB_YESNO , ; 
                        XBPMB_QUESTION+XBPMB_APPMODAL+XBPMB_MOVEABLE ) 
           IF nButton = XBPMB_RET_YES
           ...
           ELSE
              // wieder auf die Position zurück     
              lRet  := .F. 
              SetAppFocus(oSelf)     
           ENDIF
       ENDIF
...
ENDCASE
RETURN lRet
gruss by OHR
Jimmy
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: Xbase für Anfänger

Beitrag von brandelh »

Hi,

um Missverständnissen vorzubeugen, ein richtiges Clipper Valid ist mit Windows nicht möglich :!:
Ein Clipper Valid mit Return .f. geht nicht aus dem Get Feld raus.
Ein KillInputFocus wird aber erst erzeugt, nachdem das Feld schon verlassen wurde.
Man kann zwar ein mit setAppFocus() den Cursor wieder in das Feld zwingen, aber das widerspricht dem normalen Windowsverhalten.
Wenn dann zusätzlich auch das neue Feld (das jetzt ja aktiv ist) eine solche Valid hat, hängt man in einer Endlosschleife !

Unter Windows ist es besser vor dem Speichern alle Daten auf einmal zu prüfen.
Um den Inhalt eines SLE zu prüfen MUSS man :EditBuffer() abfragen, denn :getData()
würde einen eventuell bestehenden :datalink ausführen und somit schon schreiben.
Das wird in der Hilfe zwar irgendwo erwähnt, in vielen Beispielen wird dennoch :getData() verwendet,
ohne Hinweis was passieren könnte !
Gruß
Hubert
Benz
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 440
Registriert: Mo, 30. Mai 2011 15:06
Danksagung erhalten: 1 Mal

Re: Xbase für Anfänger

Beitrag von Benz »

@AUGE_OHR

Ich habe deinen Code mal getestet, die fehlende Klammer bei killinputfocus eingesetzt , die Namen geändert, den Rechtschreibfehler bei EMPTY geändert (alles nicht böse gemeint !) nur leider funktioniert es immer noch nicht :-(

Und seid mir nicht böse, ich verstehe glaub ich schon, was ihr meint, nur habe ich keinen Plan wie ich es umsetzen könnte (außer, wie mein Name schon sagt -> Cut & Paste :-D) :oops:

Gruß
Antworten