Seite 1 von 1

Dialog-Funktion und onchange

Verfasst: 16.12.2013 15:47
von ProgOldie
Hallo,
ich will die Daten einer DB per Dialog() sichtbar machen und ändern können, indem ich Kiffis Beispiel http://www.purebasic.fr/german/viewtopi ... =3&t=27566 verallgemeinern will. Den Namen des jeweiligen Gadgets definiere ich aus Zeilen und Spaltennummer gemäß 'Zeile|Spalte'. Das läuft alles schon recht gut.

Nun aber will ich als Erweiterung eine Prozedur aufrufen, wenn sich der Inhalt des Gadgets ändert. Ich komme aber leider nicht mit dem onchange klar. Hier 'mal ein Auszug aus einer Zeile zum Befüllen eines Gadgets

Code: Alles auswählen

" < string name='5|7' onchange='changeproc()' width='100' text='" + GetDatabaseString(DB, 0) + "' />" +.......
Die Prozedur changeproc() soll das Ereignis abfangen, wenn der Wert im Gadget mit dem Namen '5|7' geändert wurde.

Zunächst:Ist die Syntax für das Befüllen dieser Zeile im Hinblick auf onchange richtig?
Was mache ich beim Aufruf der Änderungsprozedur falsch?

Re: Dialog-Funktion und onchange

Verfasst: 16.12.2013 15:57
von ts-soft
OnChange() wird nur aufgerufen, wenn ein Anwender den Wert im Gadget geändert hat, nicht wenn der
Wert programmiertechnisch geändert wird! In diesem Falle solltest Du ein entsprechendes PostEvent()
einfügen oder OnChange() selber aufrufen.

Re: Dialog-Funktion und onchange

Verfasst: 16.12.2013 18:02
von ProgOldie
@ts-soft
OnChange() wird nur aufgerufen, wenn ein Anwender den Wert im Gadget geändert hat.
Genau darum geht's mir ja. Ich will bei einer Änderung des in der Tabelle angezeigten Wertes diese Änderung in die DB übertragen. Ich habe erst gedacht, es ginge nach Erzeugung der Tabelle mit

Code: Alles auswählen

Repeat
  Ev=WindowEvent()
  If Ev
    Select Ev
      Case #PB_Event_Gadget
        EvGad=EventGadget()
        EvType=EventType()
        Select EvType
            Case #PB_EventType_LostFocus
              Changed(EvGad)
        EndSelect
   EndSelect
  EndIf    
Until Ev=#PB_Event_CloseWindow
Das aber klappt nicht.
Liegt ein Fehler in der Eventabarbeitung oder eben doch beim 'onchange' vor?

Dank vorab!

Re: Dialog-Funktion und onchange

Verfasst: 16.12.2013 18:18
von ts-soft
Ein lauffähiges Beispiel wäre schön wünschenswert, ansonsten gibts hier nur theoretische Auskünfte :wink:
Deine OnChange() Procedure kann ich hier nirgends entdecken, ansonsten wäre ein reagieren auf onlostfocus()
wohl sinnvoller, als wenn bei jedem Tastendruck was in die DB eingetragen wird.

Deine losen, nicht ausführbare Snippets, sind nicht hilfreich. Zumindest Dein Eventloop mit WindowEvent anstatt
WaitWindowEvent, wird die CPU unnütz belasten und könnte ein Problem sein, für das Funktionieren.

Gruß
Thomas

Re: Dialog-Funktion und onchange

Verfasst: 16.12.2013 18:42
von ProgOldie
Hallo, hier der Code:

Code: Alles auswählen

EnableExplicit

;Erster Versuch einer Verallgemeinerung von Kiffis Beispiel 
;http://www.purebasic.fr/german/viewtopic.php?f=3&t=27566

CompilerIf #PB_Compiler_Unicode
  #XmlEncoding = #PB_UTF8
CompilerElse
  #XmlEncoding = #PB_Ascii
CompilerEndIf

Define DB.i,Ev.i,EvGad.i,EvWin.i,EvType.i
Define Counter
;Define XML$,ColNames$,ColTypes$,Cols.i,nr.i



UseSQLiteDatabase()

; TestTabelle erzeugen und befüllen

