* * * *

Privacy Policy

Blog italiano

Clicca qui se vuoi andare al blog italiano su Lazarus e il pascal.

Forum ufficiale

Se non siete riusciti a reperire l'informazione che cercavate nei nostri articoli o sul nostro forum vi consiglio di visitare il
Forum ufficiale di Lazarus in lingua inglese.

Lazarus 1.0

Trascinare un file nel programma
DB concetti fondamentali e ZeosLib
Recuperare codice HTML da pagina web
Mandare mail con Lazarus
Stabilire il sistema operativo
Esempio lista in pascal
File INI
Codice di attivazione
Realizzare programmi multilingua
Lavorare con le directory
Utilizzare Unità esterne
TTreeView
TTreeview e Menu
Generare controlli RUN-TIME
LazReport, PDF ed immagini
Intercettare tasti premuti
Ampliare Lazarus
Lazarus e la crittografia
System Tray con Lazarus
UIB: Unified Interbase
Il file: questo sconosciuto
Conferma di chiusura di un applicazione
Liste e puntatori
Overload di funzioni
Funzioni a parametri variabili
Proprietà
Conversione numerica
TImage su Form e Panel
Indy gestiore server FTP lato Client
PopUpMenu sotto Pulsante (TSpeedButton)
Direttiva $macro
Toolbar
Evidenziare voci TreeView
Visualizzare un file Html esterno
StatusBar - aggirare l'errore variabile duplicata
Da DataSource a Excel
Le permutazioni
Brute force
Indy 10 - Invio email con allegati
La gestione degli errori in Lazarus
Pascal Script
Linux + Zeos + Firebird
Dataset virtuale
Overload di operatori
Lavorare con file in formato JSON con Lazarus
Zeos ... dietro le quinte (prima parte)
Disporre le finestre in un blocco unico (come Delphi)
Aspetto retrò (Cmd Line)
Lazarus 1.0
Come interfacciare periferica twain
Ubuntu - aggiornare free pascal e lazarus
fpcup: installazioni parallele di lazarus e fpc
Free Pascal e Lazarus sul Raspberry Pi
Cifratura: breve guida all'uso dell'algoritmo BlowFish con lazarus e free pascal.
Creare un server multithread
guida all'installazione di fpc trunk da subversion in linux gentoo
Indice
DB concetti fondamentali e connessioni standard
Advanced Record Syntax
DB concetti fondamentali e DBGrid
DB concetti fondamentali e TDBEdit, TDBMemo e TDBText
Advanced Record Syntax: un esempio pratico
Superclasse form base per programmi gestionali (e non)
Superclasse form base per programmi gestionali (e non) #2 - log, exception call stack, application toolbox
Superclasse form base per programmi gestionali (e non) #3 - traduzione delle form
Superclasse form base per programmi gestionali (e non) #4 - wait animation
Un dialog per la connessione al database:TfmSimpleDbConnectionDialog
Installare lazarus su mac osx sierra
immagine docker per lavorare con lazarus e free pascal
TDD o Test-Driven Development
Benvenuto! Effettua l'accesso oppure registrati.
Settembre 08, 2024, 02:18:34 am

Inserisci il nome utente, la password e la durata della sessione.

21 Visitatori, 0 Utenti

Autore Topic: Come richiamare una procedure/function interna ad altra Form  (Letto 838 volte)

petrusic

  • Hero Member
  • *****
  • Post: 613
  • Karma: +0/-0
Come richiamare una procedure/function interna ad altra Form
« il: Luglio 15, 2024, 10:51:45 pm »
Mi trovo di fronte alla necessità di richiamare dalla Form9 una procedura che è dichiarata all'interno diella Form8.

Ho letto questo ed ho provato a riportare il conecetto nel mio programma, ma non riesco ma completare la compilazione per via di un ERRORE incontrato dal compilartore.

Riporto le porzioni di codice inserite:

Nella Fom8 (dove si trova la procedura da richiamare):
Codice: [Seleziona]
unit Frm8;

{$mode ObjFPC}{$H+}
interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, Grids,
  StdCtrls,
  UModuloDatiDB, utilmie, Types;
