Written by xinyimanposted in Lazarus 1.0 Ottobre 17, 2011, 11:05:00 am21627 ViewsRating: 0 (0 Rates)Print
Può capitare a volte di avere la necessità di trascinare un file su un programma aperto per poter effettuare una qualsiasi tipologia di elaborazione su tale file. In Lazarus è davvero molto semplice effettuare tale operazione.
Per prima cosa create una nuova applicazione di prova, cliccate sulla form appena creata e impostate la proprietà AllowDropFile a true, ora andate nell'evento FormDropFiles della form e fate in modo che coincida con il seguente codice:
procedure TForm1.FormDropFiles(Sender: TObject; const FileNames: array of String);
begin
ShowMessage(FileNames[0]);
end;
Ora compilate e lanciate il programma. Provate a trascinare un file qualsiasi sulla finestra del eseguibile appena lanciato e vedrete il percorso e il nome di tale file. Ora stà a voi e alla vostra fantasia farne quello che volete.
Destructor MyMailObject.Destroy();
begin
//Free finale degli oggetti
StrList.Free; //Prova
MyTesto.Free;
MyToList.Free;
MyCCList.Free;
MyAllegatoList.Free;
Mime.Free; //Prova
smtp.Free;
end;
procedure MyMailObject.SetMyUser(UserP: string);
begin
MyUser:=UserP;
end;
procedure MyMailObject.SetMyPassword(PasswordP: string);
begin
MyPassword:=PasswordP;
end;
procedure MyMailObject.SetMySMTPHost(SMTPHostP: string);
begin
MySMTPHost:=SMTPHostP;
end;
procedure MyMailObject.SetMyPorta(PortaP: string);
begin
MyPorta:=PortaP;
end;
procedure MyMailObject.SetSSLTLS(SicurezzaP: boolean);
begin
if SicurezzaP=TRUE then
MySicurezza:=2
else
MySicurezza:=1;
end;
procedure MyMailObject.SetMyNome(NomeP: string);
begin
MyNome:=NomeP;
end;
procedure MyMailObject.SetMyFrom(FromP: string);
begin
MyFrom:=FromP;
end;
procedure MyMailObject.SetMyRisposta(RispostaP: string);
begin
MyRisposta:=RispostaP;
end;
procedure MyMailObject.AddDestinatario(DestP: string);
begin
MyToList.Add(DestP);
end;
procedure MyMailObject.AddMyAllegatoList(AllegatoListP: string);
begin
MyAllegatoList.Add(AllegatoListP);
end;
procedure MyMailObject.SetMyOggetto(OggettoP: string);
begin
MyOggetto:=OggettoP;
end;
procedure MyMailObject.AddRowCorpoMail(RigaP: string);
begin
StrList.Add(RigaP);
end;
function MyMailObject.MySendMail(var Errore: string): boolean;
var
ret: boolean;
k: integer;
begin
ret:=FALSE;
Errore:='';
try
//====================================
//If authorization is required, then fill in username
smtp.UserName := MyUser;
//Specify user's password
smtp.Password := MyPassword;
//Specify target server IP (or symbolic name)
smtp.TargetHost := MySMTPHost;
//Specify target server port
if (Trim(MyPorta) = '') then begin
//Porta non impostata
smtp.TargetPort := '25'; //Porta di default
end
else begin
smtp.TargetPort := MyPorta;
end;
//Enable SSL|TLS protocols
smtp.autoTLS := True;
//smtp.Timeout := 60;
if (MySicurezza = 2) then begin
//SSL/TLS
smtp.FullSSL := True;
end;
//Connect to SMTP server
if not smtp.Login() then Errore:=Concat(Errore, #13#10 , 'SMTP ERROR: Login:' , smtp.EnhCodeString);
//if not smtp.StartTLS () then showmessage('SMTP ERROR: StartTLS:' + smtp.EnhCodeString);
//If you successfully pass authorization to the remote server
if smtp.AuthDone then begin
//Corpo mail
for k := 0 to (MyTesto.Count - 1) do begin
StrList.Add(MyTesto[k]);
end;
//Mime.Header.CharsetCode := UTF_8; //Da' errore
Mime.Header.From := MyNome + ' <' + MyFrom + '>';
//E-mail per rispondere (eventuale)
if (Trim(MyRisposta) = '') then begin
//E-Mail di risposta non indicata
Mime.Header.ReplyTo := MyFrom; //Indirizzo di risposta = indirizzo mittente
end
else begin
//E-Mail di risposta indicata
Mime.Header.ReplyTo := MyRisposta;
end;
//To
for k := 0 to (MyToList.Count - 1) do begin
Mime.Header.ToList.Add(Trim(MyToList[k]));
end;
//CC (eventuale)
if (MyCCList.Count > 0) then begin
for k := 0 to (MyCCList.Count - 1) do begin
Mime.Header.CCList.Add(Trim(MyCCList[k]));
end;
end;
//Oggetto
Mime.Header.Subject := MyOggetto;
//Corpo mail
Mime.AddPartMultipart(MyCorpoMail, Nil);
Mime.AddPartText(StrList, Mime.MessagePart);
//Eventuali allegati
if (MyAllegatoList.Count > 0) then begin
//Ci sono allegati
{//Questo blocco funziona correttamente, ma non e' possibile impostare il nome degli allegati che vengono poi visualizzati dal destinatario
for k := 0 to (MyAllegatoList.Count - 1) do begin
hdAttach := Trim(MyAllegatoList[k]);
if (hdAttach <> '') then begin
Mime.AddPartBinaryFromFile(hdAttach, Mime.MessagePart);
end;
end;
}
tmp := TMemoryStream.Create;
for k := 0 to (MyAllegatoList.Count - 1) do begin
try
tmp.Clear; //Cmq. non sembra necessario
tmp.LoadFromFile(Trim(MyAllegatoList[k]));
Mime.AddPartBinary(tmp, RetNomeFile(MyAllegatoList[k]), Mime.MessagePart); //Nome da visualizzare allegato
finally
//tmp.Free;
end;
end;
tmp.Free;
end;
//Codifica messaggio
Mime.EncodeMessage;
//Invio: From
if not SMTP.MailFrom(MyFrom, Length(Mime.Lines.Text)) then exit;
//Invio: To
for k := 0 to (MyToList.Count - 1 ) do begin
if not SMTP.MailTo(Trim(MyToList[k])) then exit;
end;
//Invio: CC
if (MyCCList.Count > 0) then begin
//Ci sono indirizzi CC
for k := 0 to (MyCCList.Count - 1) do begin
if not SMTP.MailTo(Trim(MyCCList[k])) then exit;
end;
end;
//Invio: Corpo messaggio + eventuali allegati
if not SMTP.MailData(Mime.Lines) then exit;
end;
//Logout
if not smtp.Logout() Then
Errore:=Concat(Errore, #13#10 , 'SMTP ERROR: Logout:' , smtp.EnhCodeString);
//Se arrivati qui tutto OK
ret := True; //OK
Result:=ret;
finally
//Processa messaggi
Application.ProcessMessages;
end;
end;
function MyMailObject.RetNomeFile(PathFile: string): string;
var
car, car2, ret: string;
i: integer;
begin
ret:='';
car:='/';
{$IFDEF WIN32}
car:='\';
{$ENDIF}
for i:=1 to Length(PathFile) do
begin
car2:=PathFile[i];
if car2=car then
begin
ret:='';
end
else
begin
ret:=Concat(ret, car2);
end;
end;
RetNomeFile:=ret;
end;
end.
Ora ipotizziamo che il progetto contiene solo una form di nome Unit1 e che a sua volta contiene solo un pulsante chiamato Button1. Il codice del programma sarà.
Nell'articolo precedente abbiamo visto come si possa scrivere a video qualcosa tramite il comando write o writeln. Bene, oltre a scrivere a video, all'utente può tornare utile ricevere dei dati dalla tastiera. Questo è possibile tramite il comando read o readln. Facciamo un esempio. Apriamo una nuova console application e nella parte dichiarativa andiamo ad immettere la seguente riga:
write('Inserisci un numero da uno a dieci: '); readln(PrimaVariabile); writeln('Il numero da te immesso è: ', PrimaVariabile); repeat until keypressed;
Ovviamente ricordiamoci di andare ad inserire la unit Crt. Se lanciamo il programma appena realizzato, noteremo che con questo semplice comando possiamo leggere input da tastiera. Si noti che la variabile dichiarata è di tipo integer, ovvero numerica; se noi al posto di digitare un numero digitassimo un carattere ci restituirebbe un errore e il programma verrebbe immediatamente terminato.
Si può considerare una variabile come un contenitore dove andare ad immagazzinare un informazione. Questa informazione può variare nel tempo, proprio per questo si chiama variabile. Si può considerare una costante al pari di una variabile ma una volta riempita con un valore quello rimane fisso fino alla fine del programma. Quando si dichiara una variabile si occupa dello spazio in memoria per tutta la durata del programma o della funzione o della procedura, dipende dove questa variabile è dichiarata. Si può anche dire allocare in memoria una variabile. Affronteremo questo capitolo in maniera pratica come sarà di consuetudine in questa community. Per capire l'argomento di discussione di questo capitolo apriamo una nuova console application come abbiamo fatto precedentemente per il primo programma.
Dove troviamo scritto { add your program here } andiamo ad aggiungere le seguenti righe:
writeln('La costante da me dichiarata con il nome MiaCostante ha un valore di:', MiaCostante);
PrimaVariabile := 'A'; SecondaVariabile := 3; TerzaVariabile := 3.3; QuartaVariabile := TerzaVariabile + 1; QuintaVariabile := 'Ecco a cosa servono le variabili!';
writeln('PrimaVariabile: ', PrimaVariabile); writeln('SecondaVariabile: ', SecondaVariabile); writeln('TerzaVariabile: ', TerzaVariabile); writeln('QuartaVariabile: ', QuartaVariabile); writeln('QuintaVariabile: ', QuintaVariabile); writeln('La costante da me dichiarata con il nome MiaCostante ha un valore di:', MiaCostante);
PrimaVariabile := 'B'; SecondaVariabile := SecondaVariabile + 2; TerzaVariabile := 3.3 + 1; QuartaVariabile := TerzaVariabile + 1; QuintaVariabile := 'Ecco a cosa servono le variabili! Fine';
Ora analizziamo quello che abbiamo appena fatto. Prendiamo in esame l'ultima modifica effettuata, var è una parola riservata che sta a significare che voglio dichiarare delle variabili o delle costanti. Dichiarare vuol dire che si decide che tipo di contenuto può possedere la variabile in questione, se numerica intera, numerica decimale, alfanumerica, stringa, o altro.
Consideriamo solo le variabili che abbiamo aggiunto noi, la prima si chiama PrimaVariabile ed è definita come char, ovvero può contenere caratteri. La seconda si chiama SecondaVariabile ed è definita integer, ovvero un tipo numerico intero come il 5 o 8 ma non ad esempio 4,5 o 4.3. La TerzaVariabile e la QuartaVariabile sono di tipo real ovvero numerico con la virgola. Mentre la QuintaVariabile è di tipo string ovvero può contenere una lettera come una parola o una frase alfanumerica. E poi per ultima la costante MiaCostante, che avrà il valore 5 per tutta la vita del programma. Ora vediamo in pratica come si differenzia una variabile da una costante. Come si può notare nella prima parte di codice che abbiamo modificato in questo programma abbiamo assegnato dei valori alle variabili e poi le abbiamo stampate a video, e poi nuovamente rivalorizzate e successivamente ristampate. Se il lettore si prendesse la briga di provare a riassegnare un valore alla costante noterebbe che in fase di compilazione del programma si otterrebbe un errore, perchè una costante non può essere rivalorizzata dopo essere stata dichiarata. Compilando attraverso il solito pulsantino che contiene un triangolino verde saremo in grado di vedere il risultato del nostro articolo.
I tipi principali delle variabili disponibili nel linguaggio free pascal sono: integer, shortint, smallint, longint, longword, int64, byte, word, cardinal, qword, boolean, bytebool, longbool, char.
Per quanto riguarda i tipi numerici li possiamo così classificare:
Tipo
Range
Dimensione in bytes
Byte
0..255
1
Shortint
-128..127
1
Smallint
-32768..32767
2
Word
0..65535
2
Integer
o Smallint o Longint
2 o 4
Cardinal
Longword
4
Longint
-2147483648 .. 2147483647
4
Longword
0..4294967295
4
Int64
-9223372036854775808 .. 9223372036854775807
8
QWord
0 .. 18446744073709551615
8
Per quanto riguarda il tipo integer che può variare da smallint a longint è il freepascal a fare la conversione automatica del tipo in base al contenuto stesso della varibile.
Oltre ai tipi interi esistono anche i tipi booleani ovvero variabili che contengono i valori TRUE e FALSE (VERO o FALSO).
Nome
Dimensione in bytes
Valore TRUE/VERO
Boolean
1
1
ByteBool
1
Qualsiasi valore diverso da zero
WordBool
2
Qualsiasi valore diverso da zero
LongBool
4
Qualsiasi valore diverso da zero
Free pascal e quindi anche lazarus visto che si basa su questo linguaggio comprende anche il tipo Char che è esattamente un byte di dimensione e contiene uno dei caratteri ASCII. Una costante di tipo carattere quando verrà dichiarata avrà il valore tra virgolette ad esempio 'A'. Un carattere può anche essere specificato dal suo codice ASCII facendolo precedere dal carattere #. Ad esempio #65 equivale ad 'A'.
Oltre il tipo Char esiste anche il tipo String che che è definito come in Turbo Pascal ovvero una sequenza di caratteri, con una specifica dimensione facoltativa. Essa sostiene inoltre anche AnsiString con lunghezza illimitata come in Delphi.
Il tipo string va da 1 carattere a 255 e viene dichiarato nel seguente modo:
In questa maniera abbiamo dichiarato una variabile di nome NomeVariabile che può contenere 50 caratteri, ovvero una stringa di 50 caratteri. Mentre le variabili dichiarate come AnsiString sono quelle che terminano con null e vengono gestiti tramite puntatori dal linguaggio, ma del tutto trasparenti al'utente programmatore. Facciamo un esempio se dichiaro la variabile
ottengo una variabile potenzialmente infinita (può essere grande tanto quanto la memoria messa a disposizione dalla macchina su cui gira il programma). Facciamo un confronto, se dichiaro una stringa non ansi come ho fatto precedentemente allora se andando avanti nell'esecuzione del programma necessito di memorizzare nella variabile una stringa di 51 caratteri non posso farlo e il programma va in errore in fase di compilazione (o meglio segnala che c'è un errore ma il programma viene realizzato ma tronca la stringa a 10 caratteri), nel secondo caso no.
Facciamo un esempio pratico creando una nuova console application e modificandola in modo che sia così:
procedure TMyApplication.DoRun; var ErrorMsg: String; PrimaVariabile: string[10]; SecondaVariabile: AnsiString; begin // quick check parameters ErrorMsg:=CheckOptions('h','help'); if ErrorMsg'' then begin ShowException(Exception.Create(ErrorMsg)); Halt; end;
// parse parameters if HasOption('h','help') then begin WriteHelp; Halt; end;
{ add your program here } clrscr(); PrimaVariabile:='sono 10 lettere mie'; SecondaVariabile:='sono 10 lettere'; writeln(PrimaVariabile); writeln(SecondaVariabile); repeat until keypressed; // stop program loop Terminate; end;
constructor TMyApplication.Create(TheOwner: TComponent); begin inherited Create(TheOwner); StopOnException:=True; end;
destructor TMyApplication.Destroy; begin inherited Destroy; end;
procedure TMyApplication.WriteHelp; begin { add your help code here } writeln('Usage: ',ExeName,' -h'); end;
var Application: TMyApplication;
{$IFDEF WINDOWS}{$R project1.rc}{$ENDIF}
begin Application:=TMyApplication.Create(nil); Application.Title:='My Application'; Application.Run; Application.Free; end.
Se compilate oltre a vedere il risultato vedrete che viene riportato un errore in fase di compilazione dovuta al fatto che la stringa contenuta in PrimaVariabile contiene più caratteri di quelli consentiti.
Free pascal supporta anche l'implementazione delphi Pchar che è definito come un puntatore ad un tipo Char. Può essere paragonato ad una stringa che termina con il null, vale a dire che il Pchar è un puntatore ad un array di tipo char che termina con il carattere null. Free pascal permette l'inizializzazione delle variabile di tipo Pchar sotto forma di costanti o tramite inizializzazine dirette. Ad esempio dichiariamo in una nuova console application la seguente variabile nella parte dichiarativa del programma:
se salviamo ed eseguiamo il programma allora noteremo che avremo lo stesso risultato del programma precedente.
N.B. Le variabili possono essere suddivise in due macrocategorie: variabili globali e variabili locali. Le variabili globali sono dichiarate nella sezione dichiarativa del programma principale. Hanno visibilità e "vita" per tutta la durata del programma e in tutte le procedure. Le variabili locali sono dichiarate nella sezione dichiarativa di una procedura/funzione. Hanno visibilità e "vita" solo all'interno della procedura in cui sono state dichiarate.
N.B. Tutti i real vengono visualizzati in notazione scientifica, che non sempre è bella da vedere o utile ai fini della visualizzazione. Per ovviare a questo problema basta specificare quante cifre avrà la parte decimale. La sintassi per fare questo è:
In questo caso writeln('Esempio real: 'MiaVariabile:6:2) avremo come risultato un valore di 6 cifre di cui 2 sono decimali, ovviamente la MiaVariabile doveva essere dichiarata real.
Il Pascal è un linguaggio di programmazione, e non è il solo, ma noi approfondiremo questo perché Lazarus si basa proprio su Free Pascal. Analizziamo ora il significato del termine 'linguaggio di programmazione'. 'linguaggio' è un modo di comunicare. Noi, per esempio, comunichiamo con i nostri connazionali tramite l'italiano, mentre se volessimo parlare con un inglese dovremmo comunicare con lui tramite l'inglese, con un francese usando il francese e così via. Quindi possiamo capire che il Pascal, essendo un linguaggio, ha le sue regole di sintassi esattamente come la lingua italiana. Ora analizziamo il termine 'di programmazione'. Si riferisce all'atto di programmare un computer perché, come tutti sanno, se il computer non fosse programmato per fare qualcosa (scrivere documenti, calcolare, trasmettere dati) sarebbe solo un ammasso di pezzi elettronici e basta. Iniziamo a capire la sintassi del Pascal attraverso la scrittura della nostra prima console application. Innanzitutto andare sulla voce 'File', poi su 'Nuovo'. Ora si dovrebbe aprire una finestra con alcune voci. Tra queste dovrebbe comparire 'Console Application'. Cliccando su ok ci si dovrebbe aprire una finestra con questo scritto dentro.
program project1; {$mode objfpc}{$H+} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, SysUtils, CustApp, { you can add units after this }; type { TMyApplication } TMyApplication = class(TCustomApplication) protected procedure DoRun; override; public constructor Create(TheOwner: TComponent); override; destructor Destroy; override; procedure WriteHelp; virtual; end; { TMyApplication } procedure TMyApplication.DoRun; var ErrorMsg: String; Esco: String; begin // quick check parameters ErrorMsg:=CheckOptions('h','help'); if ErrorMsg'' then begin ShowException(Exception.Create(ErrorMsg)); Halt; end; // parse parameters if HasOption('h','help') then begin WriteHelp; Halt; end; { add your program here } // stop program loop Terminate; end; constructor TMyApplication.Create(TheOwner: TComponent); begin inherited Create(TheOwner); StopOnException:=True; end; destructor TMyApplication.Destroy; begin inherited Destroy; end; procedure TMyApplication.WriteHelp; begin { add your help code here } writeln('Usage: ',ExeName,' -h'); end;
var Application: TMyApplication; {$IFDEF WINDOWS}{$R project1.rc}{$ENDIF} begin Application:=TMyApplication.Create(nil); Application.Title:='My Application'; Application.Run; Application.Free; end.
Questo codice è la base di partenza per ogni nuovo programma da linea di comando. Per il momento prendiamo per buono quello che c'è scritto, ed andiamo ad inserire la parte che a noi interessa approfondire al momento. Dove troviamo la scritta
Salviamo in una directory a noi nota con il nome PrimoProgramma; poi clicchiamo sul pulsante a forma di triangolino verde e vedremo comparire il risultato del nostro primo programma. Ora andiamo ad analizzare quello che abbiamo fatto. Aggiungendo la voce Crt nelle uses abbiamo inserito una libreria che ci permette di utilizzare determinate funzioni e procedure (in questo caso mi permette di usare il clrscr e il keypressed). Ora prendiamo in esame ogni singola riga:
Writeln mi permette di scrivere a video tutto quello che sta tra le parentesi. In questo caso mi ha stampato la stringa Primo programma, anche se non la vedo a video (con la prossima riga di codice scopriremo come mai) ed è andato a capo.
Clrscr vuol dire clear screen, ovvero pulisci schermo. E quindi è per questo che non si vede a video la scritta "Primo Programma", perchè è stata scritta ma poi cancellata.
readkey; {volendo avrei potuto usare anche la dicitura: repeat until keypressed;}
Aspetto che l'utente digiti un tasto qualsiasi. Questo perchè se non avessimo inserito quest'ultima istruzione non avremmo visto a video nessun risultato, perchè sarebbe stato eseguito ma non si sarebbe fermato e quindi si sarebbe automaticamente chiusa la finestra. Volendo si può sostituire readkey; con repeat until keypressed; si otterrebbe comunque lo stesso risultato. Bene, a questo punto abbiamo capito che per scrivere a video si possono usare le due parole write e writeln, la prima non va a capo dopo aver scritto quello che deve mentre la seconda sì. Ok ora iniziamo a vedre anche le altre cose importanti che questo primo programma ci può offrire. Iniziamo con una premessa: il file sorgente non contiene solo parole che servono per realizzare il programma, ma anche parole che servono a ricordarsi cosa un pezzo di codice scritto precedentemente realizzava. Cio' si può ottenere tramite i commenti, ovvero pezzi di codice ignorati dal compilatore. Prendiamo un esempio se scrivo writeln('Hello world!'); a video vedrò la suddetta scritta ma se invece scrivessi {writeln('Hello world!');} a video non vedrei niente perchè il compilatore lo ignorerebbe considerandolo un commento. L'utilità di questa pratica (commentare i sorgenti) è quella di mettere delle informazioni, note o impressioni che sicuramente non ci si può ricordare (ad esempio a distanza di due mesi). Servono per la manutenzione del codice sorgente. Ora notiamo che il programma inizia con la parola Program che è una di quelle parole riservate del linguaggio pascal, e identifica l'inizio della scrittura di un programma pascal. Program viene seguito dal nome del programma nell'esempio riportato da PrimoProgramma. Un'altra parola riservata molto utile è Uses che come abbiamo visto precede le librerie necessarie al funzionamento del programma stesso. Notiamo anche che nel corso del programma ci siamo imbattuti più volte nella digitura begin e in end , bene queste due parole servono al compilatore a differenziare la parte esecutiva del programma. A volte troviamo l'end con il punto e altre con il punto e virgola, la prima versione sta a identificare la parte esecutiva principale del programma, mentre la seconda serve a identificare la parte esecutiva di procedure e funzioni (argomento che verrà trattato più avanti - in altri articoli) Quindi tutto quello che noi vogliamo vedere a video verrà immesso tra un begin ed un end. Tutto il resto lo capiremo nel corso di altri articoli. N.B. Definizione di codice sorgente: sono uno o più file che contenenti delle informazione che se correttamente compilate danno vita ad un programma. N.B. Definizione di compilatore: è un programma che legge i codici sorgenti e se sono corretti sintatticamente genera un programma. N.B. Lazarus genera eseguibili veramente molto grossi, basta andare a vedere le dimensioni del programma appena creato. Per ovviare a questo problema basta selezionare Progetto → Opzioni compilatore... nelle voci Codice e Linking verificare che i parametri siano li stessi sotto riportati. Le voci che devono essere selezionate sono:
Collegamenti intelligenti (-CX)
Mostra i numeri di linea nella backtrace degli errori di esecuzione (-gl)
Esegue strip degli eseguibili (-Xs)
Link intelligente (-XX)
Se questo modo di compilare non dovesse ridurre le dimensioni degli eseguibili si può tentare quanto segue per l'ambiente windows:
Aprire una console
Tramite console andare nella cartella di Lazarus che contiene il programma STRIP.exe, generalmente c:\Lazarus\fpc\Numero della Versione Pascal\bin\i386-win32 o c:\Programmi\Lazarus\fpc\Numero della Versione Pascal\bin\i386-win32
Digitare il comando: strip --strip-all Applicazione.exe
Digitare il comando: upx -9 Applicazione.exe
Ovviamente applicazione.exe è il nome del programma scritto in FreePascal/Lazarus che si intende ridurre di dimensione, ad esempio C:\ProgrammaProva.exe . Bene avete appena creato il vostro primo programma in free pascal usando Lazarus.
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.
Questo sito utilizza cookie, anche di terze parti, per offriti servizi in linea con le tue preferenze. Chiudendo questo banner, scorrendo questa pagina, cliccando su un link o proseguendo la navigazione in altra maniera, acconsenti all’uso dei cookie.