Execution d'une fonction identique de plusieurs fiche [Résolu]

Messages postés
296
Date d'inscription
dimanche 14 mars 2004
Statut
Membre
Dernière intervention
18 décembre 2014
- - Dernière réponse : f0xi
Messages postés
4200
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
2 janvier 2019
- 6 août 2013 à 23:01
Bonjour,

J'ai construit une application MDI qui permet d'analyser un réseau CAN.
A partir d'une fiche de configuration, on peut ajouter des fiches "traces", "graphique",etc...

Toutes ces fiches ont un point commun : une procedure appelé Work exemple :

TFDataView = class(TForm)
    SG_DataView: TStringGrid;
    ...
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    ...
  private
    { Déclarations privées }
    ...
  public
    { Déclarations publiques }
    Setup : TStringList;
    Procedure ReadSetup(var ListSetup : TStringList);
    Procedure WriteSetup(var ListSetup : TStringList);
    Procedure Start;
    Procedure Stop;
    Procedure Work(var Buffer : Array of byte;var Count : integer);
  end;


J'aimerais lors de la création de la fiche récupérer un Handle, une adresse de ma fiche créé afin de pouvoir rapidement executer la fonction work.

Actuellement, j'utilise l'acces par nom est c'est trop long (en temps de traitement). j'utilise par exemple :

TFDataView(Application.FindComponent(name)).Work(Buffer,Count);

avec name contenant le nom de la fiche TDataview pour executer cette fonction work

Pour acceder à la fonction Work du TDataView.

Ca fonctionne mais comme cette fonction est appelé plusieurs fois par seconde ( toutes les 10ms environ), lorsqu'il y a une évolution de mes données contenu dans le buffer, mon programme met 2s avant d'afficher le résultat.

Mon objectif est d'optimiser le code.

Le top : au moment de la création de la nouvelle fiche, récupérer l'adresse de la fonction work de l'objet. et pour l'execution, appeler cette fonction par son adresse mémorisée dans un tableau.

Je pense que le temps perdu vient du FindComponent(name).
Si je pouvais m'en passer, je gagnerais un temps précieux.

Merci à vous tous
Afficher la suite 

6 réponses

Meilleure réponse
Messages postés
3809
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
1 septembre 2019
32
1
Merci
Salut,

pourquoi pas directement avec le nom de la fiche ?

var
  MaFiche: TFDataView;
  ...

  MaFiche := TFDataView.Create(Self);
  MaFiche.Work(Buffer, Count);

Dire « Merci » 1

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 193 internautes nous ont dit merci ce mois-ci

Commenter la réponse de Cirec
Messages postés
192
Date d'inscription
mercredi 29 décembre 2004
Statut
Membre
Dernière intervention
2 octobre 2014
1
1
Merci
Bonjour,

Pourquoi ne pas utiliser les TObjectList ou TcomponentList plutôt que des tableaux ?

Jean

Dire « Merci » 1

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 193 internautes nous ont dit merci ce mois-ci

Commenter la réponse de jderf
Messages postés
296
Date d'inscription
dimanche 14 mars 2004
Statut
Membre
Dernière intervention
18 décembre 2014
2
0
Merci
Merci pour ton aide Cirec.
En fait, je ne peux pas car je conserve les noms des objets que je créé dynamiquement dans un tableau de chaine. Pendant l'execution,le programme recoit un tableau de valeur venant de l'interface (le buffer) et ensuite, je prend mon tableau de chaine et j'execute une à une les fonction work de mes fiches ( dans l'ordre que l'utilisateur a choisi).

Donc à l'instant où je recoit des données, je connais uniquement les noms car les object que je créé sont des fiches qui sont toutes différentes (un TDataView permet de voir des valeurs particulières, un TPlot permet de tracer des courbes à partir des données recu).

Je ne sais pas s'il est possible de créer des tableaux pouvant contenir des fiches différentes. Ca me permettrais de faire par exemple :
var  F : TDataView;
begin
  F : TDataView.Create(Self);
  Tableau[i] := F;
end;

et lorsque je veux l'executer :
Tableau[i].work(buffer,nbbuffer);


Sinon, je suis en train de regarder s'il est possible de donner l'ordre à ma fiche par un SendMessage(....) d'executer work.
car il est possible de récupérer le Handle de la fiche au moment de la création.
Mais là, je ne sais pas non plus comment ca marche exactement.

Oniria

Mon site web :
Commenter la réponse de Oniria
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
5
0
Merci
Salut Oniria,

c' est asssez simple.
Tu crées une variable de type TFDataView que tu affectes qu' une seule fois:
var
aDataView : TFDataView;

aDataView := TFDataView(Application.FindComponent(name));

Tu n' as plus qu' à appeler au bon endroit :
aDataView.Work();

a+
Commenter la réponse de cs_MAURICIO
Messages postés
296
Date d'inscription
dimanche 14 mars 2004
Statut
Membre
Dernière intervention
18 décembre 2014
2
0
Merci
Mauricio, je ne peux pas faire ce que tu me dis car mes fiches sont créées dynamiquement. Je n'ai pas une seule fiche de chaque, mais l'utilisateur peut ajouter 2 fiche de "PLOT", 3 fiche "Dataview" etc...
Il faut donc que je passe par un tableau quelconque.

Jderf : je ne connaissais pas ces composants ... Merci de l'info, je vais regarder comment ils fonctionnent.

En tout cas, merci beaucoup de votre aide si précieuse.
f0xi
Messages postés
4200
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
2 janvier 2019
26 -
Je confirme l'utilisation du TObjectList voir même d'une TList surchargée pour le type TFDataView.

si tu possède Delphi à partir de D2009, tu peux faire cela en quelque lignes :

Unit (*...*);

interface 

uses (*...*), Generics.Collections;

Type
  TFDataView = class
    (*...*)
  end;

  TFDataViewList = TList<TFDataView>;

(*...*)

var
  FDataViewList = TFDataViewList;

implementation

(*...*)

initialization 
  FDataViewList := TFDataViewList.Create;
finalization
  FDataViewList.Free;
end.

que tu pourras utiliser comme cela :

ajout d'un FDataView :

FDV := TFDataView.Create((*...*));
FDV.Index := FDataViewList.Add( FDV );


suppression d'un FDataView :

FDataViewList.Delete(FDV.index);
FDV.Free;


Execution d'une méthode ou autre :

for index := 0 to FDataViewList.Count-1 do
  FDataViewList.Items[ index ].Invalidate;
Commenter la réponse de Oniria
Messages postés
296
Date d'inscription
dimanche 14 mars 2004
Statut
Membre
Dernière intervention
18 décembre 2014
2
0
Merci
Bonjour,
Merci f0xi, je ne savais pas qu'on pouvait surcharger une liste comme ca.
Pour résoudre mon probléme, j'ai opté pour un tableau de TComponent qui me permet de supprimer tous les appels à Application.Fincomponent(..).
Je suis en train de tester (plutot debugger car le programme est très gros et pour l'instant, je supprime les bugs)mais je pense que je vais gagner pas mal de temps lorsque ce programme de m.... va fonctionner.
C'est facile de coder quelque chose mais optimiser, c'est bien plus dur. d'ailleur, je me demande s'il ne faudrait pas que j'utilise des threads pour améliorer la fluidité car ce n'est pas encore le top.

En tout cas, merci à tous car j'ai appris plein de choses.
f0xi
Messages postés
4200
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
2 janvier 2019
26 -
Les thread ne sont pas necessaires, debug, optimises, concentre toi la dessus. les threads peuvent vite t'amener des problèmes que tu ne voulais pas.

N'hesite pas a user de progressbar pour montrer l'avancement des process et de prevenir l'utilisateur que tel ou tel action peu prendre du temps.

Un array of TComponent peut être sympa, mais reste peu souple, utilise plutot un TList de base il suffit de transtyper l'items pour y mettre n'importe quoi.
Les liste generiques sont très rapide, performance identique a des TList normales ou TObjectList, mais pas besoin de transtyper ou de s'en inquieter. C'est l'idéal pour maintenir une liste de fenetre qui vont etre créées, ouvertes, fermées, détruites, peu de risque de memory leak contrairement à un array fixe.
Commenter la réponse de Oniria