<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>https://docwiki.embarcadero.com/RADStudio/Rio/f/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Alejandra.Barrientos</id>
	<title>RAD Studio - Contributions [fr]</title>
	<link rel="self" type="application/atom+xml" href="https://docwiki.embarcadero.com/RADStudio/Rio/f/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Alejandra.Barrientos"/>
	<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/fr/Sp%C3%A9cial:Contributions/Alejandra.Barrientos"/>
	<updated>2026-08-16T13:48:51Z</updated>
	<subtitle>Contributions</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/f/index.php?title=Codage_des_r%C3%A9ponses_aux_actions_des_utilisateurs_dans_l%27%C3%A9diteur_de_code_(tutoriel_de_l%27EDI)&amp;diff=213848</id>
		<title>Codage des réponses aux actions des utilisateurs dans l&#039;éditeur de code (tutoriel de l&#039;EDI)</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/f/index.php?title=Codage_des_r%C3%A9ponses_aux_actions_des_utilisateurs_dans_l%27%C3%A9diteur_de_code_(tutoriel_de_l%27EDI)&amp;diff=213848"/>
		<updated>2021-10-08T21:17:57Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos : RS-108915 Updated Screenshots&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Parent|Démarrage de votre première application {{Variables|Product}} - Index (tutoriel de l&#039;EDI)}}&lt;br /&gt;
&lt;br /&gt;
En suivant les instructions de cette section, vous rendrez votre application interactive et lui fournirez les fonctionnalités de votre choix. Vous coderez les gestionnaires d&#039;événement, c&#039;est-à-dire les réponses aux clics sur les divers éléments du menu principal et à d&#039;autres types d&#039;interaction de l&#039;utilisateur.&lt;br /&gt;
&lt;br /&gt;
==Commencement du code==&lt;br /&gt;
&lt;br /&gt;
Commencez l&#039;écriture du code en définissant une variable &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; que vous utiliserez pendant l&#039;exécution de l&#039;application pour stocker le nom du fichier texte ouvert. &lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dans {{Delphi}}, sélectionnez l&#039;onglet &#039;&#039;&#039;Code&#039;&#039;&#039; dans la barre d&#039;état pour ouvrir &#039;&#039;&#039;[[Editeur de code|l&#039;éditeur de code]]&#039;&#039;&#039;. Utilisez &#039;&#039;&#039;l&#039;éditeur de code&#039;&#039;&#039; pour définir une variable &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; appelée &amp;lt;code&amp;gt;CurrentFile&amp;lt;/code&amp;gt; dans la section private de la classe &#039;&#039;&#039;TTextEditorForm&#039;&#039;&#039; dans la partie &amp;lt;source lang=&amp;quot;delphi&amp;quot; enclose=&amp;quot;none&amp;quot;&amp;gt;interface&amp;lt;/source&amp;gt; :&lt;br /&gt;
&lt;br /&gt;
: [[Image:Code_Editor-CurrentFile_Delphi.jpg|Link=|Code Editor for Delphi]]&lt;br /&gt;
: &#039;&#039;Définition de la variable private &amp;lt;code&amp;gt;CurrentFile&amp;lt;/code&amp;gt; (vue {{Delphi}})&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dans {{CBuilder}}, sélectionnez l&#039;onglet &#039;&#039;&#039;TextEditorUnit.h&#039;&#039;&#039; dans la barre d&#039;état pour ouvrir le fichier en-tête de l&#039;unité dans &#039;&#039;&#039;[[Editeur de code|l&#039;éditeur de code]]&#039;&#039;&#039;. Utilisez &#039;&#039;&#039;l&#039;éditeur de code&#039;&#039;&#039; pour déclarer une variable &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt; appelée &amp;lt;code&amp;gt;CurrentFile&amp;lt;/code&amp;gt; dans la section &amp;lt;source lang=&amp;quot;cpp&amp;quot; enclose=&amp;quot;none&amp;quot;&amp;gt;private&amp;lt;/source&amp;gt; de &#039;&#039;&#039;TTextEditorForm&#039;&#039;&#039; :&lt;br /&gt;
&lt;br /&gt;
: [[Image:Code_Editor-CurrentFile_C++.jpg|Link=|Code Editor for C++]]&lt;br /&gt;
: &#039;&#039;Définition de la variable private &amp;lt;code&amp;gt;CurrentFile&amp;lt;/code&amp;gt; (vue {{CBuilder}})&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pour permuter entre les modes &#039;&#039;&#039;[[Concepteur de fiches|Concepteur de fiches]]&#039;&#039;&#039; et &#039;&#039;&#039;[[Editeur de code|Editeur de code]]&#039;&#039;&#039;, appuyez sur &amp;lt;code&amp;gt;F12&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Mise à jour de la barre d&#039;état en réponse aux actions sur l&#039;éditeur de texte==&lt;br /&gt;
&lt;br /&gt;
Lorsque les utilisateurs déplacent le &#039;&#039;signe d&#039;insertion&#039;&#039; (curseur de texte) ou modifient le contenu de votre composant &#039;&#039;&#039;[[lib_fr:FMX.Memo.TMemo|TMemo]]&#039;&#039;&#039;, vous devez mettre à jour la barre d&#039;état. Comme vous devez mettre à jour la barre d&#039;état en réponse à de nombreux événements différents, vous avez la possibilité de définir une procédure unique dans votre code et de l&#039;appeler ultérieurement à partir d&#039;un gestionnaire d&#039;événement pour procéder à la mise à jour.&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dans {{Delphi}}, pour définir cette nouvelle procédure dans votre application, ajoutez la signature de procédure suivante à la section private de la classe &#039;&#039;&#039;TTextEditorForm&#039;&#039;&#039; dans la partie &amp;lt;source lang=&amp;quot;delphi&amp;quot; enclose=&amp;quot;none&amp;quot;&amp;gt;interface&amp;lt;/source&amp;gt; , juste en dessous de la variable &amp;lt;code&amp;gt;CurrentFile&amp;lt;/code&amp;gt; que vous avez précédemment définie :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
procedure UpdateStatusBar;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cliquez avec le bouton droit sur &amp;lt;code&amp;gt;UpdateStatusBar&amp;lt;/code&amp;gt; dans votre code, puis sélectionnez &#039;&#039;&#039;Compléter la classe au niveau du curseur&#039;&#039;&#039; de manière à ce que {{Product}} ajoute une définition squelette pour votre procédure à la partie &amp;lt;source lang=&amp;quot;delphi&amp;quot; enclose=&amp;quot;none&amp;quot;&amp;gt;implementation&amp;lt;/source&amp;gt; de votre code :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
procedure TTextEditorForm.UpdateStatusBar;&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Définissez la logique de la procédure &amp;lt;code&amp;gt;UpdateStatusBar&amp;lt;/code&amp;gt; entre ces mots-clés &amp;lt;source lang=&amp;quot;delphi&amp;quot; enclose=&amp;quot;none&amp;quot;&amp;gt;begin&amp;lt;/source&amp;gt; et &amp;lt;source lang=&amp;quot;delphi&amp;quot; enclose=&amp;quot;none&amp;quot;&amp;gt;end&amp;lt;/source&amp;gt; comme suit :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
LineNumber.Text := &#039;L: &#039; + (Editor.CaretPosition.Line+1).ToString;&lt;br /&gt;
ColumnNumber.Text := &#039;C: &#039; + (Editor.CaretPosition.Pos+1).ToString;&lt;br /&gt;
LineCount.Text := &#039;Lines: &#039; + Editor.Lines.Count.ToString;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dans C++, pour définir cette nouvelle fonction dans votre application, ajoutez la signature de fonction suivante à la section &amp;lt;source lang=&amp;quot;cpp&amp;quot; enclose=&amp;quot;none&amp;quot;&amp;gt;private&amp;lt;/source&amp;gt; de la classe &#039;&#039;&#039;TTextEditorForm&#039;&#039;&#039; dans le fichier &#039;&#039;TextEditorUnit.h&#039;&#039;, juste en dessous de la variable &amp;lt;code&amp;gt;CurrentFile&amp;lt;/code&amp;gt; que vous avez précédemment définie :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void UpdateStatusBar();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sélectionnez le fichier d&#039;implémentation, &#039;&#039;TextEditorUnit.cpp&#039;&#039;, et implémentez cette fonction comme suit&amp;amp;nbsp;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void TTextEditorForm::UpdateStatusBar()&lt;br /&gt;
{&lt;br /&gt;
    TextEditorForm-&amp;gt;LineNumber-&amp;gt;Text = L&amp;quot;L: &amp;quot; + String(TextEditorForm-&amp;gt;Editor-&amp;gt;CaretPosition.Line+1);&lt;br /&gt;
    TextEditorForm-&amp;gt;ColumnNumber-&amp;gt;Text = L&amp;quot;C: &amp;quot; + String(TextEditorForm-&amp;gt;Editor-&amp;gt;CaretPosition.Pos+1);&lt;br /&gt;
    TextEditorForm-&amp;gt;LineCount-&amp;gt;Text = L&amp;quot;Lines: &amp;quot; + String(TextEditorForm-&amp;gt;Editor-&amp;gt;Lines-&amp;gt;Count);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vous pouvez à présent appeler &amp;lt;code&amp;gt;UpdateStatusBar&amp;lt;/code&amp;gt; à partir de n&#039;importe quel gestionnaire d&#039;événement pour mettre à jour votre barre d&#039;état.&lt;br /&gt;
&lt;br /&gt;
Votre application doit mettre à jour pour la première fois les informations affichées sur la barre d&#039;état lorsque votre application démarre. Pour cela, vous pouvez utiliser l&#039;événement &#039;&#039;&#039;OnCreate&#039;&#039;&#039; de votre fiche&amp;amp;nbsp;:&lt;br /&gt;
&lt;br /&gt;
# Sélectionnez l&#039;onglet &#039;&#039;&#039;Conception&#039;&#039;&#039; pour revenir au [[Concepteur de fiches|Concepteur de fiches]].&lt;br /&gt;
# Sur la vue [[Vue Structure|Structure]], sélectionnez votre composant fiche, que vous avez nommé &amp;lt;code&amp;gt;TextEditorForm&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Sur [[Inspecteur d&#039;objets|l&#039;inspecteur d&#039;objets]], ouvrez l&#039;onglet &#039;&#039;&#039;Evénements&#039;&#039;&#039;.&lt;br /&gt;
# Sur l&#039;onglet &#039;&#039;&#039;Evénements&#039;&#039;&#039;, double-cliquez sur le champ de valeur de l&#039;événement &#039;&#039;&#039;OnCreate&#039;&#039;&#039;. {{Product}} bascule vers [[Editeur de code|l&#039;éditeur de code]] et ajoute une définition squelette pour votre nouveau gestionnaire d&#039;événement. Utilisez ce gestionnaire d&#039;événement pour appeler votre procédure &amp;lt;code&amp;gt;UpdateStatusBar&amp;lt;/code&amp;gt;&amp;amp;nbsp;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&#039;&#039;&#039;{{Delphi}}&amp;amp;nbsp;:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
procedure TTextEditorForm.FormCreate(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  Editor.Lines.Add(&#039;&#039;);&lt;br /&gt;
  UpdateStatusBar;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&#039;&#039;&#039;C++&amp;amp;nbsp;:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void __fastcall TTextEditorForm::FormCreate(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
        TextEditorForm-&amp;gt;Editor-&amp;gt;Lines-&amp;gt;Add(L&amp;quot;&amp;quot;);&lt;br /&gt;
        UpdateStatusBar();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notez qu&#039;avant d&#039;appeler &amp;lt;code&amp;gt;UpdateStatusBar&amp;lt;/code&amp;gt;, ce code ajoute une ligne vide à votre composant TMemo. Cette action initialise le nombre de lignes du mémo, de sorte que le libellé du nombre de lignes dans la barre d&#039;état affiche &amp;quot;1&amp;quot; ligne à partir du début au lieu de &amp;quot;0&amp;quot; ligne.&lt;br /&gt;
&lt;br /&gt;
Répétez les étapes ci-dessus avec les événements &#039;&#039;&#039;OnKeyUp&#039;&#039;&#039; et &#039;&#039;&#039;OnMouseUp&#039;&#039;&#039; de votre composant TMemo, que vous avez nommé &amp;lt;code&amp;gt;Editor&amp;lt;/code&amp;gt;&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&#039;&#039;&#039;{{Delphi}}&amp;amp;nbsp;:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
procedure TTextEditorForm.EditorKeyUp(Sender: TObject; var Key: Word;&lt;br /&gt;
  var KeyChar: Char; Shift: TShiftState);&lt;br /&gt;
begin&lt;br /&gt;
  UpdateStatusBar;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TTextEditorForm.EditorMouseUp(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
  Shift: TShiftState; X, Y: Single);&lt;br /&gt;
begin&lt;br /&gt;
  UpdateStatusBar;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;C++&amp;amp;nbsp;:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void __fastcall TTextEditorForm::EditorKeyUp(TObject *Sender, WORD &amp;amp;Key, System::WideChar &amp;amp;KeyChar,&lt;br /&gt;
          TShiftState Shift)&lt;br /&gt;
{&lt;br /&gt;
    UpdateStatusBar();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void __fastcall TTextEditorForm::EditorMouseUp(TObject *Sender, TMouseButton Button,&lt;br /&gt;
          TShiftState Shift, float X, float Y)&lt;br /&gt;
{&lt;br /&gt;
    UpdateStatusBar();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Création de gestionnaires d&#039;événement pour les entrées du menu Fichier==&lt;br /&gt;
&lt;br /&gt;
Vous êtes maintenant prêt à définir les réponses aux clics sur les éléments de menu. Dans le [[Concepteur de fiches|Concepteur de fiches]] ouvert, sélectionnez &amp;lt;code&amp;gt;NewAction&amp;lt;/code&amp;gt; dans la vue [[Vue Structure|Structure]]&amp;amp;nbsp;:&lt;br /&gt;
&lt;br /&gt;
:[[Image:Code_Editor-IDETutorialSelectingNewAction.jpg|Link=|Selecting New Action]]&lt;br /&gt;
&lt;br /&gt;
Sélectionnez ensuite l&#039;onglet &#039;&#039;&#039;Evénements&#039;&#039;&#039; dans &#039;&#039;&#039;l&#039;inspecteur d&#039;objets&#039;&#039;&#039;, et double-cliquez sur la zone d&#039;édition correspondant à l&#039;événement &amp;lt;code&amp;gt;OnExecute&amp;lt;/code&amp;gt;. &#039;&#039;&#039;L&#039;éditeur de code&#039;&#039;&#039; s&#039;ouvre et affiche un squelette pour votre nouveau gestionnaire d&#039;événement.  Ecrivez dans ce gestionnaire d&#039;événement le code qui s&#039;exécute lorsque les utilisateurs choisissent {{Menu|Fichier &amp;amp;gt; Nouveau}}.&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&#039;&#039;&#039;{{Delphi}}&amp;amp;nbsp;:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
procedure TTextEditorForm.NewActionExecute(Sender: TObject);&lt;br /&gt;
var&lt;br /&gt;
  UserResponse: Integer;&lt;br /&gt;
begin&lt;br /&gt;
  // Ask for confirmation if the memo is not empty.&lt;br /&gt;
  if not Editor.Text.IsEmpty then&lt;br /&gt;
  begin&lt;br /&gt;
    UserResponse := TDialogServiceSync.MessageDialog(&lt;br /&gt;
      &#039;This will clear the current document. Do you want to continue?&#039;,&lt;br /&gt;
      TMsgDlgType.mtInformation, mbYesNo, TMsgDlgBtn.mbYes, 0);&lt;br /&gt;
    if UserResponse = mrYes then&lt;br /&gt;
    begin&lt;br /&gt;
      Editor.Text := &#039;&#039;;&lt;br /&gt;
      Editor.Lines.Add(&#039;&#039;); // Initialize the memo line count to &amp;quot;1&amp;quot;.&lt;br /&gt;
      UpdateStatusBar;&lt;br /&gt;
      CurrentFile := &#039;&#039;; // New files have no file name until saved.&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&#039;&#039;&#039;C++&amp;amp;nbsp;:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void __fastcall TTextEditorForm::NewActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    if (!TextEditorForm-&amp;gt;Editor-&amp;gt;Text.IsEmpty()) {&lt;br /&gt;
        int UserResponse = TDialogServiceSync::MessageDialog(&lt;br /&gt;
            L&amp;quot;This will clear the current document. Do you want to continue?&amp;quot;,&lt;br /&gt;
            TMsgDlgType::mtInformation, mbYesNo, TMsgDlgBtn::mbYes, 0);&lt;br /&gt;
        if (UserResponse == mrYes) {&lt;br /&gt;
            TextEditorForm-&amp;gt;Editor-&amp;gt;Text = L&amp;quot;&amp;quot;;&lt;br /&gt;
            TextEditorForm-&amp;gt;Editor-&amp;gt;Lines-&amp;gt;Add(L&amp;quot;&amp;quot;);  // Initialize the memo line count to &amp;quot;1&amp;quot;.&lt;br /&gt;
            UpdateStatusBar();&lt;br /&gt;
            CurrentFile = L&amp;quot;&amp;quot;;  // New files have no file name until saved.&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cliquez sur l&#039;onglet &#039;&#039;&#039;Conception&#039;&#039;&#039; pour revenir au &#039;&#039;&#039;Concepteur de fiches&#039;&#039;&#039;, et répétez le processus pour les actions restantes utilisées par les entrées du menu Fichier :  &amp;lt;code&amp;gt;OpenAction&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;SaveAction&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;SaveAsAction&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ExitAction&amp;lt;/code&amp;gt;.  Il s&#039;agit des implémentations des gestionnaires d&#039;événement de l&#039;événement &#039;&#039;&#039;OnExecute&#039;&#039;&#039; de chacune de ces actions :&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&#039;&#039;&#039;{{Delphi}}&amp;amp;nbsp;:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
// File &amp;gt; Open&lt;br /&gt;
procedure TTextEditorForm.OpenActionExecute(Sender: TObject);&lt;br /&gt;
var&lt;br /&gt;
  FileName: String;&lt;br /&gt;
begin&lt;br /&gt;
  if OpenFileDialog.Execute = True then&lt;br /&gt;
  begin&lt;br /&gt;
    FileName := OpenFileDialog.FileName;&lt;br /&gt;
    if FileExists(FileName) then&lt;br /&gt;
    begin&lt;br /&gt;
      Editor.Lines.LoadFromFile(FileName);&lt;br /&gt;
      CurrentFile := FileName;&lt;br /&gt;
      Caption := &#039;Text Editor - &#039; + ExtractFileName(FileName);&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// File &amp;gt; Save&lt;br /&gt;
procedure TTextEditorForm.SaveActionExecute(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  if CurrentFile = &#039;&#039; then&lt;br /&gt;
    SaveAsAction.Execute()&lt;br /&gt;
  else&lt;br /&gt;
    Editor.Lines.SaveToFile(CurrentFile);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// File &amp;gt; Save As&lt;br /&gt;
procedure TTextEditorForm.SaveAsActionExecute(Sender: TObject);&lt;br /&gt;
var&lt;br /&gt;
  FileName: String;&lt;br /&gt;
  UserResponse: TModalResult;&lt;br /&gt;
begin&lt;br /&gt;
  if SaveFileDialog.Execute = True then&lt;br /&gt;
  begin&lt;br /&gt;
    FileName := SaveFileDialog.FileName;&lt;br /&gt;
    if FileExists(FileName) then&lt;br /&gt;
    begin&lt;br /&gt;
      UserResponse := TDialogServiceSync.MessageDialog(&lt;br /&gt;
        &#039;File already exists. Do you want to overwrite?&#039;,&lt;br /&gt;
        TMsgDlgType.mtInformation, mbYesNo, TMsgDlgBtn.mbYes, 0);&lt;br /&gt;
      if UserResponse = mrNo then&lt;br /&gt;
        Exit;&lt;br /&gt;
    end;&lt;br /&gt;
    Editor.Lines.SaveToFile(FileName);&lt;br /&gt;
    CurrentFile := FileName;&lt;br /&gt;
    Caption := &#039;Text Editor - &#039; + ExtractFileName(FileName);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// File &amp;gt; Exit&lt;br /&gt;
procedure TTextEditorForm.ExitActionExecute(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  Application.Terminate;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&#039;&#039;&#039;C++&amp;amp;nbsp;:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// File &amp;gt; Open&lt;br /&gt;
void __fastcall TTextEditorForm::OpenActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    if (TextEditorForm-&amp;gt;OpenFileDialog-&amp;gt;Execute()) {&lt;br /&gt;
        String FileName = TextEditorForm-&amp;gt;OpenFileDialog-&amp;gt;FileName;&lt;br /&gt;
        if (FileExists(FileName)) {&lt;br /&gt;
            TextEditorForm-&amp;gt;Editor-&amp;gt;Lines-&amp;gt;LoadFromFile(FileName);&lt;br /&gt;
            CurrentFile = FileName;&lt;br /&gt;
            Caption = L&amp;quot;Text Editor - &amp;quot; + ExtractFileName(FileName);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// File &amp;gt; Save&lt;br /&gt;
void __fastcall TTextEditorForm::SaveActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentFile == L&amp;quot;&amp;quot;) {&lt;br /&gt;
        TextEditorForm-&amp;gt;SaveAsAction-&amp;gt;Execute();&lt;br /&gt;
    } else {&lt;br /&gt;
        TextEditorForm-&amp;gt;Editor-&amp;gt;Lines-&amp;gt;SaveToFile(CurrentFile);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// File &amp;gt; Save As&lt;br /&gt;
void __fastcall TTextEditorForm::SaveAsActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    if (TextEditorForm-&amp;gt;SaveFileDialog-&amp;gt;Execute()) {&lt;br /&gt;
        String FileName = TextEditorForm-&amp;gt;SaveFileDialog-&amp;gt;FileName;&lt;br /&gt;
        if (FileExists(FileName)) {&lt;br /&gt;
            String UserResponse = TDialogServiceSync::MessageDialog(&lt;br /&gt;
                L&amp;quot;File already exists. Do you want to overwrite?&amp;quot;,&lt;br /&gt;
                TMsgDlgType::mtInformation, mbYesNo, TMsgDlgBtn::mbYes, 0);&lt;br /&gt;
            if (UserResponse == System::Uitypes::TMsgDlgBtn::mbNo) {&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        TextEditorForm-&amp;gt;Editor-&amp;gt;Lines-&amp;gt;SaveToFile(FileName);&lt;br /&gt;
        CurrentFile = FileName;&lt;br /&gt;
        Caption = L&amp;quot;Text Editor - &amp;quot; + ExtractFileName(FileName);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// File &amp;gt; Exit&lt;br /&gt;
void __fastcall TTextEditorForm::ExitActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    Application-&amp;gt;Terminate();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Création de gestionnaires d&#039;événement pour les entrées du menu Edition et Format==&lt;br /&gt;
&lt;br /&gt;
Pour implémenter les actions des entrées du menu dans les menus Edition et Format, vous devez suivre la même procédure que pour les actions du menu Fichier. Ces gestionnaires d&#039;événement sont très simples : ils transmettent simplement l&#039;action à votre mémo, car toutes les fonctionnalités requises sont déjà implémentées dans la classe [[lib_fr:FMX.Memo.TMemo|TMemo]], et ils appellent &amp;lt;code&amp;gt;UpdateStatusBar&amp;lt;/code&amp;gt; si l&#039;action peut avoir un effet sur la position du signe d&#039;insertion ou sur le nombre de lignes.&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&#039;&#039;&#039;{{Delphi}}&amp;amp;nbsp;:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
// Edit &amp;gt; Cut&lt;br /&gt;
procedure TTextEditorForm.CutActionExecute(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  Editor.CutToClipboard;&lt;br /&gt;
  UpdateStatusBar;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// Edit &amp;gt; Copy&lt;br /&gt;
procedure TTextEditorForm.CopyActionExecute(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  Editor.CopyToClipboard;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// Edit &amp;gt; Paste&lt;br /&gt;
procedure TTextEditorForm.PasteActionExecute(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  Editor.PasteFromClipboard;&lt;br /&gt;
  UpdateStatusBar;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// Edit &amp;gt; Select All&lt;br /&gt;
procedure TTextEditorForm.SelectAllActionExecute(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  Editor.SelectAll;&lt;br /&gt;
  UpdateStatusBar;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// Edit &amp;gt; Undo&lt;br /&gt;
procedure TTextEditorForm.UndoActionExecute(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  Editor.UnDo;&lt;br /&gt;
  UpdateStatusBar;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// Edit &amp;gt; Delete&lt;br /&gt;
procedure TTextEditorForm.DeleteActionExecute(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  if Editor.SelLength &amp;gt; 0 then&lt;br /&gt;
    Editor.DeleteSelection&lt;br /&gt;
  else&lt;br /&gt;
    Editor.DeleteFrom(Editor.CaretPosition, 1, [TDeleteOption.MoveCaret]);&lt;br /&gt;
  UpdateStatusBar;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// Format &amp;gt; Word Wrap&lt;br /&gt;
procedure TTextEditorForm.WordWrapActionExecute(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  Editor.WordWrap := not Editor.WordWrap;&lt;br /&gt;
  WordWrapAction.Checked := Editor.WordWrap;&lt;br /&gt;
  UpdateStatusBar;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&#039;&#039;&#039;C++&amp;amp;nbsp;:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// Edit &amp;gt; Cut&lt;br /&gt;
void __fastcall TTextEditorForm::CutActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    TextEditorForm-&amp;gt;Editor-&amp;gt;CutToClipboard();&lt;br /&gt;
    UpdateStatusBar();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Edit &amp;gt; Copy&lt;br /&gt;
void __fastcall TTextEditorForm::CopyActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    TextEditorForm-&amp;gt;Editor-&amp;gt;CopyToClipboard();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Edit &amp;gt; Paste&lt;br /&gt;
void __fastcall TTextEditorForm::PasteActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    TextEditorForm-&amp;gt;Editor-&amp;gt;PasteFromClipboard();&lt;br /&gt;
    UpdateStatusBar();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Edit &amp;gt; Select All&lt;br /&gt;
void __fastcall TTextEditorForm::SelectAllActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    TextEditorForm-&amp;gt;Editor-&amp;gt;SelectAll();&lt;br /&gt;
    UpdateStatusBar();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Edit &amp;gt; Undo&lt;br /&gt;
void __fastcall TTextEditorForm::UndoActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    TextEditorForm-&amp;gt;Editor-&amp;gt;UnDo();&lt;br /&gt;
    UpdateStatusBar();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Edit &amp;gt; Delete&lt;br /&gt;
void __fastcall TTextEditorForm::DeleteActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    if (TextEditorForm-&amp;gt;Editor-&amp;gt;SelLength &amp;gt; 0) {&lt;br /&gt;
        TextEditorForm-&amp;gt;Editor-&amp;gt;DeleteSelection();&lt;br /&gt;
    } else {&lt;br /&gt;
        TextEditorForm-&amp;gt;Editor-&amp;gt;DeleteFrom(&lt;br /&gt;
            TextEditorForm-&amp;gt;Editor-&amp;gt;CaretPosition, 1,&lt;br /&gt;
            Fmx::Memo::TDeleteOptions() &amp;lt;&amp;lt; Fmx::Memo::TDeleteOption::MoveCaret);&lt;br /&gt;
    }&lt;br /&gt;
    UpdateStatusBar();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Format &amp;gt; Word Wrap&lt;br /&gt;
void __fastcall TTextEditorForm::WordWrapActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    TextEditorForm-&amp;gt;Editor-&amp;gt;WordWrap = !TextEditorForm-&amp;gt;Editor-&amp;gt;WordWrap;&lt;br /&gt;
    TextEditorForm-&amp;gt;WordWrapAction-&amp;gt;Checked = TextEditorForm-&amp;gt;Editor-&amp;gt;WordWrap;&lt;br /&gt;
    UpdateStatusBar();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Suivant==&lt;br /&gt;
&lt;br /&gt;
[[Compilation et exécution de l&#039;application (tutoriel de l&#039;EDI)|Compilation et exécution de l&#039;application]]&lt;br /&gt;
&lt;br /&gt;
{{DEFAULTSORT:Codage des reponses aux actions des utilisateurs dans l&#039;editeur de code (tutoriel de l&#039;EDI)}}&lt;br /&gt;
[[Category:Delphi]]&lt;br /&gt;
[[Category:C++]]&lt;br /&gt;
[[Category:XE6]]&lt;br /&gt;
[[Category:AMMigrate]]&lt;br /&gt;
&lt;br /&gt;
[[en:Coding responses to user actions in the Code Editor (IDE Tutorial)]]&lt;br /&gt;
[[de:Programmieren von Reaktionen auf Benutzeraktionen im Quelltext-Editor (IDE-Tutorial)]]&lt;br /&gt;
[[ja:ユーザー アクションに対する応答をコード エディタでコーディングする（IDE チュートリアル）]]&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/f/index.php?title=Fichier:Code_Editor-IDETutorialSelectingNewAction.jpg&amp;diff=213847</id>
		<title>Fichier:Code Editor-IDETutorialSelectingNewAction.jpg</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/f/index.php?title=Fichier:Code_Editor-IDETutorialSelectingNewAction.jpg&amp;diff=213847"/>
		<updated>2021-10-08T21:17:06Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos : MsUpload&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;MsUpload&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/f/index.php?title=Fichier:Code_Editor-CurrentFile_Delphi.jpg&amp;diff=213846</id>
		<title>Fichier:Code Editor-CurrentFile Delphi.jpg</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/f/index.php?title=Fichier:Code_Editor-CurrentFile_Delphi.jpg&amp;diff=213846"/>
		<updated>2021-10-08T21:16:53Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos : MsUpload&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;MsUpload&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/f/index.php?title=Fichier:Code_Editor-CurrentFile_C%2B%2B.jpg&amp;diff=213845</id>
		<title>Fichier:Code Editor-CurrentFile C++.jpg</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/f/index.php?title=Fichier:Code_Editor-CurrentFile_C%2B%2B.jpg&amp;diff=213845"/>
		<updated>2021-10-08T21:16:51Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos : MsUpload&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;MsUpload&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/f/index.php?title=D%C3%A9claration_des_g%C3%A9n%C3%A9riques&amp;diff=213827</id>
		<title>Déclaration des génériques</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/f/index.php?title=D%C3%A9claration_des_g%C3%A9n%C3%A9riques&amp;diff=213827"/>
		<updated>2021-07-30T16:45:45Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos : RS-107222&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Parent|Génériques - Index}}&lt;br /&gt;
La déclaration d&#039;un générique est similaire à la déclaration d&#039;un type de classe, d&#039;enregistrement ou d&#039;interface normal. La différence réside dans le fait qu&#039;un ou plusieurs paramètres de type placés entre les crochets angulaires (&amp;amp;lt; et &amp;amp;gt;) suivent l&#039;identificateur de type dans la déclaration d&#039;un générique.&lt;br /&gt;
&lt;br /&gt;
Un paramètre de type peut être utilisé comme un identificateur de type typique dans un corps de méthode et une déclaration de type de conteneur.&lt;br /&gt;
&lt;br /&gt;
Par exemple :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
 type&lt;br /&gt;
   TPair&amp;lt;TKey,TValue&amp;gt; = class   // TKey and TValue are type parameters&lt;br /&gt;
     FKey: TKey;&lt;br /&gt;
     FValue: TValue;&lt;br /&gt;
     function GetValue: TValue;&lt;br /&gt;
   end;&lt;br /&gt;
 &lt;br /&gt;
 function TPair&amp;lt;TKey,TValue&amp;gt;.GetValue: TValue;&lt;br /&gt;
 begin&lt;br /&gt;
   Result := FValue;&lt;br /&gt;
 end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note| Vous devez appeler le constructeur par défaut et initialiser les champs de classe avant d&#039;appeler la méthode &#039;&#039;&#039;GetValue&#039;&#039;&#039;.}}&lt;br /&gt;
&lt;br /&gt;
==Argument de type==&lt;br /&gt;
&lt;br /&gt;
Les types génériques sont instanciés en fournissant des arguments de type. Dans {{Delphi}}, vous pouvez utiliser n&#039;importe quel type comme argument de type, à l&#039;exception des types suivants : un tableau statique, une chaîne courte ou un type d&#039;enregistrement qui contient (de façon récursive) un champ d&#039;un ou de plusieurs de ces deux types.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
 type&lt;br /&gt;
   TFoo&amp;lt;T&amp;gt; = class&lt;br /&gt;
     FData: T;&lt;br /&gt;
   end;&lt;br /&gt;
 var&lt;br /&gt;
   F: TFoo&amp;lt;Integer&amp;gt;; // &#039;Integer&#039; is the type argument of TFoo&amp;lt;T&amp;gt;&lt;br /&gt;
 begin&lt;br /&gt;
   ...&lt;br /&gt;
 end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Types imbriqués==&lt;br /&gt;
&lt;br /&gt;
Un type imbriqué dans un générique est lui-même un générique.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TFoo&amp;lt;T&amp;gt; = class                   // A generic class&lt;br /&gt;
  type&lt;br /&gt;
    TBar = class&lt;br /&gt;
      X: Integer;&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pour accéder au type imbriqué TBar, vous devez spécifier une construction du premier type TFoo :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
 var&lt;br /&gt;
   N: TFoo&amp;lt;Double&amp;gt;.TBar;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Un générique peut également être déclaré dans une classe normale en tant que type imbriqué :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type &lt;br /&gt;
 TBaz = class                        // A regular class&lt;br /&gt;
  type&lt;br /&gt;
    TQux&amp;lt;T&amp;gt; = class&lt;br /&gt;
      X: Integer;&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
 &lt;br /&gt;
type&lt;br /&gt;
   TOuter = class&lt;br /&gt;
   type&lt;br /&gt;
     TData&amp;lt;T&amp;gt; = class&lt;br /&gt;
       FFoo1: TFoo&amp;lt;Integer&amp;gt;;         // declared with closed constructed type&lt;br /&gt;
       FFoo2: TFoo&amp;lt;T&amp;gt;;               // declared with open constructed type&lt;br /&gt;
       FFooBar1: TFoo&amp;lt;Integer&amp;gt;.TBar; // declared with closed constructed type&lt;br /&gt;
       FFooBar2: TFoo&amp;lt;T&amp;gt;.TBar;       // declared with open constructed type&lt;br /&gt;
       FBazQux1: TBaz.TQux&amp;lt;Integer&amp;gt;; // declared with closed constructed type&lt;br /&gt;
       FBazQux2: TBaz.TQux&amp;lt;T&amp;gt;;       // declared with open constructed type&lt;br /&gt;
       ...&lt;br /&gt;
     end;&lt;br /&gt;
   var&lt;br /&gt;
     FIntegerData: TData&amp;lt;Integer&amp;gt;;&lt;br /&gt;
     FStringData: TData&amp;lt;String&amp;gt;;&lt;br /&gt;
   end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Types de base==&lt;br /&gt;
&lt;br /&gt;
Le type de base d&#039;un type de classe ou d&#039;interface paramétré peut être un type réel ou un type construit. Le type de base ne peut pas être un paramètre de type seul.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
  type&lt;br /&gt;
    TFoo1&amp;lt;T&amp;gt; = class(TBar)            // Actual type&lt;br /&gt;
    end;&lt;br /&gt;
 &lt;br /&gt;
    TFoo2&amp;lt;T&amp;gt; =  class(TBar2&amp;lt;T&amp;gt;)       // Open constructed type&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    TFoo3&amp;lt;T&amp;gt; = class(TBar3&amp;lt;Integer&amp;gt;)  // Closed constructed type&lt;br /&gt;
    end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Si TFoo2&amp;amp;lt;String&amp;amp;gt; est instancié, une classe ancêtre devient TBar2&amp;amp;lt;String&amp;amp;gt; et TBar2&amp;amp;lt;String&amp;amp;gt; est automatiquement instancié.&lt;br /&gt;
&lt;br /&gt;
==Types de classe, d&#039;interface et d&#039;enregistrement==&lt;br /&gt;
&lt;br /&gt;
Les types de classe, d&#039;interface, d&#039;enregistrement et de tableau peuvent être déclarés avec des paramètres de type.&lt;br /&gt;
&lt;br /&gt;
Par exemple :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
 type&lt;br /&gt;
   TRecord&amp;lt;T&amp;gt; = record&lt;br /&gt;
     FData: T;&lt;br /&gt;
   end;&lt;br /&gt;
 &lt;br /&gt;
 type&lt;br /&gt;
   IAncestor&amp;lt;T&amp;gt; = interface&lt;br /&gt;
     function GetRecord: TRecord&amp;lt;T&amp;gt;;&lt;br /&gt;
   end;&lt;br /&gt;
 &lt;br /&gt;
   IFoo&amp;lt;T&amp;gt; = interface(IAncestor&amp;lt;T&amp;gt;)&lt;br /&gt;
     procedure AMethod(Param: T);&lt;br /&gt;
   end;&lt;br /&gt;
 &lt;br /&gt;
 type&lt;br /&gt;
   TFoo&amp;lt;T&amp;gt; = class(TObject, IFoo&amp;lt;T&amp;gt;)&lt;br /&gt;
     FField: TRecord&amp;lt;T&amp;gt;;&lt;br /&gt;
     procedure AMethod(Param: T);&lt;br /&gt;
     function GetRecord: TRecord&amp;lt;T&amp;gt;;&lt;br /&gt;
   end;&lt;br /&gt;
&lt;br /&gt;
 type&lt;br /&gt;
   anArray&amp;lt;T&amp;gt;= array of T;&lt;br /&gt;
   IntArray= anArray&amp;lt;integer&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Types procéduraux==&lt;br /&gt;
&lt;br /&gt;
Le type de procédure et le pointeur de méthode peuvent être déclarés avec des paramètres de type. Les types de paramètre et les types de résultat peuvent également utiliser des paramètres de type.&lt;br /&gt;
&lt;br /&gt;
Par exemple :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
 type&lt;br /&gt;
   TMyProc&amp;lt;T&amp;gt; = procedure(Param: T);&lt;br /&gt;
   TMyProc2&amp;lt;Y&amp;gt; = procedure(Param1, Param2: Y) of object;&lt;br /&gt;
 type&lt;br /&gt;
   TFoo = class&lt;br /&gt;
     procedure Test;&lt;br /&gt;
     procedure MyProc(X, Y: Integer);&lt;br /&gt;
   end;&lt;br /&gt;
 &lt;br /&gt;
 procedure Sample(Param: Integer);&lt;br /&gt;
 begin&lt;br /&gt;
   Writeln(Param);&lt;br /&gt;
 end;&lt;br /&gt;
 &lt;br /&gt;
 procedure TFoo.MyProc(X, Y: Integer);&lt;br /&gt;
 begin&lt;br /&gt;
   Writeln(&#039;X:&#039;, X, &#039;, Y:&#039;, Y);&lt;br /&gt;
 end;&lt;br /&gt;
 &lt;br /&gt;
 procedure TFoo.Test;&lt;br /&gt;
 var&lt;br /&gt;
   X: TMyProc&amp;lt;Integer&amp;gt;;&lt;br /&gt;
   Y: TMyProc2&amp;lt;Integer&amp;gt;;&lt;br /&gt;
 begin&lt;br /&gt;
   X := Sample;&lt;br /&gt;
   X(10);&lt;br /&gt;
   Y := MyProc;&lt;br /&gt;
   Y(20, 30);&lt;br /&gt;
 end;&lt;br /&gt;
 &lt;br /&gt;
 var&lt;br /&gt;
   F: TFoo;&lt;br /&gt;
 begin&lt;br /&gt;
   F := TFoo.Create;&lt;br /&gt;
   F.Test;&lt;br /&gt;
   F.Free;&lt;br /&gt;
 end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Méthodes paramétrées==&lt;br /&gt;
&lt;br /&gt;
Les méthodes peuvent être déclarées avec des paramètres de type. Les types de paramètre et les types de résultat peuvent utiliser des paramètres de type. Cependant, les constructeurs et les destructeurs ne possèdent pas de paramètres de types, et ni les uns ni les autres ne peuvent avoir de méthodes virtuelles, dynamiques ou de message. Les méthodes paramétrées sont semblables à des méthodes surchargées.&lt;br /&gt;
&lt;br /&gt;
Il existe deux façons d&#039;instancier une méthode :&lt;br /&gt;
&lt;br /&gt;
* Spécifier explicitement l&#039;argument de type&lt;br /&gt;
* Déduire automatiquement de l&#039;argument de type&lt;br /&gt;
&lt;br /&gt;
Par exemple :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TFoo = class&lt;br /&gt;
    procedure Test;&lt;br /&gt;
    procedure CompareAndPrintResult&amp;lt;T&amp;gt;(X, Y: T);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
procedure TFoo.CompareAndPrintResult&amp;lt;T&amp;gt;(X, Y: T);&lt;br /&gt;
var&lt;br /&gt;
  Comparer : IComparer&amp;lt;T&amp;gt;;&lt;br /&gt;
begin&lt;br /&gt;
  Comparer := TComparer&amp;lt;T&amp;gt;.Default;&lt;br /&gt;
  if Comparer.Compare(X, Y) = 0 then&lt;br /&gt;
    WriteLn(&#039;Both members compare as equal&#039;)&lt;br /&gt;
  else&lt;br /&gt;
    WriteLn(&#039;Members do not compare as equal&#039;);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TFoo.Test;&lt;br /&gt;
begin&lt;br /&gt;
  CompareAndPrintResult&amp;lt;String&amp;gt;(&#039;Hello&#039;, &#039;World&#039;);&lt;br /&gt;
  CompareAndPrintResult(&#039;Hello&#039;, &#039;Hello&#039;);&lt;br /&gt;
  CompareAndPrintResult&amp;lt;Integer&amp;gt;(20, 20);&lt;br /&gt;
  CompareAndPrintResult(10, 20);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
  F: TFoo;&lt;br /&gt;
begin&lt;br /&gt;
  F := TFoo.Create;&lt;br /&gt;
  F.Test;&lt;br /&gt;
  ReadLn;&lt;br /&gt;
  F.Free;&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Portée des paramètres de type==&lt;br /&gt;
&lt;br /&gt;
La portée d&#039;un paramètre de type couvre la déclaration de type et les corps de tous ses membres, mais n&#039;inclut pas les types descendants.&lt;br /&gt;
&lt;br /&gt;
Par exemple :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
 type&lt;br /&gt;
   TFoo&amp;lt;T&amp;gt; = class&lt;br /&gt;
     X: T;&lt;br /&gt;
   end;&lt;br /&gt;
 &lt;br /&gt;
   TBar&amp;lt;S&amp;gt; = class(TFoo&amp;lt;S&amp;gt;)&lt;br /&gt;
     Y: T;  // error!  unknown identifier &amp;quot;T&amp;quot;&lt;br /&gt;
   end;&lt;br /&gt;
 &lt;br /&gt;
 var&lt;br /&gt;
   F: TFoo&amp;lt;Integer&amp;gt;;&lt;br /&gt;
 begin&lt;br /&gt;
   F.T  // error! unknown identifier &amp;quot;T&amp;quot;&lt;br /&gt;
 end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Voir aussi==&lt;br /&gt;
&lt;br /&gt;
*[[Présentation des génériques|Présentation des génériques]]&lt;br /&gt;
*[[Terminologie des génériques|Terminologie des génériques]]&lt;br /&gt;
*[[Contraintes dans les génériques|Contraintes dans les génériques]]&lt;br /&gt;
*[[Compatibilité des types et surcharges dans les génériques|Compatibilité des types et surcharges dans les génériques]]&lt;br /&gt;
*[[Variable classe dans les génériques|Variable classe dans les génériques]]&lt;br /&gt;
&lt;br /&gt;
{{DEFAULTSORT:Declaration des generiques}}&lt;br /&gt;
[[Category:Delphi]]&lt;br /&gt;
[[Category:Guide du langage Delphi]]&lt;br /&gt;
[[Category:AMMigrate]]&lt;br /&gt;
&lt;br /&gt;
[[en:Declaring Generics]]&lt;br /&gt;
[[de:Deklaration von Generics]]&lt;br /&gt;
[[ja:ジェネリックスの宣言]]&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/f/index.php?title=Propri%C3%A9t%C3%A9s_(Delphi)&amp;diff=213823</id>
		<title>Propriétés (Delphi)</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/f/index.php?title=Propri%C3%A9t%C3%A9s_(Delphi)&amp;diff=213823"/>
		<updated>2021-06-29T20:06:19Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos : /* Spécificateurs de stockage */ RS-107569&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Parent|Classes et objets - Index}}&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;property&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;type&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;integerConstant&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;read&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;write&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;stored&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;default&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;nodedefault&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;implements&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;var&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;virtual&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;register&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;dynamic&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;const&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;index&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;True&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;False&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;Boolean&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;nil&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;&#039;&#039;&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;class property&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;published&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;class var&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;public&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;private&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;protected&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;strict private&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&amp;lt;ideTag id=&amp;quot;strict protected&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;Cette rubrique traite les sujets suivants :&lt;br /&gt;
&lt;br /&gt;
* Accès aux propriétés&lt;br /&gt;
* Propriétés tableau&lt;br /&gt;
* Spécificateurs d&#039;indice&lt;br /&gt;
* Spécificateurs de stockage&lt;br /&gt;
* Redéclarations et redéfinitions de propriétés&lt;br /&gt;
* Propriétés de classes&lt;br /&gt;
&lt;br /&gt;
==A propos des propriétés==&lt;br /&gt;
&lt;br /&gt;
Comme un champ, une propriété définit un attribut d&#039;un objet. Mais alors qu&#039;un champ n&#039;est rien de plus qu&#039;un emplacement de stockage dont le contenu peut être consulté et modifié, une propriété associe des actions spécifiques à la lecture et la modification de ses données. Les propriétés proposent un moyen de contrôler l&#039;accès aux attributs d&#039;un objet et permettent le calcul des attributs.&lt;br /&gt;
&lt;br /&gt;
La déclaration d&#039;une propriété spécifie son nom et son type, et contient au moins un spécificateur d&#039;accès. Une déclaration de propriété a la syntaxe suivante :&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;property &#039;&#039;&#039;&#039;&#039;propertyName[indexes]: type &#039;&#039;&amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;index&amp;lt;/span&amp;gt;&#039;&#039; integerConstant specifiers;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
where&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;propertyName&#039;&#039; est un identificateur correct.&lt;br /&gt;
* &#039;&#039;[indexes]&#039;&#039; est facultatif, c&#039;est une suite de déclarations de paramètre séparées par des point-virgules. Chaque déclaration de paramètre est de la forme &#039;&#039;identificateur1&#039;&#039;, ..., &#039;&#039;identificateurn&#039;&#039;: type. Pour plus d&#039;informations, voir la section Propriétés tableau plus loin.&lt;br /&gt;
* type doit être un identificateur de type prédéfini ou déclaré précédemment. C&#039;est-à-dire que les déclarations de propriétés comme &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;property Num: 0..9&amp;lt;/span&amp;gt; ... sont incorrectes.&lt;br /&gt;
* la clause index &#039;&#039;integerConstant&#039;&#039; est facultative. Pour plus d&#039;informations, voir la section Spécificateurs d&#039;indice plus loin.&lt;br /&gt;
* specifiers est une suite de spécificateurs &#039;&#039;&#039;read&#039;&#039;&#039;, &#039;&#039;&#039;write&#039;&#039;&#039;, &#039;&#039;&#039;stored&#039;&#039;&#039;, &#039;&#039;&#039;default&#039;&#039;&#039; (ou &#039;&#039;&#039;nodefault&#039;&#039;&#039;) et &#039;&#039;&#039;implements&#039;&#039;&#039;. Chaque déclaration de propriété doit comporter au moins un spécificateur &#039;&#039;&#039;read&#039;&#039;&#039; ou &#039;&#039;&#039;write&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Les propriétés sont définies par leurs spécificateurs d&#039;accès. A la différence des champs, les propriétés ne peuvent être transmises comme paramètre &#039;&#039;&#039;var&#039;&#039;&#039;. De même, il n&#039;est pas possible d&#039;appliquer l&#039;opérateur &#039;&#039;&#039;@&#039;&#039;&#039; à une propriété. En effet, une propriété n&#039;existe pas nécessairement en mémoire. Elle peut, par exemple, avoir une méthode &#039;&#039;&#039;read&#039;&#039;&#039; qui obtient une valeur d&#039;une base de données ou génère une valeur aléatoire.&lt;br /&gt;
&lt;br /&gt;
==Accès aux propriétés==&lt;br /&gt;
&lt;br /&gt;
Chaque propriété a un spécificateur &#039;&#039;&#039;read&#039;&#039;&#039;, un spécificateur &#039;&#039;&#039;write&#039;&#039;&#039; ou les deux. Ce sont les spécificateurs d&#039;accès. Ils ont la forme suivante :&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;read &#039;&#039;&#039;&#039;&#039;fieldOrMethod&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;write &#039;&#039;&#039;&#039;&#039;fieldOrMethod&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
où &#039;&#039;fieldOrMethod&#039;&#039; est le nom du champ ou de la méthode déclaré dans la même classe ou dans une classe ancêtre.&lt;br /&gt;
&lt;br /&gt;
* Si &#039;&#039;fieldOrMethod&#039;&#039; est déclaré dans la même classe, il doit apparaître avant la déclaration de la propriété. S&#039;il est déclaré dans une classe ancêtre, il doit être visible dans le descendant ; ce ne peut donc pas être un champ ou une méthode privé d&#039;une classe ancêtre déclarée dans une autre unité.&lt;br /&gt;
* Si &#039;&#039;fieldOrMethod&#039;&#039; est un champ, il doit être de même type que la propriété.&lt;br /&gt;
* Si &#039;&#039;fieldOrMethod&#039;&#039; est une méthode, elle ne peut être &#039;&#039;&#039;dynamique&#039;&#039;&#039; et, si elle est &#039;&#039;&#039;virtuelle&#039;&#039;&#039;, elle ne peut être surchargée. En outre, les méthodes d&#039;accès pour une propriété publiée doivent utiliser la convention d&#039;appel par défaut &#039;&#039;&#039;register&#039;&#039;&#039;.&lt;br /&gt;
* Dans un spécificateur &#039;&#039;&#039;read&#039;&#039;&#039;, si &#039;&#039;fieldOrMethod&#039;&#039; est une méthode, ce doit être une fonction sans paramètre renvoyant une valeur de même type que celui de la propriété. Une exception est une méthode d&#039;accès pour une propriété indicée ou une propriété tableau.&lt;br /&gt;
* Dans un spécificateur &#039;&#039;&#039;write&#039;&#039;&#039;, si &#039;&#039;fieldOrMethod&#039;&#039; est une méthode, ce doit être une procédure prenant un seul paramètre valeur ou &#039;&#039;&#039;const&#039;&#039;&#039; du même type que la propriété (ou plus, s&#039;il s&#039;agit d&#039;une propriété tableau ou d&#039;une propriété indicée).&lt;br /&gt;
&lt;br /&gt;
Par exemple, soit ces déclarations :&lt;br /&gt;
&lt;br /&gt;
 property Color: TColor read GetColor write SetColor;&lt;br /&gt;
&lt;br /&gt;
la méthode &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;GetColor&amp;lt;/span&amp;gt; doit être déclarée comme suit :&lt;br /&gt;
&lt;br /&gt;
 function GetColor: TColor;&lt;br /&gt;
&lt;br /&gt;
et la méthode &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;SetColor&amp;lt;/span&amp;gt; doit utiliser l&#039;une des déclarations suivantes :&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 procedure SetColor(Value: TColor);&lt;br /&gt;
 procedure SetColor(const Value: TColor);&lt;br /&gt;
&lt;br /&gt;
Le nom du paramètre de &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;SetColor&amp;lt;/span&amp;gt; n&#039;a pas besoin d&#039;être &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;Value&amp;lt;/span&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Quand une propriété est référencée dans une expression, sa valeur est lue en utilisant le champ ou la méthode indiqué par le spécificateur &#039;&#039;&#039;read&#039;&#039;&#039;. Quand une propriété est référencée dans une instruction d&#039;affectation, sa valeur est modifiée en utilisant le champ ou la méthode indiqué par le spécificateur &#039;&#039;&#039;write&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
L&#039;exemple suivant déclare une classe appelée &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;TCompass&amp;lt;/span&amp;gt; ayant une propriété publiée &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;Heading&amp;lt;/span&amp;gt;. La valeur de &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;Heading&amp;lt;/span&amp;gt; est lue via le champ &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;FHeading&amp;lt;/span&amp;gt; et écrite via la procédure &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;SetHeading&amp;lt;/span&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 type&lt;br /&gt;
    THeading = 0..359;&lt;br /&gt;
    TCompass = class(TControl)&lt;br /&gt;
      private&lt;br /&gt;
         FHeading: THeading;&lt;br /&gt;
         procedure SetHeading(Value: THeading);&lt;br /&gt;
      published&lt;br /&gt;
         property Heading: THeading read FHeading write SetHeading;&lt;br /&gt;
         ...&lt;br /&gt;
     end;&lt;br /&gt;
&lt;br /&gt;
Etant donné cette déclaration, les instructions :&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 if Compass.Heading = 180 then GoingSouth;&lt;br /&gt;
 Compass.Heading := 135;&lt;br /&gt;
&lt;br /&gt;
correspondent à :&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 if Compass.FHeading = 180 then GoingSouth;&lt;br /&gt;
 Compass.SetHeading(135);&lt;br /&gt;
&lt;br /&gt;
Dans la classe &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;TCompass&amp;lt;/span&amp;gt;, aucune action n&#039;est associée à la lecture de la propriété &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;Heading&amp;lt;/span&amp;gt; ; l&#039;opération &#039;&#039;&#039;read&#039;&#039;&#039; consiste simplement à récupérer la valeur stockée dans le champ &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;FHeading&amp;lt;/span&amp;gt;. Par contre, l&#039;affectation d&#039;une valeur à la propriété &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;Heading&amp;lt;/span&amp;gt; se transforme en un appel de la méthode &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;SetHeading&amp;lt;/span&amp;gt; qui, probablement, stocke la nouvelle valeur dans le champ &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;FHeading&amp;lt;/span&amp;gt; mais effectue également d&#039;autres actions. La méthode &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;SetHeading&amp;lt;/span&amp;gt; peut, par exemple, être implémentée de la manière suivante :&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 procedure TCompass.SetHeading(Value: THeading);&lt;br /&gt;
 begin&lt;br /&gt;
             if FHeading &amp;amp;lt;&amp;amp;gt; Value then&lt;br /&gt;
              begin&lt;br /&gt;
                FHeading := Value;&lt;br /&gt;
                Repaint;    // actualise l&#039;interface utilisateur afin de refléter la nouvelle valeur&lt;br /&gt;
              end;&lt;br /&gt;
 end;&lt;br /&gt;
&lt;br /&gt;
Une propriété dont la déclaration ne contient qu&#039;un spécificateur &#039;&#039;&#039;read&#039;&#039;&#039; est une propriété en lecture seule, et la propriété dont la déclaration ne comporte que le spécificateur &#039;&#039;&#039;write&#039;&#039;&#039; est une propriété en écriture seule. Affecter une valeur à une propriété en lecture seule ou utiliser une propriété en écriture seulement dans une expression sont des erreurs.&lt;br /&gt;
&lt;br /&gt;
==Propriétés tableau==&lt;br /&gt;
&lt;br /&gt;
Les propriétés tableau sont des propriétés indicées. Elles peuvent représenter les éléments d&#039;une liste, les contrôles enfant d&#039;un contrôle ou les pixels d&#039;un bitmap.&lt;br /&gt;
&lt;br /&gt;
La déclaration d&#039;une propriété tableau inclut une liste de paramètres spécifiant le nom et le type des indices. Par exemple,&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 property Objects[Index: Integer] : TObject read GetObject write SetObject;&lt;br /&gt;
 property Pixels[X, Y: Integer] : TColor read GetPixel write SetPixel;&lt;br /&gt;
 property Values[const Name: string]: string read GetValue write SetValue;&lt;br /&gt;
&lt;br /&gt;
Le format d&#039;une liste de paramètres indice est le même que celui de la liste de paramètres d&#039;une procédure ou d&#039;une fonction, à cette différence que la déclaration des paramètres est placée entre crochets au lieu de parenthèses. A la différence des tableaux qui ne peuvent utiliser que des indices de type scalaire, les propriétés tableau peuvent avoir des indices de type quelconque.&lt;br /&gt;
&lt;br /&gt;
Pour les propriétés tableau, les spécificateurs d&#039;accès doivent indiquer des méthodes et pas des champs. La méthode d&#039;un spécificateur &#039;&#039;&#039;read&#039;&#039;&#039; doit être une fonction ayant les mêmes paramètres, en nombre, en ordre et en type, que ceux indiqués dans la liste de paramètres indice de la propriété et dont le type de résultat est identique au type de la propriété. La méthode indiquée par le spécificateur &#039;&#039;&#039;write&#039;&#039;&#039; doit être une procédure ayant les mêmes paramètres, en nombre, en ordre et en type, que ceux indiqués dans la liste de paramètres indice de la propriété plus un paramètre valeur ou &#039;&#039;&#039;const&#039;&#039;&#039; supplémentaire du même type que la propriété.&lt;br /&gt;
&lt;br /&gt;
Par exemple, les méthodes d&#039;accès des propriétés tableau déclarées dans l&#039;exemple précédent peuvent se déclarer de la manière suivante :&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 function GetObject(Index: Integer): TObject;&lt;br /&gt;
 function GetPixel(X, Y: Integer): TColor;&lt;br /&gt;
 function GetValue(const Name: string): string;&lt;br /&gt;
 procedure SetObject(Index: Integer; Value: TObject);&lt;br /&gt;
 procedure SetPixel(X, Y: Integer; Value: TColor);&lt;br /&gt;
 procedure SetValue(const Name, Value: string);&lt;br /&gt;
&lt;br /&gt;
Vous accédez à une propriété tableau en indiçant l&#039;identificateur de la propriété. Par exemple, les instructions :&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 if Collection.Objects[0] = nil then Exit;&lt;br /&gt;
 Canvas.Pixels[10, 20] := clRed;&lt;br /&gt;
 Params.Values[&#039;PATH&#039;] := &#039;C:\BIN&#039;;&lt;br /&gt;
&lt;br /&gt;
correspondent à :&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 if Collection.GetObject(0) = nil then Exit;&lt;br /&gt;
 Canvas.SetPixel(10, 20, clRed);&lt;br /&gt;
 Params.SetValue(&#039;PATH&#039;, &#039;C:\BIN&#039;);&lt;br /&gt;
&lt;br /&gt;
La définition d&#039;une propriété tableau peut être suivie de la directive &#039;&#039;&#039;default&#039;&#039;&#039;, auquel cas, la propriété tableau devient la propriété par défaut de la classe. Par exemple,&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 type&lt;br /&gt;
    TStringArray = class&lt;br /&gt;
     public&lt;br /&gt;
        property Strings[Index: Integer] : string ...; default;&lt;br /&gt;
           ...&lt;br /&gt;
     end;&lt;br /&gt;
&lt;br /&gt;
Si une classe a une propriété par défaut, vous pouvez accéder à cette propriété en utilisant la forme abrégée &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;object[index]&amp;lt;/span&amp;gt; équivalente à &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;object.property[index]&amp;lt;/span&amp;gt;. Par exemple, étant donné les déclarations précédentes, &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;StringArray.Strings[7]&amp;lt;/span&amp;gt; peut s&#039;abréger en &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;StringArray[7]&amp;lt;/span&amp;gt;. Une classe peut n&#039;avoir qu&#039;une seule propriété par défaut avec une signature donnée (liste de paramètres en tableau), mais il est possible de surcharger la propriété par défaut. Changer ou masquer la propriété par défaut dans les classes dérivées peut entraîner un comportement inattendu, car le compilateur effectue toujours les liaisons aux propriétés de manière statique.&lt;br /&gt;
&lt;br /&gt;
==Spécificateurs d&#039;indice==&lt;br /&gt;
&lt;br /&gt;
Les spécificateurs d&#039;indice permettent à plusieurs propriétés de partager la même méthode d&#039;accès alors qu&#039;elles représentent des valeurs différentes. Un spécificateur d&#039;indice est constitué de la directive &#039;&#039;&#039;index&#039;&#039;&#039; suivie d&#039;une constante entière comprise entre -2147483647 et 2147483647. Si une propriété a un spécificateur d&#039;indice, ses spécificateurs &#039;&#039;&#039;read&#039;&#039;&#039; et &#039;&#039;&#039;write&#039;&#039;&#039; doivent indiquer des méthodes et pas des champs. Par exemple,&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 type&lt;br /&gt;
    TRectangle = class&lt;br /&gt;
      private&lt;br /&gt;
        FCoordinates: array[0..3] of Longint;&lt;br /&gt;
        function GetCoordinate(Index: Integer): Longint;&lt;br /&gt;
        procedure SetCoordinate(Index: Integer; Value: Longint);&lt;br /&gt;
      public&lt;br /&gt;
        property Left: Longint index 0 read GetCoordinate write SetCoordinate;&lt;br /&gt;
        property Top: Longint index 1 read GetCoordinate write SetCoordinate;&lt;br /&gt;
        property Right: Longint index 2 read GetCoordinate write SetCoordinate;&lt;br /&gt;
        property Bottom: Longint index 3 read GetCoordinate write SetCoordinate;&lt;br /&gt;
        property Coordinates[Index: Integer] : Longint read GetCoordinate write SetCoordinate;&lt;br /&gt;
        ...&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
La méthode d&#039;accès d&#039;une propriété ayant un spécificateur d&#039;accès doit prendre un paramètre supplémentaire de type Integer. Pour une fonction &#039;&#039;&#039;read&#039;&#039;&#039;, ce doit être le dernier paramètre ; pour une procédure &#039;&#039;&#039;write&#039;&#039;&#039;, ce doit être l&#039;avant-dernier paramètre (avant le paramètre spécifiant la valeur de la propriété). Quand un programme accède à la propriété, la constante entière est automatiquement transmise à la méthode d&#039;accès.&lt;br /&gt;
&lt;br /&gt;
Etant donné les déclarations précédentes, si &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;Rectangle&amp;lt;/span&amp;gt; est de type &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;TRectangle&amp;lt;/span&amp;gt;, alors :&lt;br /&gt;
&lt;br /&gt;
 Rectangle.Right := Rectangle.Left + 100;&lt;br /&gt;
&lt;br /&gt;
correspond à&lt;br /&gt;
&lt;br /&gt;
 Rectangle.SetCoordinate(2, Rectangle.GetCoordinate(0) + 100);&lt;br /&gt;
&lt;br /&gt;
==Spécificateurs de stockage==&lt;br /&gt;
&lt;br /&gt;
Les directives facultatives &#039;&#039;&#039;stored&#039;&#039;&#039;, &#039;&#039;&#039;default&#039;&#039;&#039; et &#039;&#039;&#039;nodefault&#039;&#039;&#039; sont appelées des spécificateurs de stockage. Sans effet sur le comportement du programme, les spécificateurs de stockage indiquent si on enregistre ou non la valeur des propriétés publiées dans les fichiers fiche.&lt;br /&gt;
&lt;br /&gt;
La directive &#039;&#039;&#039;stored&#039;&#039;&#039; doit être suivie par &#039;&#039;&#039;True&#039;&#039;&#039;, &#039;&#039;&#039;False&#039;&#039;&#039;, le nom d&#039;un champ &#039;&#039;&#039;Boolean&#039;&#039;&#039; ou par le nom d&#039;une méthode sans paramètre qui renvoie une valeur &#039;&#039;&#039;Boolean&#039;&#039;&#039;. Par exemple,&lt;br /&gt;
&lt;br /&gt;
 property Name : TComponentName read FName write SetName stored False;&lt;br /&gt;
&lt;br /&gt;
Si la propriété n&#039;a pas de directive &#039;&#039;&#039;stored&#039;&#039;&#039;, elle est traitée comme si stored &#039;&#039;&#039;True&#039;&#039;&#039; était spécifié.&lt;br /&gt;
&lt;br /&gt;
La directive &#039;&#039;&#039;default&#039;&#039;&#039; doit être suivie par une constante du même type que la propriété. Par exemple,&lt;br /&gt;
&lt;br /&gt;
 property Tag: Longint read FTag write FTag default 0;&lt;br /&gt;
&lt;br /&gt;
Pour redéfinir une valeur &#039;&#039;&#039;default&#039;&#039;&#039; héritée sans en spécifier de nouvelle valeur, utilisez la directive &#039;&#039;&#039;nodefault&#039;&#039;&#039;. Les directives &#039;&#039;&#039;default&#039;&#039;&#039; et &#039;&#039;&#039;nodefault&#039;&#039;&#039; ne sont gérées que pour les types scalaires et pour les types ensemble dont les bornes inférieure et supérieure du type de base de l&#039;ensemble sont des valeurs scalaires comprises entre 0 et 31 ; si une telle propriété est déclarée sans &#039;&#039;&#039;default&#039;&#039;&#039; ni &#039;&#039;&#039;nodefault&#039;&#039;&#039;, elle est traitée comme si &#039;&#039;&#039;nodefault&#039;&#039;&#039; était spécifié. Pour les réels, les pointeurs et les chaînes, il y a une valeur &#039;&#039;&#039;par défaut&#039;&#039;&#039; implicite de 0, &#039;&#039;&#039;nil&#039;&#039;&#039; et &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/span&amp;gt; (la chaîne vide), respectivement.&lt;br /&gt;
&lt;br /&gt;
{{Note|  Vous ne pouvez pas utiliser la valeur scalaire -2147483648 comme valeur par défaut. Cette valeur est utilisée de manière interne pour représenter &#039;&#039;&#039;nodefault&#039;&#039;&#039;. }}&lt;br /&gt;
&lt;br /&gt;
Quand on enregistre l&#039;état d&#039;un composant, les spécificateurs de stockage des propriétés publiées du composant sont vérifiés. Si la valeur en cours de la propriété est différente de sa valeur &#039;&#039;&#039;par défaut&#039;&#039;&#039; (ou s&#039;il n&#039;y a pas de valeur par défaut) et si le spécificateur &#039;&#039;&#039;stored&#039;&#039;&#039; a la valeur &#039;&#039;&#039;True&#039;&#039;&#039;, alors la valeur de la propriété est enregistrée. Sinon, la valeur de la propriété n&#039;est pas enregistrée.&lt;br /&gt;
&lt;br /&gt;
{{Note|  Les valeurs des propriétés ne sont pas automatiquement initialisées à la valeur par défaut. C&#039;est-à-dire que la directive default agit uniquement lorsque les valeurs des propriétés sont enregistrées dans le fichier fiche, mais pas sur la valeur initiale de l&#039;instance nouvellement créée d&#039;une propriété.}}&lt;br /&gt;
&lt;br /&gt;
Les spécificateurs de stockage ne sont pas gérés pour les propriétés tableau. La directive &#039;&#039;&#039;default&#039;&#039;&#039; a une signification différente quand elle est utilisée dans une déclaration de propriété tableau. Voir Propriétés tableau, ci-avant.&lt;br /&gt;
&lt;br /&gt;
==Redéclarations et redéfinitions de propriétés==&lt;br /&gt;
&lt;br /&gt;
Une déclaration de propriété qui ne spécifie pas de type est appelée une redéfinition de propriété. La redéfinition de propriété permet de modifier la visibilité ou les spécificateurs hérités d&#039;une propriété. La redéfinition la plus simple est constituée uniquement du mot réservé &#039;&#039;&#039;property&#039;&#039;&#039; suivi de l&#039;identificateur de la propriété héritée ; cette forme est utilisée pour changer la visibilité d&#039;une propriété. Si, par exemple, une classe ancêtre déclare une propriété comme protégée, une classe dérivée peut la redéclarer dans la section publique ou publiée de la classe. La redéfinition de propriété peut comporter les directives &#039;&#039;&#039;read&#039;&#039;&#039;, &#039;&#039;&#039;write&#039;&#039;&#039;,&#039;&#039;&#039;stored&#039;&#039;&#039;, &#039;&#039;&#039;default&#039;&#039;&#039; et &#039;&#039;&#039;nodefault&#039;&#039;&#039; ; ces directives redéfinissent la directive correspondante héritée. Une directive redéfinie peut remplacer un spécificateur d&#039;accès hérité, ajouter un spécificateur manquant ou augmenter la visibilité d&#039;une propriété. Elle ne peut pas supprimer un spécificateur d&#039;accès ou réduire la visibilité d&#039;une propriété. Une redéfinition peut comporter la directive &#039;&#039;&#039;implements&#039;&#039;&#039; qui s&#039;ajoute à la liste des interfaces implémentées sans en supprimer d&#039;interfaces héritées.&lt;br /&gt;
&lt;br /&gt;
Les déclarations suivantes illustrent la redéfinition de propriété :&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 type&lt;br /&gt;
    TAncestor = class&lt;br /&gt;
        ...&lt;br /&gt;
      protected&lt;br /&gt;
        property Size: Integer read FSize;&lt;br /&gt;
        property Text: string read GetText write SetText;&lt;br /&gt;
        property Color: TColor read FColor write SetColor stored False;&lt;br /&gt;
        ...&lt;br /&gt;
    end;&lt;br /&gt;
 &lt;br /&gt;
 type&lt;br /&gt;
 &lt;br /&gt;
    TDerived = class(TAncestor)&lt;br /&gt;
        ...&lt;br /&gt;
      protected&lt;br /&gt;
        property Size write SetSize;&lt;br /&gt;
      published&lt;br /&gt;
        property Text;&lt;br /&gt;
        property Color stored True default clBlue;&lt;br /&gt;
        ...&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
La redéfinition de &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;Size&amp;lt;/span&amp;gt; ajoute un spécificateur &#039;&#039;&#039;write&#039;&#039;&#039; afin de permettre la modification de la propriété. La redéfinition des propriétés &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;Text&amp;lt;/span&amp;gt; et &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;Color&amp;lt;/span&amp;gt; fait passer la visibilité des propriétés de protégée à publiée. La redéfinition de la propriété &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;Color&amp;lt;/span&amp;gt; spécifie également que sa valeur doit être enregistrée quand elle n&#039;est pas &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;clBlue&amp;lt;/span&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Une redéclaration de propriété qui inclut un identificateur de type masque la propriété héritée au lieu de la redéfinir. Cela signifie qu&#039;une nouvelle propriété est créée portant le même nom que celle héritée. Toute déclaration de propriété spécifiant un type doit être une déclaration complète et doit donc comporter au moins un spécificateur d&#039;accès.&lt;br /&gt;
&lt;br /&gt;
Si une propriété est masquée ou redéfinie dans une classe dérivée, le substitut de la propriété est toujours statique. C&#039;est-à-dire que c&#039;est le type déclaré (à la compilation) de la variable utilisée pour identifier un objet qui détermine l&#039;interprétation de ses identificateurs de propriété. Ainsi, une fois le code suivant exécuté, la lecture ou l&#039;affectation d&#039;une valeur à &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;MyObject.Value&amp;lt;/span&amp;gt; appelle &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;Method1&amp;lt;/span&amp;gt; ou &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;Method2&amp;lt;/span&amp;gt; même si &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;MyObject&amp;lt;/span&amp;gt; contient une instance de &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;TDescendant&amp;lt;/span&amp;gt;. Mais vous pouvez transtyper &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;MyObject&amp;lt;/span&amp;gt; en &amp;lt;span class=&amp;quot;code&amp;quot;&amp;gt;TDescendant&amp;lt;/span&amp;gt; pour accéder aux propriétés de la classe dérivée et à leurs spécificateurs d&#039;accès.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 type&lt;br /&gt;
     TAncestor = class&lt;br /&gt;
       ...&lt;br /&gt;
       property Value : Integer read Method1 write Method2;&lt;br /&gt;
     end;&lt;br /&gt;
 &lt;br /&gt;
     TDescendant = class(TAncestor)&lt;br /&gt;
       ...&lt;br /&gt;
       property Value : Integer read Method3 write Method4;&lt;br /&gt;
     end;&lt;br /&gt;
 &lt;br /&gt;
  var MyObject: TAncestor;&lt;br /&gt;
       ...&lt;br /&gt;
      MyObject := TDescendant.Create;&lt;br /&gt;
&lt;br /&gt;
==Propriétés de classes==&lt;br /&gt;
&lt;br /&gt;
Les propriétés de classes sont accessibles sans référence d&#039;objet. Les accesseurs de propriétés de classes doivent être déclarés comme méthodes &#039;&#039;&#039;statiques de classe&#039;&#039;&#039; ou &#039;&#039;&#039;champs classe&#039;&#039;&#039;. Une propriété de classe se déclare à l&#039;aide des mots-clés &#039;&#039;&#039;class property&#039;&#039;&#039;. Les propriétés de classes ne peuvent pas être publiées (&#039;&#039;&#039;published&#039;&#039;&#039;) et ne peut pas avoir de définition de valeur &#039;&#039;&#039;stored&#039;&#039;&#039; ou &#039;&#039;&#039;default&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
La déclaration de bloc &#039;&#039;&#039;class var&#039;&#039;&#039; vous permet d&#039;introduire un bloc de champs de classe statique dans une déclaration de classe. Tous les champs déclarés après &#039;&#039;&#039;class var&#039;&#039;&#039; ont des attributs de stockage statique. Un bloc &#039;&#039;&#039;class var&#039;&#039;&#039; se termine par :&lt;br /&gt;
&lt;br /&gt;
# Une autre déclaration &#039;&#039;&#039;class var&#039;&#039;&#039;&lt;br /&gt;
# Une [[Méthodes (Delphi)|déclaration de procédure ou fonction (c&#039;est-à-dire méthode)]] (y compris des procédures de classe et des fonctions de classe) &lt;br /&gt;
# Une déclaration de propriété (y compris des propriétés de classes)&lt;br /&gt;
# Une [[Méthodes (Delphi)|déclaration de constructeur ou de destructeur]]&lt;br /&gt;
# Un [[Classes et objets (Delphi)|spécificateur de portée de visibilité]] (&#039;&#039;&#039;public&#039;&#039;&#039;, &#039;&#039;&#039;private&#039;&#039;&#039;, &#039;&#039;&#039;protected&#039;&#039;&#039;, &#039;&#039;&#039;published&#039;&#039;&#039;, &#039;&#039;&#039;strict private&#039;&#039;&#039; et &#039;&#039;&#039;strict protected&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Par exemple :&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 type&lt;br /&gt;
    TMyClass = class&lt;br /&gt;
      strict private&lt;br /&gt;
        class var         // Remarquez que les champs doivent être déclarés comme champs de classe&lt;br /&gt;
           FRed: Integer;&lt;br /&gt;
           FGreen: Integer;&lt;br /&gt;
           FBlue: Integer;&lt;br /&gt;
        public             // termine le bloc class var.&lt;br /&gt;
           class property Red: Integer read FRed write FRed;&lt;br /&gt;
           class property Green: Integer read FGreen write FGreen;&lt;br /&gt;
           class property Blue: Integer read FBlue write FBlue;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
Vous pouvez accéder aux propriétés de classes ci-dessus avec le code :&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 TMyClass.Red := 0;&lt;br /&gt;
 TMyClass.Blue := 0;&lt;br /&gt;
 TMyClass.Green := 0;&lt;br /&gt;
&lt;br /&gt;
==Voir aussi==&lt;br /&gt;
&lt;br /&gt;
*[[Classes et objets (Delphi)]]&lt;br /&gt;
*[[Champs (Delphi)]]&lt;br /&gt;
*[[Méthodes (Delphi)]]&lt;br /&gt;
*[[Evénements]]&lt;br /&gt;
*[[Déclarations de types imbriqués]]&lt;br /&gt;
*[[Références de classes]]&lt;br /&gt;
*[[Exceptions (Delphi)]]&lt;br /&gt;
*[[Surcharge d&#039;opérateurs (Delphi)]]&lt;br /&gt;
*[[Assistances de classes et d&#039;enregistrements (Delphi)]]&lt;br /&gt;
&lt;br /&gt;
{{DEFAULTSORT:Proprietes (Delphi)}}&lt;br /&gt;
[[Category:{{Delphi}}]]&lt;br /&gt;
[[Category:Guide du langage {{Delphi}}]]&lt;br /&gt;
[[Category:AMMigrate]]&lt;br /&gt;
&lt;br /&gt;
[[en:Properties (Delphi)]]&lt;br /&gt;
[[de:Eigenschaften (Delphi)]]&lt;br /&gt;
[[ja:プロパティ]]&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/f/index.php?title=Comptage_automatique_des_r%C3%A9f%C3%A9rences_dans_les_compilateurs_mobiles_Delphi&amp;diff=213806</id>
		<title>Comptage automatique des références dans les compilateurs mobiles Delphi</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/f/index.php?title=Comptage_automatique_des_r%C3%A9f%C3%A9rences_dans_les_compilateurs_mobiles_Delphi&amp;diff=213806"/>
		<updated>2021-03-04T14:20:24Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos : Addded Templates&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Parent|Considérations Delphi pour les applications multi-périphériques}}&lt;br /&gt;
&lt;br /&gt;
Les utilisateurs de {{Delphi}} sont depuis longtemps familiers à la notion de comptage automatique de références (Automatic Reference Counting, ARC). Dans le passé, les compilateurs de bureau {{Delphi}} (DCC32, DCC64, DCCOSX) supportaient ARC pour les interfaces (introduit dans &#039;&#039;&#039;{{Delphi}} 3&#039;&#039;&#039;), les tableaux dynamiques et les chaînes (&#039;&#039;&#039;AnsiString&#039;&#039;&#039; a été introduit dans &#039;&#039;&#039;{{Delphi}} 2&#039;&#039;&#039;). A présent, les compilateurs mobiles {{Delphi}} introduisent le comptage automatique des références pour les classes. En conséquence, la notion de &#039;&#039;&#039;référence faible&#039;&#039;&#039; a également été introduite afin de gérer les &amp;quot;cycles&amp;quot;, avec une autre fonctionnalité : la &#039;&#039;&#039;Surcharge des opérateurs pour les classes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Pour obtenir une description détaillée du comptage automatique de références, voir &#039;&#039;&#039;[https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html Release Notes for ARC (Apple Computers)]&#039;&#039;&#039; (EN).&lt;br /&gt;
&lt;br /&gt;
==Comptage automatique des références==&lt;br /&gt;
&lt;br /&gt;
Le &#039;&#039;&#039;comptage automatique de références&#039;&#039;&#039; est une façon de gérer la durée de vie d&#039;un objet sans libérer l&#039;objet quand il n&#039;est plus nécessaire. Un bon exemple est une variable locale qui référence un objet qui sort de la portée. Ensuite, l&#039;objet est automatiquement détruit. Comme vu ci-dessus, Delphi prend déjà en charge le comptage de références pour les chaînes et les objets référencés par le biais de variables de type interface. Toutefois, ARC dans les compilateurs mobiles Delphi a une certaine souplesse permettant de résoudre des problèmes tels que les références circulaires qui sont difficiles à gérer avec les variables de type interface.&lt;br /&gt;
&lt;br /&gt;
Une autre notion introduite dans les nouveaux compilateurs mobiles {{Delphi}} est la &#039;&#039;&#039;référence faible&#039;&#039;&#039;. Celle-ci permet de résoudre des problèmes de références circulaires.&lt;br /&gt;
&lt;br /&gt;
Le schéma de gestion de la mémoire est le même pour les apps compilées pour le périphérique iOS et le simulateur iOS :&lt;br /&gt;
&lt;br /&gt;
* DCCIOSARM (le compilateur {{Delphi}} pour le périphérique iOS 32 bits) dispose par défaut du comptage de références automatique.&lt;br /&gt;
* DCCIOSARM (le compilateur {{Delphi}} pour le périphérique iOS 64 bits) dispose par défaut du comptage de références automatique.&lt;br /&gt;
* DCCIOS32.EXE (le compilateur {{Delphi}} pour le simulateur iOS) active également ARC, bien que DCCIOS32 soit basé sur l&#039;architecture du compilateur traditionnel. &lt;br /&gt;
&lt;br /&gt;
{{Note| La seule zone dans laquelle ces nouvelles fonctionnalités apparaissent dans le code source de {{Variables|Product}} est à l&#039;intérieur des blocs conditionnels &amp;lt;code&amp;gt;{$AUTOREFCOUNT}&amp;lt;/code&amp;gt; au sein de la RTL (par exemple, dans &#039;&#039;System.pas&#039;&#039;).  }}&lt;br /&gt;
&lt;br /&gt;
==Changements du style de codage==&lt;br /&gt;
&lt;br /&gt;
Puisque les nouveaux compilateurs mobiles supportent le comptage automatique de références, le code peut être simplifié considérablement quand vous avez besoin de faire référence à des objets temporaires au sein d&#039;une méthode. La gestion de la mémoire est complètement ignorée :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.CreateOnly;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  MyObj.DoSomething;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;exemple ci-dessus, le destructeur de l&#039;objet est appelé quand le programme atteint l&#039;instruction &#039;&#039;&#039;end&#039;&#039;&#039;, c&#039;est-à-dire quand la variable &amp;lt;code&amp;gt;MyObj&amp;lt;/code&amp;gt; sort de la portée.&lt;br /&gt;
&lt;br /&gt;
Il est également possible d&#039;arrêter l&#039;utilisation de l&#039;objet avant la fin de la méthode. Pour ce faire, définissez la variable sur &#039;&#039;&#039;nil&#039;&#039;&#039; :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.SetNil;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  MyObj.DoSomething (False); // True =&amp;gt; raise&lt;br /&gt;
  MyObj := nil;	&lt;br /&gt;
  // do something else&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dans ce cas, l&#039;objet est détruit avant la fin de la méthode, exactement comme nous définissons la variable sur &#039;&#039;&#039;nil&#039;&#039;&#039;. Dans le cas où la procédure &amp;lt;code&amp;gt;DoSomething&amp;lt;/code&amp;gt; déclenche une exception, l&#039;instruction d&#039;affectation &#039;&#039;&#039;nil&#039;&#039;&#039; sera ignorée. En fin de compte, quand la méthode est terminée, l&#039;objet est toujours détruit.&lt;br /&gt;
&lt;br /&gt;
Au fur et à mesure que le cycle de vie de l&#039;objet suit le flux du programme, vous pouvez interroger le compteur de références d&#039;un objet (seulement sur les plates-formes disposant du comptage de références) en utilisant la nouvelle propriété RefCount :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
public&lt;br /&gt;
    property RefCount: Integer read FRefCount;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note| L&#039;interrogation du compteur de références d&#039;un objet n&#039;est pas recommandée et en général, ne doit pas être utilisée. }}&lt;br /&gt;
&lt;br /&gt;
===La vitesse des opérations à blocage===&lt;br /&gt;
&lt;br /&gt;
Les opérations d&#039;incrémentation et de décrémentation du compteur de références d&#039;un objet sont accomplies en utilisant des opérations thread-safe afin que le membre d&#039;instance du compteur de références soit thread-safe. Cela signifie que la variable d&#039;instance du compteur de références est correctement &#039;&#039;&#039;délimitée en mémoire&#039;&#039;&#039; afin de garantir que tous les threads observent immédiatement le changement et ne peuvent pas modifier une valeur &#039;&#039;&#039;obsolète&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{{Note| Le mécanisme de comptage de références automatique ne protège pas des conditions de concurrence et des blocages. }}&lt;br /&gt;
&lt;br /&gt;
===ARC et la directive {$AUTOREFCOUNT}===&lt;br /&gt;
&lt;br /&gt;
Vous devez envisager l&#039;usage de la directive &amp;lt;code&amp;gt;{$IFDEF AUTOREFCOUNT}&amp;lt;/code&amp;gt; afin d&#039;obtenir le meilleur code pour les deux scénarios : ARC et le scénario traditionnel. &amp;lt;code&amp;gt;AUTOREFCOUNT&amp;lt;/code&amp;gt; définit le code qui utilise le comptage de références automatique, tel que le code pour les compilateurs mobiles {{Delphi}}. C&#039;est une directive importante, différente de &amp;lt;code&amp;gt;{$IFDEF NEXTGEN}&amp;lt;/code&amp;gt; (la directive qui définit les nouvelles fonctionnalités de langage des compilateurs mobiles).  &amp;lt;code&amp;gt;AUTOREFCOUNT&amp;lt;/code&amp;gt; pourrait être utile à l&#039;avenir, dans le cas où ARC est implémenté au-dessus des compilateurs de bureau {{Delphi}}.&lt;br /&gt;
&lt;br /&gt;
==Les méthodes [[lib_fr:System.TObject.Free|Free]] et [[lib_fr:System.TObject.DisposeOf|DisposeOf]] sous ARC==&lt;br /&gt;
&lt;br /&gt;
Pour les classes, les développeurs {{Delphi}} sont habitués à un modèle de codage différent, basé sur l&#039;appel de la méthode &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt;, protégé par un bloc &amp;lt;code&amp;gt;try-finally&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Par exemple :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.TryFinally;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  try&lt;br /&gt;
    MyObj.DoSomething;&lt;br /&gt;
  finally&lt;br /&gt;
    MyObj.Free;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Avec les compilateurs de bureau {{Delphi}}, &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; est une méthode de &amp;lt;code&amp;gt;TObject&amp;lt;/code&amp;gt; qui vérifie si la référence en cours n&#039;est pas nil, et dans ce cas, appelle le destructeur &amp;lt;code&amp;gt;Destroy&amp;lt;/code&amp;gt; qui retire l&#039;objet de la mémoire après l&#039;exécution du code de destructeur adéquat.&lt;br /&gt;
&lt;br /&gt;
Dans le nouveau compilateur mobile {{Delphi}}, l&#039;appel de &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; est remplacé par l&#039;affectation de la variable à &#039;&#039;&#039;nil&#039;&#039;&#039;. Dans le cas où il s&#039;agissait de la dernière référence à l&#039;objet, il est toujours retiré de la mémoire après l&#039;appel de son destructeur. Pour les autres références, rien ne se passe (sauf une décrémentation du compteur de références).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
FreeAndNil (MyObj);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De la même façon, un appel comme celui ci-dessus définit l&#039;objet sur &#039;&#039;&#039;nil&#039;&#039;&#039; et déclenche de nouveau la destruction de l&#039;objet seulement si aucune autre variable n&#039;y fait référence. Dans la plupart des cas, c&#039;est correct, étant donné que vous ne voulez pas détruire les objets utilisés dans une autre partie d&#039;un programme. D&#039;autre part, il existe des scénarios où vous devez exécuter immédiatement le code du destructeur, indépendamment de la présence d&#039;autres références en suspens à l&#039;objet. Pour permettre aux développeurs de forcer l&#039;exécution du destructeur (sans libérer l&#039;objet réel de la mémoire), le nouveau compilateur introduit un modèle dispose :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
MyObject.DisposeOf;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cet appel exécute avec vigueur le code du destructeur, même avec des références en suspens existantes.  A ce stade, l&#039;objet est placé dans un état spécial, de telle sorte que le destructeur n&#039;est pas appelé de nouveau dans le cas d&#039;autres opérations de destruction ou quand le compteur de références atteint la valeur zéro et que la mémoire est réellement libérée. Cet état &#039;&#039;&#039;disposed&#039;&#039;&#039; (ou l&#039;état &#039;&#039;&#039;zombie&#039;&#039;&#039;) est assez significatif, et vous pouvez interroger un objet pour celui-ci en utilisant la propriété &amp;lt;code&amp;gt;[[lib_fr:System.TObject.Disposed|Disposed]]&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Comme mentionné plus tôt, les blocs &#039;&#039;&#039;try-finally&#039;&#039;&#039; classiques utilisés avec les compilateurs de bureau {{Delphi}} fonctionnent toujours correctement sous le nouveau compilateur, même s&#039;ils ne sont pas requis.&lt;br /&gt;
Toutefois, dans la plupart des cas, vous souhaiterez utiliser à la place le modèle &#039;&#039;&#039;dispose&#039;&#039;&#039; (à moins que vous ne vouliez recompiler le code pour les versions antérieures de {{Delphi}}).&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;exemple ci-dessous, l&#039;effet reste le même avec le compilateur classique, puisque &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; appelle Free. A la place, sur ARC, le code exécute le destructeur quand c&#039;est attendu (au même moment que le compilateur classique, mais la mémoire est gérée par le mécanisme ARC).&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  try&lt;br /&gt;
    MyObj.DoSomething;&lt;br /&gt;
  finally&lt;br /&gt;
    MyObj.DisposeOf;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note| Le stockage de l&#039;indicateur Disposed est un bit dans le champ &amp;lt;code&amp;gt;FRefCount&amp;lt;/code&amp;gt;, prenant en compte qu&#039;un objet a une limite de 2&amp;lt;sup&amp;gt;30&amp;lt;/sup&amp;gt; références.}}&lt;br /&gt;
&lt;br /&gt;
==Méthodes de construction et de destruction de TObject sous ARC==&lt;br /&gt;
&lt;br /&gt;
C&#039;est un résumé des méthodes de la classe &amp;lt;code&amp;gt;TObject&amp;lt;/code&amp;gt; relatives à la création et à la destruction.&lt;br /&gt;
&lt;br /&gt;
Une des façons de voir la différence entre &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; consiste à considérer l&#039;intention. Lors de l&#039;utilisation de &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt;, l&#039;intention est que l&#039;utilisateur nécessite que cette référence particulière soit détachée de l&#039;instance. Elle n&#039;implique aucune sorte de destruction ou de désallocation. En revanche, &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; est la manière pour le développeur de préciser explicitement l&#039;instance nécessaire pour &amp;quot;se libérer lui-même&amp;quot;. Elle n&#039;implique jamais nécessairement des désallocations, &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; effectue un &amp;quot;pré-nettoyage&amp;quot; explicite de l&#039;instance, qui dépend alors de la sémantique du compteur de références normal pour désallouer éventuellement l&#039;instance.&lt;br /&gt;
&lt;br /&gt;
==Références faibles==&lt;br /&gt;
&lt;br /&gt;
Un autre concept important pour ARC est le rôle des &#039;&#039;&#039;références faibles&#039;&#039;&#039; que vous pouvez créer en les identifiant avec l&#039;attribut &amp;lt;code&amp;gt;[weak]&amp;lt;/code&amp;gt;. Supposons que deux objets s&#039;auto-référencent en utilisant un champ, et qu&#039;une variable externe fait référence au premier. Le compteur de références du premier objet sera 2 (la variable externe, et le deuxième objet), tandis que le compteur de références du deuxième objet est 1. A présent, comme la variable externe sort de la portée, le compteur de références des deux objets reste à 1, et ils restent en mémoire indéfiniment.&lt;br /&gt;
&lt;br /&gt;
Pour résoudre ce type de situation, et de nombreux scénarios similaires, utilisez une référence faible pour rompre les références circulaires quand la dernière référence externe sort de la portée. &lt;br /&gt;
&lt;br /&gt;
Une &#039;&#039;&#039;référence faible&#039;&#039;&#039; est une référence à un objet qui n&#039;incrémente pas son compteur de références. Pour déclarer une référence faible, utilisez l&#039;attribut &amp;lt;code&amp;gt;[weak]&amp;lt;/code&amp;gt;, supporté par les compilateurs mobiles {{Delphi}}. &lt;br /&gt;
&lt;br /&gt;
Etant donné le scénario précédent, si la référence depuis le deuxième objet de retour vers le premier est faible, les deux objets sont détruits quand la variable externe sort de la portée. Voici un exemple de cette situation :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TMyComplexClass = class;&lt;br /&gt;
&lt;br /&gt;
  TMySimpleClass = class&lt;br /&gt;
  private&lt;br /&gt;
    [Weak] FOwnedBy: TMyComplexClass;&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create();&lt;br /&gt;
    destructor Destroy (); override;&lt;br /&gt;
    procedure DoSomething(bRaise: Boolean = False);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TMyComplexClass = class&lt;br /&gt;
  private&lt;br /&gt;
    fSimple: TMySimpleClass;&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create();&lt;br /&gt;
    destructor Destroy (); override;&lt;br /&gt;
    class procedure CreateOnly;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dans l&#039;extrait de code suivant, le constructeur de la classe complexe crée un objet de l&#039;autre classe :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
constructor TMyComplexClass.Create;&lt;br /&gt;
begin&lt;br /&gt;
  inherited Create;&lt;br /&gt;
  FSimple := TMySimpleClass.Create;&lt;br /&gt;
  FSimple.FOwnedBy := self;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
N&#039;oubliez pas que le champ &amp;lt;code&amp;gt;FOwnedBy&amp;lt;/code&amp;gt; est une référence faible ; il n&#039;augmente donc pas le compteur de références de l&#039;objet auquel il se réfère, dans ce cas l&#039;objet en cours (&#039;&#039;&#039;self&#039;&#039;&#039;). &lt;br /&gt;
&lt;br /&gt;
Etant donné cette structure de classe, nous pouvons écrire :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMyComplexClass.CreateOnly;&lt;br /&gt;
var&lt;br /&gt;
  MyComplex: TMyComplexClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyComplex := TMyComplexClass.Create;&lt;br /&gt;
  MyComplex.fSimple.DoSomething;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cela ne provoque aucune perte de mémoire, tant que la référence faible est utilisée correctement.&lt;br /&gt;
&lt;br /&gt;
Un autre exemple de l&#039;utilisation des références faibles est cet extrait de code de la RTL {{Delphi}} ; il fait partie de la déclaration de la classe [[lib_fr:System.Classes.TComponent|TComponent]] :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TComponent = class(TPersistent, IInterface,&lt;br /&gt;
    IInterfaceComponentReference)&lt;br /&gt;
  private&lt;br /&gt;
    [Weak] FOwner: TComponent;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si vous utilisez l&#039;attribut &#039;&#039;&#039;weak&#039;&#039;&#039; dans du code compilé par l&#039;un des compilateurs de bureau {{Delphi}}, l&#039;attribut est ignoré. Avec DCC32, vous devez vous assurer que vous ajoutez le code approprié dans le destructeur d&#039;un objet &amp;quot;propriétaire&amp;quot; pour libérer également l&#039;objet &amp;quot;possédé&amp;quot;. L&#039;appel de &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; est autorisé, bien que l&#039;effet soit différent dans les compilateurs mobiles {{Delphi}}. Le comportement est correct dans la plupart des circonstances.&lt;br /&gt;
&lt;br /&gt;
{{Note| Quand une instance a sa mémoire libérée, toutes les références &#039;&#039;&#039;[weak]&#039;&#039;&#039; actives sont définies sur &#039;&#039;&#039;nil&#039;&#039;&#039;. Comme une référence &#039;&#039;&#039;strong&#039;&#039;&#039; (normal), une variable &#039;&#039;&#039;[weak]&#039;&#039;&#039; peut seulement être &#039;&#039;&#039;nil&#039;&#039;&#039; ou référencer une instance valide. C&#039;est la raison principale pour laquelle une référence &#039;&#039;&#039;weak&#039;&#039;&#039; doit être assignée à une référence &#039;&#039;&#039;strong&#039;&#039;&#039; avant d&#039;être testée à &#039;&#039;&#039;nil&#039;&#039;&#039; et déréférencée. L&#039;affectation à une référence strong ne permet pas la libération prématurée de l&#039;instance.}}&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  O: TComponent;// a strong reference&lt;br /&gt;
begin&lt;br /&gt;
  O := FOwner;  // assigning a weak reference to a strong reference&lt;br /&gt;
  if O &amp;lt;&amp;gt; nil then&lt;br /&gt;
    O.&amp;lt;method&amp;gt;;// safe to dereference&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note| Vous pouvez seulement passer une variable &#039;&#039;&#039;[Weak]&#039;&#039;&#039; à un paramètre &#039;&#039;&#039;var&#039;&#039;&#039; ou &#039;&#039;&#039;out&#039;&#039;&#039; qui est également marqué comme &#039;&#039;&#039;[Weak]&#039;&#039;&#039;. Vous ne pouvez pas passer une référence &#039;&#039;&#039;strong&#039;&#039;&#039; régulière à un paramètre &#039;&#039;&#039;[Weak]&#039;&#039;&#039; &#039;&#039;&#039;var&#039;&#039;&#039; ou &#039;&#039;&#039;out&#039;&#039;&#039;. }}&lt;br /&gt;
&lt;br /&gt;
==L&#039;attribut Unsafe==&lt;br /&gt;
&lt;br /&gt;
Pour définir l&#039;attribut &#039;&#039;&#039;unsafe&#039;&#039;&#039; sur une fonction, utilisez cette syntaxe :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
[Result: Unsafe] function ReturnUnsafe: TObject;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Warning| &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; peut également être appliqué aux variables (membres) et aux paramètres. Il doit être seulement utilisé en dehors de l&#039;unité [[lib_fr:System|System]] dans de très rares situations. Il est considéré comme dangereux et son utilisation n&#039;est pas recommandée car aucun code associé au comptage de références n&#039;est généré.}}&lt;br /&gt;
&lt;br /&gt;
{{Note| Vous pouvez seulement passer une variable &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; à un paramètre &#039;&#039;&#039;var&#039;&#039;&#039; ou &#039;&#039;&#039;out&#039;&#039;&#039; qui est également marqué en tant que &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039;. Vous ne pouvez pas passer une référence &#039;&#039;&#039;strong&#039;&#039;&#039; régulière à un paramètre &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; &#039;&#039;&#039;var&#039;&#039;&#039; ou &#039;&#039;&#039;out&#039;&#039;&#039;. }}&lt;br /&gt;
==Surcharge des opérateurs pour les classes==&lt;br /&gt;
&lt;br /&gt;
Un très intéressant effet de bord de l&#039;utilisation du gestionnaire de mémoire ARC est que le compilateur peut gérer la durée de vie des objets temporaires renvoyés par les fonctions. Un cas spécifique est celui des objets temporaires renvoyés par les opérateurs. En fait, une nouvelle fonctionnalité du nouveau compilateur {{Delphi}} est la capacité à définir des opérateurs pour les classes, en utilisant une syntaxe et un modèle identiques à ceux ayant été disponibles pour les enregistrements depuis {{Delphi}} 2006.&lt;br /&gt;
&lt;br /&gt;
{{Note| L&#039;exemple de code suivant fonctionne avec les compilateurs mobiles {{Delphi}} (iOS), mais ne peut pas être compilé par les compilateurs de bureau {{Delphi}}. }}&lt;br /&gt;
&lt;br /&gt;
En tant qu&#039;exemple, considérez la simple classe suivante :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TNumber = class&lt;br /&gt;
  private&lt;br /&gt;
    FValue: Integer;&lt;br /&gt;
    procedure SetValue(const Value: Integer);&lt;br /&gt;
  public&lt;br /&gt;
    property Value: Integer read FValue write SetValue;&lt;br /&gt;
    constructor Create(Value: Integer);&lt;br /&gt;
    function ToString: string; override;&lt;br /&gt;
    class operator Add (a, b: TNumber): TNumber;&lt;br /&gt;
    class operator Implicit (n: TNumber): Integer;&lt;br /&gt;
    class operator Implicit(n: Integer): TNumber;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
constructor TNumber.Create(Value: Integer); begin&lt;br /&gt;
  inherited Create;&lt;br /&gt;
  Self.Value := Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Add(a, b: TNumber): TNumber; begin&lt;br /&gt;
  Result := TNumber.Create(a.Value + b.Value); end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Implicit (n: TNumber): Integer; begin&lt;br /&gt;
  Result := n.Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Implicit (n: Integer): TNumber; begin&lt;br /&gt;
  Result := TNumber.Create(n);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TNumber.SetValue(const Value: Integer); begin&lt;br /&gt;
  FValue := Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TNumber.ToString: string;&lt;br /&gt;
begin&lt;br /&gt;
  Result := IntToStr(Value);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure Test;&lt;br /&gt;
var&lt;br /&gt;
  a, b, c: TNumber;&lt;br /&gt;
begin&lt;br /&gt;
  a := 10;&lt;br /&gt;
  b := 20;&lt;br /&gt;
  c := a + b;&lt;br /&gt;
  Writeln(c.ToString);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Voir aussi==&lt;br /&gt;
&lt;br /&gt;
* [[Comptage automatique des références dans C++|Comptage automatique des références dans C++]]&lt;br /&gt;
* [[Développement d&#039;applications mobiles iOS|Développement d&#039;applications mobiles iOS]]&lt;br /&gt;
* [[DCCIOS32.EXE, le compilateur Delphi pour le simulateur iOS|DCCIOS32, le compilateur Delphi pour le simulateur iOS]]&lt;br /&gt;
* [[DCCIOSARM.EXE, le compilateur Delphi pour le périphérique iOS 32 bits|DCCIOSARM, le compilateur Delphi pour le périphérique iOS 32 bits]]&lt;br /&gt;
* [[DCCIOSARM64.EXE, le compilateur Delphi pour le périphérique iOS 64 bits|DCCIOSARM64, le compilateur Delphi pour le périphérique iOS 64 bits]]&lt;br /&gt;
* [https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html Release Notes for ARC (Apple Computers)] (EN)&lt;br /&gt;
* [[Utilisation du comptage de références|Utilisation du comptage de références]] (à propos des interfaces avec les compilateurs de bureau {{Delphi}})&lt;br /&gt;
&lt;br /&gt;
===Exemple de code===&lt;br /&gt;
&lt;br /&gt;
* [[samp_en:AutomaticReferenceCounting (Delphi)|AutomaticReferenceCounting ({{Delphi}})]]&lt;br /&gt;
&lt;br /&gt;
{{DEFAULTSORT:Comptage automatique des references dans les compilateurs mobiles Delphi}}&lt;br /&gt;
[[Category:Delphi]]&lt;br /&gt;
[[Category:XE4]]&lt;br /&gt;
[[Category:AMMigrate]]&lt;br /&gt;
&lt;br /&gt;
[[en:Automatic Reference Counting in Delphi Mobile Compilers]]&lt;br /&gt;
[[de:Automatische Referenzzählung in mobilen Delphi-Compilern]]&lt;br /&gt;
[[ja:Delphi モバイル コンパイラでの自動参照カウント]]&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/f/index.php?title=Mod%C3%A8le:PackageVersion&amp;diff=213789</id>
		<title>Modèle:PackageVersion</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/f/index.php?title=Mod%C3%A8le:PackageVersion&amp;diff=213789"/>
		<updated>2021-01-06T16:03:25Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos : RS-98408&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ #switch: {{RadstudioVersion|{{{1|{{RadstudioVersion}}}}}}}&lt;br /&gt;
| {{Version|XE7}} = 210&lt;br /&gt;
| {{Version|XE8}} = 220&lt;br /&gt;
| {{Version|Seattle}} = 230&lt;br /&gt;
| {{Version|Berlin}} = 240&lt;br /&gt;
| {{Version|Godzilla}} = 250&lt;br /&gt;
| {{Version|Rio}} = 260&lt;br /&gt;
}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[rad_fr:Versions du compilateur]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Modèles de données]]&lt;br /&gt;
[[Category:Modèles affectés par les changements de version majeure]]&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/f/index.php?title=Installation_d%27un_d%C3%A9bogueur_sur_une_machine_distante&amp;diff=213788</id>
		<title>Installation d&#039;un débogueur sur une machine distante</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/f/index.php?title=Installation_d%27un_d%C3%A9bogueur_sur_une_machine_distante&amp;diff=213788"/>
		<updated>2021-01-05T23:26:46Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos : /* Fichiers du débogueur distant installés sur la machine distante */ RS-98408&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Parent|Débogage distant - Procédures d&#039;ancien style|Débogage distant - Procédures d&#039;ancien style}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Remarque :&#039;&#039;&#039; Cette rubrique décrit comment installer le débogueur distant d&#039;ancien style.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Remarque :&#039;&#039;&#039; Bien que la solution de débogage distant d&#039;ancien style soit toujours prise en charge, nous vous recommandons d&#039;utiliser la nouvelle [[Débogage des applications multi-périphériques|solution de débogage distant et multi-périphérique]], qui vous permet d&#039;utiliser :&lt;br /&gt;
* Le débogueur intégré pour déboguer les applications distantes et multi-périphériques.&lt;br /&gt;
* Le [[Gestionnaire de déploiement|Gestionnaire de déploiement]] pour configurer et déployer vos applications.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Fichiers du débogueur distant installés sur la machine distante==&lt;br /&gt;
&lt;br /&gt;
Sur un PC Windows, les fichiers du débogueur distant sont installés par défaut dans {{Path|{{InstallPath}}\PAServer}} quand vous [[Installation de Platform Assistant sur Windows|installez &#039;&#039;&#039;Platform Assistant&#039;&#039;&#039;]], même si vous pouvez sélectionner un autre répertoire d&#039;installation. Toutefois, si vous n&#039;installez pas Platform Assistant, vous devez copier vous-même les fichiers suivants du débogueur distant sur la machine distante :&lt;br /&gt;
&lt;br /&gt;
* {{Path|rmtdbg{{PackageVersion}}.exe}}&lt;br /&gt;
* {{Path|bccide.dll}}&lt;br /&gt;
* {{Path|bordbk{{PackageVersion}}.dll}}&lt;br /&gt;
* {{Path|bordbk{{PackageVersion}}N.dll}}&lt;br /&gt;
* {{Path|comp32x.dll}}&lt;br /&gt;
* {{Path|dcc32{{PackageVersion}}.dll}} pour un système Win32&lt;br /&gt;
* {{Path|dcc64{{PackageVersion}}.dll}} pour un système Win64&lt;br /&gt;
* {{Path|dccosx{{PackageVersion}}.dll}} pour un système OS X&lt;br /&gt;
&lt;br /&gt;
:&lt;br /&gt;
::&#039;&#039;&#039;Remarque :&#039;&#039;&#039; Sur le PC de développement, les fichiers du débogueur distant sont livrés dans {{Path|{{InstallPath}}\bin}}.&lt;br /&gt;
&lt;br /&gt;
==Pour recenser le débogueur distant==&lt;br /&gt;
&lt;br /&gt;
Sur l&#039;ordinateur distant, recensez {{Path|bordbk{{PackageVersion}}.dll}} et {{Path|bordbk{{PackageVersion}}.dll}} en exécutant l&#039;utilitaire de recensement {{Path|regsvr32.exe}}.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Par exemple, sur Windows 7, entrez {{Code|C:\Windows\System32\regsvr32.exe bordbk{{PackageVersion}}.dll}} à l&#039;invite de commande, puis entrez :&lt;br /&gt;
&lt;br /&gt;
 C:\Windows\System32\regsvr32.exe bordbk{{PackageVersion}}.dll&lt;br /&gt;
&lt;br /&gt;
==Voir aussi==&lt;br /&gt;
&lt;br /&gt;
*[[Présentation du débogage distant|Présentation du débogage distant]]&lt;br /&gt;
*[[Etablissement d&#039;une connexion pour le débogage distant|Etablissement d&#039;une connexion pour le débogage distant]]&lt;br /&gt;
*[[Préparation des fichiers pour le débogage distant|Préparation des fichiers pour le débogage distant]]&lt;br /&gt;
* [[Débogage des applications multi-périphériques|Débogage des applications multi-périphériques (nouvelle solution de débogage distant)]]&lt;br /&gt;
&lt;br /&gt;
{{DEFAULTSORT:Installation d&#039;un debogueur sur une machine distante}}&lt;br /&gt;
[[Category:Utilisation de RAD Studio]]&lt;br /&gt;
[[Category:Delphi]]&lt;br /&gt;
[[Category:C++]]&lt;br /&gt;
&lt;br /&gt;
[[en:Installing a Debugger on a Remote Machine]]&lt;br /&gt;
[[de:Debugger auf einem externen Computer installieren]]&lt;br /&gt;
[[ja:リモート マシンへデバッガをインストールする]]&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/f/index.php?title=Utilisation_d%27un_client_HTTP&amp;diff=213784</id>
		<title>Utilisation d&#039;un client HTTP</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/f/index.php?title=Utilisation_d%27un_client_HTTP&amp;diff=213784"/>
		<updated>2020-12-10T18:42:59Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos : /* Gestion de l&amp;#039;authentification d&amp;#039;accès de base HTTP */ RS-102658&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Parent|Utilisation de la RTL dans les applications multi-périphériques}}&lt;br /&gt;
&lt;br /&gt;
La RTL fournit deux composants que vous pouvez utiliser pour envoyer des requêtes HTTP aux serveurs et gérer leurs réponses :&lt;br /&gt;
&lt;br /&gt;
*  [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient|TNetHTTPClient]]&lt;br /&gt;
* [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest|TNetHTTPRequest]]&lt;br /&gt;
&lt;br /&gt;
: {{Note| Vous pouvez également utiliser une instance de [[lib_fr:System.Net.HttpClient.THTTPClient|THTTPClient]] pour gérer vos requêtes HTTP.}}&lt;br /&gt;
&lt;br /&gt;
==Configuration de votre application à la conception==&lt;br /&gt;
&lt;br /&gt;
===Création d&#039;un client HTTP===&lt;br /&gt;
&lt;br /&gt;
Pour créer un client HTTP permettant d&#039;envoyer une requête HTTP, déplacez un composant [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient|TNetHTTPClient]] de la &#039;&#039;&#039;[[Palette d&#039;outils|palette d&#039;outils]]&#039;&#039;&#039; sur une fiche ou un module de données de votre application. Le [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient|TNetHTTPClient]] ne nécessite aucune configuration initiale.&lt;br /&gt;
&lt;br /&gt;
===Création et configuration de requêtes HTTP===&lt;br /&gt;
&lt;br /&gt;
Vous avez également besoin de déposer un ou plusieurs composants [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest|TNetHTTPRequest]] sur votre fiche ou module de données.&lt;br /&gt;
&lt;br /&gt;
Dès que vous avez déposé votre nouveau composant requête HTTP, double-cliquez sur sa propriété [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.Client|Client]] dans &#039;&#039;&#039;[[Inspecteur d&#039;objets|l&#039;inspecteur d&#039;objets]]&#039;&#039;&#039; afin que sa valeur soit le composant client HTTP que vous avez déposé auparavant.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez utiliser n&#039;importe quel nombre de composants requête. Néanmoins, si vous devez envoyer plusieurs requêtes HTTP différentes, une meilleure approche consiste à utiliser un seul composant requête HTTP et à le reconfigurer à l&#039;exécution pour envoyer chaque requête.&lt;br /&gt;
&lt;br /&gt;
==Envoi d&#039;une requête et gestion de sa réponse==&lt;br /&gt;
&lt;br /&gt;
===Envoi d&#039;une requête HTTP===&lt;br /&gt;
&lt;br /&gt;
Pour envoyer une requête HTTP, vous devez spécifier au moins les éléments suivants :&lt;br /&gt;
&lt;br /&gt;
* Une [[Wikipedia:Hypertext Transfer Protocol#Request methods|méthode de requête HTTP (EN)]]&lt;br /&gt;
* Une URL de ressource&lt;br /&gt;
&lt;br /&gt;
La méthode de requête HTTP détermine l&#039;action que le serveur doit effectuer sur la ressource située à l&#039;URL spécifiée. Cette action peut concerner l&#039;envoi des données de la ressource ou la mise à jour de la ressource avec les données incluses dans votre requête.&lt;br /&gt;
&lt;br /&gt;
La façon dont vous envoyez une requête HTTP au moyen d&#039;un composant [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest|TNetHTTPRequest]] dépend de la méthode de requête HTTP que vous souhaitez utiliser.&lt;br /&gt;
&lt;br /&gt;
: {{Note| Les fonctions qui envoient une requête, [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.Execute|Execute]] ou les fonctions spécifiques à une méthode, sont toutes bloquantes. Ainsi, ces fonctions ne se terminent pas tant qu&#039;une réponse n&#039;a pas été fournie par le serveur. Voir [[#Suivi de la progression du téléchargement des données de la réponse|Suivi de la progression du téléchargement des données de la réponse]] ci-dessous.}}&lt;br /&gt;
&lt;br /&gt;
====Envoi d&#039;une requête HTTP en utilisant les méthodes de requête HTTP DELETE, GET, HEAD, OPTIONS et TRACE====&lt;br /&gt;
&lt;br /&gt;
Les méthodes de requête HTTP suivantes ne nécessitent pas de données en entrée autres que l&#039;URL de la ressource cible :&lt;br /&gt;
&lt;br /&gt;
*  [http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.7 DELETE (EN)]&lt;br /&gt;
*  [http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3 GET (EN)]&lt;br /&gt;
* [http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4 HEAD (EN)]&lt;br /&gt;
* [http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.2 OPTIONS (EN)]&lt;br /&gt;
* [http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.8 TRACE (EN)]&lt;br /&gt;
&lt;br /&gt;
Pour envoyer une requête HTTP en utilisant l&#039;une de ces méthodes de requête HTTP, configurez d&#039;abord votre requête à la conception :&lt;br /&gt;
&lt;br /&gt;
# Configurez la propriété [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.URL|URL]] avec l&#039;URL de la ressource cible.&lt;br /&gt;
# Configurez la propriété [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.MethodString|MethodString]] avec le nom de la méthode de requête HTTP que vous souhaitez utiliser.&lt;br /&gt;
#: {{Note| Les noms des méthodes de requête HTTP [http://tools.ietf.org/html/rfc7230 sont sensibles à la casse (EN)].}}&lt;br /&gt;
&lt;br /&gt;
Appelez ensuite &#039;&#039;&#039;[[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.Execute|Execute]]&#039;&#039;&#039; pour envoyer votre requête.&lt;br /&gt;
&lt;br /&gt;
====Envoi d&#039;une requête HTTP en utilisant les méthodes de requête HTTP MERGE, PATCH et PUT====&lt;br /&gt;
&lt;br /&gt;
En plus de l&#039;URL de la ressource cible, les méthodes de requête HTTP suivantes nécessitent des données en entrée :&lt;br /&gt;
&lt;br /&gt;
* [http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6 PUT (EN)]&lt;br /&gt;
* [http://tools.ietf.org/html/rfc5789 PATCH (EN)]&lt;br /&gt;
* [http://www.odata.org/documentation/odata-version-2-0/operations/#Operations MERGE (EN)]&lt;br /&gt;
&lt;br /&gt;
Pour envoyer une requête HTTP en utilisant l&#039;une de ces méthodes de requête HTTP, appelez sa fonction correspondante (voir le tableau ci-dessous). Dans votre appel, spécifiez l&#039;URL de la ressource cible en premier argument et une instance de [[lib_fr:System.Classes.TStream|TStream]] en second argument.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Méthode de requête HTTP&lt;br /&gt;
! Fonction TNetHTTPRequest&lt;br /&gt;
|-&lt;br /&gt;
| PUT&lt;br /&gt;
| [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.Put|Put]]&lt;br /&gt;
|-&lt;br /&gt;
| PATCH&lt;br /&gt;
| [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.Patch|Patch]]&lt;br /&gt;
|-&lt;br /&gt;
| MERGE&lt;br /&gt;
| [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.Merge|Merge]]&lt;br /&gt;
|-&lt;br /&gt;
| PATCH via PUT*&lt;br /&gt;
| [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.PatchAlternative|PatchAlternative]]&lt;br /&gt;
|-&lt;br /&gt;
| MERGE via PUT*&lt;br /&gt;
| [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.MergeAlternative|MergeAlternative]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt; Certains proxies HTTP ne prennent pas en charge les dernières méthodes de requête HTTP standard (telles que PATCH) ou les méthodes de requête HTTP non standard (telles que MERGE). Dans ces cas, vous pouvez établir un proxy entre les méthodes de requête HTTP et une autre méthode de requête HTTP. Pour cela, la requête inclut des en-têtes qui spécifient la méthode de requête HTTP prévue.&lt;br /&gt;
&lt;br /&gt;
====Envoi d&#039;une requête HTTP en utilisant la méthode de requête HTTP POST====&lt;br /&gt;
&lt;br /&gt;
En plus de l&#039;URL de la ressource cible, la méthode de requête HTTP [http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5 POST (EN)] nécessite des données en entrée.&lt;br /&gt;
&lt;br /&gt;
Pour envoyer une requête HTTP en utilisant la méthode de requête HTTP POST, appelez [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.Post|Post]]. Dans votre appel, vous devez spécifier l&#039;URL de la ressource cible en premier argument. Les autres arguments dépendent de la façon dont vous souhaitez fournir les données d&#039;entrée de votre requête :&lt;br /&gt;
&lt;br /&gt;
* Pour envoyer le contenu d&#039;un fichier local, spécifiez le chemin local d&#039;accès à ce fichier en second argument de votre appel.&lt;br /&gt;
* Pour envoyer le contenu d&#039;un flux, fournissez votre instance de [[lib_fr:System.Classes.TStream|TStream]] en second argument de votre appel.&lt;br /&gt;
* Pour envoyer les données d&#039;une fiche encodées en tant que [[Wikipedia:MIME#Multipart messages|message multi-partie MIME (EN)]] suivant le [http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.2 standard HTML 4 (EN)], fournissez votre instance de [[lib_fr:System.Net.Mime.TMultipartFormData|TMultipartFormData]] en second argument de votre appel.&lt;br /&gt;
* Pour envoyer le contenu d&#039;une liste de chaînes, fournissez votre instance de [[lib_fr:System.Classes.TStrings|TStrings]] en second argument de votre appel, et si vos chaînes ne sont pas encodées en UTF-8, fournissez une instance de [[lib_fr:System.SysUtils.TEncoding|TEncoding]] en quatrième argument. Par exemple :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{Delphi}} :&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
NetHTTPRequest1.Post(&#039;http://www.example.com/rest/items&#039;, String1, nil, TEncoding.Default);&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;C++ :&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
NetHTTPRequest1-&amp;gt;Post(&amp;quot;http://www.example.com/rest/items&amp;quot;, String1, NULL, TEncoding::Default);&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Gestion d&#039;une réponse HTTP===&lt;br /&gt;
&lt;br /&gt;
Lorsque le serveur cible envoie une réponse à votre requête, l&#039;événement [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.OnRequestCompleted|OnRequestCompleted]] de votre composant requête HTTP se produit. Définissez un [[Gestionnaires d&#039;événement|gestionnaire d&#039;événement]] pour cet événement afin de lire les données provenant de la réponse du serveur. En cas d&#039;erreur pendant votre requête, l&#039;événement [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.OnRequestError|OnRequestError]] de votre composant requête HTTP se produit à la place.&lt;br /&gt;
&lt;br /&gt;
Le gestionnaire d&#039;événement de [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.OnRequestCompleted|OnRequestCompleted]] reçoit deux paramètres :&lt;br /&gt;
&lt;br /&gt;
* {{Arg|Sender}} est votre composant requête HTTP.&lt;br /&gt;
* {{Arg|AResponse}} est un objet qui implémente l&#039;interface [[lib_fr:System.Net.HttpClient.IHTTPResponse|IHTTPResponse]].&lt;br /&gt;
&lt;br /&gt;
Vous pouvez obtenir toutes les données de la réponse à partir de {{Arg|AResponse}} :&lt;br /&gt;
&lt;br /&gt;
* [[lib_fr:System.Net.HttpClient.IHTTPResponse.Version|Version]] indique la version du protocole HTTP que le serveur a utilisé.&lt;br /&gt;
* [[lib_fr:System.Net.HttpClient.IHTTPResponse.StatusCode|StatusCode]] contient le [[Wikipedia:List of HTTP status codes|code d&#039;état]] de la réponse, et [[lib_fr:System.Net.HttpClient.IHTTPResponse.StatusText|StatusText]] contient un texte compréhensible qui décrit l&#039;état, comme &amp;quot;OK&amp;quot; lorsque StatusCode est égal à 200.&lt;br /&gt;
* [[lib_fr:System.Net.URLClient.IURLResponse.ContentAsString|ContentAsString]] contient le corps de la réponse sous la forme d&#039;une chaîne. Vous pouvez également lire les données brutes de la réponse (y compris les en-têtes et le corps) en tant que flux de [[lib_fr:System.Net.URLClient.IURLResponse.ContentStream|ContentStream]].&lt;br /&gt;
* Vous pouvez lire les en-têtes de la réponse en utilisant les propriétés [[lib_fr:System.Net.URLClient.IURLResponse.Headers|Headers]], [[lib_fr:System.Net.HttpClient.IHTTPResponse.HeaderValue|HeaderValue]], [[lib_fr:System.Net.HttpClient.IHTTPResponse.ContainsHeader|ContainsHeader]], ou l&#039;une des propriétés d&#039;assistance suivantes qui fournissent la valeur des champs d&#039;en-tête de réponse HTTP communs : [[lib_fr:System.Net.HttpClient.IHTTPResponse.ContentCharSet|ContentCharSet]], [[lib_fr:System.Net.HttpClient.IHTTPResponse.ContentEncoding|ContentEncoding]], [[lib_fr:System.Net.HttpClient.IHTTPResponse.ContentLanguage|ContentLanguage]], [[lib_fr:System.Net.HttpClient.IHTTPResponse.ContentLength|ContentLength]], [[lib_fr:System.Net.HttpClient.IHTTPResponse.Date|Date]], [[lib_fr:System.Net.HttpClient.IHTTPResponse.LastModified|LastModified]], [[lib_fr:System.Net.URLClient.IURLResponse.MimeType|MimeType]].&lt;br /&gt;
* [[lib_fr:System.Net.HttpClient.IHTTPResponse.Cookies|Cookies]] contient les [[lib_fr:System.Net.HttpClient.TCookies|cookies]] de la réponse du serveur.&lt;br /&gt;
&lt;br /&gt;
==Gestion des cookies==&lt;br /&gt;
&lt;br /&gt;
La propriété [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient.AllowCookies|AllowCookies]] du composant client HTTP vous permet de spécifier si vous acceptez les cookies envoyés par le serveur dans la réponse.&lt;br /&gt;
Si [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient.AllowCookies|AllowCookies]] vaut {{True}}, le client HTTP enregistre les cookies reçus dans son [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient.CookieManager|CookieManager]].&lt;br /&gt;
&lt;br /&gt;
:{{Note| Le client HTTP ajoute toujours ses [[lib_fr:System.Net.HttpClient.TCookieManager.Cookies|cookies existants]] à la requête, quelle que soit la valeur de [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient.AllowCookies|AllowCookies]].}}&lt;br /&gt;
&lt;br /&gt;
==Gestion des redirections==&lt;br /&gt;
&lt;br /&gt;
Utilisez la propriété [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient.HandleRedirects|HandleRedirects]] pour contrôler la manière dont le composant client HTTP gère les redirections. La valeur par défaut vaut {{True}}, ce qui signifie que le composant client HTTP suit automatiquement les redirections.&lt;br /&gt;
&lt;br /&gt;
Utilisez la propriété [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient.MaxRedirects|MaxRedirects]] du composant client HTTP pour spécifier le nombre maximal de redirections que le composant peut suivre. Si le composant client HTTP atteint le nombre maximal de redirections spécifié, il déclenche une exception de type [[lib_fr:System.Net.HttpClient.ENetHTTPRequestException|ENetHTTPRequestException]].&lt;br /&gt;
&lt;br /&gt;
==Gestion du téléchargement des données de réponse==&lt;br /&gt;
&lt;br /&gt;
Au fur et à mesure que votre client HTTP télécharge la réponse à votre requête, l&#039;événement [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.OnReceiveData|OnReceiveData]] de votre objet requête HTTP se produit. Fournissez un gestionnaire d&#039;événement pour [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.OnReceiveData|OnReceiveData]] afin de suivre la progression du téléchargement des données de la réponse. Votre gestionnaire d&#039;événement reçoit les paramètres suivants :&lt;br /&gt;
&lt;br /&gt;
* {{Arg|Sender}}, qui est votre objet requête HTTP.&lt;br /&gt;
* {{Arg|AContentLength}}, qui est la longueur attendue des données de la réponse en nombre d&#039;octets.&lt;br /&gt;
* {{Arg|AReadCount}}, qui est le nombre d&#039;octets des données de la réponse que le client HTTP a téléchargé jusqu&#039;ici.&lt;br /&gt;
* {{Arg|Abort}}, qui est le paramètre booléen qui vous permet d&#039;annuler le téléchargement.&lt;br /&gt;
&lt;br /&gt;
Lorsque le téléchargement est terminé, [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.OnReceiveData|OnReceiveData]] se produit pour la dernière fois, et les valeurs de {{Arg|AContentLength}} et {{Arg|AReadCount}} sont identiques. [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.OnRequestCompleted|OnRequestCompleted]] se produit peu de temps après.&lt;br /&gt;
&lt;br /&gt;
===Suivi de la progression du téléchargement des données de la réponse===&lt;br /&gt;
&lt;br /&gt;
Pour suivre l&#039;évolution du téléchargement des données, utilisez les valeurs de {{Arg|AContentLength}} et {{Arg|AReadCount}} dans le gestionnaire d&#039;événement [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.OnReceiveData|OnReceiveData]].&lt;br /&gt;
Voici un exemple qui calcule le pourcentage de données téléchargées :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&#039;&#039;&#039;{{Delphi}} :&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
procedure TForm1.NetHTTPRequest1ReceiveData(const Sender: TObject;&lt;br /&gt;
AContentLength, AReadCount: Int64; var Abort: Boolean);&lt;br /&gt;
var&lt;br /&gt;
    percentageDownloaded:Double;&lt;br /&gt;
begin&lt;br /&gt;
    if AContentLength &amp;gt; 0 then&lt;br /&gt;
        percentageDownloaded :=  (AReadCount / AContentLength) * 100;&lt;br /&gt;
    else&lt;br /&gt;
        // the server did not provide the Content-Length header&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&#039;&#039;&#039;C++ :&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void __fastcall TForm1::NetHTTPRequest1ReceiveData(TObject * const Sender, __int64 AContentLength,&lt;br /&gt;
     __int64 AReadCount, bool &amp;amp;Abort)&lt;br /&gt;
{&lt;br /&gt;
    float percentageDownloaded;&lt;br /&gt;
    if (AContentLength &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
        percentageDownloaded = ((float)AReadCount / (float)AContentLength) * 100.f;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        // the server did not provide the Content-Length header&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Annulation du téléchargement des données de réponse===&lt;br /&gt;
&lt;br /&gt;
Pour annuler le téléchargement des données de réponse, changez la valeur de {{Arg|Abort}} en {{True}} dans le gestionnaire d&#039;événement [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.OnReceiveData|OnReceiveData]].&lt;br /&gt;
&lt;br /&gt;
==Envoi d&#039;une requête avec des en-têtes personnalisés==&lt;br /&gt;
&lt;br /&gt;
Le composant client HTTP et le composant requête HTTP vous permettent tous deux de définir des en-têtes personnalisés. &lt;br /&gt;
Les en-têtes personnalisés que vous pouvez spécifier sont les suivants :&lt;br /&gt;
&lt;br /&gt;
* Dans le composant client HTTP :&lt;br /&gt;
** [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient.Accept|Accept]]&lt;br /&gt;
** [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient.AcceptCharSet|AcceptCharSet]]&lt;br /&gt;
** [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient.AcceptEncoding|AcceptEncoding]]&lt;br /&gt;
** [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient.AcceptLanguage|AcceptLanguage]]&lt;br /&gt;
** [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient.ContentType|ContentType]]&lt;br /&gt;
** [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient.UserAgent|UserAgent]]&lt;br /&gt;
&lt;br /&gt;
* Dans le composant requête HTTP :&lt;br /&gt;
** [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.Accept|Accept]]&lt;br /&gt;
** [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.AcceptCharSet|AcceptCharSet]]&lt;br /&gt;
** [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.AcceptEncoding|AcceptEncoding]]&lt;br /&gt;
** [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.AcceptLanguage|AcceptLanguage]]&lt;br /&gt;
&lt;br /&gt;
Lorsque vous [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.Execute|exécutez]] une requête, la méthode [[lib_fr:System.Net.HttpClient.THTTPClient.Execute|THTTPClient.Execute]] du framework HTTP combine les en-têtes personnalisés à partir du composant client HTTP et du composant requête HTTP correspondant, puis ajoute ces en-têtes à la requête finale.&lt;br /&gt;
&lt;br /&gt;
==Gestion des connexions sécurisées==&lt;br /&gt;
&lt;br /&gt;
Le composant client HTTP prend en charge les connexions (HTTPS) sécurisées. Le framework HTTP gère automatiquement les demandes de certificat émises et déclenche l&#039;événement approprié si nécessaire :&lt;br /&gt;
&lt;br /&gt;
* [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.OnNeedClientCertificate|OnNeedClientCertificate]] lorsqu&#039;un serveur demande un certificat au client.&lt;br /&gt;
* [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.OnValidateServerCertificate|OnValidateServerCertificate]] si le serveur fournit un certificat non valide.&lt;br /&gt;
&lt;br /&gt;
Pour plus d&#039;informations sur la gestion des certificats, voir les sections [[Utilisation d&#039;un client HTTP#Gestion des certificats côté serveur|Gestion des certificats côté serveur]] et [[Utilisation d&#039;un client HTTP#Gestion des certificats côté client|Gestion des certificats côté client]].&lt;br /&gt;
&lt;br /&gt;
==Gestion de l&#039;authentification et des certificats==&lt;br /&gt;
&lt;br /&gt;
===Gestion de l&#039;authentification d&#039;accès de base HTTP===&lt;br /&gt;
&lt;br /&gt;
Lorsque vous envoyez une requête HTTP à un serveur qui requiert une [[Wikipedia:Basic access authentication|authentification d&#039;accès de base HTTP]], l&#039;événement [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient.OnAuthEvent|OnAuthEvent]] de votre objet client HTTP se produit. Pour soumettre vos informations d&#039;authentification d&#039;accès, fournissez un gestionnaire pour cet événement, et si la valeur du deuxième paramètre que le gestionnaire d&#039;événement reçoit ({{Arg|AnAuthTarget}}) est [[lib_fr:System.Net.URLClient.TAuthTargetType|TAuthTargetType.Server]], remplissez les variables {{Arg|AUserName}} et {{Arg|APassword}} avec votre nom d&#039;utilisateur et mot de passe pour l&#039;accès HTTP. Par exemple :&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{Delphi}} :&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
procedure TForm1.NetHTTPClient1AuthEvent(const Sender: TObject;&lt;br /&gt;
  AnAuthTarget: TAuthTargetType; const ARealm, AURL: string;&lt;br /&gt;
  var AUserName, APassword: string; var AbortAuth: Boolean;&lt;br /&gt;
  var Persistence: TAuthPersistenceType);&lt;br /&gt;
begin&lt;br /&gt;
  if AnAuthTarget = TAuthTargetType.Server then&lt;br /&gt;
  begin&lt;br /&gt;
    AUserName := &#039;MyUsername&#039;;&lt;br /&gt;
    APassword := &#039;1234&#039;;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;C++ :&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void __fastcall TForm1::NetHTTPClient1AuthEvent(TObject * const Sender,&lt;br /&gt;
  TAuthTargetType AnAuthTarget, const UnicodeString ARealm,&lt;br /&gt;
  const UnicodeString AURL, UnicodeString &amp;amp;AUserName, UnicodeString &amp;amp;APassword,&lt;br /&gt;
  bool &amp;amp;AbortAuth, TAuthPersistenceType &amp;amp;Persistence)&lt;br /&gt;
{&lt;br /&gt;
    if (AnAuthTarget == TAuthTargetType::Server) {&lt;br /&gt;
        AUserName = &amp;quot;MyUsername&amp;quot;;&lt;br /&gt;
        APassword = &amp;quot;1234&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Votre gestionnaire d&#039;événement reçoit également le domaine du serveur HTTP qui requiert une authentification ({{Arg|ARealm}}) et l&#039;URL cible de votre requête ({{Arg|AURL}}).&lt;br /&gt;
&lt;br /&gt;
Pour abandonner le processus d&#039;authentification HTTP, définissez la valeur de {{Arg|AbortAuth}} sur {{True}}.&lt;br /&gt;
&lt;br /&gt;
===Envoi d&#039;une requête derrière un proxy===&lt;br /&gt;
&lt;br /&gt;
Lorsque vous êtes derrière un [[Wikipedia:Proxy server|proxy]] qui requiert une authentification, vous pouvez définir les [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient.ProxySettings|paramètres proxy]] qui sont utilisés pour l&#039;authentification.&lt;br /&gt;
L&#039;exemple suivant montre comment procéder :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&#039;&#039;&#039;{{Delphi}} :&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
NetHTTPClient1.ProxySettings := TProxySettings.Create(&#039;192.168.1.1&#039;, 8080, &#039;MyUserName&#039;, &#039;MyPassword&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&#039;&#039;&#039;C++ :&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
TProxySettings  MyProxySettings(&amp;quot;192.168.1.1&amp;quot;, 8080, &amp;quot;MyUserName&amp;quot;, &amp;quot;MyPassword&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
NetHTTPClient1-&amp;gt;ProxySettings = MyProxySettings;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pour spécifier les paramètres de proxy, vous avez aussi la possibilité de fournir une chaîne URL qui inclut les informations associées au proxy :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&#039;&#039;&#039;{{Delphi}} :&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
NetHTTPClient1.ProxySettings := TProxySettings.Create(&#039;http://MyUserName:MyPassword@192.168.1.1:8080&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&#039;&#039;&#039;C++ :&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
TProxySettings  MyProxySettings(&amp;quot;http://MyUserName:MyPassword@192.168.1.1:8080&amp;quot;);&lt;br /&gt;
NetHTTPClient1-&amp;gt;ProxySettings = MyProxySettings;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sinon, vous pouvez spécifier les informations d&#039;identification pour l&#039;authentification proxy dans le gestionnaire d&#039;événement [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient.OnAuthEvent|OnAuthEvent]]. Consultez la section [[Utilisation d&#039;un client HTTP#Gestion de l&#039;authentification d&#039;accès de base HTTP|Gestion de l&#039;authentification d&#039;accès de base HTTP]] et vérifiez que la valeur de {{Code|AnAuthTarget}} vaut {{Const|TAuthTargetType.Proxy}} plutôt que {{Const|TAuthTargetType.Server}}.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Gestion des paramètres proxy avec un client HTTP&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Le tableau suivant explique la manière dont le client HTTP gère les paramètres proxy du système sur différentes plates-formes :&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
!Plate-forme&lt;br /&gt;
!Comportement&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
Windows&lt;br /&gt;
|&lt;br /&gt;
Le client HTTP utilise les paramètres proxy du système. Vous pouvez ignorer les paramètres proxy du système et vous pouvez également fournir d&#039;autres paramètres proxy pour le client HTTP.&lt;br /&gt;
&lt;br /&gt;
Pour ignorer les paramètres proxy du système, créez des paramètres proxy pour le client HTTP et spécifiez {{Code|&amp;lt;nowiki&amp;gt;http://direct&amp;lt;/nowiki&amp;gt;}} comme URL. &lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
OS X&lt;br /&gt;
|&lt;br /&gt;
Le client HTTP utilise toujours les paramètres proxy du système. Même si vous fournissez d&#039;autres paramètres proxy pour le client HTTP, celui-ci utilise les paramètres proxy du système.&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
iOS&lt;br /&gt;
|&lt;br /&gt;
Le client HTTP utilise toujours les paramètres proxy du système. Même si vous fournissez d&#039;autres paramètres proxy pour le client HTTP, celui-ci utilise les paramètres proxy du système.&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
Android&lt;br /&gt;
|&lt;br /&gt;
Le client HTTP utilise les paramètres proxy du système. Vous ne pouvez pas ignorer ces paramètres, mais vous pouvez fournir d&#039;autres paramètres proxy pour le client HTTP.&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
Linux&lt;br /&gt;
|&lt;br /&gt;
Le client HTTP utilise les paramètres proxy du système. Vous ne pouvez pas ignorer ces paramètres, mais vous pouvez fournir d&#039;autres paramètres proxy pour le client HTTP.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
:{{Note| Si le système ne spécifie aucun paramètre proxy (la connexion est directe), cela est également considéré comme un &amp;quot;réglage&amp;quot;. Par exemple, sur un système iOS ou OS X n&#039;ayant aucun paramètre proxy défini, vous ne pouvez pas fournir de paramètres proxy pour le client HTTP. Les paramètres que vous fournissez sont ignorés car les paramètres du système (réglage &amp;quot;aucun proxy&amp;quot;) sont utilisés.}}&lt;br /&gt;
&lt;br /&gt;
===Gestion du stockage des informations d&#039;identification utilisateur===&lt;br /&gt;
&lt;br /&gt;
[[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient|TNetHTTPClient]] vous permet de stocker les informations d&#039;identification pour l&#039;authentification HTTP ou proxy. Chaque [[lib_fr:System.Net.URLClient.TCredentialsStorage.TCredential|information d&#039;identification]] stockée peut contenir un nom d&#039;utilisateur, un mot de passe, un [[lib_fr:System.Net.URLClient.TAuthTargetType|type cible d&#039;authentification]], un domaine et une URL cible.&lt;br /&gt;
&lt;br /&gt;
L&#039;exemple suivant montre comment utiliser [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient.CredentialsStorage|TNetHTTPClient.CredentialsStorage]] pour enregistrer des informations d&#039;identification, puis les utiliser pour s&#039;authentifier lors de la connexion à un serveur HTTP nécessitant une authentification de base :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;Créez des informations d&#039;identification et ajoutez-les à votre stockage dédié :&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&#039;&#039;&#039;{{Delphi}} :&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
NetHTTPClient1.CredentialsStorage.AddCredentials(TCredentialsStorage.TCredential.Create(TAuthTargetType.Server, &#039;&#039;, &#039;&#039;, &#039;MyUserName&#039;, &#039;MyPassword&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&#039;&#039;&#039;C++ :&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
TCredentialsStorage::TCredential *MyCredential = new TCredentialsStorage::TCredential(TAuthTargetType::Server, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;MyUserName&amp;quot;, &amp;quot;MyPassword&amp;quot;);&lt;br /&gt;
NetHTTPClient1-&amp;gt;CredentialsStorage-&amp;gt;AddCredential(*MyCredential);&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Utilisez les informations d&#039;identification enregistrées.&lt;br /&gt;
&lt;br /&gt;
Par exemple, vous pouvez écrire un gestionnaire d&#039;événement [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient.OnAuthEvent|OnAuthEvent]] dans lequel vous pouvez :&lt;br /&gt;
* Utiliser [[lib_fr:System.Net.URLClient.TCredentialsStorage.FindAccurateCredential|TCredentialsStorage.FindAccurateCredential]] pour rechercher des informations d&#039;identification correspondant au type d&#039;authentification nécessaire ({{Code|TAuthTargetType.Server}}).&lt;br /&gt;
* Utiliser le nom d&#039;utilisateur et le mot de passe correspondant aux informations d&#039;identification appropriées pour l&#039;authentification.&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&#039;&#039;&#039;{{Delphi}} :&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
procedure TForm1.NetHTTPClient1AuthEvent(const Sender: TObject;&lt;br /&gt;
  AnAuthTarget: TAuthTargetType; const ARealm, AURL: string; var AUserName,&lt;br /&gt;
  APassword: string; var AbortAuth: Boolean;&lt;br /&gt;
  var Persistence: TAuthPersistenceType);&lt;br /&gt;
var&lt;br /&gt;
    MyCredential: TCredentialsStorage.TCredential;&lt;br /&gt;
begin&lt;br /&gt;
    MyCredential := NetHTTPClient1.CredentialsStorage.FindAccurateCredential(AnAuthTarget, &#039;&#039;);&lt;br /&gt;
    AUserName := MyCredential.UserName;&lt;br /&gt;
    APassword := MyCredential.Password;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&#039;&#039;&#039;C++ :&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void __fastcall TForm2::NetHTTPClient1AuthEvent(TObject * const Sender, TAuthTargetType AnAuthTarget,&lt;br /&gt;
  const UnicodeString ARealm, const UnicodeString AURL,&lt;br /&gt;
  UnicodeString &amp;amp;AUserName, UnicodeString &amp;amp;APassword, bool &amp;amp;AbortAuth,&lt;br /&gt;
  TAuthPersistenceType &amp;amp;Persistence)&lt;br /&gt;
{&lt;br /&gt;
    TCredentialsStorage::TCredential MyCredential;&lt;br /&gt;
&lt;br /&gt;
    MyCredential = NetHTTPClient1-&amp;gt;CredentialsStorage-&amp;gt;FindAccurateCredential(AnAuthTarget, &amp;quot;&amp;quot;);&lt;br /&gt;
    AUserName = MyCredential.UserName;&lt;br /&gt;
    APassword = MyCredential.Password;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Gestion des certificats côté serveur===&lt;br /&gt;
&lt;br /&gt;
Si le serveur fournit un certificat SSL non valide, l&#039;événement [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.OnValidateServerCertificate|OnValidateServerCertificate]] se produit. Fournissez un gestionnaire d&#039;événement pour {{Code|OnValidateServerCertificate}} afin de vérifier le certificat serveur ({{Arg|Certificate}}) et déterminer si vous acceptez ou non ce dernier. Si vous acceptez le certificat serveur, définissez la valeur du paramètre {{Arg|Accept}} sur {{True}}.&lt;br /&gt;
&lt;br /&gt;
===Gestion des certificats côté client===&lt;br /&gt;
&lt;br /&gt;
Si le serveur requiert un certificat client, l&#039;événement [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.OnNeedClientCertificate|OnNeedClientCertificate]] se produit. Fournissez un gestionnaire d&#039;événement pour {{Code|OnNeedClientCertificate}} afin de vérifier votre liste de certificats client ({{Arg|ACertificateList}}) et déterminer le certificat que vous souhaitez envoyer au serveur. Pour envoyer un certificat de la liste, définissez la valeur de {{Arg|AnIndex}} sur l&#039;index du certificat cible dans {{Arg|ACertificateList}}.&lt;br /&gt;
&lt;br /&gt;
: {{Note| Si la méthode HTTP de la première requête à un serveur qui requiert un certificat côté client n&#039;est ni HEAD ni GET (c&#039;est donc POST), le code d&#039;état de la réponse du serveur est 413. Envoyez toujours une requête HEAD ou GET en premier. L&#039;utilisation d&#039;une requête HEAD est généralement un meilleur choix, puisque moins de données sont transférées.}}&lt;br /&gt;
&lt;br /&gt;
==Rendre les requêtes asynchrones==&lt;br /&gt;
&lt;br /&gt;
Les requêtes sont synchrones par défaut. Pendant une requête, l&#039;exécution de votre application s&#039;arrête quand vous lancez votre requête, et reprend la main seulement quand vous obtenez une réponse du serveur ou quand la requête dépasse le délai d&#039;attente.&lt;br /&gt;
&lt;br /&gt;
Si vous voulez rendre vos requêtes asynchrones, afin que les requêtes n&#039;arrêtent pas l&#039;exécution de votre application, vous devez activer la propriété [[lib_fr:System.Net.HttpClientComponent.TNetHTTPClient.Asynchronous|Asynchronous]] du composant client ou la propriété [[lib_fr:System.Net.HttpClientComponent.TNetHTTPRequest.Asynchronous|Asynchronous]] du composant requête, selon le composant utilisé pour effectuer votre requête.&lt;br /&gt;
&lt;br /&gt;
==Voir aussi==&lt;br /&gt;
&lt;br /&gt;
* [[lib_fr:System.Net.URLClient|System.Net.URLClient]]&lt;br /&gt;
* [[lib_fr:System.Net.HttpClient|System.Net.HttpClient]]&lt;br /&gt;
* [[lib_fr:System.Net.HttpClientComponent|System.Net.HttpClientComponent]]&lt;br /&gt;
&lt;br /&gt;
* [[Utilisation du tethering d&#039;app|Utilisation du tethering d&#039;app]]&lt;br /&gt;
* [[Utilisation du Bluetooth|Utilisation du Bluetooth]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Multi-périphérique]]&lt;br /&gt;
[[Category:AMMigrate]]&lt;br /&gt;
&lt;br /&gt;
[[en:Using an HTTP Client]]&lt;br /&gt;
[[de:Verwenden eines HTTP-Clients]]&lt;br /&gt;
[[ja:HTTP クライアントの使用]]&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
</feed>