type

  { TForm8 }

  TForm8 = class(TForm)
    BPulsNoAmmort: TButton;
    BPulsAmmortOk: TButton;
    GridPreAmmort: TStringGrid;
    procedure BPulsNoAmmortClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure GridPreAmmortDrawCell(Sender: TObject; aCol, aRow: Integer;
      aRect: TRect; aState: TGridDrawState);
    procedure GridPreAmmortEnter(Sender: TObject);

public
  procedure ScriMovGridPreAmmort(voceCesp, coVoCesp, dtMovim, impMovim, descrMovim, voceSotCtoCas, coVoceSotCtoCas: String);

var
  striAmmortMan: AnsiString;

private

var
// bla bla
end;

var
  Form8: TForm8;

implementation
uses
  Frmmain, Frm9;
{$R *.lfm}

{ TForm8 }       
// bla bla                                                                                                               

Nella Fom9 (dove richiamo la procedura della Form8):
Codice: [Seleziona]
unit Frm9;

{$mode ObjFPC}{$H+}

interface

uses
  Classes, SysUtils, DB, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls, Grids, LCLType, Math, memds, LR_Class, LR_DBSet, lr_e_pdf, Types,
  Frm8, Frm12, UModuloDatiDB, utilmie;

type
  { TForm9 }

  TForm9 = class(TForm)
    BPulsAvanti: TButton;
// bla bla

  private
    FAltraForm: TForm8;
    procedure SetAltraForm(AValue: TForm8);
  public
    property AltraForm: TForm8 read FAltraForm write SetAltraForm;

var
  dataFin, segnoIniFinAn: String;

end;

var
  Form9: TForm9;

// bla bla
implementation

// bla bla
        Form8.AltraForm.scriMovGridPreAmmort(voCespite, coCespite, dtMov, impMov, descrMov, voSotCtoCas, coSotCtoCas);      //<--- ERRORE in compilazione

L'ERRORE segnalato dal compilatore è:  frm9.pas(2305,15) Error: identifier idents no member "AltraForm"
 ???
ciao ciao

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1324
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:Come richiamare una procedure/function interna ad altra Form
« Risposta #1 il: Luglio 16, 2024, 09:31:44 am »
Codice: [Seleziona]
        Form8.AltraForm.scriMovGridPreAmmort(voCespite, coCespite, dtMov, impMov, descrMov, voSotCtoCas, coSotCtoCas);      //<--- ERRORE in compilazione
L'ERRORE segnalato dal compilatore è:  frm9.pas(2305,15) Error: identifier idents no member "AltraForm"
 ???

"AltraForm" è definita in TForm9, non in TForm8. Quindi togli il Form8 davanti alla chiamata di "AltraForm":

Codice: [Seleziona]
        AltraForm.scriMovGridPreAmmort(voCespite, coCespite, dtMov, impMov, descrMov, voSotCtoCas, coSotCtoCas);
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1324
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:Come richiamare una procedure/function interna ad altra Form
« Risposta #2 il: Luglio 16, 2024, 10:45:15 am »
Aggiungo un commento a quanto detto sino a qua.

La chiamata di procedure o funzioni tra Form diverse in genere sarebbe da evitare.
La Form è un contenitore visuale e in genere viene usato per gestire tutti gli aspetti visuali e procedurali relativi alla Form stessa (magari con l'eccezione della Form Principale ...).

Il fatto che da una Form si chiami una procedura di un'altra Form indica molte volte che il codice non è stato sviluppato bene. Ci sono ovviamente delle eccezioni pienamente giustificate su ciò, ad esempio se devo richiamare un dato dopo che la Form è stata nascosta (come per le Form modali), etc ....

Se c'è necessità di elaborare qualcosa da più parti, è meglio creare una classe / record non visuale e usare questa per effettuare le operazioni (ad esempio una Form può alimentare i dati della classe e un'altra Form li può estrarre elaborati e visualizzare quando serve).

Istanziando la classe / record come globale avremo la possibilità di chiamare le varie funzioni non solo da una qualsiasi Form, ma anche da eventuali  Thread.

