You are on page 1of 53

IntraWeb Tutorial - John COLIBRI.

 résumé : comment créer ses pages Web de façon visuelle en utilisant


IntraWeb et Delphi. En particulier l'accès aux bases de données (BDE,
Interbase, ADO) via des Edit ou des grilles, en mode affichage ou edition
 mots clé : IntraWeb - Développement de site Web - conception Rad -
Programmation Internet - grille modifiable
 logiciel utilisé : Windows XP personnel, Delphi 2006 Win32, Intraweb 8
 matériel utilisé : Pentium 2.800 Mhz, 512 Meg de mémoire, 250 Giga disque
dur
 champ d'application : Delphi 5, Delphi 6, Delphi 7, Delphi 8, Delphi 2005,
Delphi 2006, Delphi 2007
 niveau : développeur Delphi et Internet
 plan :
o Présentation IntraWeb
o La Première Applications IntraWeb
o Le fonctionnement Intraweb
o Quelques Techniques IntraWeb
o Commentaires sur IntraWeb
o Télécharger le code source Delphi

1 - Présentation IntraWeb
Intraweb est un jeu de composants Delphi permettant de développer des applications Web de
façon visuelle: le développeur choisit ses composants sur la Palette, les dépose sur la Forme,
modifie ses propriétés dans l'Inspecteur d'Objet, et effectue des traitements dans du code
Pascal (Delphi)

Depuis Delphi 2, Borland a fait de gros efforts pour nous offrir des composants permettant de
créer des sites Web. Ces composants (WebBroker, WebSnap) étaient cependant surtout
orientés vers la création de pages dynamiques par code. La partie construction visuelle de la
présentation de la page (mise en page, image, couleurs) n'était pas possible visuellement.

Personne n'a compris pourquoi une société capable de poser et ajuster quelques labels et
boutons sur une tForm Windows a choisi de ne pas permettre de poser quelques labels et
boutons sur une future page .HTML.

C'est donc ce vide immense qui a été comblé par Intraweb, et nous allons présenter
l'utilisation de cette technique.

Nous allons utiliser Delphi 2006, mais ce que nous présentons pourrait être réalisé avec les
composants Intraweb disponibles pour les versions Delphi 5, Delphi 6, Delphi 7, Delphi 8,
Delphi 2005, Delphi 2006, Turbo Delphi et Delphi 2007
2 - La Première Applications IntraWeb
Commençons par l'exemple simple de la calculette:
l'utilisateur tape l'adresse Web d'une page permettant de faire des multiplications
son explorateur web lui présente une page avec 2 Edit et un bouton
l'utilisateur tape 2 nombre et clic le bouton
son explorateur lui renvoie le résultat

Nous allons donc construire une page Web

 avec deux Edit et un Bouton


 lorsque l'utilisateur cliquera le bouton, nous calculerons le résultat et l'afficherons
dans un label

Par conséquent
créez sur votre disque un dossier 01_calculator
lancez Delphi 2006
lancez le Wizard Intraweb en sélectionnant "File | New | Other | Intraweb | Intraweb
wizard"
L'emplacement des Wizards Intraweb dans les menus Delphi ainsi que le contenu des
différents dialogues varie avec les versions de Delphi, mais le mécanisme reste le même
Intraweb présente un dialogue permettant spécifier le type d'application Intraweb que
vous souhaitez créer

les valeurs par défaut ("StandAlone", et "with Datamodule") conviennent. Ajoutez


simplement le chemin

C:\programs\fr\web\intraweb\01_calculator

et le nom de votre projet

p_01_calculator

et cliquez "Ok"
Intraweb crée 3 unités

 celle qui communiquera le Serveur Web


 celle qui gèrera les sessions
 et surtout l'unité correspondant à la page que verra l'utilisateur

Ces fichiers sont visibles dans le gestionnaire de projet:


sauvegardez le projet et ses unités avec des noms correspondant à l'application dans le
bon répertoire.

Cette étape peut être sautée, mais notre expérience de Delphi 2006 nous a appris à
effectuer cette sauvegarde avant de poursuivre. Donc sélectionnez chaque unité tour à
tour et sélectionnez "Save As" pour

 sauvegarder ServerController sous le nom de u_01_server_controller


 sauvegarder UserSessionUnit sous le nom de u_01_user_session_unit
 sauvegarder Unit1 sous le nom de u_01_calculator

en vérifiant que chaque fichier va bien dans notre répertoire

Puis, dans u_01_server_controler, dans le USES, changez le nom UserSessionUnit en


u_01_user_session_unit
Compilez pour vérifier que tout est cohérent
comme nous utilisons XP avec son pare feu Internet, la sécurité Windows nous demande
si nous acceptons exécuter ce programme
cliquez "Débloquer"
le Serveur IntraWeb est affiché

fermez ce Serveur (l'icône "x" en haut à droite)


de retour dans Delphi, sélectionnez la page u_01_calculator (pas le contrôleur ou la
session).

Puis dans la Palette, sélectionnez la page correspondant aux composants visuels "IW
Standard", puis sélectionnez un tIwEdit
et posez-le sur la Forme.

Posez-en un second, puis, de la même page de la Palette, un tIwButton et un tIwLabel


La Forme aura l'allure suivante:

créez l'événement qui va calculer la multiplication en double-cliquant sur IwButton1


(exactement comme pour une application Windows), et tapez le code qui va effectuer le
calcul
procedure TIWForm1.IWButton1Click(Sender: TObject);
begin
IwLabel1.Caption:=
IntToStr(StrToInt(IwEdit1.Text)* StrToInt(IwEdit2.Text));
end; // IWButton1Click

compilez
le Serveur Internet Intraweb est affiché:

lancez l'explorateur Web

 soit en cliquant sur l'icône désignée par la flèche rouge


 soit en tapant F9
 soit par le menu "File | Execute"

Internet Explorer est lancé, et notre page est présentée:

tapez deux nombres, par exemple 3 et 5 et cliquez "IwButton1"


le résultat est affiché dans Internet Explorer
Notez que:

 nous avons utilisé IntraWeb en mode "StandAlone": notre application contient en fait
un Serveur Web qui est chargé de fournir notre page à Internet Explorer. Il existe un
autre mode, dit mode "Page" dont nous parlerons à la fin de notre présentation
 comme indiqué, l'emplacement dans les menus Delphi du Wizard qui lance le serveur
Standalone peut varier énormément selon la version de Delphi. Mais en naviguant un
peu dans ces menus, il n'est guère difficile de trouver la page Intraweb, et sur cette
page une icône correspondant au mode Standalone
 lorsque nous exécutons le projet et lançons le Serveur (F9 ou l'icône verte), il ne faut
pas trop tarder à remplir la page et cliquer sur le bouton. Il y a en effet une
temporisation qui peut bloquer la réponse. Dans ce cas relancez l'exécution Delphi

Nous allons à présent examiner le principe du fonctionnement Intraweb, puis présenter


quelques exemples d'applications simples utilisant Intraweb.

3 - Le fonctionnement Intraweb
3.1 - Fonctionnement Internet

Un petit rappel rapide sur le fonctionnement des sites Web:


un développeur écrit des fichiers avec une syntaxe spéciale (.HTML) correspondant à
ses pages. Voici par exemple une page simple avec un texte de bienvenue:

<HTML>
<BODY>
Bienvenue sur notre site
</BODY>
</HTML>

La page, qui peut être rédigée en utilisant NotePad (ou tout autre éditeur de texte
ASCII) est sauvegardée sur disque, sous le nom de HELLO.HTML, par exemple

le développeur lance un Serveur Web, qui est une application qui écoute et attend les
requêtes provenant de clients. Ce serveur peut être IIS (Internet Information Server),
Apache, un serveur Web écrit en utilisant des Sockets Delphi:

un utilisateur lance un explorateur web (Internet Explorer, Netscape, un client Web écrit
avec des Sockets Delphi, ...), et demande à l'explorateur web de rapporter la page
HELLO.HTML:
le Serveur Web localise HELLO.HTM, l'envoie vers l'explorateur, qui l'affiche:

3.2 - Fonctionnement Intraweb en mode Application

Si nous utilisons Intraweb,

 la construction du texte .HTML de la page sera fait de façon visuelle en posant des
composants sur la Forme. Les propriétés de ces composants seront utilisées par
Intraweb pour générer le fichier .HTML
 le Serveur Web est un Le fichier .HTML résultant

Ceci peut être schématisé ainsi:


le développeur charge Delphi avec les composants Intraweb:
en utilisant la Palette, l'Inspecteur d'Objet et les Formes, il construit ses pages et
compile l'application, qui est placée sur disque, dans un fichier nommé, par exemple,
HELLO.EXE:

cette application est lancée, et elle correspond à un Serveur Web Intraweb, plus les
paramètres des pages construites:

un utilisateur lance un explorateur web (Internet Explorer, Netscape, un client Web écrit
avec des Sockets Delphi, ...), et demande à l'explorateur web de rapporter la page
HELLO.HTML:
le Serveur Web Intraweb utilise les paramètres de la Forme pour construire la page
HELLO.HTML, et la retourne au client qui l'affiche:

La génération d'une page .HTML à partir d'un Forme n'est en fait pas très complexe: il suffit
d'analyser les propriétés des contrôles et générer les balises .HTML (<BODY>, <INPUT>
etc) correspondantes. Nous avons d'ailleurs présenté dans l'article Delphi Web Designer un
projet Delphi permettant de générer une page .HTML à l'aide de contrôles Delphi (tPanel,
tEdit, tLabel ...) posés sur une tForm. Notre générateur est bien entendu très simplet par
rapport aux contrôles IntraWeb, mais il permet de comprendre le principe. De plus, Intraweb
a ajouté le Serveur Web, et même le lancement de l'Explorateur Web.

