Autore Topic: loop nel codice degli oggetti interni ad una Form  (Letto 2071 volte)

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
loop nel codice degli oggetti interni ad una Form
« il: 25 Luglio 2010, 19:33:45 »
A volte per passare da un oggetto all'altro del form utilizzo l'istruzione .setfocus, però andando in  debug vedo che quasi sempre vengono rieseguite alcune classi della Form prima che il Focus passi effettivamente all'oggetto successivo. A volte, addiritturam,  il loop é infinito e s'interrompe solo quando clicco su un punto qualsiasi della Form.
Si tratta di una realtà incontrata sin dai primi approci con Gambas, ma che ho sempre superato con artifici di codice all'interno delle routine delle Form.
Si tratta di una situazione pratica divenuta ormai insopportabile. Es.:
Codice: gambas [Seleziona]
PUBLIC SUB Form_GotFocus()
Dim ...................................
....bla............
....bla............
....bla............
 PRINT "Chiudo Form_GotFocus"
  Form_LostFocus()
END

PUBLIC SUB Form_LostFocus()
'-----------------------------
  SdoIniMovvg.SetFocus
END


Ebbene, pur essendo, nella sequenza gerarchica, una TextBox, la successiva candidata a prendere il focus, programma va in loop all'interno delle
Form_Activate, Form_GotFocus,  Form_LostFocus, senza mai passare alla TextBox pretendente.
Non ho capito ancora come fare per uscire dal suddetto labirinto.
 ??? ??? ???
 :( :(


P.S.: La console di Gambas riporta "Passaggio in Nascosta_GotFocus" e non "Passaggio in TextBoxProva_GotFocus": Si tratta di una stringa lasciata col vecchio nome attribuito alla TextBoxProva, ma basta leggere TextBoxProva_GotFocus. Chiedo scusa per averne dimenticato la correzione.
« Ultima modifica: 28 Luglio 2010, 00:03:55 da Picavbg »
:ciao:

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: loop nel codice degli oggetti interni ad una Form
« Risposta #1 il: 26 Luglio 2010, 11:36:59 »
Credo che sia il caso che tu pensi prima alle ferie... poi alla programmazione... :-)

Scherzi a parte, devi sempre tener conto prima della gerarchia degli oggetti: Form, controlli interni.
In secundis, fare molta attenzione a cambiare lo stato di un oggetto all'interno dello stesso evento che lo stato ha generato. Questo può causare i problemi che hai descritto.

Forse, e dico forse, credo dovresti prima capire bene la logica con cui funziona la gestione degli oggetti grafici, e questo vedo che l'hai inizto a fare, seguendo gli eventi che si scatenano. Tieni presente che, però, alcuni eventi seguono una logica ciclica, che serve per aggiornare continuamente lo schermo, per cui è normale che noti scatenarsi lo stesso evento anche se tu non interagisci con la finestra. Inoltre, anche il solo fatto di monitorare un evento con artifici più o meno visivi, altera in ogni caso la sequenza degli eventi, per cui questo deve essere compreso bene.

Un esempio:
il SetFocus lo puoi settare, ad esempio, quando la finestra viene aperta (metodo Open), ma se lo fai durante l'evento stesso Focus, il manager impazzisce e si alluppa, a meno che tu non riesca a bloccarlo in qualche modo, cosa altamente sconsigliata, perchè và ad impattare su altre funzionalità.
E' come dire al manager di chiudere la finestra all'interno dello stesso evento Close. A parte alcune correzioni fatte sul codice di Gambas ad evitare il problema, questo potrebbe causare il crash dell'applicazione, perchè l'evento si occupa di chiamare le opportune funzioni di rilascio degli oggetti, e l'ulteriore chiamata andrebbe a liberare oggetti non più esistenti...

Capito?

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: loop nel codice degli oggetti interni ad una Form
« Risposta #2 il: 26 Luglio 2010, 15:16:13 »
Credo che sia il caso che tu pensi prima alle ferie... poi alla programmazione... :-)
Le prenderei con piacere, ma non  ho a chi rivolgermi per ottenerle.  Che ci vuoi fare, é questo il triste e duro destino dei pensionati.  :rotfl:

Ti ringrazio per l'attenzione che mi hai dedicato, ma non riesco a penetrare nella logica esecutiva dei controlli da parte di Gambas. Se mi puoi seguire nel ragionamento, vorrei descriverti sommariamente la mia impostazione della Form3 del mio programma.
Elenco dei controlli interni alla Form3.class in ordine di sequenzialità:
1) Form_Show   --->  da corpo agli oggetti del form agendo sulle loro proprietà ed accede alle tabelle necessarie per i successivi passi;
2) Form_Activate  ---> contiene solamente l'istruzione  ME.SetFocus ed ha lo scopo di rendere visibile la Form all'utente per l'interagibilità con l'utente;
3) Form_GotFocus  --->  Senza l'istruzione ME.SetFocus posta nella procedura Form_Activate non viene avviata. Contiene ulteriori gestioni di flusso dati ed eventuali messaggi destinati all'utente. La procedura viene conclusa dall'istruzione Form_LostFocus(), per dare corso alle operazioni di completamento del ciclo delle procedure Form.
4) Form_LostFocus  --->  contiene l'istruzione TextBox1.SetFocus per forzare un passaggio al primo controllo attivo nell'elenco "Gerarchia".É stato aggiunto successivamente alla scoperta che quel 1° controllo, pur essendo attivo, non prendeva il focus (curosore non presente nella casella).