Ciao
« Ultima modifica: Luglio 16, 2024, 10:49:00 am da DragoRosso »
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

petrusic

  • Hero Member
  • *****
  • Post: 613
  • Karma: +0/-0
Re:Come richiamare una procedure/function interna ad altra Form
« Risposta #3 il: Luglio 16, 2024, 03:58:50 pm »
Aggiungo un commento a quanto detto sino a qua.

La chiamata di procedure o funzioni tra Form diverse in genere sarebbe da evitare.
La Form è un contenitore visuale e in genere viene usato per gestire tutti gli aspetti visuali e procedurali relativi alla Form stessa (magari con l'eccezione della Form Principale ...).

Ho capito. A tal proposito devo dirti che, pur non avendone coscienza, ho sempre fatto così, passando al momento della chiamata della Form, la stringa coi dati da mostrare, ma questa volta pensavo di sfruttare l'idea per risparmiare i tempi di costruzione della stringa (nella Form9) e di estrazione dalla stessa (nella Form8). Ciò, però, mi porterebbe naturalmente ad usare un ciclo iterativo di chiamate alla procedura della Form8 per riempire le celle della StringGrid da mostrare, alla fine di tale ciclo, con la solita chiamata .ShowModal.

Citazione
(author=DragoRosso)
Se c'è necessità di elaborare qualcosa da più parti, è meglio creare una classe / record non visuale e usare questa per effettuare le operazioni (ad esempio una Form può alimentare i dati della classe e un'altra Form li può estrarre elaborati e visualizzare quando serve).

Istanziando la classe / record come globale avremo la possibilità di chiamare le varie funzioni non solo da una qualsiasi Form, ma anche da eventuali  Thread.

Questo tuo suggerimento potrebbe un'opportunità per conoscere meglio Lazarus.   :) ::)
« Ultima modifica: Luglio 16, 2024, 04:09:24 pm da petrusic »
ciao ciao

petrusic

  • Hero Member
  • *****
  • Post: 613
  • Karma: +0/-0
Re:Come richiamare una procedure/function interna ad altra Form
« Risposta #4 il: Luglio 16, 2024, 05:05:30 pm »
@ DragoRosso

Ritorno alla tua precedente risposta perchè, riflettendo sulla Classe intermedia che hai chiamato  classe / record, ho individuato la classe TCollection (una classe base per raccolte (non ordinate) di TCollectionItems)

Nel wiki di Lazarus è riportato il seguente
esempio
Contiene le funzioni .GetItems e .SetItems.

Potrebbe fare al caso mio, se l'Item potesse essere un array bidimensionale.