3.3 - Architecture IntraWeb en mode Application

Voici la structure d'un projet IntraWeb en mode Application:


et:

 nous utiliserons le Serveur Web IntraWeb (plutôt que les composants WebBroker)
 ce Serveur est construit à l'aide des composants Indy. Ceci explique d'ailleurs les
possibilités SSL (Secure Socket Layer, ou encore mode TCP/IP sécurisé) offertes par
Intraweb
 IwServerController est chargé de gérer l'application, et en particulier
o les sessions utilisateur
o les exceptions

Voici un diagramme de classe UML simplifié (les classes Intraweb représentées sont
celles de Delphi 6):

Les pages sont appelées par un Explorateur Web en utilisant une URL ayant la
structure suivante (visible sur la capture d'écran ci-dessus):
et:

o le port est spécifié par tIwServerController.Port


o le type de commande est géré par tIwServerController.ExecCmd
o chaque session a un identificateur (calculé, entre autres, à l'aide de la date),
utilisé par les cookies ou les champs cachés
 tIwAppForm est l'ancêtre de toutes nos formes. Cette classe sert de conteneur pour
tous les contrôles et permet de définir les propriétés des pages. Le diagramme de
classe simplifié est le suivant:

 pour mettre en page nos Formes, tIwAppForm utilise un descendant de tIwLayoutMgr


 Si aucun tIwLayoutManager n'est placé sur la Forme, un gestionnaire de position est
créé par défaut.

3.4 - Forme CGI

Nos schémas ci-dessus ont présenté la mécanique de requête de page par un Explorateur, et la
réponse .HTML du Serveur Web.

Lorsque la page .HTML contient des zones de saisie (texte, checkbox, bouton radio, listbox),
il y a un double aller-retour entre l'Explorateur et le Serveur.

Tout d'abord, il faut comprendre que la mécanique utilisée pour qu'un utilisateur échange des
informations avec un Serveur est l'antique technique des <FORM> .HTML. Elle fonctionne
ainsi:

le développeur place dans son texte .HTML une balise <FORM> à l'intérieur de
laquelle se trouvent des balises pour:

 au moins un bouton
 des contrôles de saisie. Par exemple un Edit

Voici une telle page pour convertir des Euros en Dollars:


et le texte .HTML correspondant est le suivant:

<HTML>
<HEAD>
</HEAD>
<BODY>
<FORM METHOD="POST"
ACTION="http://www.jcolibri.com/convert.exe">
valeur en euro ?
<INPUT TYPE="edit"NAME="les_euros"><BR>
<INPUT TYPE="submit"VALUE="convertis"><BR>
</FORM>
</BODY>
</HTML>

 <INPUT TYPE="edit" ...> est l'Edit


 <INPUT TYPE="submit" ...> est le bouton
 <FORM METHOD="POST" ACTION="http://www.jcolibri.com/convert.exe">
est la balise qui définit le formulaire Web. Cette balise indique quel est le
logiciel sur le Serveur qui traitera la conversion: CONVERT.EXE

le développeur crée donc ce logiciel. Le contenu de ce type de programme a été


présenté dans l'article CGI Form. Ce type de logiciel est donc placé sur le Serveur
Web:
le Serveur Web est lancé (IIS, Netscape ...)

Voici alors la situation:


un utilisateur lance son Explorateur, et demande la page EURO.HTML:

le Serveur retourne la page avec la <FORM>:

l'utilisateur entre un montant (123, par exemple) et clique le bouton "convertis"


le Serveur

 analyze les paramètres (la valeur 123)


 charge CONVERT.EXE et lui transmet les paramètres
 CONVERT.EXE effectue la conversion, et construit une nouvelle page .HTML.
Supposons que cette réponse contienne uniquement la valeur ne dollars ($ 166).
Cette page est renvoyée au Serveur
 le Serveur retourne cette page .HTML à l'utilisateur

et l'Explorateur affiche la réponse:

Le point extrêmement important est que le traitement du "clic" est effectué sur le Serveur.
Cette mécanique est chevillée dans le protocole .HTML, et est identique que nous mettions en
oeuvre CGI, ISAPI, NSAPI, ASP, ASP.NET ou ... Intraweb. Pour résumer

 l'utilisateur récupère une <FORM> .HTML


 il remplit les différentes informations (Edit, CheckBox etc) et envoie les données qu'il
a fourni en cliquant un Bouton
 le Serveur récupère ces informations et en fait ce qu'il veut. En général, il renvoie au
moins un accusé de réception, ou bien retourne la même page mise à jour, ou encore
renvoie un autre page .HTML

Lorsque nous utilisons une page .HTML construite avec Intraweb et qui contient des
contrôles, la mécanique est la même, sauf que

 le Serveur Web est le Serveur Intraweb


 ce Serveur est utilisé pour envoyer toutes les pages .HTML: aussi bien la page initiale,
que les pages calculées en réponse aux valeurs retournées par l'Explorateur clique sur
un Bouton. Et c'est le code situé dans l'événement OnClick du bouton qui est utilisé
pour effectuer la suite des traitements (mise à jour d'une base de données, intégration
des valeurs dans une réponse etc)
 tous les calculs se font donc sur le Serveur, et par du code Delphi usuel. Vous avez
donc accès à tout: les PROCEDUREs, les CLASSes, les UNITs, les bases de
données etc. Et dans un langage décent, pas dans un langage de script à la syntaxe
ahurissante.

Le schéma final devient dans ce cas:

Notez que:

 TOUTES nos pages, plus le Serveur Intraweb sont contenus dans un seul .EXE (en
mode Application).

Nous avons présenté la mécanique CGI pour bien illustrer le fonctionnement sous-jacent.
Mais vous n'aurez pas à programmer de CGI, ISAPI, d'écrire de balises .HTML etc: c'est
Intraweb qui mettra tout en place. C'est ce que nous allons examiner à présent.
4 - Quelques Techniques IntraWeb
4.1 - Exemples IntraWeb

Maintenant que nous avons présenté un premier exemple ainsi que le fonctionnement de base
d'IntraWeb, nous allons examiner quelques exemples un peu plus élaborés:

 navigation entre plusieurs pages - échange de données entre pages


 utilisation de contrôles liées aux bases de données (BDE, Interbase, ADO)
 affichage dans des tIwDbEdit, tIwDbGrid
 modification de tIwDbGrid

4.2 - Navigation entre plusieurs pages

4.2.1 - Transfert de page

Un site est en général composé de plusieurs pages .HTML, et l'utilisateur navigue d'une page
à une autre en utilisant des hyper-liens ou des boutons.

Dans le cas d'Intraweb

 nous créons autant de pages Intraweb additionnelles que nous souhaitons en utilisant
"File | New | Other | Intraweb | New Form"
 Intraweb gère une pile de pages actives, et
o au lancement c'est la page par défaut qui est ajoutée à la pile
o lorsque l'utilisateur clique un bouton, le Serveur prend la main, en fait dans le
OnClick du bouton de la page cliquée. Pour que le Serveur renvoie une page
vers l'utilisateur, il faut
 créer la seconde page

var my_iw_page: t_my_iw_page;

my_iw_page:= t_my_iw_page.Create(WebApplication);

 l'ajouter au sommet de la pile en appelant:

my_iw_page.Show


o ce qui peut, dans ce cas de "création + affichage" être abrégé par:
t_my_iw_page.Create(WebApplication).Show

o lorsque nous souhaitons qu'une page ne soit pas retournée à l'utilisateur, nous
appelons:

my_iw_page.Hide

o et
 la page est retirée de la liste des pages actives
 la page située au sommet de la pile est retournée à l'utilisateur

Notez que:

 les nouvelles pages sont ajoutées par "File | New | Other | Intraweb | New Form", PAS
en ajoutant une nouvelle Forme Windows ("File | New | Form")
 pour retourner une nouvelle page, il FAUT utiliser iw_page.Show(), et jamais
ShowModal. De même pour supprimer une page, il faut utiliser iw_page.Hide() (et
pas Visible:= False). Ce sont en effet ces deux primitives Show() et Hide() qui gèrent
la pile des pages IntraWeb

4.2.2 - Exemple de transfert de page

Voici un exemple avec deux pages: la première calcule le taux du dollar, la seconde renvoie
la valeur.

Commençons par créer une application IntraWeb:

lancez une nouvelle application IntraWeb par "File | New | Other | Intraweb | Intraweb
Application Wizard"
le wizard est affiché
tapez le chemin et le nom de l'application, par exemple P_02_TWO_PAGES. et cliquez
"OK"
la nouvelle application est créée
modifiez aussi le nom de UNIT1 en U_02_TWO_PAGES_1, et le nom de tIwForm1 en
tIwForm_page_1
compilez pour vérifier

Ajoutons la seconde page:

sélectionnez "File | New | Other | Intraweb | New Form"


un dialogue de sélection de type de page est affiché:

sélectionnez "Application Form", et cliquez "Ok"


une nouvelle unité avec sa tIwForm est créée
renommez l'unité U_02_TWO_PAGE_2, et la tIwForm tIwForm_page_2
compilez pour vérifier

Garnissons la première page


sélectionnez U_02_TWO_PAGES_1
de l'onglet "IW Standard" de la Tools Palette, sélectionnez un tIwLabel posez-le sur la
Forme, et changez son Caption en "valeur en euros"
de l'onglet "IW Standard", sélectionnez un tIwEdit, et initialisez Text à une valeur par
défaut, par exemple 123
de l'onglet "IW Standard", sélectionnez un tIwButton, nommez-le "convert", créez son
événement OnClick, et calculez la valeur en dollar (multiplication par 1.35 environ), et
effectuez le transfert de page:
procedure TIWForm_page_1.convertClick(Sender: TObject);
var l_euro, l_dollar: Double;
l_c_iwform_page_2: tiwform_page_2;
begin
l_euro:= StrToFloat(IwEdit1.Text);
l_dollar:= l_euro* 1.35;

l_c_iwform_page_2:= tiwform_page_2.Create(WebApplication);
l_c_iwform_page_2.iwlabel1.Caption:= IwEdit1.Text
+ ' euros = '+ FloatToStr(l_dollar)+ ' US $';
l_c_iwform_page_2.Show();

// -- same as
// with tiwform_page_2.Create(WebApplication) do
// begin
// iwlabel1.Caption:= IwEdit1.Text+ ...ooo...
// Show;
// end;
end; // convertClick

Ajoutez aussi, après IMPLEMENTATION l'importation de la page 2:

implementation
uses u_02_two_pages_2;

Et pour que la seconde page permette de revenir à la page 1 pour entrer une nouvelle valeur:

sélectionnez U_02_TWO_PAGES_2
de l'onglet "IW Standard" de la Tools Palette, sélectionnez un tIwLabel posez-le sur la
Forme
de l'onglet "IW Standard", sélectionnez un tIwButton, nommez-le "backbutton", créez
son événement OnClick, et retirez la seconde page de la pile
procedure TiwForm_page_2.backbuttonClick(Sender: TObject);
begin
Hide();
// Release();
end; // backbuttonClick

compilez et exécutez
le Serveur est affiché
clickez l'icône pour lancer l'Explorateur
la page 1 est affichée

tapez une valeur et cliquez "convert"


la seconde page est affichée
cliquez "backbutton"
la première page est affichée à nouveau:

Notez que

 l'URL affiche un nombre d'aller et retour croissant: 0, 1, 2


 le SessionId en revanche reste le même
 pour une raison inconnue, nous ne pouvons pas utiliser des Name comportant un
souligné "_"

4.2.3 - Architecture de la pile des pages

Au niveau architecture, la CLASS tIwApplication gère les différentes pages (formes):

et lorsqu'un nouvel utilisateur se connecte, tIwControllerBase lance une nouvelle session, ce


qui crée une nouvelle tIwApplication avec une nouvelle liste de pages, et une page active:

et par la suite, cet utilisateur ajoute ou retire des pages actives à sa liste par Show() et Hide().
4.2.4 - Création et Destruction

Show() et Hide() ne font que manipuler la présence de la page au sommet de la pile, et ne


gèrent ni la création, ni la suppression de l'objet.

Pour créer une page, il faut utiliser, comme nous l'avons indiqué ci-dessus:

t_my_iw_page.Create(WebApplication)

et pour libérer une page:

my_iw_page.Release

En fait dans l'exemple ci-dessus nous avons utilisé page_2.Hide(), alors que nous aurions du
employer page_2.Release()

Comme chaque page a un référence vers tIwApplication qui contient la liste des pages, il est
possible, à titre de debugging, de visualiser cette liste:

sélectionnez U_02_TWO_PAGES_1
de l'onglet "IW Standard" de la Tools Palette, sélectionnez un tIwListBox et posez-la sur
la Forme
sélectionnez un tIwButton, nommez-le "pagestack", créez son événement OnClick, et
affichez la liste des pages (exécuté par le Serveur lorsqu'il traitera pagelist.Click)
procedure TIWForm_page_1.pagestackbuttonClick(Sender: TObject);
var l_form_index: Integer;
begin
with IwListBox1 do
begin
Clear;
for l_form_index:= 0 to WebApplication.FormCount- 1 do
Items.Add(WebApplication.Forms[l_form_index].Name);
end; // with iwIlistBox1
end; // pagestackbuttonClick

compilez, exécutez et lancez l'Explorateur


cliquez sur "pagestackbutton"
notre page est affichée, ainsi qu'un item "--no_selection--" et IwUserSession (qui est le
DataModule créé par défaut par le Wizard)
cliquez trois fois sur "convert" et "backbutton", et sur "pagelistbutton"
la pile des page contient bien plusieurs pages 2:

Maintenant que vous comprenez la mécanique, plusieurs solutions sont possibles:

 dans la seconde page, dans backbutton.Click, utiliser Release() au lieu de Hide()


 placer la variable l_c_page_2 dans TIWForm_page_1, et ne créer la seconde page que
si cet attribut est NIL
 placer l_c_page_2 dans un tDataModule associé à la session (cf plus bas)

Notez aussi que


 une même page (instance de tIwForm_nnn) peut être référencée plusieurs fois dans la
pile des pages. Cela peu se produire lorsque l'application exige que cette page soit
présentées à plusieurs reprises après des visites à d'autres pages. Si nous appelons
Release(), toutes ces instances seront libérées
 une fois une tiwForm créée, elle existe tant que vous ne la supprimez pas par
t_iwForm.Release(). Il est donc très simple de transférer des données d'une page à
l'autre en accédant à ses contrôles (ce que nous avons fait en initialisant page_2.Label
depuis page_1.ButtonClick), ou à des attributs PUBLIC
 comme l'ensemble des pages utilise des Threads, il ne faut PAS utiliser des variables
globales. Plusieurs alternatives sont possible
o utiliser les attributs des pages en mémoire
o utiliser les tDataModules associés à la session (cf plus bas)
o en dernier recours, utiliser des tThreadVars

4.2.5 - Lancement depuis un Client distant

Pour le moment nous avons affiché nos pages via le Serveur Standalone. Naturellement nos
utilisateurs seront sur une machine éloignée, et c'est eux qui lanceront la demande d'une page
de notre site.

En fait, il suffit dans Internet Explorer de fournir l'adresse et le port (si ce n'est pas le port 80)
pour obtenir la page principale, puis de naviguer à partir de là.

