Delphi, niveau 2 , page 2

Contenu : Leçon 16 : Charger une image bitmap, ou Jpeg, retrouver l'adresse courante ; leçon 17 : Objets créés par tableau ; leçon 18 : Animations en Delphi ; leçon 19 : Fichier son .wav, presse-papiers, fichiers, ouverture, conversion, sauvegarde, Mathematica, Maple, Excel.

Delphi, leçon 16

1 Charger une image bitmap, ou Jpeg


Supposons votre Unit1, associée à votre Form1. Vous voulez charger une image de fond sur cette Form.
Placez sur cette Form1, un composant Image1 ;
Dans les clauses Uses de Unit1, ajoutez  Jpeg ;
A l'endroit adéquat, ajoutez le code suivant :
adresseCompleteJPG := Unit1.dossierImFond + '\' + Unit1.nomImage + '.jpg' ;
adresseCompleteBMP := Unit1.dossierImFond + '\' + Unit1.nomImage + '.bmp' ;
If FileExists(adresseCompleteJPG) Then
Form1.Image1.Picture.LoadFromFile(adresseCompleteJPG) Else
If FileExists(adresseCompleteBMP) Then
Form1.Image1.Picture.LoadFromFile(adresseCompleteBMP);

Il vous faudra auparavant avoir retrouvé l'adresse exacte du dossier contenant les images de fond.
N'entrez pas ce code sans réfléchir : dossierImFond et nomImage sont de type String et doivent être déclarés et affectés auparavant.

2 Retrouver l'adresse courante

Le bel exécutable que vous venez de peaufiner utilise des fichiers rangés, par exemple, dans le même dossier que lui. Mais une fois installé sur une autre machine, comment parviendra-t-il à retrouver ces fichiers ?
Prévoyez, tout au début de l'entrée en action de votre programme, de lire et stocker l'adresse du dossier où il se trouve. Il vous faut deux variables, et le code suivant :