Ci ragiono su.  :)
« Ultima modifica: Luglio 16, 2024, 05:07:45 pm da petrusic »
ciao ciao

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1324
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:Come richiamare una procedure/function interna ad altra Form
« Risposta #5 il: Luglio 17, 2024, 12:30:10 pm »
Riporto per chi è curioso un esempio (l'ho fatto in dieci minuti, non è perfetto ovviamente) di isolamento di oggetti.

In questo caso si tratta di due FORM.

Da notare che nessuna delle due unita delle FORM (unit1 e unit2) è inserita in alcuna uses ,,,

E' un esempio basilare scheletrico  su come si può effettuare una "astrazione" in modo da isolare completamente  (o quasi) due oggetti complessi come le FORM.

Ciao

P.S.: FPC ha un baco, riporta che una variabile non è usata, quando invece lo è ed è il fulcro di tutto. In Delphi non viene segnalato ciò. Il codice è esattamente identico. Ciò è solo a livello di segnalazione, non inficia il funzionamento.
« Ultima modifica: Luglio 17, 2024, 12:34:56 pm da DragoRosso »
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

petrusic

  • Hero Member
  • *****
  • Post: 613
  • Karma: +0/-0
Re:Come richiamare una procedure/function interna ad altra Form
« Risposta #6 il: Luglio 17, 2024, 05:25:50 pm »
Riporto per chi è curioso un esempio (l'ho fatto in dieci minuti, non è perfetto ovviamente) di isolamento di oggetti.

Non riesco a capire come funziona l'esempio che hai pubblicato nell'ultimo tuo post. Mi sa che alla fine mi convenga affidarmi ai miei metodi di passare dati da una Form ad un'altra. Forse allungano un pò il processo operativo, ma mi risultano comprensibili
ciao ciao

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1324
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:Come richiamare una procedure/function interna ad altra Form
« Risposta #7 il: Luglio 17, 2024, 06:58:55 pm »
Non preoccuparti, scegli la strada che ti dà più sicurezza. Il codice lo devi mantenere te, quindi è meglio che scegli il modo che ritieni, come anche tu riporti, più comprensibile.

Ciao
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

petrusic

  • Hero Member
  • *****
  • Post: 613
  • Karma: +0/-0
Re:Come richiamare una procedure/function interna ad altra Form
« Risposta #8 il: Luglio 19, 2024, 04:31:33 pm »
Ritorno sull'argomento perchè in questo momento utilizzo molto gli array bidimensionali e mi attira l'idea di passare alla 2.a Form un array già pronto all'uso, piuttosto che costruire una String del tipo Riga1Col1+chr(9)+Riga1Col2+chr(9)+...+Riga1Col1n+chr(13)+Riga2Col1+chr(9)+...+RiganColn,
per poi, nella Form di destinazione, ritornare a comporre l'array da scorrere per la successiva operatività,

Se è chiaro quello che voglio dire, ciò mi permetterebbe di costruire, col Focus dentro 1.a Form, l'array occorrente direttamente nella classe, diciamo, intermedia (per es. daticomunji).
Poi,
Nel momento in cui la 2.a Form prende il Focus, essa potrebbe leggere direttamente i dati, pronti all'uso, nella Classe daticomuni e procedere, quindi, più rapidamente alla compilazione, per es., della StringGrid finale.

Se potessi fare un lavoro del genere, avrei comnpiuto un gran passo avanti nel linguaggio.  ;)

ciao ciao

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1324
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:Come richiamare una procedure/function interna ad altra Form
« Risposta #9 il: Luglio 19, 2024, 06:42:46 pm »
Vedi l'allegato ....
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1324
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:Come richiamare una procedure/function interna ad altra Form
« Risposta #10 il: Luglio 20, 2024, 11:21:47 am »
Ho lasciato volontariamente incompleta la funzionalità del record "TDatiCoumni" ... tra l'altro ad esempio manca la funzione di "CLEAR" dello stesso in modo che l'array interno si svuoti di eventuali contenuti.

Come suggerimento posso dire che per cancellare l'array interno si può usare una modalità semplicissima senza scomodarsi a ciclare per l'intero array ...
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

petrusic

  • Hero Member
  • *****
  • Post: 613
  • Karma: +0/-0
Re:Come richiamare una procedure/function interna ad altra Form
« Risposta #11 il: Luglio 20, 2024, 03:46:16 pm »
Vedi l'allegato DatiComuni.zip

Ti ringrazio per la pazienza ed il tempo che mi stai dedicando.
Con questo secondo esempio, mi sembra tutto molto più chiaro e comincio a capire il meccanismo.

Ora posso provare a metterlo in campo.  :D
ciao ciao

petrusic

  • Hero Member
  • *****
  • Post: 613
  • Karma: +0/-0
Re:Come richiamare una procedure/function interna ad altra Form
« Risposta #12 il: Luglio 20, 2024, 10:35:29 pm »
@ DragoRosso

Ho cominciato a familiarizzare con la tecnica di passaggio dati fra due Form facendoli transitare da una Classe di variabili.
Dall'ultimo esempio che mi hai girato, ho capito che la Unit1 è la Form cedente dati, mentre la Unit2 è la Form ricevente. La Unit3 è la Classe "daticomuni".

Quest'ultima viene inizializzata col comando "DatiComuni.Init(5, 2)" , inserito all'interno della Unit1.
La Unit2 con la sua Form2, contenente la StringGRid da riempire coi dati provenienti dalla Unit1, contiene una sola procedura
Codice: [Seleziona]
procedure TForm2.FormShow(Sender: TObject);
var row, col: integer;
begin
  //Legge il record e lo inserisce nella griglia
  for row := 0 to DatiComuni.NumRow-1 do
    for col := 0 to DatiComuni.NumCol-1 do
      StringGrid1.Cells[col+1, row+1] :=  DatiComuni.Dati[row, col];
end;                           
che si occupa del riempimento delle celle della StringGrid1.

Non ho trovato la
Citazione
procedure FormCreate
così come non ho trovato la
Citazione
Application.CreateForm(TForm2, Form2);
nella Unit1.

Ho provato ad eseguire il programmino di esempio che mi hai girato e funziona perfettamente.

Ma come può funzionare se manca il Create della Form2 ?
ciao ciao

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1324
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:Come richiamare una procedure/function interna ad altra Form
« Risposta #13 il: Luglio 21, 2024, 09:39:48 am »
La Unit3 è la Classe "daticomuni".
Non è proprio una classe, bensì un record. I record "avanzati" possono agire similmente alle classi, ma sono più .... snelli .... ad esempio non bisogna istanziarli. Puoi leggere qui: https://www.lazaruspascal.it/index.php?page=145
Gli advanced record implementano delle funzionalità che le classi non hanno: ad esempio si possono sostituire gli operatori ... cioè posso ad esempio eseguire una somma tra due record o una moltiplicazione, o altro (operator overloading).

Non ho trovato la
Citazione
procedure FormCreate
così come non ho trovato la
Citazione
Application.CreateForm(TForm2, Form2);
nella Unit1.
In Lazarus, per impostazione predefinita, le FORM e i DATAMODULE (e solo questi due oggetti) vengono "autoistanziati" all'avvio dell'applicazione.
E' possibile evitare ciò andando nelle opzioni di progetto / FORM (vedi allegato).
Quando si modifica quella opzione (quindi si inserisce una FORM in AUTOCREAZIONE o meno), viene cambiato automaticamente il file di progetto .lpr (in questo caso Project2.lpr) inserendo o togliendo la riga Application.CreateForm corrispondente.

Per quello che riguarda l'evento "FormCreate", esso non è obbligatorio e serve solo se hai delle attività da svolgere immediatamente dopo la creazione della Form stessa.
Nel caso della Form1 (in unit1.pas), viene eseguita l'inizializzazione di DatiComuni (ossia l'allocazione dello spazio per righe e colonne volute) ... è solo per quello che nella Form1 esiste quell'evento.

