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.:
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.
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:
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.
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:
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
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.
:( :(
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
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:
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.
:( :(
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:
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
:( :(
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:
PUBLIC SUB SdoIniMovvg_GotFocus()
'----------------- DIM varie ----------------
PRINT "Passaggio in SdoIniMovvg_GotFocus"
IF b_SwSdoIni = FALSE THEN
----- bla_bla -----
----- bla_bla -----
ENDIF
END
e
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.
:( :(
Che sofferenza !!! :rolleyes:
Mentre aspetto la tua risposta, ho continuato simulando una chiusura di giornata non bilanciata. In queste condizioni, la mia logica vorrebbe che il controllo tornasse dalla Form3.class alla FMain. Class, perciò ho scritto :
Nella Form3.FineBilancioGG_Click
PUBLIC SUB FineBilancioGG_Click()
DIM DB_Connection AS NEW Connection
bla...bla...bla
bla...bla...bla
SELECT CASE Message.Error("TOTALI DI QUDRATURA ERRATI" & Chr(10) & Chr(10) & "Cosa vuoi fare ?", "Correggo e Ripeto Chiusura", "Finisco, ma lascio la giornata 'APERTA'")
CASE 2
b_SwFrm3Clo = TRUE
ME.Close
END SELECT
END
Nella Form2. PulsFineMovv_Click, da cui avevo richiamato la Form3:
PUBLIC SUB PulsFineMovv_Click()
Form3.Showmodal
IF Form3.b_SwFrm3Clo = TRUE 'Test necessario per riconoscere la decisione operativa di "CHIUSURA GIORNATA"
Form3.b_SwFrm3Clo = FALSE
ME.Close
ENDIF
END
Ecco, purtroppo, l'ultima Me.Close non viene eseguita ed il controolo rimane dentro la Form2.class.
Per dare un'idea graficamente schematica, dovrebbe avvenire quanto riprortato nell'allegato
Come fare per ritornare alla FMain? ???
:( :(
Scusa il ritardo...
Anche se hai aperto un'altra discussione, ti faccio subito un esempio su _new().
Mettiamo come esempio, di aver creato una Form, di nome XYZ, che deve accettare due parametri, di cui uno obbligatorio:
PUBLIC SUB _new(parametro1 AS String, OPTIONAL parametro2 AS Boolean = FALSE)
...
ME.Text = parametro1
ME.FullScreen = parametro2
END
Nota: tieni presente che i parametri OPTIONAL devono seguire sempre i parametri obbligatori: parametro1 è obbligatorio in questo caso.
Ora, vogliamo creare la form, per cui dobbiamo procedere con il seguente codice:
DIM p1 AS String = "PROVA" 'Titolo della form
DIM p2 AS Boolean = TRUE 'Espande la form
DIM f AS NEW XYZ(p1, p2)
Come vedi la cosa è relativamente semplice. Il metodo _new() viene sempre eseguito, e prima di procedere alla sua visualizzazione, la Form viene condizionata dal codice inserito in questo metodo. Una volta terminato, il metodo _new() non viene più chiamato (altrimenti scombinerebbe tutto), e la gestione passa al manager delle form (a Gambas tanto per intenderci...).
Comunque, se hai dubbi domanda, sò che a volte rispondo con un certo ritardo, ma alla fine la risposta arriva... :-)