Вы находитесь на странице: 1из 14

ALLER PLUS LOIN AVEC DELPHI 6

Support de formation

Aller plus loin avec Delphi 6

1. Les API (Application Program Interface) Windows


Pour aller plus loin dans la programmation fentre, il faut s'intresser au cur mme de Windows. Il existe des bibliothques de procdures et de fonctions fournies l'utilisateur sous forme de DLL afin de raliser les tches de programmation les plus pointues (par exemple l'attaque d'un modem sur un port srie). Les outils graphiques se trouvent au sein du GDI (Graphic Device Independance). Ce systme est indpendant de l'cran ou de l'imprimante connects. Delphi met notre disposition ces mthodes "bas niveau" en incluant les prototypes de celles-ci dans l'unit "Windows".

1.1

La notion de "handle"

Nous avons bien compris que l'essentiel de notre travail se fait sur les classes qui comportent l'ensemble des dfinitions des proprits et des mthodes. Une classe peut gnrer des objets au cours d'une opration de cration. Lorsque l'objet est cr, la mthode de cration rserve la mmoire ncessaire pour "loger" l'objet. Pour manipuler l'objet, il faut connatre son adresse: c'est le rle des "Handle" ou poignes (16384 max.) qui sont des pointeurs contenant l'adresse de celui-ci. Ces pointeurs sont utiles pour manipuler tous types d'objets Windows: visuels: fentres, barres d'outils et de menus, boutons, listes, graphiques (GDI): bitmaps, stylos, brosses, systmes (kernel): processus et traitements, communications, fichiers,

Maurice GINDENSPERGER (V 6.0)

page 2/14

Aller plus loin avec Delphi 6

1.2

Exemple d'utilisation: trac d'un carr


procedure TForm1.Button1Click(Sender: TObject); var Poignee: THandle; Contexte:HDC; begin Poignee:=Form1.Handle; Contexte:=GetDC(Poignee); Rectangle(Contexte, 10, 10, 400, 400); ReleaseDC(Poignee,Contexte); end;

Puisque nous utilisons les fonctions du GDI, il nous faut une poigne supplmentaire (de type HDC), appele contexte de dispositif. En effet, ceci permet d'indiquer au systme o nous allons dessiner (cran, imprimante, ).

Maurice GINDENSPERGER (V 6.0)

page 3/14

Aller plus loin avec Delphi 6

2.
2.1

MULTITRAITEMENT
Le problme du systme multitches

Windows est un systme d'exploitation multitches, c'est dire que plusieurs programmes (tches) peuvent tre excutes simultanment. Pourtant, ce systme d'exploitation n'est pas premptif , c'est dire qu'une application peut mobiliser le processeur temps complet. Il est donc indispensable d'ajouter des lignes de code dans nos applications pour viter ce phnomne, particulirement embarrassant dans l'excution des boucles (ex: Application.ProcessMessages). Chaque fois que nous excutons une application standard, une tche est cre. Windows rserve une zone de mmoire (4Go. virtuels) pour ses besoins. D'autre part la tche va excuter un traitement nomm "Thread": c'est le traitement principal de l'application. Lors de l'excution active du traitement, il est souvent difficile de lancer une autre action ou mme de dplacer la fentre d'excution. Essayez le code suivant dans une fiche pourvue d'un "Edit" et d'un "Button": procedure TForm1.Button1Click(Sender: TObject); var i:integer; begin for i:=1 to 100000 do Edit1.Text:=IntToStr(i); end; On ne voit mme pas l'affichage dfiler, puisque les messages envoys au composant "Edit" ne sont pas traits pendant l'excution de la boucle. Le fait de rajouter une ligne de code amliore la situation, on peut mme dplacer la fentre. procedure TForm1.Button1Click(Sender: TObject); var i:integer; begin for i:=1 to 10000 do begin Edit1.Text:=IntToStr(i); Application.ProcessMessages; end; end;

Maurice GINDENSPERGER (V 6.0)

page 4/14

Aller plus loin avec Delphi 6

