![]() |
|
Home | Linux | Réseaux | Developpement | Divers | FAQ | Forum | Guestbook | Musique | |
Kylix 2.0 Open Edition1 - IntroductionKylix est en fait le clône de Delphi pour Linux. Attendu depuis bien longtemps, Kylix risque d'être le fer de lance des migrations des applications développées sous Win32 avec son grand frère Delphi. Ce document décrit l'installation de la version 2.0 de Kylix sur une Mandrake 8.1 Download Edition. Ayant récupéré une version lors de Linux Expo 2002, je me suis jeté dessus lors de mon retour.
2 - InstallationSi comme moi vous possédez une Red Hat 7.0 vous devez installer les patches necessaires ; sans
quoi l'installation sera impossible. $ mount /mnt/cdrom $ cd /mnt/cdrom/patches/glibc_redhat/7.0/ $ rpm -Uvh glibc-[2c]* $ rpm -Fvh glibc-[dp]* nscd-* Après cela, revenez à la racine du cd et lancez : $ ./setup.sh Installez vers le répertoire /opt/kylix pour une installation globale L'installation finie, connectez vous sur le site http://www.borland.com et enregistrez-vous afin d'obtenir votre numéro de serie et vottre clé qui permettent d'activer Kylix. 3 - UtilisationLors de la première utilisation Kylix vous demande de saisir le numéro de serie et la clé correspondante. Il vous est égallement demandé d'enregistrer votre version - choisissez le mode online c'est le lus simple. 4 - Petits trucs de paramétragePensez à créer un répertoire par projet ; jusque là c'est classique. Mais le plus bizard, c'est que les application créées avec Kylix ne se lancent pas aussi facilement en console que depuis Kylix lui même. Pour y remédier créer un petit script de ce type : #!/bin/bash LD_LIBRARY_PATH=/opt/kylix2./bin:/opt/kylix2/lib:$LD_LIBRARY_PATH export LD_LIBRARY_PATH ./toto Merci à la mailing-list ProjetDelphi et en particulier à Spir. 5 - Trucs et astuces - Kylix et Delphi5.1 Ajouter une date d'expiration à une applicationSysUtils inclut une fonction appelée EncodeDate qui permet de comparer des dates. Dans cet exemple, la fonction Date est utilisée pour obtenir la date courante du système, laquelle est ensuite comparée à la date de référence stockée dans les variables TheYear, TheMonth, et TheDate. Si la date courante est supérieure à celle de référence, alors l'application se fermera. En pratique, on désactive divers boutons ou des contrôles pour limiter les fonctionnalités, plutôt que de fermer l'application ; vous devriez fournir une application limitée afin qu'un utilisateur potentiel s'enregistre ou achète le produit.
unit Unit1;
interface
uses
Windows, SysUtils, Classes, Forms, Dialogs;
type
TForm1 = class(TForm)
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormShow(Sender: TObject);
var
TheYear, TheMonth, TheDay : Integer;
begin
TheYear := 2001;
TheMonth := 12;
TheDay := 1;
if (Date >= EncodeDate(TheYear, TheMonth, TheDay)) then
begin
ShowMessage('This application demo has expired.');
Close;
end;
end;
end.
5.2 Compter les mots dans un MemoInsérer 1 label, 1 bouton et 1 memo.
procedure TForm1.Button1Click(Sender: TObject);
function Palabras(Link:string):integer;
var
n:integer;
befspace:boolean;
begin
befspace:=FALSE;
if Link='' then Result:=0 else Result:=1;
for n:=1 to Length(Link) do
begin
if befspace and
(Link[n]<>' ')and
(Link[n]<>#13)and
(Link[n]<>#10)
then Inc(Result);
befspace:=(Link[n]=' ') or (Link[n]=#13) or (Link[n]=#10);
end;
end;
begin
Label1.caption:=IntToStr(Palabras(Memo1.Text));
end;
end;
5.3 Comment fermer une fiche ?
procedure TForm1.Button1Click(Sender: TObject); begin Close; end;
5.4 Ouvrir une fiche à l'aide d'un boutonType standard - permet d'accéder aux disponibilités de la fiche située en dessous de la fiche appellée procedure TForm1.Button1Click(Sender: TObject); begin Form2.Show; end;Type modal - interdit d'accéder aux disponibilités de la fiche située en dessous de la fiche appellée procedure TForm1.Button1Click(Sender: TObject); begin Form2.ShowModal; end;
5.5 Charger une image depuis sa source pour alléger l'exécutable
procedure TForm1.FormCreate(Sender: TObject);
begin
Image1.Picture.LoadFromFile('mon-image.jpg');
end;
Note : enregistrer le projet avant de l'exécuter afin que Delphi trouve le fichier, sinon ça plantera.
5.6 Comment afficher un dialogue d'information
procedure TForm1.Button1Click(Sender: TObject);
begin
MessageDlg('Bla bla bla', mtInformation, [mbOK], 0);
end;
5.7 Afficher un dialogue de danger
procedure TForm1.Button1Click(Sender: TObject);
begin
MessageDlg(' Bla bla bla ', mtWarning, [mbOK], 0);
end;
5.8 Afficher un dialogue d'erreur
procedure TForm1.Button1Click(Sender: TObject);
begin
MessageDlg(' Bla bla bla ', mtError, [mbOK], 0);
end;
5.9 Afficher un dialogue de confirmation
procedure TForm1.Button1Click(Sender: TObject);
begin
MessageDlg('Bla bla bla', mtConfirmation, [mbOK], 0);
end;
5.10 Afficher un dialogue custom
procedure TForm1.Button1Click(Sender: TObject);
begin
MessageDlg('Bla bla bla', mtCustom, [mbOK], 0);
end;
5.11 Utiliser une fonctionnalité avec un mot de passePlacer un composant Edit et affecter lui la valeur * dans PasswordChar
procedure TForm1.Button1Click(Sender: TObject);
begin
if Edit1.Text='mon mot de passe'
then Form2.Show
else
MessageDlg('Mot de passe incorect', mtError, [mbOK], 0);
end;
5.12 Arrêter Windows
procedure TForm1.Button1Click(Sender: TObject); begin ExitWindowsEx(EWX_SHUTDOWN, 0) ; end;
5.13 Redémarer Windows
procedure TForm1.Button1Click(Sender: TObject); begin ExitWindowsEx(EWX_REBOOT, 0) ; end;
5.14 Copier le contenu d'un Memo vers le presse papier
procedure TForm1.Button1Click(Sender: TObject); begin Memo1.CopyToClipboard ; end;
5.15 Couper le contenu d'un Memo vers le presse papier
procedure TForm1.Button1Click(Sender: TObject); begin Memo1.CutToClipboard ; end;
5.16 Coller le contenu d'un Memo vers le presse papier
procedure TForm1.Button1Click(Sender: TObject); begin Memo1.PasteFromClipboard; end;
5.17 Sélectionner tout le contenu d'un Memo
procedure TForm1.Button1Click(Sender: TObject); begin Memo1.SelectAll; end;
5.18 Effacer le contenu d'un Memo
procedure TForm1.Button1Click(Sender: TObject); begin Memo1.ClearSelection; end;
5.19 Annuler la suppression du contenu du Memo
procedure TForm1.Button1Click(Sender: TObject);
begin
with Memo do
if HandleAllocated then SendMessage(Handle, EM_UNDO, 0, 0);
end;
5.20 Ouvrir le lecteur de cdrom
uses mmsystem;
procedure TForm1.Button1Click(Sender: TObject);
begin
mciSendString('Set cdaudio door open wait', nil, 0, 0);
end;
5.21 Fermer le lecteur de cdrom
uses mmsystem;
procedure TForm1.Button1Click(Sender: TObject);
begin
mciSendString('Set cdaudio door closed wait', nil, 0, 0);
end;
5.22 Ouvrir une url - site internet ou adresse email
uses shellapi; procedure TForm1.Image1Click(Sender: TObject); begin shellexecute(0,'open',PCHar(image1.hint),'','', SW_SHOW ); end;
5.23 Connaître la vitesse de son processeur
Function vitesse_cpu: Extended;
var
t: DWORD;
mhi, mlo, nhi, nlo: DWORD;
t0, t1, chi, clo, shr32: Comp;
begin
shr32 := 65536;
shr32 := shr32 * 65536;
t := GetTickCount;
while t = GetTickCount do begin end;
asm
DB 0FH
DB 031H
mov mhi,edx
mov mlo,eax
end;
while GetTickCount < (t + 1000) do begin end;
asm
DB 0FH
DB 031H
mov nhi,edx
mov nlo,eax
end;
chi := mhi ; if mhi < 0 then chi := chi + shr32 ;
clo := mlo ; if mlo < 0 then clo := clo + shr32 ;
t0 := chi * shr32 + clo ;
chi := nhi ; if nhi < 0 then chi := chi + shr32 ;
clo := nlo ; if nlo < 0 then clo := clo + shr32 ;
t1 := chi * shr32 + clo ;
Result := (t1 - t0) / 1E6 ;
end;
Puis créer une procédure sur un bouton comme ceci :
procedure TForm1.Button1Click(Sender: TObject); begin Showmessage( FloatToStr(Round(vitesse_cpu)) + ' MHz'); end; sectionObtenir son adresse IP
function LocalIP : string;
type
TaPInAddr = array [0..10] of PInAddr;
PaPInAddr = ^TaPInAddr;
var
phe : PHostEnt;
pptr : PaPInAddr;
Buffer : array [0..63] of char;
I : Integer;
GInitData : TWSADATA;
begin
WSAStartup($101, GInitData);
Result := '';
GetHostName(Buffer, SizeOf(Buffer));
phe :=GetHostByName(buffer);
if phe = nil then
begin
Exit;
end;
pptr := PaPInAddr(Phe^.h_addr_list);
I := 0;
while pptr^[I] <> nil do
begin
result:=StrPas(inet_ntoa(pptr^[I]^));
Inc(I);
end;
WSACleanup;
end;
5.24 Masquer une application dans la barre des tâches
procedure TForm1.FormShow(Sender: TObject); var Owner : HWnd; begin Owner:=GetWindow(Handle,GW_OWNER); ShowWindow(Owner,SW_HIDE); end;
5.25 Réduire un float
procedure TForm1.Button1Click(Sender: TObject);
var
a,b:real;
S1: String;
begin
a:=strtofloat(edit1.text);
b:=a*6.55957;
if RadioButton1.Checked = true
then S1 := FormatFloat('0.0', b)
else
if RadioButton2.Checked = true
then S1 := FormatFloat('0.00', b)
else
if RadioButton3.Checked = true
then S1 := FormatFloat('0.000', b)
else
if RadioButton4.Checked = true
then S1 := FormatFloat('0.0000', b)
else
S1 := FormatFloat('0.00000', b);
Edit2.Text:=S1;
end;
5.26 Clés de Registre pour un projet InstallShield Express avec liens ODBC
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI\PodLibData] "Driver"="C:\\WINNT\\System32\\odbcjt32.dll" "DBQ"="E:\\dev\\delphi\\PodLibEdit-beta D4\\data\\Pod-Library.mdb" "DriverId"=dword:00000019 "FIL"="MS Access;" "SafeTransactions"=dword:00000000 "UID"="" [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI\PodLibData\Engines] [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI\PodLibData\Engines\Jet] "ImplicitCommitSync"="" "MaxBufferSize"=dword:00000800 "PageTimeout"=dword:00000005 "Threads"=dword:00000003 "UserCommitSync"="Yes"
5.27 Envoyer un mail
procedure TForm1.Button1Click(Sender: TObject);
begin
NMSMTP1.Host := 'mail.host.com';
NMSMTP1.UserID := 'username';
NMSMTP1.Connect;
NMSMTP1.PostMessage.FromAddress := 'webmaster@swissdelphicenter.ch';
NMSMTP1.PostMessage.ToAddress.Text := 'user@host.com';
NMSMTP1.PostMessage.Body.Text := 'This is the message';
NMSMTP1.PostMessage.Subject := 'Mail subject';
NMSMTP1.SendMail;
showmessage('Mail sent !');
end;
5.28 Dessiner des courbes mathématiques
procedure TForm1.pbPaint(Sender: TObject);
const
pi = 3.1416;
rx = 150;
ry = 80;
var
TheRect: TRect;
x,y,t: Integer;
OrgX,OrgY: Integer;
begin
TheRect := Rect(0,0,pb.Width,pb.Height);
pb.Canvas.FillRect(TheRect);
t := 0;
OrgX := pb.Width div 2;
OrgY := pb.Height div 2;
x := OrgX + Trunc(rx * cos(2 * t * (pi/180)));
y := OrgY + Trunc(ry * sin(6 * t * (pi/180)));
pb.Canvas.MoveTo(x,y);
for t := 1 to 360 do
begin
x := OrgX + Trunc(rx * cos(2 * t * (pi/180)));
y := OrgY + Trunc(ry * sin(6 * t * (pi/180)));
pb.Canvas.LineTo(x,y);
end;
end;
5.29 Création d'une barre d'état
private
{ Déclarations privées }
procedure DoHint(Sender: TObject);
procedure TForm1.DoHint(Sender: TObject);
begin
StatusBar1.SimpleText := Application.Hint;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnHint := DoHint;
end;
5.30 Obtenir la version de Windows
function GetWindowsVersion:string;
var
OsVinfo : TOSVERSIONINFO;
temp : array[0..50] of Char;
begin
ZeroMemory(@OsVinfo,sizeOf(OsVinfo));
OsVinfo.dwOSVersionInfoSize := sizeof(TOSVERSIONINFO);
if GetVersionEx(OsVinfo) then
begin
if OsVinfo.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS then
begin
if (OsVinfo.dwMajorVersion = 4) and (OsVinfo.dwMinorVersion > 0) then
StrFmt(temp,'Windows 98 - Version %d.%.2d.%d', [OsVinfo.dwMajorVersion,
OsVinfo.dwMinorVersion, OsVinfo.dwBuildNumber AND $FFFF])
else
StrFmt(temp,'Windows 95 - Version %d.%d Build %d', [OsVinfo.dwMajorVersion,
OsVinfo.dwMinorVersion, OsVinfo.dwBuildNumber AND $FFFF]);
end;
if OsVinfo.dwPlatformId = VER_PLATFORM_WIN32_NT then
begin
if OsVinfo.dwMajorVersion = 5 then
StrFmt(temp,'Microsoft Windows 2000 Version %d.%.2d.%d', [OsVinfo.dwMajorVersion,
OsVinfo.dwMinorVersion, OsVinfo.dwBuildNumber AND $FFFF])
else
StrFmt(temp,'Microsoft Windows NT Version %d.%.2d.%d', [OsVinfo.dwMajorVersion,
OsVinfo.dwMinorVersion, OsVinfo.dwBuildNumber AND $FFFF]);
end;
end;
else
StrCopy(temp,'GetversionEx() failed!');
Result:=string(temp);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
label1.caption:=GetWindowsVersion;
end;
5.31 Utilisation de fichiers .INI
uses Inifiles;
public
{ Déclarations publiques }
FichierIni: TIniFile;
S1: String;
I1: Integer;
B1: Boolean;
procedure TForm1.btnWStrClick(Sender: TObject);
begin
S1:=EditStr.Text;
FichierIni:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'test.ini');
FichierIni.WriteString('Test','String',S1);
end;
procedure TForm1.btnRStrClick(Sender: TObject);
begin
FichierIni:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'test.ini');
S1:=FichierIni.ReadString('Test','String',S1);
EditStr.Text:=S1;
end;
procedure TForm1.btnWIntClick(Sender: TObject);
begin
I1:=StrToInt(EditInt.Text);
FichierIni:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'test.ini');
FichierIni.WriteInteger('Test','Integer',I1);
end;
procedure TForm1.btnRIntClick(Sender: TObject);
begin
FichierIni:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'test.ini');
I1:=FichierIni.ReadInteger('Test','Integer',I1);
EditInt.Text:=IntToStr(I1);
end;
procedure TForm1.btnWBoolClick(Sender: TObject);
begin
B1:=CB1.Checked;
FichierIni:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'test.ini');
FichierIni.WriteBool('Test','Boolean',B1);
end;
procedure TForm1.btnRBoolClick(Sender: TObject);
begin
FichierIni:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'test.ini');
FichierIni.ReadBool('Test','Boolean',B1);
CB1.Checked:=B1;
end;
5.32 Comment masquer une fiche au démarrage
program Project1;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.RES}
begin
Application.Initialize;
Application.ShowMainForm := False;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
5.33 Désactiver l'utilisation de la souris et du clavier pendant n secondes
function FunctionDetect (LibName, FuncName: String; var LibPointer: Pointer): boolean;
var LibHandle: tHandle;
begin
Result := false;
LibPointer := NIL;
if LoadLibrary(PChar(LibName)) = 0 then exit;
LibHandle := GetModuleHandle(PChar(LibName));
if LibHandle <> 0 then
begin
LibPointer := GetProcAddress(LibHandle, PChar(FuncName));
if LibPointer <> NIL then Result := true;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var xBlockInput : function (Block: BOOL): BOOL; stdcall;
begin
if FunctionDetect ('USER32.DLL', 'BlockInput', @xBlockInput) then
begin
xBlockInput (True); // Disable Keyboard & mouse
Sleep(10000); // Wait for for 10 Secounds
xBlockInput (False); // Enable Keyboard & mouse
end;
end;
5.34 Créer un contrôle flottantUn contrôle flottant est un élément de type fenêtre (un panel par exemple) que l'on peut déplacer lors de son exécution. Par exemple, créer un panel sur la fiche, à l'événement OnMouseDown, écrire cette séquence : ReleaseCapture; TWinControl(Sender).perform(WM_SYSCOMMAND, $F012, 0);Puis, on peut déplacer le composant où l'on veut.
5.35 Obtenir le volume audio et le paramétrer
unit uMain;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, Forms, Dialogs,
ExtCtrls,StdCtrls, mmsystem; //You must add this in the uses line
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
myvolume: array[0..10] of longint;
{ Public declarations }
end;
var
Form1: TForm1;
implementation
%{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
var
Count, i: integer;
begin
Count := auxGetNumDevs;
for i := 0 to Count do
begin//The i is the device: I.E. 0=Wav Volume
auxgetvolume(i,addr(myvolume[i])); //Gets the values that the user has set
auxsetvolume(i,longint(9000)*65536+longint(9000)); //Sets the volume very very low
end; //The reason for the 9000*65536 + 9000 is if you wanted to do left and right channels
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
Count, i: integer;
begin
Count := auxGetNumDevs;
for i := 0 to Count do
begin
auxsetvolume(i,myvolume[i]); //Sets the volume back to the users old settings
end;
end;
end.
5.36 Afficher à coté de l'heure une icone (tray icon)
unit unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Menus, ExtCtrls, StdCtrls, ExtDlgs;
const
WM_TASKABAREVENT = WM_USER + 1;
type
TForm1 = class(TForm)
PopupMenu1: TPopupMenu;
pop1: TMenuItem;
Rduire1: TMenuItem;
Agrandir1: TMenuItem;
N1: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure TaskbarEvent(var Msg: TMessage);
message WM_TASKABAREVENT;
procedure Rduire1Click(Sender: TObject);
procedure pop1Click(Sender: TObject);
procedure Agrandir1Click(Sender: TObject);
private
{ Déclarations privées}
public
{ Déclarations publiques}
end;
var
Form1: TForm1;
implementation
uses shellapi;
%{$R *.DFM}
procedure tform1.TaskbarEvent(var Msg: TMessage);
var
p: tpoint;
begin
if msg.LParam = WM_RButtonDown then
begin
SetForegroundWindow(Handle);
GetCursorPos(p);
PopupMenu1.Popup(p.x, p.y);
PostMessage(Handle, WM_NULL, 0, 0);
end;
{Valeur de msg.LParam: WM_MouseMove,WM_LButtonDown,WM_LbuttonUp
WM_LButtonDblClk,WM_RButtonDown,WM_RButtonUp,WM_RButtonDblClk }
end;
procedure TForm1.FormCreate(Sender: TObject);
var
NotifyIconData: TNotifyIconData;
begin
Fillchar(NotifyIconData, Sizeof(NotifyIconData), 0);
NotifyIconData.cbSize := Sizeof(NotifyIconData);
NotifyIconData.Wnd := Handle;
NotifyIconData.uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
NotifyIconData.uCallbackMessage := WM_TASKABAREVENT;
NotifyIconData.hIcon := application.icon.Handle;
NotifyIconData.szTip := 'Nom de l''application';
Shell_NotifyIcon(NIM_ADD, @NotifyIconData);
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
NotifyIconData: TNotifyIconData;
begin
FillChar(NotifyIconData, Sizeof(NotifyIconData), 0);
NotifyIconData.cbSize := Sizeof(NotifyIconData);
NotifyIconData.Wnd := Self.Handle;
NotifyIconData.uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
NotifyIconData.uCallbackMessage := WM_TASKABAREVENT;
NotifyIconData.hIcon := Application.Icon.Handle;
NotifyIconData.szTip := 'Nom de l''application';
Shell_NotifyIcon(NIM_DELETE, @NotifyIconData);
end;
procedure TForm1.Rduire1Click(Sender: TObject);
begin
Application.Minimize;
end;
procedure TForm1.pop1Click(Sender: TObject);
begin
close;
end;
procedure TForm1.Agrandir1Click(Sender: TObject);
begin
Application.Restore;
end;
end.
5.37 Centrer une image automatiquement lors de l'agrandissement de la fiche
procedure TForm1.FormResize(Sender: TObject); begin image.top := (fenetre.height - image.height) div 2; image.left := (fenetre.width - image.width) div 2; end;
5.38 Convertir une valeur décimale en binaire
Function DecToBin(dec:longint):string;
var bin:string;
begin
bin:='';
repeat
if (dec mod 2)=0 then begin
bin :='0'+bin;
dec:=dec div 2;
end
else
begin
bin :='1'+bin;
dec:=dec div 2;
end;
until dec=0;
DecToBin:=bin;
end;
5.39 Convertir une valeur décimale en octal
function IntToOct(value:longint; digits:integer):string; var rest : longint; oct : string; i : integer; begin oct := ''; while value > 0 do begin rest := value mod 8; value := value div 8; oct := inttostr(rest)+oct; end; for i := length(oct)+1 to digits do oct := '0'+oct; result := oct; end;
5.40 Convertir une valeur décimale en hexadécimaleUtiliser la fonction IntToHex de Delphi : function IntToHex(Value: Integer; Digits: Integer): string;
5.41 Plusieurs icônes pour un programmeCréer un fichier de ressources (.res) à l'aide de l'éditeur d'images de Delphi et y inclure autant icônes que souhaité. Ajouter cette ligne de code dans le source d'une fiche :
{$R MYICONS.RES}
5.42 Constante de versioning de langueL'identificateur (ID) de langage indique la page de codes qu'utilisera le système des utilisateurs pour exécuter l'application - Options de projet.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|