Ciao

P.S.: se vuoi inserire la procedura Clear questo è il suggerimento (devi inserire la dichiarazione anche nella definizione del record):
Codice: [Seleziona]
procedure TDatiCoumni.Clear;
var tempRow, tempCol: integer;
begin
  tempRow := Length(fDati);
  tempCol := Length(fDati[0]);
  //Questo azzera l'array
  SetLength(fDati, 0, 0);
  //Questo risetta l'array ponendo a default (per le stringhe vale "") il contenuto
  SetLength(fDati, tempCol, tempRow);
end;
« Ultima modifica: Luglio 21, 2024, 06:33:11 pm da DragoRosso »
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

petrusic

  • Hero Member
  • *****
  • Post: 613
  • Karma: +0/-0
Re:Come richiamare una procedure/function interna ad altra Form
« Risposta #14 il: Luglio 23, 2024, 04:05:10 pm »
Mi sembra sempre molto complicato.

Ho risolto più semplicemente a modo mio.
Ti prego di scusarmi per il tempo che hai dovuto perdere  per cercare di aiutarmi. Mi dispiace tanto.
 :-[
Comunque, Grazie di tutto.
ciao ciao

 

Recenti

How To

Utenti
  • Utenti in totale: 796
  • Latest: renato
Stats
  • Post in totale: 18962
  • Topic in totale: 2260
  • Online Today: 27
  • Online Ever: 900
  • (Gennaio 21, 2020, 08:17:49 pm)
Utenti Online
Users: 0
Guests: 21
Total: 21

Disclaimer:

Questo blog non rappresenta una testata giornalistica poiché viene aggiornato senza alcuna periodicità. Non può pertanto considerarsi un prodotto editoriale ai sensi della legge n. 62/2001.