Non vado oltre perché non serve all'indagine. Infatti, nonostante tutto, il focus non passa alla prima casella attiva della form, se prima non clicco su un punto della form, come se intanto il programma fosse dentro un ciclo iterativo infinito che s'interrompe solamente grazie allintervento esterno. Ho l'impressione che si sviluppi:
Codice: [Seleziona]
PUBLIC SUB Form_GotFocus
                     ----- bla_bla -----
                    Form_LostFocus()
END

PUBLIC SUB Form_LostFocus
                     TextBox1.SetFocus
END
PUBLIC SUB Form_GotFocus
                     ----- bla_bla -----
                    Form_LostFocus()
END

PUBLIC SUB Form_LostFocus
                     TextBox1.SetFocus
END
.....................................................
e così via.

Se, come sembra, tale comportamento é normale, io non ho capito, come uscirne.
Spero di risentirti presto.
     

« Ultima modifica: 26 Luglio 2010, 15:28:18 da Picavbg »
:ciao:

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: loop nel codice degli oggetti interni ad una Form
« Risposta #3 il: 26 Luglio 2010, 15:49:29 »
Parlo, ovviamente, senza aver guardato una linea del tuo codice, ma dal tuo discorso ne evinco che c'è qualcosa che non torna, e che forse ti stà dirigendo su una strada impervia, per non dire addirittura senza uscita.

Tieni conto che tutti gli oggeti, ovviamente grafici, hanno due distinti blocchi logici: funzionalità a basso livello, interazione utente.
Mentre la prima serve per la logica applicativa, la seconda permette di dialogare con l'utente (es. mouse, tastiera, video, ecc.).

Perdona se forse sembra monti in cattedra, ma stò cercando un modo di spiegare.

Gli eventi, appunto, fanno parte di questa seconda parte. Però, bisogna anche distinguere tra eventi scatenati dal motore applicativo, e quelli che condizionano l'interattività tra utente e applicazione.

Nel particolare:
1 - l'evento Show di una finestra, definisce il momento in cui questa diviene visibile sullo schermo, il che può essere quando passa da nascosta a visibile, oppure dopo la sua creazione (visibilità imposta dal codice di creazione).
2 - l'evento Activate viene scatenato quando la finestra prende il fuoco, un esempio è quello di più finestre aperte e visibile, ma una sola è quella che ha attualmente il fuoco (ovvero l'interazione con l'utente).
3 - l'evento GotFocus viene scatenato quando l'oggetto grafico diviene l'oggetto correntemente gestito (es. la pressione del mouse su un bottone, come anche la pressione di un tasto della tastiera su una textbox).
4 - l'evento LostFocus è l'esatto contrario, ovvero viene scatenato quando l'oggetto non è più quello attivo, perchè il fuoco è passato (o se l'è preso) su un'altro elemento grafico.

Quando si passa da un controllo ad un'altro, di eventi di tipo 3 e 4 ne vengono scatenati 2 durante il passaggio:
a) LostFocus sul primo oggetto
b) GotFocus sul secondo oggetto

però, questi oggetti fanno anche parte di un'oggetto più grande (contenitore), che potrebbe essere una Form. Ogni evento scatenzato da uno dei controlli contenuti in questo contenitore, scatena anche una serie di altri eventi a questo oggetto, e via dicendo. Tutto ciò, ovviamente, è dipendente anche dalle impostazioni date ai singoli elementi.

L'attenzione che dovresti mettere, è sull'utilizzo di questi eventi per i tuoi scopi.
Tieni conto che esistono metodi e funzioni, anche particolari, che ti permettono di gestire in modo migliore la logica di gestione di un oggetto. Un esempio è quello di usare il metodo _new(), per definire la struttura e le condizioni di partenza di una Form, il che ti permette di non utilizzare, ad esempio, l'evento Open.

Non sò se riesco a spiegare bene il concetto.

Se tu utilizzi Show per modificare l'aspetto dei controlli, ogni volta che la Form si disattiva, o si mette in background, o la iconizzi, o quant'altro, l'evente viene riscatenato quando la Form viene riattivata, e questo, oltre alla perdita di tempo per ricreare le condizioni che, peraltro, ha già in corpo, può causare anche indesiderati effetti grafici (es. flashing).
Utilizzare l'evento Activate, potrebbe essere usato, ad esempio, per rivisualizzare una finestra figlia, al riapparire della Form. Ma utilizzarla per condizionarne la struttura o gli eventi stessi è alquanto deleterio e poco gestibile.