Je souhaite voir dfiler 2 compteurs en mme temps. Je rajoute donc un 2 "Edit" et un 2 "Button" auquel j'affecte une procdure semblable: procedure TForm1.Button2Click(Sender: TObject); var j:integer; begin for j:=1 to 10000 do begin Edit2.Text:=IntToStr(j); Application.ProcessMessages; end; end; A l'excution, je constate que le fait d'appuyer sur le premier bouton fait bien dfiler le 1er compteur. Pendant ce temps, j'appuie sur le 2 bouton: le premier compteur est suspendu alors que le 2 fonctionne. Ds son arrt, le 1er termine son travail. Il est maintenant vident qu'un programme habituel n'accomplit qu'un seul traitement. Les diffrentes procdures sont empiles puis dpiles par le systme, mais ne peuvent "tourner" simultanment. L'alternative cette problmatique est la cration de traitements (Threads) " la vole", on va faire croire l'utilisateur qu'il dispose de plusieurs processeurs (16 max).

Maurice GINDENSPERGER (V 6.0)

page 5/14

Aller plus loin avec Delphi 6

2.2 Exemple d'application multi-traitements (multithread)


Raliser la fiche suivante:

A. On peut commencer crire la procdure excuter par le traitement: procedure MonTraitement; var i:integer; begin i:=0; while true do begin inc(i); Form1.Edit1.Text:=format('Le compteur : %d',[i]); end; end; N'ayons pas peur ici d'une boucle infinie, puisque le traitement peut tre interrompu par une commande particulire. B. Dclarer les variables ncessaires au traitement (en global pour l'unit): var ThreadID, hThread: THandle; Un traitement est caractris par 2 proprits, son numro et le pointeur servant le manipuler. Rappel: un "handle" est un pointeur permettant de manipuler les objets de Windows dans le cas de l'utilisation des mthodes des APIs.

Maurice GINDENSPERGER (V 6.0)

page 6/14

Aller plus loin avec Delphi 6

C. Ecrire la procdure pour le bouton "Marche1" procedure TForm1.BtM1Click(Sender: TObject); begin HThread:=CreateThread(nil,0,@MonTraitement,nil,0,ThreadID); end; Nous faisons appel ici la fonction "CreateThread" de l'API Windows ( vois dans l'aide en ligne). D. Ecrire la procdure pour le bouton "Suspend 1" procedure TForm1.BtS1Click(Sender: TObject); begin SuspendThread(HThread); end; Un traitement peut "s'endormir" !!! E. Ecrire la procdure pour le bouton "Reprend 1" procedure TForm1.BtR1Click(Sender: TObject); begin ResumeThread(HThread); end; Un traitement peut "se rveiller" !!! F. Ecrire la procdure pour le bouton "Arrt 1" procedure TForm1.BtA1Click(Sender: TObject); begin TerminateThread(hThread,0); end; Un traitement peut heureusement s'arrter.

Maurice GINDENSPERGER (V 6.0)

page 7/14

Aller plus loin avec Delphi 6

G. Vrifier le fonctionnement puis refaire de mme pour le 2 traitement. Le code complet sera voisin du suivant: unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) BtM1: TButton; Edit1: TEdit; BtA1: TButton; Edit2: TEdit; BtM2: TButton; BtA2: TButton; BtS1: TButton; BtS2: TButton; BtR1: TButton; BtR2: TButton; procedure BtM1Click(Sender: TObject); procedure BtA1Click(Sender: TObject); procedure BtM2Click(Sender: TObject); procedure BtA2Click(Sender: TObject); procedure BtS1Click(Sender: TObject); procedure BtS2Click(Sender: TObject); procedure BtR1Click(Sender: TObject); procedure BtR2Click(Sender: TObject); private { Dclarations prives} public { Dclarations publiques} end; var Form1: TForm1; ThreadID, hThread: THandle; ThreadID2, hThread2: THandle; implementation {$R *.DFM} procedure MonTraitement; var i:integer; begin i:=0; while true do
Maurice GINDENSPERGER (V 6.0)

page 8/14

Aller plus loin avec Delphi 6

begin inc(i); Form1.Edit1.Text:=format('Le compteur : %d',[i]); end; end; procedure MonTraitement2; //stdcall; var j:integer; begin j:=0; while true do begin inc(j); Form1.Edit2.Text:=format('Le compteur : %d',[j]); end; end; procedure TForm1.BtM1Click(Sender: TObject); begin HThread:=CreateThread(nil,0,@MonTraitement,nil,0,ThreadID); end; procedure TForm1.BtA1Click(Sender: TObject); begin TerminateThread(hThread,0); end; procedure TForm1.BtM2Click(Sender: TObject); begin HThread2:=CreateThread(nil,0,@MonTraitement2,nil,0,ThreadID2); end; procedure TForm1.BtA2Click(Sender: TObject); begin TerminateThread(hThread2,0); // ou mieux, utiliser la fonction ExitThread end; procedure TForm1.BtS1Click(Sender: TObject); begin SuspendThread(HThread); end; procedure TForm1.BtS2Click(Sender: TObject); begin SuspendThread(HThread2); end; procedure TForm1.BtR1Click(Sender: TObject); begin ResumeThread(HThread); end;
Maurice GINDENSPERGER (V 6.0)

