Maintenant je vais parler des composants qui sont inclus dans le package.
J'ai déjà défini un nouveau type de collection (attention, il ne descend pas du TCollection de base de Delphi). C'est la classe TComponentCollection, qui descend de TPersistent. Sa particularité est de contenir des composants sans icône (qui sont enregistrés dans l'IDE via la fonction RegisterNoIcon de Delphi), et qui sont quand même accessibles depuis la fiche, comme par exemple les TMenuItem.
Ce type de collection a une propriété Owner, de type TComponent. Le composant Owner d'une collection doit implémenter l'interface IComponentCollectionOwner, qui a une seule fonction permettant d'accéder à la collection proprement dite. Les composants qui sont des items de la collection doivent implémenter l'interface IComponentCollectionItem, qui permet de retrouver l'Owner de la collection dont ils font partie, ce qui implique qu'un composant ne peut pas être un item de 2 collections différentes, et qu'un composant ne peut pas être l'owner de plusieurs TComponentCollection.
J'ai défini un descendant de TComponent qui implémente déjà toutes les méthodes nécessaires pour un IComponentCollectionItem, c'est la classe TComponentCollectionItem. J'ai programmé un property editor pour gérer les TComponentCollection, qui crée une arborescence (en effet, rien n'empèche un TComponentCollectionitem de posséder lui-même sa propre collection de composants :D)
Lorsqu'on programme un server Web, il faut gérer l'aspect Multithreading de la connection. C'est à dire qu'à chaque fois qu'un nouveau client se connecte, un nouveau thread de connection est créé du côté du server. C'est assez problématique avec Delphi, car la VCL n'est pas "thread-safe"...
Pour pallier à ce (petit) défaut, j'ai décidé de créer un descendant de TDataModule qui contient les données de chaque connection au serveur, c'est la classe TServerDataModule. Chaque instance est créée avec Owner=nil, ce qui permet d'éviter les problèmes de synchronisation de threads, et détruite dans le thread qui l'a créée. Dans la partie initialization de l'unité qui définit le descendant de TServerDataModule, il faut enregistrer la classe descendante avec un appel de la fonction RegisterClass. Pour créer un nouveau type de TServerDataModule, il faut aller dans le menu File->New->Other... puis choisir dans la rubrique HTTP l'item "Server data module". Ensuite, une nouvelle fiche de TDataModule est créée pas Delphi, avec une propriété publiée de type THTTPFiles.
Le composant principal du package HTTPDistantAccess est le composant THTTPDistantAccess. Il a une propriété qui est: ServerDataModuleClass, de type string. Il faut lui affecter un nom de classe de descendant de TServerDataModule valide. Cette classe est instanciée à chaque fois que le server HTTP initialise une nouvelle session.
Pour réaliser un serveur web, il faut ajoutter des HTTPFiles dans la propriété HTTPFiles du THTTPServerModule. J'en ai défini pusieurs classes:
-THTMLDocument: crée un document html. Voir plus bas.
-THTTPDynamicGraphicFile: crée une image dynamiquement à chaque requête via un événement. Un autre événement sert à obtenir l'extension du graphique.
-THTTPStaticGraphicFile: crée une image statique dont la donnée est dans les resources du programme.
-THTTPDynamicFile: un document dynamique quelconque.
Le composant THTMLDocument est le plus important: c'est lui qui permet de faire des pages Web. Il publie une propriété HTMLObjects qui descend de TComponentCollection, et qui contient les objets qui apparaissent sur la page. Ces objets peuvent être de plusieurs types:
-THTMLRawCode: du code HTML brut, statique, stocké dans les resources du programme.
-THTMLDynamicRawCode: la même chose, mais le code HTML est généré dynamiquement via un événement.
-THTMLEdit: comme un TEDit, mais sur une page Web
-THTMLButton, THTMLCombobox, THTMLListBox, THTMLMemo...: des contrôles HTML standards
-THTMLGraphicObject: une image, avec une propriété HTTPGraphicFile qu'il faut relier à une THTTPGraphicFile comme défini plus haut.
-D'autres encore que j'oublie et à venir.
Le principe est le suivant: on fait coopérer du code Javascript du côté du client avec le code Delphi du côté du server, de façon à ce que les événements et les propriétés des contrôles de la page Web soient réacheminés du côté du server. Ainsi, lorsqu'on définit un événement OnClick pour un THTMLButton, l'événement est lancé sur le server chaque fois que le client clique sur le bouton. De plus, si par exemple il y a un THTMLEdit sur la page et que le client en a modifié le contenu, la propriété Text correspondante du server est mide à jour. Ainsi, lorsqu'on programme la page Web du côté du server, on programme de la même façon que si les contrôles étaient des contrôles standard Delphi. Puissant, non?
J'ai testé mon programme avec Internet Explorer et avec Netscape, ça a l'air de fonctionner à peu près. J'ai eu du mal au début car les 2 browser n'utilisent pas la même gestion des événements.
Voilà, c'est tout pour l'instant pour les explications. Le code est encore en version Bêta, je l'ai commencé il y a seulement 4 jours, et dès que j'ai le temps je le commente.
En attendant, toute remarque ou commentaire seront les bienvenus.
Là encore, les composants ont été écrits avec Delphi 7, je ne sais pas s'ils seront compatibles avec les versions antérieures de Delphi. Est-ce que quelqu'un peut me dire s'il a réussi à les installer et à les faire marcher? Merci!