Spero di aver spiegato in qualche modo il concetto. Ovviamente se non è così fammelo sapere.

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: loop nel codice degli oggetti interni ad una Form
« Risposta #4 il: 26 Luglio 2010, 22:40:58 »
Tutto sommato, anche se provengo dall'ambiente VB e da circa un paio d'anni ho cominciato a conoscere Gambas, devo dire che non avevo mai pensato ad una Interdipendenza fra le scatole cinesi di Gambas.
Della tua ampia spiegazione erano chiari già alcuni concetti legati all'intervento dell'utnte dall'esterno e gli eventi che ciasun intervento esterno può generare.
É altresì chiaro che richiamando, per es., la form1 col comando Form1.show/Showmodal viene scatenato l'evento show del Form1_Show della Form1.class. É chiaro anche che durante l'esecuzione di detta procedura, la Form non risulta ancora visibile, mentre quando il sistema, dopo la Form1_Show, passa il controllo alla procedura Form1_Activate, la Form é già ben visibile. Da quello che mi hai illustrato, sembrerebbe che la Form1 divenga visibile proprio quando, attraverso la schedulazione automatica di Form1_Activate, la form1 prende il focus.
Non capisco come mai la Proedura Form1_Got_Focus non venga avviata, perché La Form non é una casella che aspetta l'input da tastiera. Mi aspettavo perciò che venisse schedulata automaticamente come la Form_Activate.
Non capisco cosa dovrei modificare nell'uso logico delle procedure interne ad un Oggetto.class quando tu dici:
Citazione
Tieni conto che esistono metodi e funzioni, anche particolari, che ti permettono di gestire in modo migliore la logica di gestione di un oggetto. Un esempio è quello di usare il metodo _new(), per definire la struttura e le condizioni di partenza di una Form, il che ti permette di non utilizzare, ad esempio, l'evento Open.
L'unico metodo _new che io conosco é quello che viene scatenato quando si chiama in gioco una classe esterna a quella corrente con
Codice: [Seleziona]
NomeVariabileStringa = New NomeAltraClasse()
. Non saprei perciò come usarlo dentro una Formx.Class.

Non ti ho mandato il file tar.gz del programma per non farti perdere del tempo prezioso; il programma ha assunto ormai una corporatura da ragazzo da motorino ed immergervisi per trarne il consiglio da darmi costituisce un onere. Se vuoi però posso fornirtelo, insieme con le attuali tabelle, nel caso che pensassi ad un'evetuale prova. É ovvio che occorrerebbe anche una piccola illustrazione per permetterti di arrivare agevolmente al punto in cui ho incontrato le sabbie mobili.
 :( :(



:ciao:

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: loop nel codice degli oggetti interni ad una Form
« Risposta #5 il: 27 Luglio 2010, 10:54:52 »
Anche se me lo mandi, non avrei il tempo di leggerlo, purtroppo.

Ad ogni modo, ritornando sul piano teorico...

Gli esempi che ti ho fatto, sono puramente dimostrativi, e potrebbero non corrispondere esattamente alla realtaà. Tieni conto che l'interfaccia grafica di Gambas si basa fondamentalmente sulle due librerie GTK e QT, ma potrebbero aver implementato alcuni accorgimenti non perfettamente corrispondenti alla logica applicata da queste librerie.

Un'idea sulla sequenza deli eventi  si potrebbe avere implementando tutti i metodi-evento dell'oggetto, e facendo una print su console...

Riguardo alla Form, parti da un concetto sbagliato, anch'essa si comporta come qualsiasi altro oggetto grafico, e anch'essa risponde agli stessi eventi base. Se leggi la documentazione, noterai che tutti gli oggetti si basano, o derivano, da una classe ben precisa, che ha metodi ed eventi comuni a tutti gli oggetti figli. La form deriva anch'essa da questa classe.

Con altri linguaggi potresti utilizzare una finestra di dialogo per disegnarci sopra, oppure per accettare input da tastiera, e via dicendo. Anche se in Gambas molte di queste caratteristiche specifiche non sono state implementate, ragionevolmente allo scopo di rendere il linguaggio più semplice e veloce, sono comunque presenti e latenti.


Comunque, a prescindere da tutto questo, quello che ti suggerisco è di fare attenzione a come utilizzi gli eventi. Non tanto perchè magari mandi tutto in crash, tanto perchè vai ad interferire con il nomale flusso logico del gestore grafico.
Di noprma, l'evento viene utilizzato per elaborare una richiesta da parte dell'utente (es. scrivere un carattere sulla textbox alla pressione di un tasto), e magari pure spostare il fuoco da un'oggetto all'altro, sulla base di una specifica logica di programmazione. Tocca però tener presente ogni aspetto di queste implementazioni, evitando di scombinare il normale flusso logico.

Ti faccio un'altro esempio, non legato alla grafica:
prendi un timer, impostato in modo da scatenzare un evento Timer ogni secondo. Nell'evento Timer, è presente una procedura di elaborazione (di qualsiasi tipo, importa poco per l'esempio), ma mettiamo il caso che in alcuni periodi, la procedura ci metta più di un secondo, che succede?
Semplice, il timer continuerà ad andare, e avresti due o più eventi attivi in contemporanea, che potrebbero incasinare le cose, se questa particolarità non viene gestita.
Una semplice soluzione: appena entri nel timer lo disabiliti, esegui l'elaborazione, poi lo riattivi (ovviamente, la cosa si può complicare ulteriormente, se è necessario).
Sembra un giochetto semplice, ma bisogna tenerlo presente quando si applicano certe logiche, che potrebbero interferire con altri processi indipendenti.,

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: loop nel codice degli oggetti interni ad una Form
« Risposta #6 il: 27 Luglio 2010, 16:25:15 »
Mi dispiace, capisco il concetto delle priorità degli eventi Gambas scatenati da Gambas secondo lo schema gerarchico degli oggetti in esso contenuti, ma non capisco come gestire una certa sequenza personalizzata di eventi senza interferire involontariamente con la sequenza-eventi di base di Gambas,

Ho provato ad aggiungere nella Form3.Class la procedura
Codice: [Seleziona]
PUBLIC SUB _new()
  PRINT "Passaggio in Form_new"
END
per capire se e quando viene richiamata; ho ripetuto poi la riga print in tutte le procedure della Form3.Class, in modo da scoprire la sequenza esecutiva sviluppata da Gambas ed ho ottenuto:
Citazione
1) Passaggio in Form_new
2) Passaggio in Form_Show
3) Passaggio in Form_Activate
4) Passaggio in SdoIniMovvg_GotFocus
5) Passaggio in SdoIniMovvg_LostFocus

