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 :

"Partie" d'application chargée dynamiquement


Sujet :

Langage Delphi

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 74
    Points : 46
    Points
    46
    Par défaut "Partie" d'application chargée dynamiquement
    Bonjour à tous,

    Je cherche un moyen de rendre une partie de mon application dynamique. Je m'explique...

    Dans mon application je souhaiterai charger au démarrage une interface propre à un client particulier avec les fonctions et l'affichage qui lui sont propres.
    Je voudrai éviter de devoir inclure les parties de chaque client dans mon application.

    Peut-être une dll ? Un avis ou un lien ?

    Merci.

  2. #2
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    J'avais utilisé ce tuto pour faire un logiciel avec des plugins (bpl delphi) que je pouvais mettre en place comme bon me semblais
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

  3. #3
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 650
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 650
    Points : 5 197
    Points
    5 197
    Par défaut
    Je ne sais pas si j'ai bien compris la question alors voici comment je la comprends : tu cherches à masquer ou afficher certaines fonctionnalité selon le client et charger son interface personnalisée

    Pour l'interface personnalisée, tu peux stocker les informations dans un fichier XML, c'est assez simple à mettre en oeuvre. En plus si ma mémoire est bonne le tuto sur XML (disponible sur ce site) prend cet exemple.

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 74
    Points : 46
    Points
    46
    Par défaut
    @Rayek : Merci pour ce lien... Par contre ça à l'air bien tendu à mettre en place...

    @popo : Merci pour ton idée mais en plus de l'interface je souhaiterai pouvoir modifier les comportements de mes fonctions selon le profil chargé.

    Merci encore

  5. #5
    Membre éprouvé
    Avatar de octal
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    441
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 441
    Points : 957
    Points
    957
    Par défaut
    Avec Delphi tu peux utiliser la technique des BPL préconisée par Rayek, ou bien encore simplement les DLL chargées dynamiquement.

    Pour l'anecdote, j'ai connu une boite parisienne qui n'utilisait que des BPL, et les BPL étaient stockés carrément dans une base de données (firebird) mise à jour régulièrement par un outil annexe (tout les BPL avaient du coup le même nom). En fonction du profile, l'application faisait l'extraction du bon BPL correspondant au client et le chargait dynamiquement. Pire encore, pour plus de protection les PBL n'avait pas l'extension PBL, mais VXD (qu'elle idée de génie), et du coup en passant sous MacAffee v5.xx tt les VXD étaient scannés des milliers de fois et faisaient ralentir l'app comme pas possible
    http://www.pocketmt.com GLCD Font Creator home site.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 74
    Points : 46
    Points
    46
    Par défaut
    Je viens de me lancer dans la réalisation de BPL sauf que...

    Je n'arrive pas à saisir comment faire remonter un évènement du plugin vers l'application ?

    Une idée ? Un exemple ?

    Merci encore.

  7. #7
    Membre éclairé Avatar de Kaféine
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    569
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 569
    Points : 736
    Points
    736
    Par défaut
    Salut,

    Je pense que c'est plutôt ton application qui devrais envoyer des notifications au plugins, ou les plugins via une référence à IApplication donnée dans la méthode Initialize de IPlugin.

    Genre ça quoi:

    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
     
      TEventArgs = string;
     
      IAppNotifyEventListener = interface ['xxx']
        procedure OnAppNotify(const Args: TEventArgs);
      end;
     
      IApplication = interface ['xxx']
        procedure RaiseAppNotifyEvent(const Args: TEventArgs);
        procedure AddAppNotifyEventListener(const E: IAppNotifyEventListener);
        procedure RemoveAppNotifyEventListener(const E: IAppNotifyEventListener);
      end;
     
      IPlugin = interface ['xxx']
        procedure Initialize(const App: IApplication);
      end;
    Akim Merabet

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 74
    Points : 46
    Points
    46
    Par défaut
    J'ai enfin réussi à transmettre un évènement du plugin vers l'application en utilisant un callback...

    Pour ce que cela pourrait intéresser voici quelques bouts de codes.

    Dans la déclaration de l'interface
    Code Delphi : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      TClicCallback = procedure(Sender: TObject) stdcall;
    
      IPlugin = interface
        ['{FDA62CDF-8B1D-4DB3-8000-472482CE90CE}']
        function  GetComponent: TPanel;
        procedure ClicCallbackAdd(ClicCallback: TClicCallback);
    
        property Component: TPanel read GetComponent;
      end;
    La déclaration du callback dans l'application
    Code Delphi : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TFormPlugin.Button1Click(Sender: TObject);
    type
      TCreatePluginFunc = function: IPlugin; stdcall;
    var
      CreatePlugin: TCreatePluginFunc;
    begin
        ...
        FPlugin := CreatePlugin;
        FPlugin.ClicCallbackAdd(ClicCallback);
        ...
    end;
    La procédure de callback dans l'application
    Code Delphi : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    procedure ClicCallback(Sender: TObject) stdcall;
    ...
    implementation
    ...
    procedure ClicCallback(Sender: TObject);
    begin
      ShowMessage('clic');
    end;
    Et enfin côté plugin
    Code Delphi : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        FClicCallback: TClicCallback;
        procedure ClicCallbackAdd(ClicCallback: TClicCallback);
    ...
    implementation
    ...
    procedure TPluginBpl.ClicCallbackAdd(ClicCallback: TClicCallback);
    begin
      FClicCallback := ClicCallback;
    end;
    
    procedure TPluginBpl.PanelClick(Sender: TObject);
    begin
      FClicCallback(Sender);
    end;

    Merci pour votre aide

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 74
    Points : 46
    Points
    46
    Par défaut
    Résolu... Pas résolu... Résolu... Pas résolu... Résolu..?

    Je réouvre une nouvelle fois ce topic car j'ai encore besoin de vos lumières.
    Je n'arrive pas à afficher un panel créé dans un form du plugin sur un panel de l'application.
    Je m'explique... Je crée un form contenant un panel et je lui assigne comme parent un panel appartenant à l'application.
    Cela fonctionne si je crée le panel dynamiquement mais ne fonctionne plus si je dépose le panel sur mon form...

    J'ai joins l'application et 2 plugins pour vous montrer mon problème...
    Le plugin1 permet de charger le panel créé dynamiquement et le plugin2 celui créé dans le form...

    Merci pour vos réponses
    Fichiers attachés Fichiers attachés

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 74
    Points : 46
    Points
    46
    Par défaut
    Voici mon problème avec quelque morceaux de code...

    Dans le BPL chargé correctement je crée un panel dans le create du plugin
    Code Delphi : 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
      TPluginBpl = class(TInterfacedObject, ImxPlugin)
      private
        FPanel: TPanel;
        ...
      end;
    ...
    implementation
    ...
    constructor TPluginBpl.Create;
    begin
      inherited;
     
      FPanel := TPanel.Create(nil);
      ...
    end;
     
    procedure TPluginBpl.SetParent(Parent: TPanel);
    begin
      FPanel.ParentWindow := Parent.Handle;
      FPanel.Parent := TWinControl(Parent);
      FPanel.Align := alClient;
      FPanel.Visible := True;
    end;
    Dans le BPL dont je n'arrive pas à afficher le panel je crée un form contenant un panel
    Code Delphi : 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
      TPluginBpl2 = class(TInterfacedObject, ImxPlugin)
      private
        FForm: TFormPlugin;
        ...
      end;
    ...
    implementation
    ...
    constructor TPluginBpl2.Create;
    begin
      inherited;
     
      FForm := TFormPlugin.Create(nil);
      ...
    end;
     
    procedure TPluginBpl2.SetParent(Parent: TPanel);
    begin
      FForm.pnClient.ParentWindow := Parent.Handle;
      FForm.pnClient.Parent := TWinControl(Parent);
      FForm.pnClient.Align := alClient;
      FForm.pnClient.Visible := True;
    end;
    Qu'est ce qui cloche..?

    Merci

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 42
    Points : 51
    Points
    51
    Par défaut
    contrairement au premier plugin, le panel du 2ème plugin a déjà un parent
    lorsque tu affectes parentwindow...

    or dans "control.pas", setparentwindow commence par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      if (FParent = nil) and (FParentWindow <> Value) then
      begin
      ......
      end;
    il suffit donc de faire ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    procedure TPluginBpl.SetParent(Parent: TPanel);
    begin
      FPanel.Parent := nil;
      FPanel.ParentWindow := Parent.Handle;
      FPanel.Parent := TWinControl(Parent);
      FPanel.Align := alClient;
      FPanel.Visible := True;
    end;

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 74
    Points : 46
    Points
    46
    Par défaut
    Merci DenDemble j'aurai pu chercher longtemps avant de tomber dessus.

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 74
    Points : 46
    Points
    46
    Par défaut
    Je réouvre ce sujet car j'ai enfin trouvé une utilité à ce chargement dynamique.

    Mon problème est que le paquet créé ne contient pas les BPLs des autres paquets.
    C'est-à-dire qu'il m'est impossible de charger ce BPL dans une application sur une machine n'ayant pas Delphi.
    J'ai un message "Cette application n'a pas pu démarrer car rtl140.bpl est introuvable." (voir pièce jointe).

    J'ai cherché une option de compilation me permettant d'ajouter les bpl nécessaires à mon paquet mais pas trouvé...

    Une idée ?

    Merci.
    Images attachées Images attachées  

  14. #14
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 421
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 421
    Points : 24 776
    Points
    24 776
    Par défaut
    Option de Projet, Package, Construire avec Paquet d'Execution
    Je suis en C++Builder, semble que l'on ne puisse pas modifier l'option sur un projet Package
    la case est décochée mais cela contient une liste pour certains dont rtl et vcl

    Dans la liste, je rappele que l'on choisit les paquets qui devront être installés séparément, les autres utilisés par ton BPL seront intégrés dedans (donc augmentent le volume du projet)

    Je pense qu'il te faut déployer les packages Delphi, cela fait, c'est une pratique courante de déploiement (on déploiement dans System32 ou dans WOW, sinon dans le répertoire bin du logiciel)
    Ton executable et autre DLL pourront être compilé aussi en mode Package et partegeront ainsi les mêmes binaires !

    Sinon, tu aurais très bien pu partir sur une DLL surtout si tu utilises des Interfaces !

    Sinon pour tes parent, il a tout simplement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TPluginBpl.SetParent(AParent: TPanel);
    begin
      FPanel.Parent := AParent;
      FPanel.Align := alClient;
      FPanel.Visible := True;
    end;
    Attention, si tu utilises les BPL les classes TPanel de l'Exe et du Plugin sont bien les mêmes classes dont le code est dans les BPL

    Si tu n'utilises pas les BPL dans l'exe (un gros exe donc), les Classes TPanel de l'Exe et Plugin ne sont pas les mêmes en réalité, le code est dupliqué l'un dans l'Exe et l'autre dans les BPL utilisé par le Plugin
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 74
    Points : 46
    Points
    46
    Par défaut
    Qu'entends tu par déployer les packages Delphi ?
    Je suis censé copier tous les bpl Delphi en même temps que j'installe mon soft ?

    En effet la case est désactivée sur les packages... (cf pièce jointe).

    Si je transforme mon bpl en dll je n'aurai le problème de dépendance aux fichiers bpl externes ? Ma dll contiendra tout le code nécessaire à son exécution ?


    Beaucoup de questions je sais mais je profite de tes lumières pour comprendre.
    Merci beaucoup.
    Images attachées Images attachées  

  16. #16
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 421
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 421
    Points : 24 776
    Points
    24 776
    Par défaut
    Citation Envoyé par BobaL Voir le message
    Qu'entends tu par déployer les packages Delphi ?
    Je suis censé copier tous les bpl Delphi en même temps que j'installe mon soft ?
    Oui, si tu veux fonctionner avec des BPL, c'est un peu l'idée !

    Citation Envoyé par BobaL Voir le message
    Si je transforme mon bpl en dll je n'aurai le problème de dépendance aux fichiers bpl externes ? Ma dll contiendra tout le code nécessaire à son exécution ?
    Si tu n'utilises que des interfaces entre DLL et Exe, tu dois pouvoir te passer des BPL !

    Si tu coches "construire avec paquets d'execution" dans le deux, tu ne pourras pas partager* d'objet (class) mais des interfaces ça oui
    La DLL et l'EXE seront assez gros mais AUTONOME !

    Si tu coches "construire avec paquets d'execution", dans l'un deux, tu auras un binaire plus petit mais tu devras fournir les BPL dans un programme d'installation

    Si tu coches "construire avec paquets d'execution", dans les deux, tu pourras échanger des objets (et pas simplement des interfaces) et tu devrais fournir les BPL aussi !


    * en réalité, tu peux le bidouiller mais avec des risques
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

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

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