Nous utilisons à l'Institut Pascal un réseau local, et le poste sur lequel est le Serveur Intraweb
a l'adresse IP 152.178.41.18 (lancez ipconfig.exe pour éventuellement connaître l'adresse de
votre poste). Pour effectuer notre essai, il faut connaître le port. Par conséquent

compilez votre projet et lancez le Serveur Standalone


sélectionnez, dans cette application "Tools | Start URL"
l'URL est copiée dans le presse-papier
copiez cet URL dans un fichier ASCII
le port est 8888
allez sur un autre poste du réseau, lancez Internet Explorer et dans la barre d'adresse,
tapez

http://152.178.41.18:8888/ Entrée
la page est affichée dans Internet Explorer, comme précédemment

4.3 - Bases de Données

4.3.1 - Un tdbEdit et une Table BDE (dBase)


Commençons par afficher dans des dbEdit les champs de la Table ANIMALS.DBF. Nous
allons

 placer les composants d'accès aux bases de données sur le tDataModule UserSession
 initialiser la connection avec la base
 ajouter à la tIwForm quelques champs tIwDb_xxx

Par conséquent:
lancez une nouvelle application IntraWeb par "File | New | Other | Intraweb | Intraweb
Application Wizard"
le wizard est affiché
tapez le chemin et le nom de l'application, par exemple P_03_DBEDIT et cliquez "OK"
la nouvelle application est créée
modifiez aussi le nom de UNIT1 en U_03_DBEDIT
compilez pour vérifier

