IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

Appel des procédures


Sujet :

Langage Delphi

  1. #1
    Membre du Club
    Inscrit en
    Mai 2005
    Messages
    111
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 111
    Points : 49
    Points
    49
    Par défaut Appel des procédures
    Salut,
    Dans mon application j'ai des noms de procedures comme suit:
    procedure monprocedure01(memeparametre..);
    procedure monprocedure02(memeparametre..);
    procedure monprocedure03(memeparametre..);
    .
    .
    procedure monprocedure99(memeparametre..);

    comment les appellés selon leur numéro .
    et merci.

  2. #2
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Salut,
    issue de la prochaine FAQ Delphi, par Waskol :
    Un tableau de procédures ? Comment et pourquoi ?

    L'utilisation de l'instruction case ... of en Delphi, quoique pratique dans la plupart des cas de programmation peut parfois se révéler inappropriée lorsque le nombre de branchements devient trop grand :
    • Lourdeur du code
    • Vitesse d'exécution désastreuse.
    Ce cas peut parfois être rencontré lorsque l'on écrit par exemple :
    • un émulateur : on effectue une action particulière différente pour chaque instruction du microprocesseur. Dans ce cas, la vitesse d'exécution est primordiale.
    • un jeu d'aventure :
      • Chaque case d'une carte peut être un type de rencontre différente
      • Chaque objet possédé par le héros possède un effet différent lorsqu'il est utilisé, chaque arme une attaque particulière, chaque sortilège déclenche un effet particulier
    Dans ce cas c'est la clarté du code qui permettra le design d'un univers riche en contenu et rebondissements.

    Par exemple, ce type de code...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    procedure TForm1.UneActionADeterminer(Parametre:integer);
    begin
      ...
      case Parametre of
          0:MaProcedure0;
          1:MaProcedure1;
          2:MaProcedure2;
          3:MaProcedure3;
          4:MaProcedure4;
          5:MaProcedure5;
          .....
          203:MaProcedure203;
          //etc...
      end;
      ...
    end;
    ...gagnera en clarté et en célérité si nous pouvions le transformer en :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TForm1.UneActionADeterminer(Parametre:integer);
    begin
      ...
      MesProcedures[Parametre];      
      ...
    end;
    Nous venons de présenter ici le cas d'un tableau de procédures sans paramètre. Nous allons voir qu'il est tout aussi possible d'utiliser un tableau de fonctions ou bien encore d'utiliser des paramètres.

    Pour aboutir à ce résultat, nous devons :
    1. Définir un type de variable pouvant contenir un type générique de procédure ou de fonction avec ou sans paramètre (Variables procédurales) :
      Il s'agit de définir ici un type de variable un peu particulière destiné à recevoir une procédure ou une fonction. Ce genre de variable s'appelle une variable procédurale. La syntaxe pour déclarer ce type de variable est la suivante :
      <Nom du Type> = <procedure ou function>[(<paramètres>)[:<type de resultat>]] [of object;]
      (Nota : "of object" signifie que nos procédures ou fonctions seront définies dans une classe comme TForm1 par exemple : elles font partie d'un objet.)
      Ainsi aurons nous ce genre de déclarations pour des :[list:787f454628]
    2. Variables de type procedure :[list:787f454628]
    3. avec paramètres (c'est ce genre de déclaration qui est utilisé pour définir des variables de type évènement comme TNotifyEvent, TDrawItemEvent, etc..) :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      type
        TProcedureAvecParametres=procedure(a,b:integer;s:string) of object;
    4. sans paramètres :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      type
        TProcedureSimple=procedure of object;
    Variables de type function :
    Ecrire nos procédures ou fonctions :
    L'exemple suivant concerne des fonctions avec paramètres, définies dans une classe (notez le "of object")
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    type
     
    TOperationArithmetique=function(a,b:real):real of object;
     
    TForm1 = class(TForm)
        ...
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
        ...
        TableauDeFonctions:array[0..3] of TOperationArithmetique;
        function Addition(a,b:real):real;
        function Multiplication(a,b:real):real;
        function Division(a,b:real):real;
        function Soustraction(a,b:real):real;
        ...
      end;
    ...
    implementation
    ...
    function TForm1.Addition(a,b:real):real;
    begin
      result:=a+b;
    end;
     
    function TForm1.Multiplication(a,b:real):real;
    begin
      result:=a*b;
    end;
    Les fonctions sont des fonctions globales n'appartenant pas à une classe (disparition du "of object" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    type
     
    TOperationArithmetique=function(a,b:real):real;
     
    TForm1 = class(TForm)
        ...
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
        ...
        TableauDeFonctions:array[0..3] of TOperationArithmetique;
        ...
      end;
     
    function Addition(a,b:real):real;
    function Multiplication(a,b:real):real;
    function Division(a,b:real):real;
    function Soustraction(a,b:real):real;
    ...
    implementation
    ...
    function Addition(a,b:real):real;
    begin
      result:=a+b;
    end;
     
    function Multiplication(a,b:real):real;
    begin
      result:=a*b;
    end;
    ...
    Assigner une procédure à chaque élément du tableau :
    Dans cette partie de code, nous allons simplement remplir notre tableau aussi simplement que nous le ferions avec des variables simples comme des entiers ou des chaînes de caractères :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    procedure TForm1.InitialisationDuTableau
    begin
      TableauDeFonctions[0]:=Addition;
      TableauDeFonctions[1]:=Multiplication;
      ...
      //etc... 
    end;
    Utiliser notre tableau :
    • Avec des procédures sans paramètres :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      procedure TForm1.UneActionADeterminer(Parametre:integer);
      begin
        //si Parametre est compris entre la borne inférieure et la borne supérieure du tableau de procédures
        if ((Parametre>=low(TableauDeProcedures)) and (Parametre<=high(TableauDeProcedures)) then
        //si l'entrée du tableau contient effectivement quelque chose (une procédure)
        if Assigned(TableauDeProcedures[Parametre]) then
        //exécution de la procédure ad hoc
        TableauDeProcedures[Parametre];
      end;
    • Avec des fonctions acceptant des paramètres :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      procedure TForm1.Calcule(OperationChoisie:integer;NombreA,NombreB:real;var resultat:real);
      begin
         if ((OperationChoisie>=0) and (OperationChoisie<=3)) then
         if Assigned(TableauDeFonctions[OperationChoisie]) then
         resultat:=TableauDeFonctions[OperationChoisie](NombreA,NombreB);
      end;
    Un exemple complet :
    Dans un nouveau projet, nous avons placé un TButton sur notre fiche.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
    type
      //Définition d'un type de procedure simple
      TProcedureAffichage=procedure of object;
     
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
        TableauDeProcedures:array[0..2] of TProcedureAffichage;
        procedure AffichageShowMessage;
        procedure AffichageDansLaFiche;
        procedure AffichageBarreDeTitre;
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    { TForm1 }
     
    procedure TForm1.AffichageShowMessage;
    begin
      showmessage('Procedure n°1');
    end;
     
    procedure TForm1.AffichageDansLaFiche;
    begin
      canvas.font.Color:=random($ffffff);
      canvas.TextOut(10,10,'Procédure n°2');
    end;
     
    procedure TForm1.AffichageBarreDeTitre;
    var i:integer;
        oldcaption:string;
    begin
      oldcaption:=Caption;
      for i:=0 to 9 do
      begin
        caption:='Procedure n°3';
        sleep(200);
        caption:='';
        sleep(100);
      end;
      caption:=oldcaption;
    end;
     
    //Evènement OnClick du Bouton
    procedure TForm1.Button1Click(Sender: TObject);
    var i:integer;
    begin
      //choix aléatoire d'une procedure d'affichage
      i:=Random(3);
      if assigned(TableauDeProcedures[i]) then
      TableauDeProcedures[i];
    end;
     
    //Evènement OnCreate de la fiche
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      Randomize;
      TableauDeProcedures[0]:=AffichageShowMessage;
      TableauDeProcedures[1]:=AffichageDansLaFiche;
      TableauDeProcedures[2]:=AffichageBarreDeTitre;
    end;
     
    end.
    Précision sur les variables procédurales : pointeurs ou variables ?
    C'est un grand débat qui dépasse le cadre et l'objectif de cette simple FAQ. En effet, il est tout de même étonnant de constater que bien que ce type se gère comme une variable classique, c'est un type de variable à laquelle s'applique le @, le nil et le Assigned()des pointeurs. Si vous souhaitez approfondir le sujet, nous vous suggérons la lecture de la documentation de Delphi aux rubriques suivantes :
    • Assigned,fonction
    • Types procédure
    • Types procédure dans les instructions et les expressions
    Faites vos jeux !

  3. #3
    Membre du Club
    Inscrit en
    Mai 2005
    Messages
    111
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 111
    Points : 49
    Points
    49
    Par défaut
    Oui merci bien c'est trés intéréssant!!
    Juste une autre petite question: Si j'ai une centaine de fonction avec le meme nom avec un indice qui change dans le nom at ayant meme parametre est ce que je peux les appeller selon leur nom ?
    exemple:

    maprocedure1(...);
    maprocedure2(...);
    maprocedure3(...);
    maprocedure110(...);
    maprocedure130(...);

    AppellerSelonNom('maprocedure'+inttostr(i))(...);

  4. #4
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Dans ce cas là utilise une Stringlist et associe le pointeur de ta procédure dans le champ Objet ensuite tu recherches la chaîne correspondant à t procédure.
    Mais faire simple cela facilite la maintenance

Discussions similaires

  1. Comment appeler des API windows en C ?
    Par JuanLopez1966 dans le forum Windows
    Réponses: 6
    Dernier message: 22/12/2004, 10h34
  2. Réponses: 4
    Dernier message: 25/11/2004, 12h24
  3. [Oracle 9i + Portal] pb d'appel de proc. via le Web
    Par rebolon dans le forum Oracle
    Réponses: 5
    Dernier message: 19/08/2004, 16h29
  4. Appel à des fonctions incluses dans des DLL
    Par Greybird dans le forum Langage
    Réponses: 3
    Dernier message: 26/05/2003, 13h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo