Affecter une procedure OnWorkBegin

cs_Gerard Messages postés 121 Date d'inscription jeudi 10 janvier 2002 Statut Membre Dernière intervention 7 août 2018 - 8 avril 2009 à 10:29
Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 - 10 avril 2009 à 18:07
Je voudrais avoir un bargraph qui montre la progression d'un transfert de fichier.
J'utilise les composants Indy10 avec Turbo Delphi.
Je n'arrive pas à affecter mes procédures OnWorkbegin et OnWork au IdTCPClient
le code suivant sort des erreurs:

  IdTCPClient1.OnWorkBegin:= IdTCPOnWorkBegin(Sender,wmRead,AWorkCount);
  OnWork:= IdTCPWork;

Le premier me dit que les types sont incompatibles (TWorkbeginEvent et procédure)
Le second que je n'ai pas assez de paramètres...
Bien sûr j'ai tourné tout cela dans tous les sens..avec, sans paramètres...
J'ai même essayé un transtypage d'un TworkBeginEvent....

15 réponses

Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 10
8 avril 2009 à 12:58
Ben evidemment ... un TWorkBeginEvent est une méthode d'objet avec plusieurs procédures, il te faut les respecter.

Exemple simple : tu as un événement, dans un composant lambda, qui te fournit un nom d'utilisateur et son mot de passe (en plus du traditionnel Sender). La déclaration de cette méthode d'objet est :

TMonEvenement = procedure (Sender: TObject; User, Password: String) of Object;

Quand tu vas déclarer une procédure pour répondre à cet événement, il te faudra la déclarer comme çela :

procedure TForm1.ReponseEvenement(Sender: TObject; User, Password: String);

Et voilà :)

Cordialement, Bacterius !
0
Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 10
8 avril 2009 à 13:02
Oups il fallait lire "paramètres" à la place de "procédures" dans la première phrase :)

Cordialement, Bacterius !
0
cs_Gerard Messages postés 121 Date d'inscription jeudi 10 janvier 2002 Statut Membre Dernière intervention 7 août 2018
9 avril 2009 à 10:10
Merci de ta réponse, mais je ne dois pas être bien malin, ou mal réveillé...


je ne comprends pas tout.


1) Comment la première déclaration est-elle rattachée à ton objet lambda?


2) comment la procedure Réponse à l'évènement est-elle rattachée à la première déclaration?


J'ai bien sûr essayé, mais cela me sort toujours des erreurs...
0
Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 10
9 avril 2009 à 16:07
Pour lier, tu fais :

procedure TForm1.MonEvenement(LesParametresQuiCorrespondentACetEvenement);
begin
... Le code de l'événement ...
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
// On rattache l'événement
MonCompo.MonEvenement := MonEvenement;
end;

Et voilà !

Cordialement, Bacterius !
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
9 avril 2009 à 22:24
Pour que ce soit plus clair pour notre ami et si je puis me permettre :
Il eût mieux valu écrire :
procedure TForm1.FormCreate(Sender: TObject);

begin

   // On rattache l'événement

  MonCompo.
OnMonEvenement := MonEvenement;

end;

Au lieu de :
procedure TForm1.FormCreate(Sender: TObject);

begin

  // On rattache l'événement

   MonCompo.MonEvenement := MonEvenement;

end;

Autrement, pour affecter une méthode à un évènement, il faut que la méthode soit conforme à la signature du type attendu. C'est ce qu'a essayé de t'expliquer maître Bacterius

May Delphi be with you<hr />Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
0
Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 10
9 avril 2009 à 22:31
Oui désolé j'ai oublié le On. Et voilà c'est la signature de la méthode, voilà c'est le mot que je cherchais :) merci DelphiProg :)

Cordialement, Bacterius !
0
cs_Gerard Messages postés 121 Date d'inscription jeudi 10 janvier 2002 Statut Membre Dernière intervention 7 août 2018
10 avril 2009 à 06:30
Il me semble que c'est ce que j'ai fait.


Cela marche pour OnConnected et OnDisconnected (qui n'ont que Sender comme paramètre) mais pas pour OnWorkBegin et on work qui ont d'autres paramètres.
Voilà mon code:
Déclaration dans la partie publique de la déclaration de la form.
  public
    { Déclarations publiques }
    IdTCPClient1: TIdTCPClient;
    procedure IdTCPClient1OnConnected(Sender: Tobject);
    procedure IdTCPWork(Sender: TObject; AWorkMode: TWorkMode;
  const AWorkCount: Integer);
    procedure IdTCPOnWorkBegin(Sender: Tobject; AWorkMode: TWorkMode;
  const AWorkCountMax: Integer);
  end;
Partie dans la création de la form...
procedure TForm1.FormCreate(Sender: TObject);
begin
  IdTCPClient1:= TIdTCPClient.Create(self);
With IdTCPClient1 do
Begin
  Port:=3000;
  Host:='localhost';
  OnConnected:= IdTCPClient1OnConnected;
  OnDisconnected:= IdTCPClient1OnConnected;
  IdTCPClient1.OnWorkBegin:= IdTCPOnWorkBegin(Sender,wmRead,AWorkCount);
  OnWork:= IdTCPWork;
  ReadTimeout:=10000;
end;

Et bien sûr la déclaration des procédures que je n'ajoute pas: cela n'est pas le problème.
Donc: On connected et OnDisconnected marchent, mais pas OnWorkBegin et Onwork.
J'ai essayé sans paramètre (ex OnWork) ou avec paramètres (OnWorkBegin)
Dans le premier cas le compilateur me signale pas assez de paramètres, dans le second
E2010 Types incompatibles : 'TWorkBeginEvent' et 'procedure, untyped pointer or untyped parameter'
(Le type des paramètres est bien déclaré en partie commune... et on ne peut pas les redéclarer ici: syntaxe incorrecte..)
0
Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 10
10 avril 2009 à 14:42
En général, si tu reçois l'erreur "procedure, untyped pointer or untyped parameter" c'est que tu essaies de filer à un événement une procédure "flottante", c'est-à-dire qui n'est pas une méthode. Il faut que ta procédure à rattacher à l'événement soit déclarée après le "public" de la fiche, par exemple.

Cordialement, Bacterius !
0
Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 10
10 avril 2009 à 14:48
Et euh ça c'est pas bon du tout :

IdTCPClient1.OnWorkBegin:= IdTCPOnWorkBegin(Sender,wmRead,AWorkCount);

Essaye ça ?

IdTCPClient1.OnWorkBegin := IdTCPOnWorkBegin;

Si ça ne fonctionne pas c'est que tu n'as pas les bons paramètres pour OnWorkBegin, réfère-toi à la doc.

Cordialement, Bacterius !
0
cs_Gerard Messages postés 121 Date d'inscription jeudi 10 janvier 2002 Statut Membre Dernière intervention 7 août 2018
10 avril 2009 à 15:56
La doc, c'est la première chose que j'ai faite.


Ce que tu proposes, j'ai bien sûr essayé..
J'ai bien déclaré (voir mon code) la procédure, mais je ne vois pas comment elle serait rattachée à l'objet IdTCPClient1, autrement qu'au moment de la création... (Ce qui marche pour Onconnected)
Je peux comprendre inturitivement qu'il y ait une différence entre une procédure "flottante" '(quezaco?) et une méthode d'objet, mais:
Pour moi tout cela ca finit par des lignes de code, comment on fait pour qu'elles deviennent méthode d'objet?
pourquoi onconnected et Ondisconnected marchent: aucun problème; et pas OnWorkbegin et On work, qui c'est vrai ont davantage de paramètres...
0
Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 10
10 avril 2009 à 16:07
Une méthode d'objet c'est une procédure ou une fonction qui font partie d'une classe (par exemple Create pour n'importe-quel objet dans Delphi). Une procédure flottante c'est par exemple la procédure IntToStr, qui n'appartient à rien du tout (d'où le nom flottante) et tu peux l'appeller quand tu veux.
Montre tout le code et je le rectifierai, et on verra l'explication après.

Cordialement, Bacterius !
0
cs_Gerard Messages postés 121 Date d'inscription jeudi 10 janvier 2002 Statut Membre Dernière intervention 7 août 2018
10 avril 2009 à 16:46
Merci pour ta proposition, mon code il est au-dessus:
Déclaration dans la partie publique de la déclaration de la form.
  public
    { Déclarations publiques }
    IdTCPClient1: TIdTCPClient;
    procedure IdTCPClient1OnConnected(Sender: Tobject);
    procedure IdTCPWork(Sender: TObject; AWorkMode: TWorkMode;
  const AWorkCount: Integer);
    procedure IdTCPOnWorkBegin(Sender: Tobject; AWorkMode: TWorkMode;
  const AWorkCountMax: Integer);
  end;
Partie dans la création de la form...
procedure TForm1.FormCreate(Sender: TObject);
begin
  IdTCPClient1:= TIdTCPClient.Create(self);
With IdTCPClient1 do
Begin
  Port:=3000;
  Host:='localhost';
  OnConnected:= IdTCPClient1OnConnected;
  OnDisconnected:= IdTCPClient1OnConnected;
  IdTCPClient1.OnWorkBegin:= IdTCPOnWorkBegin(Sender,wmRead,AWorkCount);
  OnWork:= IdTCPWork;
  ReadTimeout:=10000;
end;

et les procédures appelées sont on ne peut plus simples:
procedure Tform1.IdTCPOnWorkBegin(Sender: Tobject; AWorkMode: TWorkMode;  const AWorkCountMax: Integer);
  begin     ProgressBar1.Max :AWorkCountMax; //Maximum taille de l'élément
     ProgressBar1.Position := 0; //Position à zéro
  end;


procedure TForm1.IdTCPWork(Sender: TObject; AWorkMode: TWorkMode;  const AWorkCount: Integer);
begin
   if AWorkMode=wmRead then //uniquement quand le composant recoit des données
     ProgressBar1.Position := AWorkCount;
end;

Les deux lignes qui posent problème sont:
  IdTCPClient1.OnWorkBegin:= IdTCPOnWorkBegin(Sender,wmRead,AWorkCount);
  OnWork:= IdTCPWork;
j'ai essayé de mettre des paramètres ou pas et j'ai une erreur (différente) pour chacune des 2 lignes.
Je peux maintenant t'envoyer tout le programme: c'est un programme qui se connecte à un serveur, qui vérifie la mise à jour de fichier, et qui s'ils ne sont pas à jour entreprend de les télécharger. Ca, ça marche bien sans problème. C'est un peu long, plusieurs minutes, et c'est pour cela que je voudrais bien un indicateur d'avancement de la tâche...
merci tu es vraiment sympa...
0
Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 10
10 avril 2009 à 16:58
J'ai trouvé : mets tes déclarations de méthode d'objet en dessous de private plutôt que de public. Chez moi ça marche quand je fais ça.

Cordialement, Bacterius !
0
cs_Gerard Messages postés 121 Date d'inscription jeudi 10 janvier 2002 Statut Membre Dernière intervention 7 août 2018
10 avril 2009 à 17:40
Oui, je vais regarder tes composants, tu as raison il faut utiliser ce qui est bien et que les gens rendent disponible!
Bon mais il faudra quand même que je récupère l'évènement onWork, car je suppose que c'est lui qui mettra à jour la porgress bar. Au moins c'est ce qui est dit dans la doc.
Pour le private, public, j'avais bien sûr essayé. Sans succès.
alors si chez toi cela marche on a une piste? D'où vient la différence?
Moi j'utilise Turbo Delphi. les composants Indy n'apparaissent pas dans les composants disponibles, il faut les déclarer mais cela ne pose pas de problème. les composants Induy marche bien, le téléchargemetn se fait bien, mais comme c'est un stream géré par Indy, je n'ai pas d'uatre accès à l'avancement de la tâche...
Et c'est embêtant car c'est destiné à être diffusé à n'importe qui (du point de vue niveau ordinateur) et sans visuel je sens que je vais avoir des problèmes...


Franchement si je peux te passer mes sources que tu voies si tu arrives à compiler, pas de problème...
0
Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 10
10 avril 2009 à 18:07
Oui je sais que TurboDelphi n'autorise pas l'installation des composants tu dois les créer dynamiquement c'est pénible. En tout cas moi je suis sur Delphi 6 et ça marche. Tu es sûr que tu as Indy 9 ? (parfois certains ont Indy 10 et regardent la doc de Indy 9 par erreur).
Pour les sources je suis d'accord, j'ai peut-être mal recopié la source. Envoie-les moi par mail, je t'envoie mon mail par message privé.

Cordialement, Bacterius !
0
Rejoignez-nous