Puis nous armons une Table


sélectionnez UserSessionUnit et sélectionnez la forme (onglet "Design" en bas)
initialisez une tTable

 de l'onglet "BDE" de la Tool Palette, sélectionnez une tTable et posez la sur la


forme tIwUserSession
 dans l'Inspecteur
o initialisez DataBaseName avec DBDEMOS
o initialisez TableName avec ANIMALS.DBF
o basculez Active sur True

de l'onglet "DataAccess" de la Palette, sélectionnez une tDataSource et posez la sur la


forme tIwUserSession. Initialisez DataSet vers Table1

Ajoutons un tIwDbEdit pour afficher un champ:

 sélectionnez U_03_DBEDIT, sélectionnez le code


 pour que les composants db_xxx puissent accéder à DataSource1, ajoutez à la clause
USES l'importation de UserSessionUnit
 sélectionnez la forme
 sélectionnez de l'onglet "IwData" de la Palette, et dans cette page sélectionnez un
tiwDbEdit:
et posez-le sur la Forme

Dans l'Inspecteur

o sélectionnez DatSource. Si vous avez bien importé UserSessionUnit, alors


IWUserSession.DataSource1Data sera affiché. Sélectionnez cette source
o sélectionnez DataField, et choisissez un champ, par exemple AREA
 compilez et exécutez
 voici le résultat:
Tant qu'a faire, nous pouvons ajouter un navigateur et afficher quelques images:

 de l'onglet "IwData" de la Palette, sélectionnez un tIwDbNavigator, posez-le sur le


Forme, et initialisez DataSource vers DataSource1
 de cette page sélectionnez un tiwDbImage, posez-le sur la Forme et initialisez
o DataSource vers DataSource1
o DataField vers BMP
 compilez et exécutez
 voici le résultat:

4.4 - tIwDbGrid et la base de données Interbase

4.4.1 - Utilisation d'une DataGrid

Pour varier les plaisirs, voici une application avec une grille et un moteur SQL Interbase.
Tout d'abord, créons un nouveau projet:
lancez une nouvelle application IntraWeb par "File | New | Other | Intraweb | Intraweb
Application Wizard"
le wizard est affiché
tapez le chemin et le nom de l'application, par exemple P_04_DBGRID et cliquez "OK"
la nouvelle application est créée
modifiez aussi le nom de UNIT1 en U_04_DBGRID_INTERBASE
compilez pour vérifier

Puis nous armons une Table, par exemple EMPLOYEE.COUNTRY


dans le Gestionnaire de Projet, sélectionnez UserSessionUnit et sélectionnez la forme
(onglet "Design" en bas)
initialisez une tTable

 de l'onglet "Interbase" de la Tools Palette, sélectionnez une tIbDataBase et


posez-la sur la Forme.
Cliquez deux fois sur IbDatabase1 pour ouvrir l'Editeur de Connection, et
initialisez ses propriétés vers votre base. Dans notre cas:
o DataBase vers
C:\Program Files\Fichiers communs\Borland
Shared\Data\EMPLOYEE.GDB
o User Name à SYSDBA
o Password à masterkey
o Login à False

Testez, et validez par "Ok"

 de l'onglet "Interbase" de la Palette, sélectionnez une tIbTransaction et reliez-la


à IbDatabase1 et réciproquement
 de l'onglet "Interbase" de la Palette, sélectionnez une tIbQuery, et initialisez
o DataBase vers IbDatabase1
o SQL avec une sélection de Table, par exemple

SELECT * FROM country

o basculez Active à True


 de l'onglet "Data Access" de la Palette, sélectionnez une tDataSource, posez-la
sur la tForm et initialisez DataSet vers IbQuery1

voici la vue de notre tDataModule:


Ajoutons un tIwDbGrid pour afficher la Table:

 sélectionnez U_04_DBGRID_INTERBASE, sélectionnez le "Code"


 pour que les composants db_xxx puissent accéder à DataSource1, ajoutez à la clause
USES l'importation de UserSessionUnit
 sélectionnez la forme
 sélectionnez de l'onglet "IwData" de la Palette, et dans cette page sélectionnez un
tiwDbGrid et posez-la sur la tForm

Dans l'Inspecteur sélectionnez DatSource. Si vous avez bien importé


UserSessionUnit, alors IWUserSession.DataSource1Data sera affiché. Sélectionnez
cette source

 compilez et exécutez
 voici le résultat:

4.4.2 - Techniques d'affichage d'une tIwDbGrid

Nous pouvons utiliser plusieurs propriétés pour varier l'affichage dans une tIwDbGrid:

 nous pouvons alterner les couleurs des lignes en utilisant RowAlternateColor


 la couleur de la ligne au-dessus de laquelle passe la souris peut être modifiée par
RollOver, RollOverColor
 la couleur de la ligne sélectionnée

Voici quelques exemples:


posez une autre tIwDbGrid sur la tForm, et liez DataSource vers DataSource1
sélectionnez RowAlternateColor et donnez-lui la valeur clSkyBlue par exemple
sélectionnez RowHeaderColor, et choisissez, par exemple clWebBisque
sélectionnez RowCurrentColor, et affectez-lui clWebLime
sélectionnez RollOver, et basculez la valeur sur True, et affectez à RollOverColor la
valeur clWebYellow
compilez et exécutez
voici le résultat:

4.4.3 - Pagination

Lorsque la Table est de grande taille, il est coûteux et inefficace de transférer vers le client
toutes les lignes. Nous pouvons limiter le nombre de lignes envoyées en utilisant RowLimit,
et en gérant par des boutons la demande de la page précédente ou suivante.

Par exemple:

posez une autre tIwDbGrid sur la tForm, et

 liez DataSource vers DataSource1


 basculez FromStart à False
 donnez à RowLimit une valeur telle que 4

posez un tIwButton sur la Forme, créez son événement OnClick et tapez le code qui
déplace la ligne courante d'un nombre de lignes égale au nombre de lignes de le
tIwDbGrid:
procedure TIWForm1.next1Click(Sender: TObject);
begin
UserSession.IbQuery1.MoveBy(IwDbGrid3.RowLimit);
end; // next1Click

Importez aussi dans la liste des USES SERVERCONTROLLER pour pouvoir accéder à
USERSESSION.IbQuery1
posez de même un bouton pour reculer
compilez et exécutez
voici le résultat :

Notez que

 IbQuery1 est sur le DataModule USERSESSION. Comme indiqué plus haut, il n'y a
PAS de variable globale nous permettant de désigner ce DataModule. En revanche,
ServerController a créé une FUNCTION, appelée UserSession, qui nous permet
d'accéder aux composant de TIWUserSession
 vous pouvez aussi ajouter le code qui inhibe les boutons lorsque nous dépassons les
limites (IbQuery.Eof etc)
 le lecteur attentif aura remarqué que dans la dbGrid2, la couleur jaune souligne bien
que c'est "japan" qui est devenue la ligne courante
 comme nous ne pouvons utiliser un IwButton1.Name tel que "next_", nous avons
utilisé "next1". Le risque est en effet, dans des WITH éventuels, d'utiliser le nom
Next ayant une signification pour d'autres composants faisant partie du WITH. Si
vous n'employez pas de WITH, nommez les boutons comme bon vous semble.
4.4.4 - tDbGrid modifiable

Nous allons examiner comment l'utilisateur peut changer les valeurs présentées dans un
grille. Nous allons en profiter pour montrer comment utiliser une connection ADO.

Commençons par créer l'application:

lancez une nouvelle application IntraWeb par "File | New | Other | Intraweb | Intraweb
Application Wizard"
le wizard est affiché
tapez le chemin et le nom de l'application, par exemple P_05_DBGRID_ADO et
cliquez "OK"
la nouvelle application est créée
modifiez aussi le nom de UNIT1 en U_05_DBGRID_ADO
compilez pour vérifier

A présent armons une Table ADO

Ici, nous allons utiliser le fichier ACCESS fourni avec Delphi, appelé DBDEMOS.MDB. Ce
fichier est situé, dans notre cas, en
C:\Program Files\Fichiers communs\Borland Shared\Data\
et nous l'avons copié dans un répertoire plus confortable, appelé \_data, proche de notre
application

Voici comment utiliser une Table ADO:

sélectionnez le DataModule USERSESSIONUNIT, et sa tForm ("Design")


de l'onglet "DbGo" de la Tools Palette, sélectionnez tAdoConnection et posez-le sur la
tForm.
Dans l'Inspecteur, sélectionnez Connection et cliquez sur l'ellipse
l'Editeur de connection ADO de Microsoft est présenté.
nous allons construire notre propre chaîne de connection, et nous sélectionnons "use
connection string | Build"
le constructeur de chaînes de connection Microsoft est présenté
comme nous allons utiliser le moteur Sql ServerADO, nous sélectionnons "Fournisseur |
Microsoft 4.0 OleDb Provider", puis cliquons "Suivant"
la page "Connexion" est présentée
nous cliquons l'ellipse à côté de "sélectionner la base de données" et allons sélectionner
dbdemos.mdb.
nous cliquons "tester la connexion", qui réussit, et fermons l'éditeur par "ok"
dans la Palette, nous sélectionnons un tAdoDataset et le posons sur la tForm. Nous
initialisons Connection vers AdoConnection1, puis sélectionnons CommandText et
cliquons sur l'ellipse
l'éditeur de requêtes est présenté
tapez la même requête que ci-dessus (dbdemos.mdb contient la même table que
employee.gdb):

SELECT * FROM country

basculez AdoDataSet.Active à True


pour pouvoir modifier la Table

 posez un tAdoCommand sur la Forme


 initialisez Connection vers AdoConnection1
 basculez CheckParams à False

Voici comment utiliser la Table ADO avec Intraweb:

sélectionnez U_02_EDIT_DBGRID_ADO
pour que les composants db_xxx puissent accéder à DataSource1, ajoutez à la clause
USES l'importation de UserSessionUnit
de l'onglet "Data Access" de la Palette, sélectionnez une tDataSource, posez-la sur la
tForm et initialisez DataSource1.DataSet vers AdoDataSet1
de l'onglet "Iw Data", selectionnez une tIwDbGrid et posez-la sur la Forme.
Sélectionnez DatataSource et initialisez-la vers DataSource1
pour que ADO fonctionne, il faut aussi s'occuper de l'initialisation des objets COM:

 sélectionnez SERVERCONTROLLER.PAS
 dans l'Inspecteur, initialisez IwServerController.ComInitialization à ciNormal
ou ciMultiThreaded

finalement, pour permettre la modification d'une ligne,

 ajoutez un composant tAdoCommand à la tForm, et initialisez Connection vers


AdoConnection1. Et il faut basculer ParamCheck sur False
 vous pouvez aussi utiliser un tAdoDataset, qu'il faut également initialiser vers
AdoConnection1

à titre de vérification, lancez l'application et vérifiez que vous voyez bien la table

Notez que:
 il faut basculler ComInitialization. Si cette étape n'est pas effectuée, vous aurez une
erreur "coinitialize" qui est, pour les utilisateurs d'ADO avec IntraWeb, l'erreur la plus
fréquente. Cette propriété n'est pas initialisée par IntraWeb par défaut, car elle n'a lieu
d'être que pour ADO
 nous avons aussi montré ici que nous pouvons placer le tDataSource sur la
TIWForm1 (comme nous pouvons choisir de le placer sur tIwUserSession)
 si la connexion ADO ne réussit pas, vous pouvez faire l'exercice avec une Table BDE,
InterBase, ou tout autre composant d'accès

Puis limitez le nombre de lignes et posez les tIwButton pour naviguer dans la grille, comme il
a été présenté dans le paragraphe précédent.

Maintenant occupons nous de la modification d'une tIwDbGrid. Apparemment ce n'est pas


prévu de façon automatique. Plusieurs solutions sont possibles

 utiliser un tIwDbGrid uniquement pour l'affichage, et employer un tIwNavigator pour