Il risultato mi ha fatto capire che Gambas non esegure tutte le procedure scritte, della Form.Class, ma solo alcune di esse e secondo la sua logica nativa.
Premesso che un metodo _new eseguito prima di  procedura _Show e di  procedura _Activate non mi permetterebbe di ottenere il risultato desideratio , ma aumenterebbe lo sconvolgimento attuale, ora dovrei scrivere e richiamare una procedura che, inserita fra i punti di interdipendenza 4) e 5), non comprometta poi il passaggio immediato al punto 5.
Ho capito che il Form3.setfocus é deleterio perché Gambas, dopo avere eseguito l'evento Form3_GotFocus, ripete tutti i passaggi posti gerchicamente sopra. Però é anche vero che quell'evento che servirebbe a me per la gestione delle MessageBox non viene schedulato automaticamente.
A questo punto non capisco come eseguire i passi di codice contenuti in quell'evento, passi fondamentali per la prosecuzione controllata del programma.

Se non posso richiamare la Form3_GotFocus che mi sembrava perfetta, forse potrei non scombinare la logica di Gambas trasferendo il codice interessato dentro un metodo _new da inserire, per esempio nella TextBox SdoIniMovvg -vedi punto 5)-, cioé la prima TextBox della sequenza gerarchica degli oggetti interni alla Form3, in grado di prendere il focus.
Dovrei provare, perché detta textBox nasce con la proprietà REadOnly=True