page 9/14

Aller plus loin avec Delphi 6

procedure TForm1.BtR2Click(Sender: TObject); begin ResumeThread(HThread2); end; end. Le fonctionnement des traitements n'empche pas l'excution d'autres tches, ni le traitement des messages par l'application: on peut donc quitter celle-ci tout moment. D'autre part, on remarque que le traitement principal du programme n'est pas sollicit et que les 2 traitements s'excutent une vitesse voisine. Il est possible de changer la priorit des traitements.

2.3

Priorit des traitements

Il est possible de changer la priorit des traitements par la fonction SetThreadPriority. Exemple pour notre bouton "Marche 1": procedure TForm1.BtM1Click(Sender: TObject); begin HThread:=CreateThread(nil,0,@MonTraitement,nil,0,ThreadID); SetThreadPriority(HThread,THREAD_PRIORITY_HIGHEST);// end; On constate maintenant que le premier compteur est plus rapide que le second. Le systme de priorit n'est pas simple, puisqu'il faut d'abord tenir compte de la classe de priorit de la tche (application). 2.3.1 Priorits des applications La fonction "GetPriorityClass" retourne la priorit de la tche. Priorit application HIGH_PRIORITY_CLASS IDLE_PRIORITY_CLASS NORMAL_PRIORITY_CLASS REALTIME_PRIORITY_CLASS Signification haute priorit: utilise presque toutes les ressources du processeur basse priorit: s'excute quand la charge du processeur est voisine de zro priorit normale priorit absolue: mme sur les disques et la souris Indice 13 4 79 24

Maurice GINDENSPERGER (V 6.0)

page 10/14

Aller plus loin avec Delphi 6

2.3.2 Priorits des threads (traitements) La fonction GetThreadPriority nous renseigne sur la priorit en cours. Indicateur de priorit du traitement THREAD_PRIORITY_ABOVE_NORMAL THREAD_PRIORITY_BELOW_NORMAL THREAD_PRIORITY_HIGHEST THREAD_PRIORITY_IDLE THREAD_PRIORITY_LOWEST THREAD_PRIORITY_NORMAL THREAD_PRIORITY_TIME_CRITICAL Indice de priorit + 1 / tche - 1 / tche + 2 / tche valeur de 1 pour toutes les tches sauf REALTIME_PRIORITY_CLASS (16). - 2 / tche + 0 / tche valeur de 15 pour toutes les tches sauf REALTIME_PRIORITY_CLASS (31).

2.4

Temps d'excution

Attention, sous Windows, on ne sait jamais quel va tre le temps d'excution d'un traitement. Il n'est videmment plus question de chronomtrer, puisque plusieurs traitements s'effectuent "en parallle". 2.4.1 Suspendre l'excution d'une dure connue Employer la fonction Sleep(Millisecondes). 2.4.2 Attendre un vnement Utiliser la fonction WaitMessage Envoyer un message au traitement: PostThreadMessage

Maurice GINDENSPERGER (V 6.0)

page 11/14

Aller plus loin avec Delphi 6

3.

DELPHI pour le WEB


Il est simple de construire des fiches DELPHI et de les dployer sur le WEB.

3.1

Cration d'une fiche ACTIVE

Choisir "Fichier- Tout fermer" puis "Fichier - Nouveau - Autre" puis "Fiche active" dans l'onglet "Active X".

Taper le nom:

Maurice GINDENSPERGER (V 6.0)

page 12/14

Aller plus loin avec Delphi 6

Une nouvelle fiche apparat. Il suffit d'y placer des composants.

Enregistrer dans un nouveau dossier bien identifi. Choisir "Excuter - recenser le serveur Active X":

Choisir "Projet - Options de dploiement pour le web"

Maurice GINDENSPERGER (V 6.0)

page 13/14

Aller plus loin avec Delphi 6

Choisir "Projet -dployer pour le Web". Si tout va bien, on doit obtenir une page WEB:

On constate le fonctionnement.

Maurice GINDENSPERGER (V 6.0)

page 14/14

Вам также может понравиться