synchroniser l'affichage entre la tIwDbGrid et les tIwDbEdits. Ce n'est pas une
solution totalement irréaliste: si vous regardez VOYAGES.SNCF.COM, il n'y a pas
de DataGrid, mais des pages avec des liens clicables, ou des boîtes d'édition pour
entrer vos coordonnées et payement
 utiliser un tIwData, le peupler et synchroniser l'affichage et la mise à jour avec la
Table
 gérer en parallèle des structures qui mémorisent où nous sommes et lancent les
UPDATE en fonction de cette position

C'est cette dernière solution que nous avons retenue. Elle s'inspire en fait de ASP.NET, ou,
lorsque nous souhaitons modifier une grille. Démontrons d'abord schématiquement ce que
nous souhaitons faire:

 prenons une grille contenant 3 colonnes utiles:

 nous lui adjoignons 3 colonnes pour gérer la modification.


 en mode présentation, la grille comporte une colonne de boutons permettant de mettre
une ligne en mode modification:
 lorsque l'utilisateur a sélectionné une ligne en cliquant sur le bouton de cette ligne,
une nouvelle grille lui est présenté comportant cette fois-ci
o des Edit qui permettent de modifier le contenu d'un champ
o deux boutons permettant de confirmer ou annuler

Voici notre grille en mode modification

An niveau IntraWeb:

 nous commençons par ajouter 3 colonnes pour nos boutons. Cela se fait en créant les
colonnes de tIwDbGrid manuellement, en utilisant la propriété tIwDbGrid.Columns
 l'incrustation de tIwButtons et tIwEdits se fait en gérant l'affichage de chaque cellule.
