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.
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
StdCtrls, ComCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Cmd_Aggiungi: TButton;
PageControl1: TPageControl;
Box_DisposizionePosti: TTabSheet;
procedure Button1Click(Sender: TObject);
procedure Cmd_AggiungiClick(Sender: TObject);
procedure EffettuaOperazione(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ private declarations }
Riga, y: integer;
x, j: integer;
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.EffettuaOperazione(Sender: TObject);
var
i: integer;
Nome: string;
begin
i:=0;
//cicla fino a quando non ho passato in rassegna tutti i conrolli del box
//cioè i pulsanti creati tramite codice
while (Box_DisposizionePosti.ControlCount>i) do
begin
if
Box_DisposizionePosti.Controls[i].Name=ActiveControl.Name then //se il
controllo è quello attivo, cioè se sono sul controllo che rappresenta il
pulsante schiacciato
begin
if ((Box_DisposizionePosti.Controls.Color)=clGreen) then
begin
//Nome del pulsante su cui ho schiacciato
Nome:=Box_DisposizionePosti.Controls.Name;
ShowMessage(Nome);
end;
end;
Inc(i);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Riga:=0;
y:=0;
j:=0;
end;
procedure TForm1.Cmd_AggiungiClick(Sender: TObject);
var
i: integer;
begin
with TEdit.Create(Self) do begin
Height:=25;
Width:=40;
if Box_DisposizionePosti.ChildSizing.Layout=cclNone then begin
y:=y+Height+2;
x:=j*Width;
SetBounds(x,y,Width,Height);
Inc(j);
end;
Name:='Cmd_Controllo_'+IntToStr(Riga);
Inc(Riga);
Parent:=Box_DisposizionePosti;
Enabled:=TRUE;
//rendo la editbox di sola lettura
ReadOnly:=TRUE;
Color:=clGreen; //di colore verde
//allineo il testo al centro della edit
Alignment:=taCenter;
Text:='Tasto' + IntToStr(Riga);
//cambio il tipo di puntatore del mouse
Cursor:=crHandPoint;
OnClick:=@EffettuaOperazione;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
begin
i:=Box_DisposizionePosti.ControlCount-1;
// cancello postazioni che non servono più
while i>=0 do
begin
Box_DisposizionePosti.Controls.Free;
Dec(i);
end;
Riga:=0;
end;
end.
A volte si presenta la necessità di generare dei controlli sulle
maschera in quantità variabile. In tal caso ci vengono in aiuto i
controlli a Run-Time. Ovvero li creo tramite codice. Ora allego un
semplice esempio, che basta compilare e provare ad eseguire per capire
di cosa parlo.
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
StdCtrls, ComCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Cmd_Aggiungi: TButton;
PageControl1: TPageControl;
Box_DisposizionePosti: TTabSheet;
procedure Button1Click(Sender: TObject);
procedure Cmd_AggiungiClick(Sender: TObject);
procedure EffettuaOperazione(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ private declarations }
Riga, y: integer;
x, j: integer;
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.EffettuaOperazione(Sender: TObject);
var
i: integer;
Nome: string;
begin
i:=0;
//cicla fino a quando non ho passato in rassegna tutti i conrolli del box
//cioè i pulsanti creati tramite codice
while (Box_DisposizionePosti.ControlCount>i) do
begin
if
Box_DisposizionePosti.Controls[i].Name=ActiveControl.Name then //se il
controllo è quello attivo, cioè se sono sul controllo che rappresenta il
pulsante schiacciato
begin
if ((Box_DisposizionePosti.Controls.Color)=clGreen) then
begin
//Nome del pulsante su cui ho schiacciato
Nome:=Box_DisposizionePosti.Controls.Name;
ShowMessage(Nome);
end;
end;
Inc(i);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Riga:=0;
y:=0;
j:=0;
end;
procedure TForm1.Cmd_AggiungiClick(Sender: TObject);
var
i: integer;
begin
with TEdit.Create(Self) do begin
Height:=25;
Width:=40;
if Box_DisposizionePosti.ChildSizing.Layout=cclNone then begin
y:=y+Height+2;
x:=j*Width;
SetBounds(x,y,Width,Height);
Inc(j);
end;
Name:='Cmd_Controllo_'+IntToStr(Riga);
Inc(Riga);
Parent:=Box_DisposizionePosti;
Enabled:=TRUE;
//rendo la editbox di sola lettura
ReadOnly:=TRUE;
Color:=clGreen; //di colore verde
//allineo il testo al centro della edit
Alignment:=taCenter;
Text:='Tasto' + IntToStr(Riga);
//cambio il tipo di puntatore del mouse
Cursor:=crHandPoint;
OnClick:=@EffettuaOperazione;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
begin
i:=Box_DisposizionePosti.ControlCount-1;
// cancello postazioni che non servono più
while i>=0 do
begin
Box_DisposizionePosti.Controls.Free;
Dec(i);
end;
Riga:=0;
end;
end.
Non vi è mai capitato di dover usare dei menù nei vostri programmi? Se la risposta è si allora sappiate che è possibile tabellare i menù (con le dovute premure) e visualizzare tali menù in una TTreeview in maniere tale da rendere il programma pulito ed efficente.
Per prima cosa vediamo il codice d'esempio che potete trovare in versione integrale all'indirizzo: www.lazaruspascal.it/esempi/MenuTabellato.zip
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
PairSplitter, ComCtrls, StdCtrls, ZConnection, ZDataset;
type
{ TForm1 }
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
PageControl1: TPageControl;
PairSplitter1: TPairSplitter;
PairSplitterSide1: TPairSplitterSide;
PairSplitterSide2: TPairSplitterSide;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
TabSheet3: TTabSheet;
TreeView1: TTreeView;
MyConn: TZConnection;
MyQuery: TZQuery;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure TreeView1Change(Sender: TObject; Node: TTreeNode);
private
{ private declarations }
function InserisciNodiFigli(NodoPadre: integer): boolean;
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
begin
MyConn.Protocol:='sqlite-3';
MyConn.HostName:='localhost';
MyConn.Database:= Application.Location + 'menu.s3db';
MyConn.Connect;
i:=0;
InserisciNodiFigli(i);
TreeView1.ShowRoot:=true;
end;
function TForm1.InserisciNodiFigli(NodoPadre: integer): boolean;
var
MyQuery2: TZQuery;
app: TTreeNode;
begin
if NodoPadre>1 then
app:=TreeView1.Items.GetLastSubNode;
MyQuery2:=TZQuery.Create(nil);
MyQuery2.Connection:=MyConn;
MyQuery2.SQL.Text:='select * FROM T_Menu WHERE NodoPadre=' + IntToStr(NodoPadre) + ' order by Posizione ASC;';
MyQuery2.Open;
if not MyQuery2.EOF then
begin
MyQuery2.First;
while not MyQuery2.EOF do
begin
if NodoPadre=0 then
begin
TreeView1.Items.Add(nil, MyQuery2.FieldByName('Descrizione').Text);
end
else if NodoPadre=1 then
begin
TreeView1.Items.AddChild(TreeView1.Items.GetLastNode, MyQuery2.FieldByName('Descrizione').Text);
end
else
begin
TreeView1.Items.AddChild(app , MyQuery2.FieldByName('Descrizione').Text);
end;
InserisciNodiFigli(MyQuery2.FieldByName('Posizione').AsInteger);
MyQuery2.Next;
end;
end;
MyQuery2.Close;
MyQuery2.Free;
InserisciNodiFigli:=true;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
MyConn.Disconnect;
end;
procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
MyQuery.SQL.Text:='select NumTab FROM T_Menu WHERE Descrizione="' + StringReplace(TreeView1.Selected.Text,'''','''''', [rfReplaceAll]) + '";';
MyQuery.Open;
if not MyQuery.EOF then
begin
MyQuery.First;
PageControl1.TabIndex:=MyQuery.FieldByName('NumTab').AsInteger;
end;
MyQuery.Close;
end;
end.
Come potete notare la funzione ricorsiva InserisciNodiFigli crea il menù popolato con i dati tabellati, e nell'esempio che abbiamo appena visto i dati sono così espressi
| Descrizione | NodoPadre | Posizione | NumTab |
| Clienti | 0 | 1 | 0 |
| Inserisci | 1 | 2 | 0 |
| Modifica | 1 | 3 | 0 |
| Ins1 | 3 | 4 | 1 |
| Ins2 | 3 | 5 | 1 |
| Elimina | 1 | 6 | 2 |
| Magazzino | 0 | 7 | 0 |
Quello che bisogna capire è che il NodoPadre deve essere zero per tutte le righe che devono comparire come voci primarie del menù, mentre il campo Posizione identifica l'ordine assoluto con il quale vengono inseriti nel menù, quindi non ci devono essere voci duplicate e i valori devono essere incrementali da 1 a N.
Per capire meglio vi consiglio di scaricare l'esempio e analizzarlo, è più facile da farlo che dirlo. Buona programmazione.
Program EsmpioMouse;
Uses Graph,Mouse;
Var X,Y:integer;
Begin
Gd:=detect;
InitGraph(Gd,Gm,'C//:FPC');
RestetMouse;
SetMouseWindow(0,0,1000,1000);
{Ecco un bottone}
Rectangle(0,0,100,100);
{Diamogli il valore di bottone per il mouse}
X:=GetmouseX;
Y:=GetmouseY;
If ((X>0) and (Y>0) and (X<100) and (Y<100) then
Write(Fine programma);
Readln;
Resetmouse;
End.
Capita spesso che si debba lavorare con le directory e i loro contenuti. Lazarus/Free Pascal permette queste operazioni in maniera facile ed intuitiva.
Segue un piccolo esempio di una Form con un Button (Nome=Button1) e una ListBox(Nome=ListBox1), quando si preme sul button1 il programma legge tutto il contenuto delle cartella in cui si trova l'eseguibile rinomina tutti i file (di 21 caratteri, estensioni comprese) in esso contenuti togliendo i primi 4 caratteri partendo da sinista.
Segue l'esempio, spero possa essere utile a qualcuno.
unit Unit1;
begin
Spazio:=size; //salvo la dimensione del file (non la uso ma è per far vedere che c'è la possibilità)