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 :

Dériver de TApplication, impossible ?


Sujet :

Langage Delphi

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 149
    Points : 61
    Points
    61
    Par défaut Dériver de TApplication, impossible ?
    Bonjour,

    Voilà ma question, tout bête.

    En regardant la VCL je m'aperçois que pour une application standard (Windows avec GUI) l'instance globale "Application" était créé dans l'unité "Controls" via un appel à "Application := TApplication.Create(nil);" dans la méthode "InitControls".
    Oh désespoir cela réduirait-il à néant la possibilité de dériver "TApplication" pour par exemple créer des projets d'un type plus spécifique que "Application Windows avec GUI) directement depuis l'EDI Delphi et dont la variable globale ne serait pas de type "TApplication" mais "TXXXApplication" (comme pour les services ou composants du panneau de configuration) qui hériterait du "TApplication" défini dans "Forms".

    Pour cela il aurait juste fallu que Borland déclare une variable globale dans "Controls" qui soit du type 'class of TApplication' et d'instancier "Application" avec... Hors Delphi 2009 ne semble pas inclure de variable de ce type.

    Comment peut-on contourner cela ? Peut-être redéclarer un type dérivé de TApplication qui contienne l'instance globale "Application" en interne et qui redirige toutes les méthodes de base de TApplication en les appelant via "Application" ? Ya un moyen de faire ça propre et en assurant une compatibilité future (si jamais on ajoutait de nouvelles méthodes/propriétés à la classe "Application") ?

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 522
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 522
    Points : 25 052
    Points
    25 052
    Par défaut
    Si tu es en Delphi 2009, tu peux faire un ToolHelp non ? étendre une classe sans l'hériter !
    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

  3. #3
    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
    je ne vois pas trop pourquoi c'est pas possible de dériver un TApplication?

    l'objet TApplication est stocké dans un variable globale il me semble. il suffit de la remplacer par un dérivé. l'inconvenient c'est qu'il faut caster pour accéder au méthode de l'objet dérivé.

    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
     
    TMonApp = class(TApplication)
    public
     function ForTest: string;
    end;
     
    function MonApp: TMonApp;
     
    implementation
     
    function MonApp: TMonApp;
    begin
      Result := Application as TMonApp;
    end;
     
    function TMonApp.ForTest: string;
    begin
      ShowMessage('Salut');
    end;
     
    initialization
       Application.Free;
       Application := TMonApp.Create(nil);
    Akim Merabet

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 522
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 522
    Points : 25 052
    Points
    25 052
    Par défaut
    Tout à fait Kafëine, c'est juste un peu oser de faire le .Free !
    Il faut être sûr que la section initialization de Controls a bien lieu AVANT celle de l'unité de TMonApp
    Je pense qu'un mécansime comme la THintWindowClass aurait pu être valable avec une TApplicationClass ... et biensur en remplaçant dans le DPR, les "uses"

    C'est un peu crado ce qu'ils ont fait pour TApplication, déclaré dans Forms, instanciés dans Controls ...
    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

  5. #5
    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
    Citation Envoyé par ShaiLeTroll
    c'est juste un peu oser de faire le .Free !
    oui c'est vrai. je supposais que l'initialization des uses de la unit était appelé avant le initialization de la unite les contenants, d'ailleurs ça à l'air d'être ce comportement si on regarde le code source du projet.

    peut être que le compromis c'est d'instancier ce TMonApp dans le source du projet justement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    begin
      Application.Free; 
      Application := TMonApp.Create(nil);
      Application.Initialize;
      Application.MainFormOnTaskbar := True;
      Application.CreateForm(TfrmMain, frmMain);
      Application.Run;
    end.
    Akim Merabet

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 522
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 522
    Points : 25 052
    Points
    25 052
    Par défaut
    Tout à fait, cela fait les clauses initialization des uses puis celle de l'unité en cours, cela fait une sorte de récursivité finalement ...

    donc si tu mets "Controls" dans uMonApp, c'est normalement OK, non, ce qui me pose plus de problème c'est le Free\Create, voire si cela ne créé par des instances dans Window genre les Mutex et autre ...
    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

  7. #7
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    Citation Envoyé par ZZZzzz2 Voir le message
    Bonjour,

    Voilà ma question, tout bête.

    En regardant la VCL je m'aperçois que pour une application standard (Windows avec GUI) l'instance globale "Application" était créé dans l'unité "Controls" via un appel à "Application := TApplication.Create(nil);" dans la méthode "InitControls".
    Oh désespoir cela réduirait-il à néant la possibilité de dériver "TApplication" pour par exemple créer des projets d'un type plus spécifique que "Application Windows avec GUI) directement depuis l'EDI Delphi et dont la variable globale ne serait pas de type "TApplication" mais "TXXXApplication" (comme pour les services ou composants du panneau de configuration) qui hériterait du "TApplication" défini dans "Forms".

    Pour cela il aurait juste fallu que Borland déclare une variable globale dans "Controls" qui soit du type 'class of TApplication' et d'instancier "Application" avec... Hors Delphi 2009 ne semble pas inclure de variable de ce type.

    Comment peut-on contourner cela ? Peut-être redéclarer un type dérivé de TApplication qui contienne l'instance globale "Application" en interne et qui redirige toutes les méthodes de base de TApplication en les appelant via "Application" ? Ya un moyen de faire ça propre et en assurant une compatibilité future (si jamais on ajoutait de nouvelles méthodes/propriétés à la classe "Application") ?
    la question que je me pose est plutôt mais pourquoi donc voudrais-tu hériter de TApplication ?

    J'ai décidé de le faire dans LVCL et RemoteVCL (sur mon site), mais en fait c'est toute la VCL (en fait non, juste un petit bout) qui est réécrite ^^
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 522
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 522
    Points : 25 052
    Points
    25 052
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Tout à fait, cela fait les clauses initialization des uses puis celle de l'unité en cours, cela fait une sorte de récursivité finalement ...
    Je viens de tomber sur un cas retord !

    J'ai 5 unités

    MachinClasses, ChoseTypes, ChoseClasses, ChoseHeriteA, ChoseHeriteB

    ChoseTypes défini des énumérations
    ChoseClasse définie une classe abstraite TChoseClasse
    TChoseHeriteA et TChoseHeriteB dans leurs unités respectives surcharge TChoseClasse et ont ChoseTypes et MachinClasses dans leurs uses
    MachinClasses contient ChoseTypes dans ses uses
    ChoseClasse contient MachinClasses et ChoseType dans ses uses ...

    J'ai créé ChoseTypes pour un problème de référence circulaire des unités entre MachinClasses et ChoseClasses

    ChoseClasses, ChoseHeriteA, ChoseHeriteB ont une section Initialization, le premier instancie un singleton et les deux autres appel un Register pour s'identifier dans un Gestionnaire de Classe de Chose ...

    J'attends, en théorie, que les sections initialization soient ChoseClasses puis ChoseHeriteA ou ChoseHeriteB

    En pratique (bien connu les problèmes entre théorie et pratique ...), j'ai eu ChoseHeriteB, ChoseHeriteA puis ChoseClasses ... Aie

    Eh bien, un rien change tout dans ChoseHeriteA ou ChoseHeriteB

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    unit ChoseHeriteA 
     
    uses ChoseTypes, ChoseClasses, MachinClasses
    J'ai ce que j'attends en théorie

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    unit ChoseHeriteA 
     
    uses ChoseClasses, ChoseTypes, MachinClasses
    Ben, c'est ce qui vient avec la pratique, ...


    EDIT : Cela dépend aussi de l'Age du Capitaine !
    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

  9. #9
    Membre averti

    Homme Profil pro
    Inscrit en
    Octobre 2003
    Messages
    908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 908
    Points : 447
    Points
    447
    Par défaut
    Pourquoi ne pas se servir des Class Helper ?

  10. #10
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Je viens de tomber sur un cas retord !
    ...
    à vu de nez ChoseClasses ne fait pas référence à ChoseTypes, sinon tu n'aurais pas eu le problème

    Mais il est aussi très pratique de définir l'ordre des unités dans le DPR !
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  11. #11
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 522
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 522
    Points : 25 052
    Points
    25 052
    Par défaut
    Citation Envoyé par rvzip64 Voir le message
    Pourquoi ne pas se servir des Class Helper ?
    Class Helper, oui, c'est ce que j'entendais pas ToolHelp, d'étendre TApplication sans l'hériter ..., tu noteras rvzip64 que ZZZzzz2 n'est jamais revenu nous voir !
    Donc pour les Class Helper, il faut un Delphi récent, moi avec mon Delphi 7, ça n'existe pas !

    Citation Envoyé par Paul TOTH Voir le message
    Mais il est aussi très pratique de définir l'ordre des unités dans le DPR !
    Mais quelle bonne idée ! je l'avais oublié celui-là !
    Bon, j'ai essayé plusieurs combinaisons (en nettoyant les DCU ou construction complète), ils semblent que le reste tout dépendant de l'age du capitaine, ce qui est bien, c'est qu'au moins maintenant je n'ai plus que la théorie, je n'ai plus plus l'autre cas génant ... c'est au moins ça de gagner, même si ne plus être capable de reproduire une anomalie est fort génant ...

    EDIT : J'ai le phénomène, lorsque je modifie une unité, et que je compile simplement, cela conserve les links entre les DCU mais modifie les liens (donc surement la séquence des uses\initialization) avec cette unité fraichement modifiée ... ouf, cela ne peux pas se produire en PROD puisque l'on force une construction complète avec FinalBuilder ... interessant tout de même !



    Citation Envoyé par Paul TOTH Voir le message
    à vu de nez ChoseClasses ne fait pas référence à ChoseTypes, sinon tu n'aurais pas eu le problème

    ChoseClasses fait référence à ChoseTypes, une function retourne une valeur énuméré déclaré des ChoseTypes, l'appel est fait dans MachinClasses

    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
    unit MachinClasses;
     
    interface
     
    uses ChoseTypes;
     
      TMachin = class(TShaiDBPersistant)
      private
        function RemoteIdentification(out RemoteMachin: TMachin): Boolean;
      public
        property State: TChoseEnum;
      end;
     
     
    implementation
     
    uses
      ChoseClasses;
     
    {* -----------------------------------------------------------------------------
    La fonction RemoteIdentification recherche ...
    @param RemoteMachin Paramètre de Sortie,...
    @return Indique si machin a été Trouvé ...
    ------------------------------------------------------------------------------ }
    function TMachin.RemoteIdentification(out RemoteMachin: TMachin): Boolean;
    var
      FoundList: TObjectList;
    begin
       Result := False;
       FoundList := TObjectList.Create();
       try
         with TChoseManager.GetClass() do // fourni un TChose selon la config (TChoseHeriteA, TChoseHeriteB, ...)
           try
             case RemoteIdentification(Self, FoundList) of // TChose à une méthode abstraite RemoteIdentification
               irStrict :
                 begin
                   Result := True;
                   RemoteMachin := FoundList[0] as TMachin;
                   FoundList.Extract(RemoteMachin);
                 end;
     
               irFuzzy :
                 begin
                   Result := Select(Self, FoundList, RemoteMachin);
                 end;
     
               irError, irIncoherent : Result := False;
             end;
           except
             on E: EMachinError do
             begin
               Result := False;
               WriteDBLog(Format('Remote Identification : %s. [%s]', [E.Message, Name]), [wDBlError]);
             end;
           else
             raise;
           end;
       finally
         FoundList.Free();
       end;
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    unit ChoseClasses;
     
    interface
     
    uses ChoseTypes, MachinClasses
     
    type
      TChose = class(TObject)
      public
        class function RemoteIdentification(Machin: TMachin; FoundList: TObjectList): TChoseEnum; virtual; abstract;
        class function Select(Machin: TMachin; FoundList: TObjectList; out SelectedMachin: TMachin): Boolean;
      end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    unit ChoseTypes;
     
    interface
     
    type
      TChoseEnum = (irStrict, irFuzzy, irError, irIncoherent);
     
     
    implementation
     
    end.
    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
    unit ChoseHeriteA;
     
    interface
     
    uses ChoseTypes, ChoseClasses, MachinClasses;
     
    type
      TChoseHeriteA = class(TChose)
      public
        class function RemoteIdentification(Machin: TMachin; FoundList: TObjectList): TChoseEnum; override;
      end;
     
    implementation
     
    {* ----------------------------------------------------------------------------}
    class function TChoseHeriteA.RemoteIdentification(Machin: TMachin; FoundList: TObjectList): TChoseEnum;
    begin
    	bla bla bla 
    end;
    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

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 149
    Points : 61
    Points
    61
    Par défaut
    Désolé pour cette réponse très tardive j'étais (entre autres) occupé mais aussi en congés.
    L'idée d'hériter de 'TApplication' est simplement comme je l'avais dis de faire une classe englobant certains mécanismes d'une application plus spécifique qu'une simple application Windows GUI.
    En l'occurence nous developpons une suite applicative composée de plusieurs modules, chacun de ses modules fonctionnent sur la même base, nous voudrions donc avoir une classe 'TXXXApplication' dont une instance correspond à un module de cette suite. Ensuite on intégrerait un nouveau type de projet en Delphi qui correspondrait à un module...

    Comme je suis sous Delphi7 je n'ai pas la possibilité d'utilisé les classes Helper, je ne sais pas exactement de quoi il s'agit mais si je n'hérite pas cela me servirait-il de la même manière qu'une classe héritée ?

    Le simplement fait d'utiliser une métaclasse dans l'unité 'TControl' lors de l'instanciation de 'Application' aurait logiquement pu permettre la dérivation de 'TApplication', dommage...

    Nous avons trouvé une autre solution, moins belle qui consiste à instancier un objet 'TXXXCore' qui correspond au 'noyeau' de notre module, ce noyeau intègre les mécanismes de base de l'ensemble de nos modules. Cette instanciation se fait directement dans le DPR. Nous passerons prochainement à Delphi2009 mais je crois qu'on restera sur cette solution qui fonctionne bien.

    Merci encore pour vos réponses !



    Citation Envoyé par ShaiLeTroll Voir le message
    Class Helper, oui, c'est ce que j'entendais pas ToolHelp, d'étendre TApplication sans l'hériter ..., tu noteras rvzip64 que ZZZzzz2 n'est jamais revenu nous voir !
    Donc pour les Class Helper, il faut un Delphi récent, moi avec mon Delphi 7, ça n'existe pas !


    Mais quelle bonne idée ! je l'avais oublié celui-là !
    Bon, j'ai essayé plusieurs combinaisons (en nettoyant les DCU ou construction complète), ils semblent que le reste tout dépendant de l'age du capitaine, ce qui est bien, c'est qu'au moins maintenant je n'ai plus que la théorie, je n'ai plus plus l'autre cas génant ... c'est au moins ça de gagner, même si ne plus être capable de reproduire une anomalie est fort génant ...

    EDIT : J'ai le phénomène, lorsque je modifie une unité, et que je compile simplement, cela conserve les links entre les DCU mais modifie les liens (donc surement la séquence des uses\initialization) avec cette unité fraichement modifiée ... ouf, cela ne peux pas se produire en PROD puisque l'on force une construction complète avec FinalBuilder ... interessant tout de même !






    ChoseClasses fait référence à ChoseTypes, une function retourne une valeur énuméré déclaré des ChoseTypes, l'appel est fait dans MachinClasses

    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
    unit MachinClasses;
     
    interface
     
    uses ChoseTypes;
     
      TMachin = class(TShaiDBPersistant)
      private
        function RemoteIdentification(out RemoteMachin: TMachin): Boolean;
      public
        property State: TChoseEnum;
      end;
     
     
    implementation
     
    uses
      ChoseClasses;
     
    {* -----------------------------------------------------------------------------
    La fonction RemoteIdentification recherche ...
    @param RemoteMachin Paramètre de Sortie,...
    @return Indique si machin a été Trouvé ...
    ------------------------------------------------------------------------------ }
    function TMachin.RemoteIdentification(out RemoteMachin: TMachin): Boolean;
    var
      FoundList: TObjectList;
    begin
       Result := False;
       FoundList := TObjectList.Create();
       try
         with TChoseManager.GetClass() do // fourni un TChose selon la config (TChoseHeriteA, TChoseHeriteB, ...)
           try
             case RemoteIdentification(Self, FoundList) of // TChose à une méthode abstraite RemoteIdentification
               irStrict :
                 begin
                   Result := True;
                   RemoteMachin := FoundList[0] as TMachin;
                   FoundList.Extract(RemoteMachin);
                 end;
     
               irFuzzy :
                 begin
                   Result := Select(Self, FoundList, RemoteMachin);
                 end;
     
               irError, irIncoherent : Result := False;
             end;
           except
             on E: EMachinError do
             begin
               Result := False;
               WriteDBLog(Format('Remote Identification : %s. [%s]', [E.Message, Name]), [wDBlError]);
             end;
           else
             raise;
           end;
       finally
         FoundList.Free();
       end;
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    unit ChoseClasses;
     
    interface
     
    uses ChoseTypes, MachinClasses
     
    type
      TChose = class(TObject)
      public
        class function RemoteIdentification(Machin: TMachin; FoundList: TObjectList): TChoseEnum; virtual; abstract;
        class function Select(Machin: TMachin; FoundList: TObjectList; out SelectedMachin: TMachin): Boolean;
      end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    unit ChoseTypes;
     
    interface
     
    type
      TChoseEnum = (irStrict, irFuzzy, irError, irIncoherent);
     
     
    implementation
     
    end.
    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
    unit ChoseHeriteA;
     
    interface
     
    uses ChoseTypes, ChoseClasses, MachinClasses;
     
    type
      TChoseHeriteA = class(TChose)
      public
        class function RemoteIdentification(Machin: TMachin; FoundList: TObjectList): TChoseEnum; override;
      end;
     
    implementation
     
    {* ----------------------------------------------------------------------------}
    class function TChoseHeriteA.RemoteIdentification(Machin: TMachin; FoundList: TObjectList): TChoseEnum;
    begin
    	bla bla bla 
    end;

  13. #13
    Membre confirmé
    Avatar de gb_68
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 232
    Points : 546
    Points
    546
    Par défaut
    Bonjour,
    en effet la dérivation de TApplication ne semble pas avoir été prévue. Néanmoins il est possible de prendre en exemple la solution utilisée pour les "Application Service" (projet Delphi). Celles-ci définissent une variable globale Application de type TServiceApplication dans SvcMgr qui masque celle de Forms et est utilisé dans le Dpr.
    Citation Envoyé par ZZZzzz2 Voir le message
    Nous avons trouvé une autre solution, moins belle qui consiste à instancier un objet 'TXXXCore' qui correspond au 'noyeau' de notre module, ce noyeau intègre les mécanismes de base de l'ensemble de nos modules. Cette instanciation se fait directement dans le DPR.
    Remarque : les variables Applications ne sont pas instanciées dans le Dpr, mais dans leur module de déclaration. Il serait peut être plus simple d'instancier l'objet 'TXXXCore' dans l'unité commune qui serait partagé entre tous les projets. Le simple fait d'inclure cette unité commune dans une unité du projet (pas forcément le Dpr) entraine l'accès ET l'instanciation de cette variable.
    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
    //exemple dans SvcMgr
    var
      Application: TServiceApplication = nil;
    //[..]
    procedure InitApplication;
    begin
      Application := TServiceApplication.Create(nil);
    end;
     
    procedure DoneApplication;
    begin
      Application.Free;
      Application := nil;
    end;
     
    initialization
      InitApplication;
    finalization
      DoneApplication;
    end.

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 149
    Points : 61
    Points
    61
    Par défaut
    Ma spécialité : répondre le plus tard possible (il faut dire que maintenant j'ai une solution).

    Merci pour ta réponse, je me suis mal exprimé quand j'ai dit instanciation dans le dpr, en fait on a fait comme tu dis, on l'instancie dans l'unité de définition directement c'est plus simple (à l'initialisation et la destruction de l'unité). En fait c'est juste que son utilisation nécessite d'allrr modifier le dpr mais ce n'est pas gênant on le faisait déjà pour des mécanismes de traduction...


    Citation Envoyé par gb_68 Voir le message
    Bonjour,
    en effet la dérivation de TApplication ne semble pas avoir été prévue. Néanmoins il est possible de prendre en exemple la solution utilisée pour les "Application Service" (projet Delphi). Celles-ci définissent une variable globale Application de type TServiceApplication dans SvcMgr qui masque celle de Forms et est utilisé dans le Dpr.Remarque : les variables Applications ne sont pas instanciées dans le Dpr, mais dans leur module de déclaration. Il serait peut être plus simple d'instancier l'objet 'TXXXCore' dans l'unité commune qui serait partagé entre tous les projets. Le simple fait d'inclure cette unité commune dans une unité du projet (pas forcément le Dpr) entraine l'accès ET l'instanciation de cette variable.
    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
    //exemple dans SvcMgr
    var
      Application: TServiceApplication = nil;
    //[..]
    procedure InitApplication;
    begin
      Application := TServiceApplication.Create(nil);
    end;
     
    procedure DoneApplication;
    begin
      Application.Free;
      Application := nil;
    end;
     
    initialization
      InitApplication;
    finalization
      DoneApplication;
    end.

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

Discussions similaires

  1. Installation Drivers Impression Brother Impossible
    Par filos dans le forum Windows 7
    Réponses: 8
    Dernier message: 22/06/2013, 10h52
  2. Réponses: 5
    Dernier message: 09/02/2010, 02h02
  3. Installation drivers du moniteur impossible
    Par marc_60 dans le forum Installation
    Réponses: 2
    Dernier message: 14/04/2008, 10h20
  4. Impossible de charger le driver MySQL
    Par supernova dans le forum JOnAS
    Réponses: 4
    Dernier message: 04/04/2007, 19h01
  5. Installation impossible des drivers
    Par MrEddy dans le forum Matériel
    Réponses: 4
    Dernier message: 02/05/2004, 11h58

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