Torno a scusarmi con te perché mi rendo conto che Ti sto rubando molto tempo, ma non riesco a trovare nella documentazione una spiegazione in merito.
Chissà se qualcuno di Voi, conoscitori esperti di Gambas, non abbia già pensato di illustrare l'argomento nell'e_zine. Salvo che lo   ??? non sia soltanto io, potrebbe essere una buona idea per fare conoscere più approfonditamente Gambas a tutti, specialmente ai neofiti.
 :( :(





:ciao:

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: loop nel codice degli oggetti interni ad una Form
« Risposta #7 il: 27 Luglio 2010, 23:45:01 »
A furia di vedere il programma in loop, sto  andando in loop pure io! ::)

Per eseguire detta ultima prova, ho creato la TextBoxProva. Ho trasferito nella sua TextBoxProva_GotFocus la parte di codice che prima avevo inserito nella Form_GotFocus. In ordine gerarchico é la prima ad essere schedulata. Purtroppo il programma continua inerosabilmente nel suo ciclo di loop. Francamente non riesco più a venirne fuori. Riporto il codice incriminato, anche se non mi sembra responsabile:
Codice: gambas [Seleziona]
PUBLIC SUB TextBoxProva_GotFocus()
'---------------------------------------- Procedura ex Form3_GotFocus --------------------------------------------------------------------
DIM DB_Connection AS NEW Connection   'inizializza la nuova connessione
DIM RecTbResta AS Result
DIM RecTbRiep AS Result

DIM EdtData AS EditData

DIM i AS Integer
DIM i_DtRestaPrec AS Integer

DIM $_DtPrecEdt AS String
DIM $_DatIeriEdt AS String
DIM $_Messaggio AS String
DIM $_MsgPuls1 AS String

DIM $_SwResta AS String

'........................................................
PRINT "Passaggio in Nascosta_GotFocus"

   WITH
      DB_Connection
      .Type = "sqlite3"
      .Host = VarGlob.$_DbPath
      .Name = VarGlob.$_DbNome
      .OPEN    'Riapro il DB
  END WITH   
  IF VarGlob.i_DtRiePrec <> i_DtRestaPrec THEN
      SELECT Message.Question("RESTA DI CASSA e RIEPILOGO CONTABILE di Inizio Giornata" & Chr(10) & "---- hanno DATE DIVERSE ----" & Chr(10) & Chr(10) & "Cosa vuoi fare ?", "FORZO CHIUSURA PROGRAMMA", "PROSEGUO")
              CASE 1      'FORZO CHIUSURA PROGRAMMA   
                QUIT
              CASE ELSE   'PROSEGUO
                RipreSalPrec()
      END SELECT
  ENDIF
  IF VarGlob.i_DtRiePrec <> i_DataIeri
      EdtData = NEW EditData(i_DataIeri)
      $_DatIeriEdt = EdtData.$_DatEdt
      $_Messaggio = "---------------------   A T T E N Z I O N E  ---------------------" & Chr(10) & "Data contabile corrente NON CONSECUTIVA" & Chr(10) & Chr(10) & " Ultima giornata contabile quadrata --> "
      IF VarGlob.i_DtRiePrec <> 0 THEN
          EdtData = NEW EditData(VarGlob.i_DtRiePrec)
          $_DtPrecEdt = EdtData.$_DatEdt
          $_MsgPuls1 = " Confermo Giornata precedente= "
      ELSE
        $_DtPrecEdt = "NESSUNA"
        $_MsgPuls1 = " FORZO CHIUSURA PROGRAMMA "
      ENDIF
      $_Messaggio &= $_DtPrecEdt & Chr(10) & " Mancano le giornate succesive e fino a ieri - - > " & $_DatIeriEdt & Chr(10) & Chr(10) & " Cosa vuoi fare ?"
      SELECT Message.Warning($_Messaggio, $_MsgPuls1, " INSERISCO manualmente" & Chr(10) & " i dati di fine giornata precedente")
        CASE 1    ' Confermo consecutività  -->   Giornata precedente = "$_DtPrecEdt"
          IF $_DtPrecEdt = "NESSUNA" THEN
              QUIT
          ENDIF
          SELECT Message.Info("Stai confermando Giornata precedente =  " & $_DtPrecEdt, "SI, confermo", "ANNULLO")
            CASE 2
              STOP EVENT
          END SELECT
        CASE ELSE       'procedi con la modifica manuale della resta di cassa ultima trovata
          Form1.$_TipoRich = "GGContPrec"
          Form1.ShowModal
          sql = "SELECT * FROM riepmovg WHERE "
          sql &= "DtCoMovg = '" & VarGlob.i_DtRiePrec & "'"
          sql &= "ORDER BY DtCoMovg"
          RecTbRiep = DB_Connection.Exec(sql)
          IF NOT RecTbRiep.Available THEN
              SdoIniMovvg.ReadOnly = FALSE
          ELSE
            $_StriMia = Str(RecTbRiep!RipFing)
            $_StriMia = Modulivari.EditImp($_StriMia)
            SdoIniMovvg.Text = $_StriMia
          ENDIF
      END SELECT
      $_DtFrame2 = VarGlob.i_DtRiePrec
      Frame2.Text = "Area di dettaglio della Resta di Cassa del:  " & $_DtGGPrec & "-" & $_DtMMPrec & "-" & $_DtAAPrec
      TextLabel1.Text = "(Riporto dal:" & $_DtGGPrec & "-" & $_DtMMPrec & "-" & $_DtAAPrec & ")"
      sql = "SELECT * FROM restacassagg WHERE "
      sql &= "DtResCasgg = '" & VarGlob.i_DtRiePrec & "'"
      sql &= "ORDER BY DtResCasgg"
      RecTbResta = DB_Connection.Exec(sql)
      IF RecTbResta.Available THEN
          i = (-1)
          FOR EACH RecTbResta
              INC i
              GriResta.Columns[i, 1].text = RecTbResta!MonResCasgg
              GriResta.Columns[i, 2].text = RecTbResta!ImpResCasgg
              GriResta.Columns[i, 3].text = RecTbResta!NoteResCasgg
          NEXT
      ELSE
        $_SwResta = "Prec"      ' "Nuova", per digitare la resta di fine giornata corrente
      ENDIF
  ENDIF
  DB_Connection.Close
END

Allego poi la finestra dell'editor di Gambas con la sottofinestra Gerarchia
Allego anche la finestra dell'editor di Gambas comprendente la console con le righe di print dimostrative del loop
Aggiungo che ho eliminato tutti i comandi di tipo .setfocus
 :( :(
:ciao:

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: loop nel codice degli oggetti interni ad una Form
« Risposta #8 il: 28 Luglio 2010, 09:28:07 »
Nella speranza di capire e farvi capire, ecco l'ultimo aggiornamento di Tutto il loop prova dopo prova:

Mi sono ricordato che la Form1.class é richiamata sia nella FMain.Class che nella Form3.Class; allora, poiché:

- per uscire dalla Form1.class e cancellare dallo schermo la relativa Form, utilizzo il metodo Hide,  ho sostituito il comando Me.Hide con Me.Close, ma la prova successiva é andata ancora in loop;

- per richiamare la Form1.class utilizzo il comando Form1.ShowModal (vedi  riga 61 della citazione nel precedente post),  in entrambi i passi di programma,  ho sostituito l'istruzione Form1.ShowModal con Form1.Show. Anche in questo caso il risultato della prova non é cambiato: Loop, sempre loop, inevitabilmente ... loop.

In mancanza di suggerimenti illuminanti, mi farò risentire dopo la prossima prova, ... da scoprire.
 :( :(

:ciao:

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: loop nel codice degli oggetti interni ad una Form
« Risposta #9 il: 29 Luglio 2010, 12:23:50 »
Perdona, forse mi è sfuggito nella discussione, ma puoi descrivere cosa realmente vuoi fare e ottenere ? Intendo, che cosa dovrebbe fare la procedura (o form che sia), e in risposta a cosa o quale evento (inteso come evento logico).

Te lo chiedo perchè, se andiamo a tentoni sul giochetto degli eventi e del codice, focalizzandoci solo su dettagli tecnici, forse non se ne esce fuori.

Nota:
il metodo "_new" è appunto un metodo, non un evento, e viene chiamato solo alla costruzione dell'oggetto (tramite l'istruzione NEW Object), dopodiche non viene più interrogato.

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: loop nel codice degli oggetti interni ad una Form
« Risposta #10 il: 29 Luglio 2010, 15:33:30 »
Alla base di tutto sta naturalmente la volontà di conoscere l'interdipendenza delle ruote dentate di Gambas che determinano il meccanismo del suo motore. Non esistendo una sorgente esplicativa in merito, probabilmente, per arrivare alla meta bisognerebbe calarsi nello studio del suo codice sorgente; la qual cosa non mi sembra facilmente abbordabile.
Premesso quanto appena detto, speravo di potere avere un'indicazione su come gestire le chiamate ai singoli oggetti di una Form, quando esse non rispettino la logica sequenza costruita nella finestra Gerarchia di una Formx.form qualsiasi, senza incappare però nella ragnatela tesa dal supervisore di  Mr. Gambas.
Ho cercato di capire qualcosa inserendo delle print dentro le procedure della mia Form3.class, ma non ne ho cavato un ragno dal buco.
Onestamente devo dirti che inserendo  :( :(due switch logici dentro gli eventi Form3.SdoIniMovvg_GotFocus e Form3.SdoIniMovvg_LostFocus nella seguente maniera:
Codice: gambas [Seleziona]
PUBLIC SUB SdoIniMovvg_GotFocus()
'----------------- DIM varie ----------------
PRINT "Passaggio in SdoIniMovvg_GotFocus"
IF b_SwSdoIni = FALSE THEN
      ----- bla_bla -----
      ----- bla_bla -----
ENDIF
END

e
Codice: gambas [Seleziona]
PUBLIC SUB SdoIniMovvg_LostFocus()
'----------------- DIM varie ----------------
 PRINT "Passaggio in SdoIniMovvg_LostFocus"
 $_StriMia = SdoIniMovvg.Text
 IF CFloat($_StriMia) = 0 THEN
      STOP EVENT
  ELSE
ENDIF
END

sono riuscito a superare l'ostacolo ed andare avanti.
Questo non significa che, secondo me, l'oggetto di questa discussione possa considerarsi ormai trascurabile, perché il problema di fondo rimane e sicuramente tornerà a galla quanto prima; quindi pur chiudendo il presente post ne inoltro immediatamente uno successivo nel quale cerco di spiegare al meglio delle mie possibilià quello che mi hai chiesto.
 :( :(
:ciao:

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: loop nel codice degli oggetti interni ad una Form
« Risposta #11 il: 29 Luglio 2010, 15:43:39 »
Cosa dovrebbe fare il programma dentro la Form3? Cerco di spiegarlo intanto a parole, poi mi dirai tu se ho capito:
1) Appurare inizialmente la sequenza di data contabile della giornata corrente rispetto alla precedente;
2) in caso di data non immediatamente successiva, dovrebbe allarmare l'utente proponendogli l'ultima data caricata col suo saldo  contabile finale;
3) in quest'ultimo caso, per accettazione da parte dell'utente, della data proposta, proseguire partendo dal saldo contabile letto nel DB ed elencare nella Gridview il dettaglio dei dati relativi alla resta di denaro contanti attinente alla stessa giornata a cui si riferisce il saldo riscontrato prima. Ciò serve per partire da una situazione contabile di fine giornata precedente quadrata. l'Utente, nella fattispecie non dovrebbe digitare né il saldo iniziale, né il relativo dettaglio di cassa contanti; quindi la TextBox.Saldo_Iniziale manterrebbe inalterata laproprietà ReadOnly=TRUE, stabilita nella costruzione della Form3.
4) nel caso in cui l'operatore volesse digitare una buova data, successiva all'ultima riscontrata automaticamente dal programma, laproprietà ReadOnly della  TextBox.Saldo_Iniziale dovrebbe essere modificata in  ReadOnly=FALSE, in modo da permettere la digitazione del saldo iniziale;
5) Una volta digitato il saldo iniziale l'utente dovrebbe scegliere nella ComboBox.Tipo_di_Contanti il nome del dettaglio di cassa, fra quelli caricati automaticamente dalla tabella del Piano dei Conti del DB. Detta casella ha e mantiene  laproprietà ReadOnly=TRUE.

Le descrizioni riportate sopra sono svolte, dopo le ultime modifiche,  dentro gli eventi
1) ---> Form3.Form_Show e
2) e 3) ---> Form3.SdoIniMovvg_GotFocus della   TextBox.Saldo_Iniziale
4) ---> Form3.SdoIniMovvg_KeyPress, per il controllo riguarda tutta la fase di digitazione dell'importo
5) ---> SdoIniMovvg_LostFocus, per l'editing dell'importo digitato e l'inserimento del nuovo record riepilogativo di fine giornata precedente.