DB = OpenDatabase(#PB_Any, ":memory:", "", "", #PB_Database_SQLite)

DatabaseUpdate(DB, "Create Table TestTable (ArtNr, Anzahl, Bezeichnung, Netto, Brutto)")

For Counter = 1 To 10
  DatabaseUpdate(DB, "Insert Into TestTable (ArtNr, Anzahl, Bezeichnung, Netto, Brutto) Values " +
                     "('ArtNr" + Str(Counter) + "', 'Anzahl" + Str(Counter) + "', 'Bezeichnung" + Str(Counter) + "', 'Netto" + Str(Counter) + "', 'Brutto" + Str(Counter) + "')")
Next

#Dialog = 0
#Xml = 0

Procedure.s get_Column_Names(DBNr.i,Table.s)
  ;reicht die Spaltenüberschriften der Query(Table) zurück, getrennt durch |
  Protected res.s,Query.s,Sp.i
  Query="Select * FROM "+Table
  If DatabaseQuery(DBNr,Query) 
    For Sp=0 To DatabaseColumns(DBNr) -1
      res=res+ DatabaseColumnName(DBNr,Sp)+"|"
    Next
  EndIf 
  ;FinishDatabaseQuery(DBNr)
  ProcedureReturn res
EndProcedure

Procedure Changed(GadNr.i)
  MessageRequester("Change","Gadgetnr="+Str(GadNr))
EndProcedure

Procedure showDataWindow(DBNum.i,Table.s)
  Protected ColNames.s,ColTypes.s,Cols.i,XML$,Sp.i,Zeile.i,change.s,GadName.s
  ColNames=get_Column_Names(DBNum,Table)
  ColTypes="string|spin|combobox|string|date"   ;Hier gebe ich willkürliche Gadgettypen für die Spalten vor
  Cols=DatabaseColumns(DBNum)
  XML$ = "<window id='#PB_Any' name='test' text='Gridbox' minwidth='auto' minheight='auto' flags='#PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget'>" +
       "    <gridbox columns="+"'"+Str(Cols)+"'"+">"
       For Sp=1 To Cols
         XML$+"<text text="+"'"+StringField(ColNames,Sp,"|") +"'"+" />"
       Next 
Zeile = 0

If DatabaseQuery(DBNum, "Select * From "+Table)

  While NextDatabaseRow(DBNum)
    Zeile=Zeile+1
    For Sp=1 To Cols
      ; Problemstelle ******************************************
      ;change müsste noch in die üpbernachste Zeile eingefügt werden, 
      ; z.B.  ...+GadName + change, dann aber passiert Absturz
       change=" onchange="+Chr(34 )+"Changed()"+Chr(34)  
      GadName=" name='"+Str(Zeile)+"|"+Str(Sp)+"' "
      XML$+"<"+StringField(ColTypes,Sp,"|") + GadName +" width='100' text='" + GetDatabaseString(DBNum, Sp -1) + "'"+" />"
    Next
  Wend
  FinishDatabaseQuery(DBNum)
EndIf


XML$  + "    </gridbox>" +
        "  </window>"
If CatchXML(#Xml, @XML$, StringByteLength(XML$), 0, #XmlEncoding) And XMLStatus(#Xml) = #PB_XML_Success
  If CreateDialog(#Dialog) And OpenXMLDialog(#Dialog, #Xml, "test")
    Repeat
    Until WaitWindowEvent() = #PB_Event_CloseWindow
  Else 
    Debug "Dialog error: " + DialogError(#Dialog)
  EndIf
Else
  Debug "XML error: " + XMLError(#Xml) + " (Line: " + XMLErrorLine(#Xml) + ")"
EndIf
  
  
EndProcedure




showDataWindow(DB,"TestTable")
;Beispiel zur Abfrage: MessageRequester("Inhalt",GetGadgetText(DialogGadget(#Dialog,"8|4")))   ; Inhalt des Gadgets von Zeile 8 und Spalte4

Repeat
  Ev=WindowEvent()
  If Ev
    Select Ev
      Case #PB_Event_Gadget
        EvGad=EventGadget()
        EvType=EventType()
        Select EvType
            Case #PB_EventType_LostFocus
              Changed(EvGad)
        EndSelect
   EndSelect
  EndIf    
Until Ev=#PB_Event_CloseWindow

Re: Dialog-Funktion und onchange

Verfasst: 16.12.2013 18:53
von ts-soft
Die Changed-Procedure hat keine Parameter, siehe Hilfe!

Code: Alles auswählen

Runtime Procedure Changed()
  Protected GadgetNr = EventGadget()
  MessageRequester("Change","Gadgetnr="+Str(GadgetNr))
EndProcedure
Runtime Keyword fehlt auch.
Zur XML-Syntax kann ich nichts sagen, habe die Dialog-Lib noch nicht wirklich
genutzt, aber Dein EventLoop mußt Du unbedingt ändern. So wird nur der Lüfter
Deiner CPU hochgedreht, Stromverbrauch steigt und es wird evtl. Wärmer im Raum :mrgreen:

PS: die Procedure Changed wird automatisch aufgerufen! Da haste wohl noch verständnisprobleme.

Re: Dialog-Funktion und onchange

Verfasst: 17.12.2013 10:51
von ProgOldie
In der Tat liegen in meinem Code zwei dicke Fehler vor:
1. In Kiffis Beispiel (bei mir in der Prozedur ShowWindow) war schon ein Eventhandling vorhanden. Mein zusätzliches war also völlig wirkungslos. Ich habe das Eventhandling jetzt komplett in ShowWindow eingebunden.
2. Das mit den Parametern bei Changed ist natürlich auch richtig. Man muss sich zwischen zwei Möglichkeiten entscheiden:
a) Man arbeitet mit onchange=Changed(), dann gibt es keine Parameter, weil man die in Changed() selbst auslesen muss oder
b) Man fängt die Events separat in einem Eventloop ab und übergibt dann die Gadgetnummer als Parameter.

Ich werden mich wohl für b) entscheiden, das ist man doch mehr gewöhnt. Ich muss nur noch sehen, wie ich die Nummer von Zeile und Spalte, die ja im Gadgetnamen enthalten sind, aus der an Changed(Gadgetnr) übergebenen Gadgetnummer ableite.

Dank und Gruß an ts-soft!