Pour cela la tIwDbGrid comporte un événement tIwDbGrid.OnRenderCell (similaire
aux événement OwnerDraw d'une tDbGrid usuelle):

procedure OnIWDBGridRenderCell(ACell: TIWGridCell;


const ARow, AColumn: Integer);

 Cet événement nous fournit


o la ligne et la colonne que nous devons dessiner
o la cellule courante, qui a un paramètres tIwGridCell.Control, que nous
utilisons pour incruster les boutons ou edits
 nous créons un événement modify_button_clic qui nous permet de mettre la
tIwDbGrid en mode édition (et récupérer les informations sur le numéro de la ligne, la
clé etc).
 nous créons les événements cancel_button_clic pour annuler tout changement, et
réafficher la grille en mode "affichage"
 et finalement un événement post_button_clic, qui
o ira récupérer les informations sur la ligne courante et les nouvelles valeurs
dans les tIwEdit pour construire une requête SQL UPDATE
o exécutera cette requête
o remettra la tIwDbGrid en mode affichage

Voici donc notre version


sélectionnez IwDbGrid1, sélectionnez sa propriété Columns et cliquez sur l'ellipse ...

un Editeur de colonnes est affiché


cliquez sur l'icône d'ajout (ou "clic droit | add") et ceci 5 fois (pour la colonne de
modification, 2 colonnes de données et 1 colonne pour Post, une pour Cancel)
affichez le "Code" et déclarez dans la partie PUBLIC de tIwForm1 les boutons et les
edits qui seront nécessaires, ainsi que les données de suivi de la ligne sélectionnée:
type TIWForm1=
class(TIWAppForm)
DataSource1: TDataSource;
IWDBGrid1: TIWDBGrid;
next1: TIWButton;
previous1: TIWButton;
// -- ...ooo...
public
m_c_do_modify_button_list: array of tIwButton;
m_c_do_post_button, m_c_do_cancel_button: tIwButton;

m_c_edit_list: array of tIwEdit;

m_do_modify: Boolean;
m_selected_row: Integer;
m_selected_key: String;

procedure handle_do_modify_click(Sender: tObject);


procedure handle_do_cancel_click(Sender: TObject);
procedure handle_do_post_click(Sender: TObject);
end; // TIWAppForm

et:

 m_c_do_modify_button_list: la liste verticale des boutons pour sélectionner une


ligne
 m_c_do_post_button, m_c_do_cancel_button: les boutons qui exécutent Post ou
Cancel
 m_c_edit_list: la liste horizontale des tIwEdit permettant de modifier les champs
de la ligne sélectionnée
 m_do_modify: le booléen qui gère l'état affichage / modification de la grille
 m_selected_row, m_selected_key: les paramètres permettant de construire la
requête
créez l'événement tIwForm.OnCreate, et créez les do_edit boutons verticaux, les edits
horizontaux et les bouton Post et Cancel:
const k_table_column_count= 2;

procedure TIWForm1.IWAppFormCreate(Sender: TObject);


var l_row_index: Integer;
l_c_do_modify_button: tIwButton;

l_column_index: Integer;
l_c_iwedit: tIwEdit;
begin
SetLength(m_c_do_modify_button_list, IwDbGrid1.RowLimit);

for l_row_index:= 0 to IwDbGrid1.RowLimit- 1 do


begin
l_c_do_modify_button:= tIwButton.Create(Self);
with l_c_do_modify_button do
begin
Caption:= 'Modify_'+ IntToStr(l_row_index);
// -- offset by 1 because of the row header
Tag:= l_row_index+ 1;
OnClick:= handle_do_modify_click;
end; // with l_iwbutton

m_c_do_modify_button_list[l_row_index]:= l_c_do_modify_button;
end; // for l_row_index

SetLength(m_c_edit_list, k_table_column_count);
for l_column_index:= 0 to k_table_column_count- 1 do
begin
l_c_iwedit:= tIwEdit.Create(Self);
with l_c_iwedit do
Text:= 'Edit_'+ IntToStr(l_column_index);
m_c_edit_list[l_column_index]:= l_c_iwedit;
end; // for l_column_index

m_c_do_post_button:= tIwButton.Create(Self);
with m_c_do_post_button do
begin
Color:= clWebLime;
Caption:= 'Post';
OnClick:= handle_do_post_click;
Visible:= False;
end; // with m_c_do_post_button

m_c_do_cancel_button:= tIwButton.Create(Self);
with m_c_do_cancel_button do
begin
Color:= clWebRed;
Caption:= 'Cancel';
OnClick:= handle_do_cancel_click;
Visible:= False;
end; // with m_c_do_cancel_button
end; // IWAppFormCreate

Notez que chaque bouton de modification contient dans tIwButton.Tag le numéro de la


ligne. Ceci sera utilisé pour retrouver la ligne courante à modifier lorsque le bouton sera
cliqué.
sélectionnez la tIwDbGrid, créez son événement OnRenderCell, et affichez, en fonction
de l'état de la dbGrid, soit les boutons pour modifier, soit les Edit et les boutons pour
Poster. Et ces dernier uniquement sur la ligne courante. En gros, il y a deux états:
affichage et modification, et en fonction du Boolean m_do_modify, nous affichons soit
les bouton de modification, soit les Edits et les boutons d'annulation/post
procedure TIWForm1.IWDBGrid1RenderCell(ACell: TIWGridCell; const ARow,
AColumn: Integer);

procedure draw_in_display_mode;
var l_field_value: String;
begin
if ARow= 0
then // column header
else
case AColumn of
0 : begin
// -- the button column
ACell.Control:= m_c_do_modify_button_list[ARow- 1];
ACell.Control.Enabled:= True;
end;
1 : begin
l_field_value:= UserSession.AdoDataset1.Fields[0].AsString;
ACell.Text:= l_field_value;
end;
2 : begin
l_field_value:=
UserSession.AdoDataset1.FieldByName('Population').AsString;
ACell.Text:= l_field_value;
end;
end; // case AColumn
end; // draw_in_display_mode

procedure draw_in_edit_mode;

procedure display_selected_row;
var l_field_value: String;
begin
case AColumn of
1 : begin
l_field_value:= UserSession.AdoDataset1.Fields[0].AsString;
ACell.Control:= m_c_edit_list[0];
m_c_edit_list[0].Text:= l_field_value;
m_selected_key:= l_field_value;
end;
2 : begin
l_field_value:= UserSession.AdoDataset1.FieldByName('Population').AsSt
ring;
ACell.Control:= m_c_edit_list[1];
m_c_edit_list[1].Text:= l_field_value;
end;
3 : begin
ACell.Control:= m_c_do_post_button;
end;
4 : begin
ACell.Control:= m_c_do_cancel_button;
end;
end; // case AColumn
end; // display_selected_row

procedure display_other_row;
var l_field_value: String;
begin
case AColumn of
1 : begin
l_field_value:= UserSession.AdoDataset1.Fields[0].AsString;
ACell.Text:= l_field_value;
end;
2 : begin
l_field_value:=
UserSession.AdoDataset1.FieldByName('Population').AsString;
ACell.Text:= l_field_value;
end;
end; // case AColumn
end; // display_other_row

begin // draw_in_edit_mode
if ARow= 0
then // column header
else
if aColumn= 0
then begin
// -- the modify column
ACell.Control:= m_c_do_modify_button_list[ARow- 1];
ACell.Control.Enabled:= False;
end
else
if ARow= m_selected_row
then display_selected_row
else display_other_row;
end; // draw_in_edit_mode

begin // IWDBGrid1RenderCell
if m_do_modify
then draw_in_edit_mode
else draw_in_display_mode;
end; // IWDBGrid1RenderCell

créez l'événement qui traitera la mise en mode edition:


procedure TIWForm1.handle_do_modify_click(Sender: tObject);
begin
with (Sender as tIwButton) do
begin
m_do_modify:= True;
m_selected_row:= Tag;

m_c_do_post_button.Visible:= True;
m_c_do_cancel_button.Visible:= True;
end; // with Sender as tIwButton
end; // handle_do_modify_click

et les événements qui traitent Cancel:

procedure TIWForm1.handle_do_cancel_click(Sender: TObject);


begin
// -- simply revert to display mode
m_do_modify:= False;

// -- reset the browse mode


m_c_do_post_button.Visible:= False;
m_c_do_cancel_button.Visible:= False;
end; // handle_do_cancel_click

et finalement la mise à jour (à modifier si vous n'utilisez pas ADO):

procedure TIWForm1.handle_do_post_click(Sender: TObject);


var l_population: String;
begin
clear_display;
display('post '+ m_selected_key);
// -- use the data access controls to update the Table
l_population:= m_c_edit_list[1].Text;

with UserSession.AdoCommand1 do
begin
CommandText:=
'UPDATE country '
+ ' SET population= '+ l_population
+ ' WHERE Name= '''+ m_selected_key+ '''';
// display('cmd '+ CommandText);
Execute;
end; // with UserSession.AdoCommand1

(*
with UserSession.AdoDataset2 do
begin
Open;

if Locate('Name', m_selected_key, [])


then begin
Edit;
FieldByName('Population').AsString:= l_population;
Post;
end;
Close;
end; // with UserSession.AdoDataset2
*)

// -- refresh AdoDataset1
UserSession.AdoDataset1.Close;
UserSession.AdoDataset1.Open;

// -- reset the browse mode


m_do_modify:= False;
m_c_do_post_button.Visible:= False;
m_c_do_cancel_button.Visible:= False;
end; // handle_do_post_click

Nous avons laissé en commentaire la modification via AdoDataset2


compilez et exécutez

voici la grille en mode affichage:


cliquez sur le second tButton:

voici la grille en mode modification:


Notez

 tout d'abord nous nous sommes entêtés à vouloir utiliser ADO. Lorsque nous avons
essayé de mettre à jour, nous avons eu une exception "OleException, missing required
parameter". Après quelques heures d'essai, nous avons décidé d'utiliser un
tAdoDataSet, et Locate n'a pas fonctionné, car la colonne COUNTRY n'existait pas.
Nous avions confondu EMPLOYEE_GDB.COUNTRY et
DBDEMOS_MDB.COUNTRY, et le nom correct pour la colonne contenant le nom
du pays est ici NAME. "OleException, missing parameter" était naturellement le
message le plus approprié pour nous mettre sur la voie. Pas aussi inutile que "Syntax
Error", mais pas loin, voire pire ...
 revenons à notre sujet. Nous aurions pu, comme ASP.NET utiliser la même colonne
pour les boutons de modification et ceux de confirmation ou annulation. Nous avons
tout laissé pour mieux montrer ce qui se passait
 nous avons créé des listes de boutons. Il faudrait naturellement les libérer, et ceci dans
tIwForm.OnDestroy
 nous avons utilisé une grille de taille fixe pour pouvoir plus facilement allouer nos
tables de boutons. Il serait possible de parcourir la Table pour allouer un nombre
variable en fonction de la taille de la table
 en plus des dbGrid, il existe aussi une grille tIwGrid (non liée à une base de données)
que nous pouvons remplir, modifier etc
 il arrive que lorsque nous créons des tIwButton ou autre contrôle par code, nous ne
connaissions pas l'UNITé Intraweb à importer. Nous pouvons naturellement
recherche cette unité en utilisant l'aide. Une solution bien connue est de déposer un
exemplaire de ce type de contrôle via la Palette, de compiler (ce qui force Delphi à
ajouter le bon USES, puis à retirer ce composant
 SELF est impératif dans tIwButton.Create(SELF) (sinon le clic ne sera pas pris en
compte)
 peut-être les nouvelles versions d'Intraweb faciliteront la modification d'une grille,
mais les messages trouvés sur les forums n'en parlent pas
 la stratégie utilisée pour modifier une grille est similaire à celle que nous avons
utilisée pour présenter la navigation dans une grille en utilisant CGI, et est la même
que celle utilisée, nous l'avons déjà indiqué, par ASP.NET
 nous pourrions utiliser la même technique pour nous positionner sur une ligne en
utilisant la grille
 il faudrait aussi gérer l'inhibition de previous et next pendant la modification
 la dernière image ci-dessus présente aussi un tIwMemo. Naturellement, nous n'avons
pu nous empêcher d'afficher différents message de mise au point, comme sous
Windows. Ici le memo affiche la requête qui va être exécutée. Les méthodes pour
afficher et effacer le memo sont dans les sources du .ZIP
 en ce qui concerne la tIwDbGrid:
o UseFrame permet de supprimer le titre de la tIwDbGrid. UseSize affiche un
cadre autour de la grille
o tIwDbGrid.Colums[0] n'est pas accepté. Il faut utiliser
tIwDbGrid.Colums[0].Items[0]
o apparemment, le titre des colonnes est compté comme une ligne de la
tIwDbGrid
o les tIwDbGridColumn ont aussi un événement OnClick que nous aurions peut
être pu utiliser au lieu de mettre en place des boutons Modify
o CellPadding est le gras dans une cellule, CellSpacing la taille de la bordure
(comme pour les <TABLE>s .HTML, naturellement
o BgColor et la couleur de la zone dessinée
o Options.dgShowTitles permet de supprimer les titres des colonnes

4.5 - Gestion des Sessions

Par définition, le protocole .HTTP est sans état: lorsqu'un Client demande une page, le
Serveur la lui envoie, et oublie tout de cette requête. Ceci évite d'avoir à gérer au niveau du
Serveur l'état de chaque Client.

Certaines applications nécessitent toutefois une gestion de la session. Si nous souhaitons


afficher les lignes d'une Table par groupe de 10 lignes, il faut bien mémoriser quelque part
que nous avons affiché les lignes 09, et lorsque nous cliquons "Next", nous souhaitons les
lignes 1011. Il faut donc que notre application (et non pas le Serveur) se charge de gérer l'état
du dialogue entre le Serveur et le Client.
Les sessions sont gérées automatiquement par Intraweb. En fait, c'est la tIwApplication qui
gère la session:

nous lançons le Serveur Intraweb


un nouvel utilisateur se connecte
un objet tIwApplication est automatiquement créé. Cet objet

 contient la pile des tIwForm créées (les pages)


 il contient un attribut tIwApplication.Data qui, par défaut, pointe vers un
tIwUserSession qui est un descendant de tDataModule

et chaque tIwForm contient une référence tIwForm.WebApplication, vers l'application.

5 - Commentaires sur IntraWeb

5.1 - Remarques

 beaucoup d'articles d'initiation Intraweb exagèrent sur le miracle de la conception


visuelle de pages Web avec Intraweb. Certes c'est beaucoup plus agréable que la
technique de construction par NotePad, mais ce n'est toujours, appliqué aux pages
.HTML, que ce que fait Delphi pour Windows depuis 1995 !
 la documentation est assez succinte, et les articles IntraWeb sont un peu emphatiques
et ampoulés, en un mot, "marketing". Il y a aussi différents documents, mais certains
ne semblent pas indiquer la version IntraWeb qu'ils sont censés documenter
 comme Indy, Intraweb a une "granularité" très fine. Un nombre impressionnant de
composants, et de pages sur la Palette.
 ce morcellement entraîne aussi de fréquents changements d'architecture. Comme
mentionné plus haut, nos diagrammes de classe ont utilisé la version Intraweb fournie
avec Delphi 6. Et les composants de la version 8 (fournis avec Delphi 2006) n'ont pas
tout à fait la même organisation.
Mentionnons toutefois que
o ces réorganisations correspondent à de nouvelles fonctionalités, et à ce titre
sont bienvenues
o les modifications touchent essentiellement l'organisation des classes internes,
et concernent un peu moins les application que nous développons.
o l'aide comporte aussi des informations sur la migration entre les versions
IntraWeb
o parmi quelques problèmes de migration rencontrés en utilisant certains
exemples écrits avec d'autres versions, mentionnons
 des propriétés qui n'existent plus ou pas encore (Font.BackColor,
Netscape, IwImage.JpegOptions, IwLabel.Color)
 vous pouvez aussi avoir, en fonction de la version Delphi et Intraweb,
des messages du style "Dynamic Grids are not available in this
edition".
 certains exemples trouvés sur le Web placent le Serveur Intraweb dans le TrayIcon (la
partie en bas à droite de la barre de tâche Windows contenant des icônes, telles que
l'heure etc). De ce fait, si le Serveur est encore chargé, vous ne pourrez pas recompiler
l'application. Nous ne pouvons pas non plus la compiler si le Serveur est visible sur la
barre de tâche, mais au mois là nous le voyons de façon évidente. Il arrive d'ailleurs
que le TrayIcon XP contienne plusieurs icônes de Serveurs Intraweb, ou même que la
barre de tâches contienne plusieurs Serveurs. Fermez-les les uns après les autres, et
passez simplement la souris sur les icônes du TrayIcon
 l'exécution du Serveur Intraweb Standalone supprime toute page ouverte dans
Internet Explorer. Cela peut devenir pénible, surtout si vous étiez à la recherche
d'informations pour résoudre un problème Intraweb, ou en train de vérifier le tutorial
Interbase en cours de frappe ...

5.2 - Autre possibilités

Intraweb permet de créer des applications Web, et le Web est censé remplacer un jour toutes
les applications locales. Il faut donc qu'Intraweb soit aussi riche que tous les composants
Windows locaux. Vaste programme.

Notre tutoriel n'a donc pu tout présenter, et parmi les domaines non présentés:

 le développement en mode "page". Ce type de pages nécessite l'utilisation d'un


Serveur de type IIS, et fonctionne en conjonction avec WebBroker, et WebSnap
 les techniques côté client
o la validation utilisant Javascript
o l'ajout de Javascript aux pages générées
o les composants de données IwClientSideDataset, l'utilisation de fichiers .XML
(XmlBroker)
 l'authentification des utilisateurs
 l'utilisation de tFrame, en particulier pour armer des menus
 les composants divers (TreeView, menus, composants Flash, vidéos etc)
 la génération de code à partir de templates
 la gestion des exceptions
 la génération de pages pour la téléphonie (WAP) ou les PDA
 l'utilisation de communications sécurisées (SSL)
 les versions .NET d'Intraweb, les outils externes utilisables en conjonction avec
Intraweb (Rave Reports ou DevExpress)

6 - Télécharger le code source Delphi


Vous pouvez télécharger:

 01_iw_calculator.zip : le premier projet Intraweb (11 K)


 02_iw_two_pages.zip : transfert de pages Web (10 K)
 03_iw_dbedit.zip : affichages de données d'une Table BDE (8 K)
 04_iw_dbgrid_interbase.zip : utilisation d'une grille, avec Interbase (9 K)
 05_iw_edit_dbgrid_ado.zip : une grille modifiable, avec une connection ADO (11 K)

Ce .ZIP qui comprend:

 le .DPR, la forme principale, les formes annexes eventuelles


 les fichiers de paramètres (le schéma et le batch de création)
 dans chaque .ZIP, toutes les librairies nécessaires à chaque projet (chaque .ZIP est
autonome)

Ces .ZIP, pour les projets en Delphi 6, contiennent des chemins RELATIFS. Par conséquent:

 créez un répertoire n'importe où sur votre machine


 placez le .ZIP dans ce répertoire
 dézippez et les sous-répertoires nécessaires seront créés
 compilez et exécutez

Ces .ZIP ne modifient pas votre PC (pas de changement de la Base de Registre, de DLL ou
autre). Pour supprimer le projet, effacez le répertoire.

La notation utilisée est la notation alsacienne qui consiste à préfixer les identificateurs par la
zone de compilation: K_onstant, T_ype, G_lobal, L_ocal, P_arametre, F_unction, C_lasse.
Elle est présentée plus en détail dans l'article La Notation Alsacienne

Comme d'habitude:

 nous vous remercions de nous signaler toute erreur, inexactitude ou problème de


téléchargement en envoyant un e-mail à jcolibri@jcolibri.com. Les corrections qui
en résulteront pourront aider les prochains lecteurs
 tous vos commentaires, remarques, questions, critiques, suggestion d'article, ou
mentions d'autres sources sur le même sujet seront de même les bienvenus à
jcolibri@jcolibri.com.
 plus simplement, vous pouvez taper (anonymement ou en fournissant votre e-mail
pour une réponse) vos commentaires ci-dessus et nous les envoyer en cliquant
"envoyer" :

Nom :
E-mail :
Commentaires * :


 et si vous avez apprécié cet article, faites connaître notre site, ajoutez un lien dans
vos listes de liens ou citez-nous dans vos blogs ou réponses sur les messageries.
C'est très simple: plus nous aurons de visiteurs et de références Google, plus nous
écrirons d'articles.

7 - Références
Intraweb est fourni en version BE avec les nouvelles versions de Delphi. Vous pouvez
récupérer les mises à jour, ou les versions plus complètes auprès de AtoZed

Nous organisons aussi régulièrement des Formations IntraWeb qui entrent en détail dans la
construction, la mise au point et le dépoloiement d'applications IntraWeb.

8 - L'auteur
John COLIBRI est passionné par le développement Delphi et les applications de Bases de
Données. Il a écrit de nombreux livres et articles, et partage son temps entre le
développement de projets (nouveaux projets, maintenance, audit, migration BDE, migration
Xe_n, refactoring) pour ses clients, le conseil (composants, architecture, test) et la
formation. Son site contient des articles avec code source, ainsi que le programme et le
calendrier des stages de formation Delphi, base de données, programmation objet,
Services Web, Tcp/Ip et UML qu'il anime personellement tous les mois, à Paris, en
province ou sur site client.

You might also like