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

Contribuez Delphi Discussion :

Composant Tree non-visuel et génération HTML à partir du DFM


Sujet :

Contribuez Delphi

  1. #1
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    mars 2010
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : mars 2010
    Messages : 278
    Points : 143
    Points
    143
    Billets dans le blog
    1
    Par défaut Composant Tree non-visuel et génération HTML à partir du DFM
    J'ai cree un composant non-visuel gérant un arbre logique selon le modèle de TTreeView, mais sans dépendances VCL, sous forme d'une classe sans être dérivé d'un autre composant.

    Je l'ai nommé TTree. Un tel arbre est composé de noeuds sous forme d'un composant sous forme d'une classe non dérivée, nommé TNode.
    un TTree peut contenir 1 ou plusieurs noeuds de premiers niveau (racines ou root). Chaque noeud, racine ou pas, peut avoir des noeuds enfant (child nodes) et ainsi de suite. Il y a des méthodes pour naviguer dans cette structure.

    On peut aisément imaginer d'autres méthodes, mais il y a déjà un jeu suffisamment complet pour une première application, un peu comme un "proof-of-concept":
    c'est la génération d'une page HTML à partir d'un fichier DFM (en mode texte, mais la conversion d'un fichier en mode binaire est facile). Le résultat s'affiche dans un browser et reproduit l'image de la fenêtre Delphi.

    Ce convertisseur est implémenté sous forme d'un composant, également non visuel, non dérivé d'un autre objet. Je l'ai nommé TDFMtoHTML.

    L'ensemble de ces 3 objets (TNode, TTree et TDFMtoHTML), est contenu dans une seule unité Delphi. Le tout a été développé avec Dephi 6 Personal Edition, et le code HTML généré est testé et opérationnel avec Firefox, Edge et Opera, indifféremment. Le code HTML utilise du code CSS inline pour adapter les éléments HTML. Pas de JavaScript.

    Certes, pour le moment, seuls quelques objets visuels Delphi sont traités:
    TForm <html>
    TLabel <label...
    TPanel <fieldset...
    TGroupBox <fieldset... with <legend>
    TButton <button...
    TMemo <textarea...
    TTreeView <textaera... just a place holder
    Seules quelques propriétés des objets sont traités:
    Name
    Caption
    Top
    Left
    Width
    Height
    Actuellement, seule la police Arial est générée, mais la propriété Font.Name est reconnue, à titre d'exemple.

    Petite précision:
    Ce projet n'a en aucun cas l'ambition de devenir un générateur de page HTML plein et entier. ll m'a servi a tester ma structure arborescente créée à partir d'un DFM, et de l'utilisant ensuite de façon récursive de produire du HTML. Comme dit au début, c'est un "proof-of-concept".

    Le projet contient deux unités:
    - DFMtoHTML.pas avec les 3 objets
    - Unit1.pas contenant le programme principal utilisant ces 3 objets.

    Je joins une archive ZIP avec le projet complet y compris son exécutable. Il comporte dans une seule fenêtre, 4 panels:
    - affichage du fichier DFM dans un TMemo
    - affichage de l'abre logique TTree chargé dans un TTreeView
    - affichage du code HTML généré dans un TMemo
    - les boutons de commande correspondant à chaque phase (chargement DFM, construction de l'arbre, génération du HTML)

    Le code DFM par défaut est celui du propre programme de démo, mais un bouton permet de créer dynamiquement une TForm avec quelques objets, et un autre bouton permet de charger générer le DFM de cette TForm dynamique et de le charger.

    Voici à quoi ressemble le programme, ayant chargé le code DFM de sa propre fenêtre, ayant généré l'arbre puis le code HTML:
    Nom : aa1.png
Affichages : 123
Taille : 41,5 Ko

    Je serais heureux de connaître votre avis sur cette petite réalisation. Merci d'avance d'y jeter un coup d'oeil.
    Fichiers attachés Fichiers attachés

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

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

    Informations forums :
    Inscription : novembre 2002
    Messages : 8 512
    Points : 27 561
    Points
    27 561
    Par défaut
    c'est amusant, par contre je n'aurais pas du tout utilisé l'approche que tu as choisi

    Delphi propose avec TReader un lecteur de DFM complet, il suffit donc de créer de nouveaux objets non VCL pour charger le DFM facilement
    tu peux utiliser l'évènement OnFindComponentClass pour pointer sur tes propres classes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    type
      TButton = class(THtmlComponent)
       ...
      published
        property Caption;
       ...
      end;
    et tu ajoutes une méthode "ToHTML: string" qu'il suffit de surcharger à chaque fois que nécessaire.

    ça te donne une solution plus propre, plus facile à maintenir, et si le DFM contient un composant non supporté tu peux simplement le dire, l'ignorer, etc...

    à une époque lointaine j'avais fait ça pour une VCL light compatible Kylix
    http://tothpaul.free.fr/sources.php?lvcl.lvcl1

    un autre essai était de créer un RemoteVCL qui permet d'afficher un DFM sur une application et d'exécuter le code sur une autre en client/server
    http://tothpaul.free.fr/sources.php?dprtcp.rmtvcl

    ensuite, il est aussi possible d'utiliser Javascript pour parser le DFM directement et construire les objets HTML en Javascript directement dans le navigateur. En effet avec DataView il est tout à fait possible de décoder des données binaires en Javascript.
    d'ailleurs il devrait être possible de faire un RemoteVCL pour client web sur ce principe
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

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

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : juillet 2006
    Messages : 12 649
    Points : 22 613
    Points
    22 613
    Par défaut
    CreateNew ? ce n'est pas très standard, ce constructeur normalement c'est pour un hérité de TForm pour se créer sans lire le DFM
    le constructeur normalement c'est Create
    le destroy doit être marqué d'un override et non d'un overload;
    Dans une utilisation polymorphique, cela pourrait provoquer une fuite mémoire

    un petit projet qui me rappelle ce que j'avais en C++Builder XE en 2010 pour me mettre à niveau par rapport à ce que je savais faire en Delphi 7
    C'est toujours formateur de faire des listes & pointeurs, un peu de récursivité, à la différence était que j'étais parti sur un générateur de XML et JSON ... mon parseur, je ne l'ai jamais fini, il était limite à certaines syntaxes mais pas toutes.
    J'ai souvent codé des arbres pour jouer mais je ne crois jamais en avoir eu besoin en vrai, en dehors du IXMLNode ou d'un IJSONNode

    J'avais aussi voulu faire une petite DB indexé avec un arbre suite à cette petite classe écrite en vitesse pour le forum ... j'ai toujours eu du mal ensuite à le maintenir dans un fichier, je me demande comme MySQL par exemple maintient ses index BTree dans un fichier tout étant performant, tu es obligé de fragmenté ton arbre, c'est assez déroutant.


    RemoteVCL cela me fait penser à un IntraWeb qui convertissait aussi la DFM en HTML

    J'ai utilisé un concept similaire, un éditeur de variable permettait de créer une fenêtre en RunTime par l'utilisateur, le DFM était stocké en XML+DB (plusieurs en fait, cela séparait le Modèle, la Vue et une gestionnaire d'historisation des valeurs en plus des valeurs en cours dans une table), les XML étaient retransformé en DFM via un XSL ou pouvait être envoyé à un WS PHP ... d'ailleurs, au final, un générateur d'application en PHP4 avec toute ses méta-data dans des tables, lors de sa version en PHP5, tout était en JSON/XML avec une chier de JS ... la j'avais fait un Arbre de DataSet pour gérer des formulaires récursifs (problématique métier de la diffusion épidémiologique)
    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

  4. #4
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    mars 2010
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : mars 2010
    Messages : 278
    Points : 143
    Points
    143
    Billets dans le blog
    1
    Par défaut
    Merci beaucoup, pour tes commentaires, ShaiLeTroll ! Je vais explorer attentivement tous les liens que tu m'as donné.

    Par rapport à tes remarques techniques:
    CreateNew: j'utilise très souvent ce constructeur pour les classes que je crée avec 'type maclasse=class..." sans donner de classe à dériver. Mais je ne le fais jamais pour des classes dérivées de composants VCL. Mais cela me permet d'initialiser à ma guise les variables privées et d'éviter la notion de "owner" pour maclasse. A ce jour, je n'ai rencontré aucun problème avec ça. Mais en tout état de cause, je vais faire un essai avec Create...

    Destroy/override: c'est certainement une confusion de ma part. Je vais regarder et changer cela.

    Merci encore une fois !

    PS.
    J'ai remplacé overload par override sur mes 3 objets, pour la commande destructor. Résultat: violation de mémoire en cliquant sur le bouton de génération du code HTML. Et cela se produit lorsque j'essaie de déposer du code HTML dans la variable privée fHTML de l'objet TDFMtoHTML (c'est un TString). J'avoue que là, je ne comprends pas...

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

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : juillet 2006
    Messages : 12 649
    Points : 22 613
    Points
    22 613
    Par défaut
    Citation Envoyé par KlausGunther Voir le message
    Merci beaucoup, pour tes commentaires, ShaiLeTroll ! Je vais explorer attentivement tous les liens que tu m'as donné.!
    Je pense que les liens de Paul Toth sont bien plus intéressant et construit, je n'ai que rarement publié mes travaux, j'ai tendance à ne jamais finir ... priorité à mon vrai boulot

    Citation Envoyé par KlausGunther Voir le message
    CreateNew: j'utilise très souvent ce constructeur pour les classes que je crée avec 'type maclasse=class..." sans donner de classe à dériver. Mais je ne le fais jamais pour des classes dérivées de composants VCL. Mais cela me permet d'initialiser à ma guise les variables privées et d'éviter la notion de "owner" pour maclasse. A ce jour, je n'ai rencontré aucun problème avec ça. Mais en tout état de cause, je vais faire un essai avec Create...
    Tes classes héritent implicitement de TObject et de son constructeur par défaut Create, tu peux y aller sans risque
    Tient le constructeur d'un TStringList par exemple c'est juste Create (la TStringList fait parti de la RTL mais pas de la VCL)

    le Owner n'est introduit qu'à partir du constructeur virtuel du TComponent ... oh comme ce constructeur virtuel est utile pour le flux DFM mais qu'il peut être pénible pour l'héritage ...
    le CreateNew a été ajouté pour ne pas charger le DFM ... cela peut être très utile
    D'ailleurs, un collègue a eu bien des misères avec le CreateNew confondu avec un constructeur avec un paramètre entier en C++Builder qui supporte pas les constructeurs nommés
    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

  6. #6
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    mars 2010
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : mars 2010
    Messages : 278
    Points : 143
    Points
    143
    Billets dans le blog
    1
    Par défaut
    J'ai poursuivi mes investigations.

    J'ai remplacé les CreateNew par Create, et tout fonctionne parfaitement ! Merci pour l'info !

    Voici l' projet à l'état actuel, dans le ZIP en pièce jointe.
    Je n'ai pas pu remplacer OVERLOAD by OVERRIDE pour le destructor: j'obtiens des violations de mémoire, alors qu'en l'état, tout fonctionne bien...
    Fichiers attachés Fichiers attachés

  7. #7
    Membre à l'essai
    Inscrit en
    mars 2003
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : mars 2003
    Messages : 23
    Points : 10
    Points
    10
    Par défaut
    Je cherchais justement un petit programme pour transformer un dfm en HTML et je suis tombé sur le votre.
    Très sympa et exactement ce qu'il me fallait.
    Je l'ai un peu amélioré en rajoutant des composants (TComboBox, TEdit, TTabSheet, ...) et en simplifiant un peu le code.
    Le voici
    Fichiers attachés Fichiers attachés

  8. #8
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    mars 2010
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : mars 2010
    Messages : 278
    Points : 143
    Points
    143
    Billets dans le blog
    1
    Par défaut
    Merci beaucoup pour le retour !

    Ce petit projet fait partie d'un ensemble bien plus vaste, et je l'avais publié comme "proof-of-concept" et pour documenter un petit problème technique.
    Je suis content que ce code a pu être utile et je prends son évolution avec plaisir.

    EDIT

    Faut juste que je le réadapte à Delphi 6 PE...

Discussions similaires

  1. Génération des pages HTML à partir d'un programme.
    Par marcandre dans le forum Langage
    Réponses: 6
    Dernier message: 26/03/2007, 17h13
  2. Réponses: 6
    Dernier message: 12/09/2006, 17h31
  3. Creer un composant non visuel(Timer) dans une DLL
    Par hugobob dans le forum Composants VCL
    Réponses: 1
    Dernier message: 06/06/2006, 16h20
  4. Je recherche un composant Tree non visuel, structure mémoire
    Par bambino3996 dans le forum Composants VCL
    Réponses: 5
    Dernier message: 05/09/2005, 17h03
  5. Destructeur pour un composant non visuel
    Par sfpx dans le forum Composants VCL
    Réponses: 4
    Dernier message: 27/08/2005, 02h14

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