Var
adresseAPIprimitive : Array[0..MAX_PATH-1] of Char ;
adressePrimitiveString : String ;
Initialization
Begin
{on cherche l'adresse du dossier contenant l’exécutable}
GetCurrentDirectory(SizeOf(adresseAPIprimitive), adresseAPIprimitive);
adressePrimitiveString := StrPas(adresseAPIprimitive) ; // l'adresse est maintenant du type String.
End;

puce Le composant PhyJiC, comporte une fonction permettant d'obtenir facilement cette adresse.
 

Retour en haut de cette page 

Delphi, leçon 17

Contenu : Objets créés par tableau

Objet, par des tableaux

Voici une autre façon de créer des objets, 'en marche'. Elle est surtout intéressante, pour un nombre assez important d'objets quasi identiques.
Nous avons choisi pour notre exemple, de créer des Edit ; nous aurions pu choisir d'autres composants. Nous aurions même pu créer de multiples exemplaires d'un composant Delphi, lui-même modifié (surchargé).
Vous ne pouvez pas créer d'événement véritablement nouveau ; mais vous pouvez dérouter un événement associé par Delphi à l'objet, sur une procédure à votre convenance.
Pour vous guider, employez l'aide en ligne, l'inspecteur d'objets, et les événements associés aux objets, que Delphi crée automatiquement.

unit Unit1;
{placer sur Form1, 1 Edit comme modèle, 1 Button et 1 Panel qui sera propriétaire des Edit créés 'en marche'. Ces Edit sont ici des éléments d'un tableau}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Panel1: TPanel;
Button1: TButton;
procedure FormCreate(Sender: TObject);
{pour servir de modèle}
procedure Edit1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
{déclaration obligatoire ici}
Procedure Cliquer(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Button1Click(Sender: TObject);
private
{Déclarations privées}
public
{Déclarations publiques}
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
Var
tableauEdit : Array[1..7] Of TEdit ; // tableau des Edit
{respecter la forme de la déclaration}
Procedure TForm1.Cliquer(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
Begin
With (Sender As TEdit) Do // réagit au clic sur un Edit créé en marche
Color := clBlue ;//couleur de l'Edit sur lequel on clique
End;
procedure TForm1.FormCreate(Sender: TObject);
Var i : Integer ;
begin
For i:=1 To 7 Do Begin
tableauEdit[i] := TEdit.Create(Panel1) ; //ou Self qui renvoie à Form1
With tableauEdit[i] Do Begin
Height := 21 ;
Left := 10 ;
Top := 10 + (i - 1) * (Height + 3) ;
{nous choisissons cet évènement qui demande et fournit
de nombreux paramètres}
OnMouseUp := Cliquer ; {cette façon de faire ne permet pas de créer un évènement réellement nouveau}
Parent := Panel1 ; //indispensable pour affichage effectif
End ; End ; end;
{procédure servant uniquement à obtenir la liste des paramètres}
procedure TForm1.Edit1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
//
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
{voici comment on appelle un Edit créé 'en marche'}
tableauEdit[1].Color := clRed ;
end;
end.

Retour en haut de cette page 

Delphi, leçon 18

Contenu : Animations en Delphi

Animations en delphi

Delphi calcule très vite, malheureusement les animations manquent de rapidité. Voici un début de solution :
Vous pourrez aussi consulter l'aide en ligne, aux mots : TBitmap, bitmap hors écran

Voici du code qui affiche des cercles dont le diamètre croît ; ce code n'est qu'un début.
Vous devrez associer les procédures procedure DetruireForm(Sender: TObject) et procedure CreerForm(Sender: TObject) aux événements associés à la Form de votre projet.

unit UnitHorsEcran;
interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;

type
TAnimationForm = class(TForm)
Button1: TButton;
Timer1: TTimer;
Edit1: TEdit;
procedure DetruireForm(Sender: TObject);
procedure PeindreForm(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure CreerForm(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
Dessin: TBitmap;
procedure Dessiner;
procedure EffacerFond(var m: TWMEraseBkgnd); message WM_ERASEBKGND;
public
{ Public declarations }
end;

var
AnimationForm: TAnimationForm;

implementation

{$R *.DFM}
Const
animation : boolean = false ;

procedure TAnimationForm.CreerForm(Sender: TObject);
begin
Dessin := TBitmap.Create;
Dessin.Height := 200 ;
Dessin.Width := 300 ;
end;

procedure TAnimationForm.DetruireForm(Sender: TObject);
begin
Dessin.Free;
end;

{ comme toute la Form va être dessinée, la gestion de ce message
évite les réaffichages inutiles de l'arrière-plan
qui peuvent provoquer des sautillements.}
procedure TAnimationForm.EffacerFond(var m : TWMEraseBkgnd);
begin
m.Result := LRESULT(False);
end;

procedure TAnimationForm.PeindreForm(Sender: TObject);
begin
Canvas.Draw(50, 50, Dessin);
end;

procedure TAnimationForm.Button1Click(Sender: TObject);
begin
animation := Not(animation) ;
end;

procedure TAnimationForm.Dessiner;
const
i : Integer = 0 ;
begin
i := i+5 ;
If i >100 then i :=0 ;
Dessin.Canvas.Ellipse(100-i,100-i,100+i,100+i) ;
Dessin.Canvas.Ellipse(100-2*i,100-2*i,100,100) ;
end;

procedure TAnimationForm.Timer1Timer(Sender: TObject);
Const
i : Integer = 0 ;

begin
If animation = False Then Exit ;
Dessiner;
//compteur d'images affichées
i := i +1 ;
Edit1.Text := IntToStr(i) ;
Invalidate;
end;

end.

Et bon courage ! Vous pouvez aussi rechercher des informations au mot clé Thread. L'ouvrage de Dick lantim, Delphi 3, édité chez Eyrolles traite du sujet et propose un exemple de code sur le Cd Rom joint.

Retour en haut de cette page 

Delphi, leçon 19

Contenu : Fichier son .wav, presse-papiers, fichiers, ouverture, conversion, sauvegarde, Mathematica, Maple, Excel.

Lecture d'un fichier son, .wav, traitement et conversion pour Excel, Mathematica, ou Maple

Vous devrez trouver dans ce code source, les informations nécessaires. Il utilise des objets Delphi que vous devrez placer sur votre Form.

unit TransDonn;
{convertit les valeurs d'un fichier .wav en listes de nombres pour
Mathematica, Maple, ou un tableur}

interface
uses
Windows, Messages, SysUtils, Dialogs ;

procedure Convertir ;  {pour transfert données}

implementation

Uses Unit1, Parametres, Options ; //autres unités, non disponibles ici

procedure Convertir ;  {pour transfert données}
Var
donnees, listeDeNombres : String ;
nomFichier : String ;
nomFichWin : File Of Byte ;
nomSortie : TextFile ;
lu, lu02, mono : Byte ;
luReel, freqEchantTrans : Real ;
lettre : Char ;
i, coefficient, inter : Integer ;
longueurTotale, longueurChunck, longueur : Integer ;
nombreBits : Integer ;
longueurMathematica : Integer ;
separateur : String ;
numeroOctetLu, longueurChunckFormat, nombreDonnees : Integer ;

Label
FIN ;

begin

nomFichier := adresseSon ; //observez la gymnastique pour ouvrir un fichier
If FileExists(nomFichier) Then BEGIN
AssignFile(nomFichWin, nomFichier) ;
Reset(nomFichWin) ;

Retour en haut de cette page 

{lecture premier chunck}
For i:=1 To 4 Do Begin
Read(nomFichWin, lu) ;
lettre := Chr(lu) ;
donnees := donnees + lettre ;
End ;

{-> RIFF si fichier .Wav}
If donnees='RIFF' Then BEGin
coefficient := 1 ; longueurTotale:=0 ;
For i:=1 To 4 Do Begin
Read(nomFichWin, lu) ;
inter := lu ;
inter :=inter * coefficient ;
longueurTotale := longueurTotale+inter ;
coefficient := coefficient*256 ;
End ;
{longueurTotale + 8 est la longueur totale du fichier}
{longueurTotale est la longueur qui reste maintenant}
{OptTransfert.Edit2.Text:=IntToStr(longueurTotale+8);}

donnees:='' ;
For i:=1 To 4 Do Begin
Read(nomFichWin, lu) ;
lettre := Chr(lu) ;
donnees := donnees + lettre ;
End ;
{-> WAVE}
If donnees='WAVE' Then BEgin
{fin de la lecture du premier chunck }

{lecture 2° chunck (Format) qui suit immédiatement le premier}
donnees:='' ;
For i:=1 To 4 Do Begin
Read(nomFichWin, lu) ;
lettre := Chr(lu) ;
donnees := donnees + lettre ;
End ;
{-> fmt , chunck de format du fichier ; fmt est suivi d'un espace ! }
If donnees='fmt ' Then Begin {ne pas oublier l'espace ! }

{donne la longueur de ce chunck, variable, contenant le descripteur de
format du son, nombre de canaux, fréquence d'échantillonnage...}
coefficient := 1 ; longueurChunck:=0 ;
For i:=1 To 4 Do Begin
Read(nomFichWin, lu) ;
inter := lu ;
inter :=inter * coefficient ;
longueurChunck := longueurChunck+inter ;
coefficient := coefficient*256 ;
End ;
longueurChunckFormat := longueurChunck ;
{lecture de datas du chunck fmt (format) }

Retour en haut de cette page 
 

{type de format, et nombre de canaux sur 2 x 2 octets}
Read(nomFichWin, lu) ;
Read(nomFichWin, lu) ; {on laisse tomber WFormatTag}
Read(nomFichWin, mono) ; {on lit le premier octet de nChannels}

Read(nomFichWin, lu) ;{2° octet}

{lecture de la fréquence d'échantillonnage, nSamplesPerSec}
coefficient := 1 ; longueur:=0 ;
For i:=1 To 4 Do Begin
Read(nomFichWin, lu) ;
inter := lu ;
inter :=inter * coefficient ;
longueur := longueur+inter ;
coefficient := coefficient*256 ;
End ;

freqEchantTrans := longueur ;

For i:=1 To 4 Do Read(nomFichWin, lu) ;{on saute nAvgBytesPerSec}

Read(nomFichWin, lu) ; {premier octet de nBlockAlign}
nombreBits:=Trunc(lu*8/mono) ;

{On saute la suite des données de ce 2° chunck}
For i:=1 To longueurChunck-13 Do Begin Read(nomFichWin, lu) ;
 {on a déjà lu 13 octets du 2° chunk}
End ;

{lecture du 3° chunck, de données, data}
donnees:='' ;
For i:=1 To 4 Do Begin
Read(nomFichWin, lu) ;
lettre := Chr(lu) ;
donnees := donnees + lettre ;
End ;
{affiche 'data' si tout va bien}

Retour en haut de cette page 
 

{lecture longueur des données}
coefficient := 1 ; longueurChunck:=0 ;
For i:=1 To 4 Do Begin
Read(nomFichWin, lu) ;
inter := lu ;
inter :=inter * coefficient ;
longueurChunck := longueurChunck+inter ;
coefficient := coefficient*256 ;
End ;
nombreDonnees := longueurChunck ;

If nombreBits=8 Then Begin CloseFile(nomFichWin) ;
//OptTransfert.StatusBar1.SimpleText:='Conversion pour Mathematica inutile' ;
 Goto FIN ; End ;

{on lit les données, et on les transforme en String de réels,
séparés par un espace, par la formule : 32768 - (octet1 + 256*octet2),
ou octet est lu en tant que byte}

listeDeNombres :='' ;

longueurMathematica:= Trunc(((nombreDonnees/2)/
Parametres.pasDeLaLecture)-1);
{longueur maximale des données utiles}

If (longueurMathematica > Parametres.nPointsFFT) Then
longueurMathematica := Parametres.nPointsFFT
Else
ShowMessage('Fichier son trop court ; les derniers points seront mis à zéro') ;

If Foptions.RadioGroup1.ItemIndex=0 Then separateur := #32 ;
{espace pour Mathematica}
If Foptions.RadioGroup1.ItemIndex=2 Then separateur := #10 ;
{10 : retour chariot pour Maple}
If Foptions.RadioGroup1.ItemIndex=1 Then separateur := #13 ;
{13 : passage à la ligne pour les tableurs}

numeroOctetLu := longueurChunckFormat + 20 + 8 ;
For i:=1 To longueurMathematica  Do Begin
If (numeroOctetLu > nombreDonnees -1) Then Break ;
Seek(nomFichWin,numeroOctetLu ) ; //on saute directement à un endroit d'un fichier
Read(nomFichWin, lu) ;
Seek(nomFichWin,numeroOctetLu + 1) ;
Read(nomFichWin, lu02) ;
numeroOctetLu := numeroOctetLu + 2 * pasDeLaLecture ;{si on ne veut lire qu'un octet de temps en temps, ce qui revient à diminuer la fréquence d'échantillonnage}
luReel := lu02*256 + lu ;
If luReel>32767 Then luReel:=luReel-65536 ;
{pour tableur}
If (Foptions.RadioGroup1.ItemIndex=1) Then
listeDeNombres := listeDeNombres +
FloatToStr((pasDeLaLecture*(i-1))/freqEchantTrans)+ #9 ; {tabulation}
//If ((Foptions.RadioGroup1.ItemIndex=0)Or
//(Foptions.RadioGroup1.ItemIndex=2))Then
{pour Mathematica et Maple, liste simple}
listeDeNombres := listeDeNombres + FloatToStr(luReel) + separateur ;
End ;

{fin des tests de validité du fichier lu}

Retour en haut de cette page 
 

End Else ShowMessage('Ceci n''est pas un fichier .Wav correct !') ;
ENd Else ShowMessage('Ceci n''est pas un fichier .Wav correct !') ;
ENd ELse ShowMessage('Ceci n''est pas un fichier .Wav correct !') ;
CloseFile(nomFichWin) ;
END Else ShowMessage('Nom de fichier incorrect !') ;

{on sauvegarde le fichier de nombres}
 

numeroSauvegarde := numeroSauvegarde + 1 ;
nomFichier := adresseSauvegarde + IntToStr(numeroSauvegarde) ;
AssignFile(nomSortie, nomFichier) ;
Rewrite(nomSortie) ;
WriteLn(nomSortie, listeDeNombres) ;
CloseFile(nomSortie) ;
FIN :

{on colle dans le presse-papier le tableau listeDesNombres ;
il faut passer par un Memo (par exemple) }
Foptions.Memo1.Clear ;
Foptions.Memo1.Text := listeDeNombres ;
Foptions.Memo1.SelectAll ;
Foptions.Memo1.CopyToClipboard ;

end ;

end.
 

Retour en haut de cette page