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 dynamique de procédure et fonction


Sujet :

Langage Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2004
    Messages
    696
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 696
    Par défaut Appel dynamique de procédure et fonction
    Bonjour,

    Comme le titre l'indique je souhaiterais appeler dynamiquement des procedure et des fonctions, un peu comme on fait avec des Dll (lors du chargement dynamique) sauf que là mes fonction et mes procedure sont dans mon exe.

    Je m'explique, j'ai un menu dynamique qui est constitué à partir d'un fichier texte (.inf) dont voici la structure :

    et je veux rajouter la procedure ou fonction appelé pour avoir kune structure du fichier .inf comme ci-dessous :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Nom_menu;Image_menue;Nom_procedure_menu
    Ainsi lorsque de la constitution de mon menu j''aurais, le nom du menu, l'image et la procédure (ou fonction) associé à ce menu.

    en résumé voici le pseudo code que je souhaite mettre en place :


    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
     
     
    1.  Lecture du fichier .inf
    2. création du menu
              2.1 Création bouton_1
                       2.1.1 Bouton_1.caption := Nom_menu
                       2.1.2 Bouton_1.glyph := Image_menue
                       2.1.3 Bouton_1.onClick :=  ChargerEtAppelerMAprocedure(' Nom_procedure_menu');
             2.2 Création bouton_2
                       2.2.1 Bouton_2.caption := Nom_menu
                       2.2.2 Bouton_2.glyph := Image_menue
                       2.2.3 Bouton_2.onClick :=  ChargerEtAppelerMAprocedure(' Nom_procedure_menu');
              2.3 Création bouton_3
              2.4 Création bouton_4
    ....
    PS la création du menu dynamque est aujourd'hui opérationnel le problème est qu'aujourd'hui la gestion du menu est comme ci-dessous :

    if Nom_menu = Calendrier then Affiche_calendrier
    else if Nom_menu = Messagerie then Affiche_calendrier

    ce qui n'est pas térrible et génant à gérer.


    j'ai pensé au code suivant, que je n'ai pas encore essayer, car je n'es pas DELPHI sur mon poste pour le moment, je ferais le test ce soir chez moi, par contre si vous avec des idées ou autre je suis preneur
    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
     
     
    procedure ChargerEtAppelerMAprocedure(NOM_PROCEDURE:String);
    var
      // Affiche_Fontionnalité est le nom de ma procedure dans mon exe
      MAprocedure: Affiche_Fontionnalité (Libelle: String);
    begin
     
      Somme := nil;
      //le Handle de l'exe
      If Handle = 0 then Exit;
     
      //Récupération de l'adresse de la fonction nommée NOM_PROCEDURE
      MAprocedure:= GetProcAddress(Handle, pAnsiChar(NOM_PROCEDURE));
     
      //Appel de la fonction si on a bien récupéré son adresse
      If Assigned(MAprocedure) then MAprocedure('');
    end;
    merci de votre aide.

    Cordialement
    Qays

  2. #2
    Membre Expert
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Par défaut
    J'avais bien pensé a une solution a base de GetProcAddress comme pour les Dlls en se basant sur le handle hInstance (qui pointe vers le handle du module courrant, donc l'exe).

    Mais d'une part, ca ne marche pas pour les methodes (OnClick requiere uen methode) et d'autre part, il faut exporter les procedures a charger. Ce qui n'est peut etre pas possible depuis l'exe et surtout pas franchement tres interessant !

    Donc je vois actuelement 3 solutions :
    1 - les RTTI
    2 - Creer fonction procedure avec un parametre TMenuItem et un parametre String (nom de l'evenement) et qui affecte apres comparaison de la claine le bon evenement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    If EvtName = 'Action1' Then MenuItem.OnClick := Self.action1;
    3 - passer par une Dll et un gestionaire OnClick unique. Mais la faut vouloir passer par les Dlls .. si c'ets interessant je detaillerais.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2004
    Messages
    696
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 696
    Par défaut
    Merci de cette réponse,

    en fait la solution 3 c'est ce que je fa

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2004
    Messages
    696
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 696
    Par défaut
    Merci de cette réponse,

    Pour la solution 2 : C'est ce que je fais aujourd'hui, le problème c'est que si je suis tributaire de l'orthographe de mes menues, en effet si pour une raison ou une autre le libellé change dans mon fichier .inf mais pas dans mon code alors le click uti sur le bouton ou menu seras "vide" (j'en est fait l'expérience), par contre si je réussie à mettre en place cette gestion (via fichier .inf) alors quelques soit le libellé de mon menu ce dernier sera toujours affecté a une procédure, donc pas de risque de bugg (orthographique)

    Pour la solution 3 : Concernant la Dll j'ai essayer mais je l'avoue ce n'est pas facile d'extraire l'ensemble de mes fonctionnalité:
    Agendas,Messagries,blocNotes,Stockage de doc en bdd, requeteur, gestion de comptes banquaires etc....



    Pour la solution 1: Les RTTI, je vais voir ce qui est possible de faire

    Merci

  5. #5
    Membre Expert
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Par défaut
    Et si ... plutot que de passer par une chaine tu ne passerais pas plutot par des ID (des codes actions) ?

  6. #6
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 491
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 491
    Par défaut
    salut

    je n'ai qu'un seul mots : MethodAdress

    @+ Phil

  7. #7
    Membre émérite
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Par défaut
    Pour ce problème, il me semble qu'il y a une solution simple, souple et conçue pour : les listes d'actions, composant TActionList.

    Dans un TActionList, on peut ajouter autant d'actions qu'on veut en mode conception, on peut même pour chacune définir une image et un Hint ! Ensuite peut retrouver une action à partir du nom, en utilisant une simple boucle qui ne changera jamais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    function  TUtilForm.FindAction(const AName : string) : TContainedAction;
    var I:Integer;
     begin
      Result := nil;
      with ActionList1 do // Ma liste d'actions
      for I := 0 to ActionCount-1 do
       if Actions[I].Name = AName then
        Result := Actions[I]
     end;
    Si on veut juste se servir de la liste d'action pour stocker les évènements, on utilisera ensuite des codes du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MenuAgenda.OnClick := FindAction('Agenda').OnExecute;
    Mais il sera plus astucieux de faire directement...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MenuAgenda.Action := FindAction('Agenda');
    ...les titres, Hints et images étant directement stockées dans la liste d'action, ce qui permet de mettre à jour automatiquement aussi bien les menus que les boutons de raccourci d'une seule instruction !

    C'est génial, les listes d'action. Depuis que j'ai découvert ça, je me force à les utiliser. On passe du temps au début, mais quel temps gagné quand on veut mettre à jour l'interface de son logiciel !

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2004
    Messages
    696
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 696
    Par défaut
    Super capJack je vais tenter dès ce soir de faire ce que tu propose

    Je vous donnerais des nouvelles dès demain
    Cordialement
    Qays

  9. #9
    Membre émérite
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Par défaut
    J'ajoute quelques informations : en plus du "Caption", du "Hint", et d'une image définie sous la forme d'un indice dans un TImageList associé à la liste d'actions, tu peux aussi associer des touches de raccourcis.

    Pour bien faire, à mon avis, il faudrait retoucher ton code, en séparant bien :

    1. la liste d'images (à priori non localisable)
    2. la liste d'actions (localisable)
    3. la liste d'associations menus/boutons <-> actions (fonctionnelle)


    Si tu tiens à tout sauvegarder, il faudrait à mon avis prévoir trois sauvegardes, ou trois parties dans une même sauvegarde.

    1. La liste d'images : pour commencer, stocke toutes tes images dans un TImageList. Dans un premier temps, si tu veux faire les choses par étape, tu affecteras cette liste à la propriété SubMenuImages de chaque sous-menu, avec une valeur ImageIndex, ce sera plus efficace que d'accéder à la propriété Bitmap, ce que je te soupçonne de faire. Ceci juste le temps de faire des essais. Si tu veux pouvoir changer les images, les sauvegarder ou les charger, opère sur le TImageList.

    2. La liste d'actions : ensuite, une fois définie ta liste d'actions, tu pourras effacer les propriétés SubMenuImages et ImageIndex de chaque élément du menu, et laisser la liste d'actions attribuer automatiquement les images via sa propriété Images, et la propriété ImageIndex de chaque action. Si tu n'envisages pas de localiser ton application, tu peux en rester là, sinon, il faudra écrire une routine de sauvegarde/chargement/modification des propriétés "Caption", "Hint" et "Shortcut" de chaque action. En général, les images ne changent pas, mais de toutes façon, elles seront définies par un index fixe qui ne devra pas être modifié. Mais on peut très bien sauvegarder cet indice, au cas où. Et, en cas de changement d'image pour un indice donné, c'est sur le TImageList qu'il faudra opérer. C'est déjà une grande modification par rapport au code du départ...

    3. Les associations : étape finale, attribution des actions aux menus et aux boutons de raccourcis, et là c'est royal : il n'y a qu'à sauvegarder le nom de l'action pour chaque item, et c'est tout !

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2004
    Messages
    696
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 696
    Par défaut
    A y est c'est OK:

    voila le code ça oeut servir:

    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
     
    //============================================================================//
    procedure TMENU_UTIL.ExecuteRoutine(Instance: TObject; Name: string);
    var
      Routine: TMethod;
      Execute: TExecute;
    begin
      Routine.Data := Pointer(Instance);
      // Returns the address of a published method.
      Routine.Code := Instance.MethodAddress(Name);
      if Routine.Code = nil then Exit;
      Execute := TExecute(Routine);
      Execute;
    end;
    //===================================//
    procedure TMENU_UTIL.ExecuteRoutine(FctName1: string;FctName2:string);
    var H: HModule;
        My_Procedure : procedure(Name_s:String);
    begin
      H := GetModuleHandle(nil);
      if H <> 0 then
      begin
        @My_Procedure := GetProcAddress(H, PChar(FctName1));
        if Assigned(My_Procedure) then My_Procedure(FctName2)
        Else ShowMessage('Fonction non trouvée !');
      End;
    end;
    Merci à tous de votre aide et conseils

    COrdialement

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Appeler dynamiquement des procédures stockées
    Par riadhhwajdii dans le forum PL/SQL
    Réponses: 18
    Dernier message: 23/09/2010, 11h45
  2. Appel dynamique de Fonction ou Procédure
    Par bepbep dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 05/02/2009, 13h18
  3. [Pro*C] Appel dynamique à une procédure stockée
    Par wedgeantilles dans le forum Interfaces de programmation
    Réponses: 3
    Dernier message: 22/10/2008, 09h19
  4. Appeler dynamiquement une procédure stockée
    Par Mark531 dans le forum Access
    Réponses: 1
    Dernier message: 05/09/2006, 17h49
  5. Réponses: 7
    Dernier message: 03/10/2005, 23h27

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