Stranezze riscontrate:
Dopo la manifestazione dell'evento Form3.SdoIniMovvg_GotFocus della   TextBox.Saldo_Iniziale, pur essendo stata adeguata la proprietà   ReadOnly=FALSE per consentire la digitazione dell'importo relativo viene scatenato immediatamente l'evento SdoIniMovvg_LostFocus
A questo punto il programma entra in un loop infinito che interessa nella situazione di pseudocodifica descritta sopra gli eventi
 Form3.SdoIniMovvg_GotFocus
 Form3.SdoIniMovvg_LostFocus; almeno così ricordo.
 ???
Spero di avere risposto secondo le tue aspettative e se hai tempo per meglio consigliarmi, o ti dovessero necessitare ulteriori notizie, sai che sono qui che aspetto.
 :( :(





:ciao:

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: loop nel codice degli oggetti interni ad una Form
« Risposta #12 il: 29 Luglio 2010, 16:59:53 »
Proverò ad elencare quello che, a mio parere, la procedura dovrebbe fare, sulla base di quello che ho capito dalle tue spiegazioni:

1) popolamento iniziale (tramite metodo _new()) dei controlli della form, in modo che il tutto parta da una situazione iniziale stabile e, secondo quanto hai descritto, con i dati che ti aspetti di vedere a video.
2) eventuali incongruenze (ad esempio un buco nelle date, non sequenzialità), verranno gestire da un'apposita logica da te creata, utilizzando funzioni specifiche e, magari, private all'interno della form stessa (a te la scelta, potrebbe anche essere che la logica venga gestita da un'apposita classe).
3) non utilizzare gli eventi focus per scatenzare altri eventi focus, questo può tranquillamente portare a loop infiniti come nel tuo caso
4) sulla base di logiche come definite sopra, determini l'abilitazione dei necessari controlli. Con questo dico anche che puoi anche utilizzare il lostfocus di un'oggetto (se necessario), per definire in lettura/scrittura determinati controlli, ma è da fare attenzione a non attivare gli stessi tipi di evento. Se sulla base di certe informazioni, come ad esempio un buco di date, hai la necessità di abilitare un campo in edit, questo puoi farlo all'interno dell'evento lostfocus, ma prima di farlo, vedi se è possibile fare altrimenti, magari dopo che la logica sottostante determini questo problema.
5) per evitare di incocciare con gli eventi, puoi gestire il tutto con messaggi e pulsanti appositi: ad esempio, se ti accorgi di un problema, emetti un messaggio, abiliti un tasto, e solo alla pressioni di quest'ultimo esegui il codice che gestisce il problema.

In pratica, tu puoi dire alla form, di attivare una determinata funzione, quando la stessa form viene visualizzata a video, ma non puoi interagire con il normale flusso di eventi che determinano la visualizzazione della stessa form.

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: loop nel codice degli oggetti interni ad una Form
« Risposta #13 il: 29 Luglio 2010, 23:40:52 »
Proverò ad elencare quello che, a mio parere, la procedura dovrebbe fare, sulla base di quello che ho capito dalle tue spiegazioni:

1) popolamento iniziale (tramite metodo _new()) dei controlli della form, in modo che il tutto parta da una situazione iniziale stabile e, secondo quanto hai descritto, con i dati che ti aspetti di vedere a video.
2) eventuali incongruenze (ad esempio un buco nelle date, non sequenzialità), verranno gestire da un'apposita logica da te creata, utilizzando funzioni specifiche e, magari, private all'interno della form stessa (a te la scelta, potrebbe anche essere che la logica venga gestita da un'apposita classe).
3) non utilizzare gli eventi focus per scatenzare altri eventi focus, questo può tranquillamente portare a loop infiniti come nel tuo caso
4) sulla base di logiche come definite sopra, determini l'abilitazione dei necessari controlli. Con questo dico anche che puoi anche utilizzare il lostfocus di un'oggetto (se necessario), per definire in lettura/scrittura determinati controlli, ma è da fare attenzione a non attivare gli stessi tipi di evento. Se sulla base di certe informazioni, come ad esempio un buco di date, hai la necessità di abilitare un campo in edit, questo puoi farlo all'interno dell'evento lostfocus, ma prima di farlo, vedi se è possibile fare altrimenti, magari dopo che la logica sottostante determini questo problema.
5) per evitare di incocciare con gli eventi, puoi gestire il tutto con messaggi e pulsanti appositi: ad esempio, se ti accorgi di un problema, emetti un messaggio, abiliti un tasto, e solo alla pressioni di quest'ultimo esegui il codice che gestisce il problema.

In pratica, tu puoi dire alla form, di attivare una determinata funzione, quando la stessa form viene visualizzata a video, ma non puoi interagire con il normale flusso di eventi che determinano la visualizzazione della stessa form.
Se non ho capito male,
1) dovrei spostare il codice contenuto nell'evento Form_show, da quest'ultimo al metodo _new, in modo da essere sicuro che venga svolto una volta sola.
     Va bene, lo posso fare, perché in quel pezzo non ci sono interventi esterni dell'utente. Però il metodo _new agisce prima di tutti gli eventi Form, quindi prima ancora del Form_show; ma ciò significa che il codice contenuto lì dentro viene eseguito prima ancora che compaia a video la Form stessa. La qual cosa é scomoda per quanto contenuto attualmente nell'evento Form_GotFocus. Riallacciandomi pertanto al
2)  la gestione dei messaggi relativi a buchi fra date, per usare la tua terminologia, diventa più comprensibile se la Form é già ben in mostra e francamente non ho capito come agire. Forse, potrei provare a spostare tutto dentro la classe della prima casella della Form che prende automaticamente il focus.
3) Nella Form3 non ho ancora utilizzato comandi setfocus.
4) L'evento lostFocus interviene in un momento molto importante e non  saprei come rimpiazzarlo. In VB c'era la possibilità di attivarlo o disattivarlo preventivamente, in Gambas non mi pare che sia possibile.
5) Va bene per le situazioni che richiedono un intervento esterno, ma per scelte condizionali automatiche, agire nella identica maniera significherebbe spezzettare anomalmente e rallentare oltremodo l'ordinario svolgimento del programma.

In definitiva, dopo avere ragionato tanto ed adattato altrettanto il programma, scrivendo fiumi di codice, mi ritrovo, ad oltre un anno dal fervoroso inizio, a stabilire con quale linguaggio approntare la gestione contabile familiare.  Mi verrebbe voglia di  :hatecomputer:

Ti sembrerò drastico, ma dopo avere letto il tuo ultimo post, mi sono cadute le pa...role di ottimismo con le quali affrontavo le difficoltà quotidiane col gambero.
Guarirò ?
 :( :(
:ciao:

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: loop nel codice degli oggetti interni ad una Form
« Risposta #14 il: 30 Luglio 2010, 12:09:13 »
Ma si, dai...

Come ho detto, non sò nulla del tuo programma, per cui quello che scrivo lo devi prendere solo come suggerimento e indizio per analizzare le cose sotto più punti di vista.
In effetti, come avrai notato, non ho scritto nulla a livello di codice per fare gli esempi, perchè non voglio influire sul tuo metodo di operare, in particolare se hai già esperienza di programmazione.
In VB, come in tutti gli altri linguaggi, esistono delle particolarità, o caratteristiche, che lo contraddistinguono, per cui quello che ti suggerisco è di prenderne la logica, ma non il dettaglio.
Quello che inoltre voglio dire, e stò tentando di fare, è di spingerti a valutare altre possibilità, per cui non devi affliggerti.
Tieni conto che, riguardo alla contabilità, sono abbastanza ignorante, e già capire quello che vuoi fare per me è alquanto ostico, e quindi non voglio entrare in merito al dettaglio di quello che stai costruendo.
Mi sembra però, che sei ad un punto in cui non riesci ad andare indietro per valutare meglio le cose, e questo accade di sovente... :-(
L'uso degli eventi, io non l'ho escuso, altrimenti che ci stanno a fare? Quello che ho affermato è di fare attenzione a come li usi.

 P.S.: Se leggi sul wiki, quanto descritto circa il metodo _new(), questo metodo è presente e utilizzato da tutti gli oggetti proprio per agire su questi prima della loro attivazione. Il metodo viene eseguito solo una volta, in corrispondenza dell'istruzione NEW quando crei l'oggetto. Tramite questo metodo, puoi passare alla classe, parametri che, altrimenti, non sarebbero previsti dalla classe base. Molti, non conoscendo questo metodo, utilizzano variabili globali per passare le informazioni tra gli oggetti, ma questo è un uso anomalo in un linguaggio ad oggetti.

Comunque, il mio consiglio è quello di fermarti un attimo, e riflettere bene su quello che vuoi ottenere, poi procedi a passi con delle form di esempio, e vedi il comportamento, al di fuori della logica finale.