SALUT MES AMIS: j'ai un probleme avec le timer de Delphi je voudrer ajouter une parametre dans timer et j'arrive pas a ajouter alors aider moi svp, mon problem c'est a chaque fois on clic sur la form un nouveau boutton doit etre creer et la valaur 100 est affecter au caption de ce button j'usqua se mement c'est simple mais le probleme qui se pose: j'ai associe a chaque button une timer qui creer de meme principe de button maintenat je voudrer décrementer la valeur de chaque button indepondament au autres button jusqu'a arrivé a 0. merci d'avance et j'attend votre reponse.
cs_karim18
Messages postés3Date d'inscriptiondimanche 5 mars 2006StatutMembreDernière intervention18 juin 2006 18 juin 2006 à 02:34
ce programme n'existe pas ??????????????
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201413 23 févr. 2006 à 07:45
ACHP132--> à condition de pas travailler sous XP puisque dans ce cas il n'y a pas de dos mais seulement une émulation du dos gérer par Windows et il reprend la main régulièrement pour traiter les messages.
Comme tu travailles en temps partagé tu ne garantiras pas la durée du traitement (ni à la milliseconde et encore moins à la microseconde)
ACHPI32
Messages postés50Date d'inscriptionmercredi 2 avril 2003StatutMembreDernière intervention 9 mai 2009 23 févr. 2006 à 01:15
y'a pu qu'a sortir le free pascal ou le TP7 et faire un programme sous DOS... lol
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201413 17 févr. 2006 à 23:44
pour éviter l'appel a application.ProcessMessage il faudrait passer par une gestion évènementielle (comme le fait le timer) et ne gérer que l'évènement. Mais même dans ce cas la précision n'est pas garantie en effet Windows place l'évènement dans une file de traitement et il ne sera traité que lorsque les précédents auont été traité. La réaction est meilleure que le traitement du thread seul mais il n'est pas "en temps réel" mais en batch (par exemple si un évènement comme un ontimer est en court de traitement l'évenement ne sera traité qu'après et cela peut prendre des millisecondes) l'avantage est que le thread continue d'être traité et qu'on ne cumule pas les erreurs, enfin dans la limite de charge du processeur. Comme il n'y a qu'un seul processeur il faut bien qu'il traite toutes les demandes!
On rencontre d'ailleurs le même problème quand on gère des interruptions: on donne des priorités mais il y a toujours des taches favorisées et d'autres qui attendent; quand on travaille en assembleur et qu'il n'y a pas trop de processus en cours on arrive à s'en sortir mais dans le cas de window s'est pratiquement impossible (le nombre et la priorité des processus peut varier)
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202235 17 févr. 2006 à 23:04
tu sais de ou viens ton probleme ?
je vais te le dire : l'appel de Application.ProcessMessage dans ton thread.
mais si on l'enleve, l'application freeze ... normal.
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201413 15 févr. 2006 à 15:50
non laisses la elle est un exemple d'ulisation de thread par contre il vaudrait peut être mieux la renommer et mettre un avertissement
@+
jlen
Sylvainlefou
Messages postés43Date d'inscriptionvendredi 27 décembre 2002StatutMembreDernière intervention15 février 2006 15 févr. 2006 à 15:37
Ok, vous confirmez ce que je pensais, mon timer est nul et useless, lol, tempi ! :) :)
Je vire la source où peut-elle servir ?
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201413 15 févr. 2006 à 15:25
oui kenavo le MMTimer il est très précis mais assez gourmand en ressource.
de toute façon dés que tu mets un application.processmessage le taux d'occupation passe à 100% en effet windows reboucle sur l'instruction while tant que la condition de sortie n'est pas remplie; mais cela n'a pas d'influence sur le déroulement des autres programes puisqu'il ne revient dans le while q'après avoir traité les messages et autres threads cela permet simplement une réponse plus rapide qu'un scan et sans bloquer Windows le probléme restant c'est qu'on ne peut pas déterminer à l'avance combien durera une boucle puisqu'elle dépend du nombre et de la priorité des thread et des messages et que par conséquent cette durée est tout à fait aléatoire (ce qui est d'ailleurs à l'origine du manque de précision de ce timer.
@+
jlen
cs_Kenavo
Messages postés702Date d'inscriptionvendredi 21 mars 2003StatutMembreDernière intervention 1 octobre 20095 15 févr. 2006 à 14:52
Arghhhh .....
"If FEnabled=True then Main; "
"until FEnabled = False;"
Ben non ! Ecris plutôt :
"If FEnabled then Main; "
"until not FEnabled;"
Sinon pour le timer, c'est une catastrophe ! Je déconseille aux âmes sensibles d'aller voir le taux d'occupation du processeur !
Le meilleur timer est .... le timer le mieux adapté au problème !
Rylryl l'utilisait pour séquencer des trames de télécommande RC5 (durée de la trame 25 ms, duré du bit 1,78 ms) où il était adapté : Besoin de précision et utilisation courte. Pour des périodes de l'ordre de la seconde, le timer TTimer est très correct. Entre 1 et 100 millisecondes, le timer multimedia est sans doute le plus adapté.
Kenavo
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201413 14 févr. 2006 à 18:31
retour sur le pc principal
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201413 14 févr. 2006 à 18:27
test à partir d'un autr PC
Sylvainlefou
Messages postés43Date d'inscriptionvendredi 27 décembre 2002StatutMembreDernière intervention15 février 2006 14 févr. 2006 à 15:40
Le petit exemple d'utilisation du timer a était codé simplement pour montrer l'irrégularité du timer, il est vrai qu'ils n'est pas trés propre.
f0xi : merci, c'est vrai qu'un while...do semble plus logique qu'un repeat...until, je ne met pas a jour la source mais je modifie mon code.
Sinon la liste servait a montrer que, chaque seconde, il y avant un décalage de x milliseconde. cependant, un label reste beaucoup plus léger pour la machine (méme si les temps d'executions de "OnTimer" sont compensée).
pepitto : cette gestion des timers est la maniere plus direct, d'utiliser les timers windows (API). C'est ca qui est utiliser par le composant TTimer.
jlen100: il faut alors géré, en plus du temps d'execution de "OnTimer", les temps de Application.ProcessMessages et des differentes boucles, de la creation du thread... il y a pas mal de choses a changer, je vais voir cela.
Merci a tous
Sylvainlefou
Messages postés43Date d'inscriptionvendredi 27 décembre 2002StatutMembreDernière intervention15 février 2006 14 févr. 2006 à 14:58
Message envoyé par jlen100 :
"salut,pas mal ton code. Une petite chose tu n'as pas donné de priorité à la construction (si je ne trompe pas par défaut elle doit être à Priority := tpNormal)
pour les décalages j'ai eu le même probleme avec un thread et ce quelque soit la priorité donnée; le decalage pouvant atteindre 15ms en fait cela s'explique facilement : avec le Application.processmessages on indique au programme qu'il doit redonner la main à windows qui gère la file d'attente (et celà est préférable sous peine de blocage) résultat il faut bien qu'il traite aussi les autres threads et cela prend comme le refroidissement du fût du canon ... un certain temps.
en conclusion il est pratiquement impossible de garantir un timming précis en dessous de la milliseconde sans bloquer le processus (interdire à windows de traiter les threads).
Pour obtenir des timming plus petit il faut passer par des cartes d'extension qui génèrent le signal (avec ou sans bufferisation des données s'il faut les transmettre) une carte à microcontroleur fait génèralement l'affaire avec des horloge à 20 ou 50MHz on arrive facilement à des signaux precis à 50 à 100ns
Mais la persistance rétienienne étant ~100ms un timer standard réglé à 40/50 ms fait très bien l'affaire tu peux même descendre à 20ms en gardant un bonne reproductivité. Mais comme je ne connais pas ton application je ne fairais pas plus de commentaires"
j'espère que cela pourra t'être utile
@+
jlen
cs_pepitto
Messages postés22Date d'inscriptionjeudi 13 novembre 2003StatutMembreDernière intervention25 juin 2008 14 févr. 2006 à 13:34
Si tu n'est pas à la seconde je te propose d'utiliser une petite fonction simple (tu peux trouver l'aide dans Win32.hlp) qui utilise les messages :
procedure TForm1.OnTimer(var msg : Tmessage);
begin
// ici places les action à effecturer toutes les secondes
if Msg.wParam = 1234 then // si plusieurs timers une sellection
// est possible avec wParam
begin
end;
end;
//-------------------------------------------------
dans Procedure Tform1.Create(Sender: TObject); ajoute
setTimer(Handle,
1234, // identifiant du timer
1000, // temps en milliseconde (1 seconde dans ce cas)
nil); // voir aide (je ne suis pas trop copain avec l'anglais)
// pour stopper le timer utilies
Killtimer(Handle,
1234); //identifiant du timer
Toutes ces lignes peuvent t'éviter de creer un timer est peut être très simple d'utilisation (Quand on essaie l'emploie les <<message>>)
Salut,
Wolf ce qui est valable pour toi ne l'est pas forcément pour les autres.
Si aujourd'hui tu ne vois aucune utilité à un timer de haute précision, demain il en sera peut être autrement. C'est sur que pour afficher un message où fermer un rideau c'est pas utile d'être précis à la microseconde mais il n'y a pas que ça, je pense notamment au multimédia qui dans certaine circonstance demande une précision extrême mais il y a encore plein d'autres applications.
@+
Cirec
wolf691300
Messages postés41Date d'inscriptionmardi 15 juin 2004StatutMembreDernière intervention31 mars 2006 14 févr. 2006 à 09:12
Je ne suis pas à une seconde près pour créer une application. Tant que l'exécutable fonctionne bien avec un Timer normal ... J'en vois aucune utilité d'amélioration, idem dans le monde réel.
Wolf691300
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202235 14 févr. 2006 à 06:43
procedure TForm1.MicroTimer1OnTimer(Sender: TComponent);
var t : int64;
begin
QueryPerformanceCounter(t);
caption := format('%s || %d',[TimeToStr(now),t]);
end;
__________________________________________________________________
modification de Main() :
Procedure MicroTimer.Main();
var
Time_now, Time_memo, IntervalRecalc: Int64;
Ic : integer;
begin
Time_now := 0;
Time_memo := 0;
Ic := 0;
while FEnabled do begin
IntervalRecalc := FInterval - (Time_now - Time_memo) * 1000000 div FFrq_Base;
FThread:= MicroTimerTh.Create(FFrq_Base, IntervalRecalc);
while (not(FThread.ThreadTerminated)) and (FEnabled) do
if Ic = 1000 then begin
Application.ProcessMessages;
Ic := 0;
end;
Inc(Ic);
end;
QueryPerformanceCounter(Time_memo);
FOnTimer(Self);
QueryPerformanceCounter(Time_now);
end;
end;
__________________________________________________________________
Modification d'execute :
procedure MicroTimerTh.Execute;
var
Time_memo, Time_now, dif: Int64;
begin
QueryPerformanceCounter(Time_memo);
while dif <= FInterval do begin
QueryPerformanceCounter(Time_now);
dif := (Time_now - Time_memo) * 1000000 div FFrq_Base;
end;
end;
__________________________________________________________________
evite de balancer des données qui change tout le temps dans une liste ... utilise un label plutot ou un tstringlist (durant le calcul).
24 oct. 2007 à 22:55
18 juin 2006 à 02:34
23 févr. 2006 à 07:45
Comme tu travailles en temps partagé tu ne garantiras pas la durée du traitement (ni à la milliseconde et encore moins à la microseconde)
23 févr. 2006 à 01:15
17 févr. 2006 à 23:44
On rencontre d'ailleurs le même problème quand on gère des interruptions: on donne des priorités mais il y a toujours des taches favorisées et d'autres qui attendent; quand on travaille en assembleur et qu'il n'y a pas trop de processus en cours on arrive à s'en sortir mais dans le cas de window s'est pratiquement impossible (le nombre et la priorité des processus peut varier)
17 févr. 2006 à 23:04
je vais te le dire : l'appel de Application.ProcessMessage dans ton thread.
mais si on l'enleve, l'application freeze ... normal.
15 févr. 2006 à 15:50
@+
jlen
15 févr. 2006 à 15:37
Je vire la source où peut-elle servir ?
15 févr. 2006 à 15:25
de toute façon dés que tu mets un application.processmessage le taux d'occupation passe à 100% en effet windows reboucle sur l'instruction while tant que la condition de sortie n'est pas remplie; mais cela n'a pas d'influence sur le déroulement des autres programes puisqu'il ne revient dans le while q'après avoir traité les messages et autres threads cela permet simplement une réponse plus rapide qu'un scan et sans bloquer Windows le probléme restant c'est qu'on ne peut pas déterminer à l'avance combien durera une boucle puisqu'elle dépend du nombre et de la priorité des thread et des messages et que par conséquent cette durée est tout à fait aléatoire (ce qui est d'ailleurs à l'origine du manque de précision de ce timer.
@+
jlen
15 févr. 2006 à 14:52
"If FEnabled=True then Main; "
"until FEnabled = False;"
Ben non ! Ecris plutôt :
"If FEnabled then Main; "
"until not FEnabled;"
Sinon pour le timer, c'est une catastrophe ! Je déconseille aux âmes sensibles d'aller voir le taux d'occupation du processeur !
Le meilleur timer est .... le timer le mieux adapté au problème !
Rylryl l'utilisait pour séquencer des trames de télécommande RC5 (durée de la trame 25 ms, duré du bit 1,78 ms) où il était adapté : Besoin de précision et utilisation courte. Pour des périodes de l'ordre de la seconde, le timer TTimer est très correct. Entre 1 et 100 millisecondes, le timer multimedia est sans doute le plus adapté.
Kenavo
14 févr. 2006 à 18:31
14 févr. 2006 à 18:27
14 févr. 2006 à 15:40
f0xi : merci, c'est vrai qu'un while...do semble plus logique qu'un repeat...until, je ne met pas a jour la source mais je modifie mon code.
Sinon la liste servait a montrer que, chaque seconde, il y avant un décalage de x milliseconde. cependant, un label reste beaucoup plus léger pour la machine (méme si les temps d'executions de "OnTimer" sont compensée).
pepitto : cette gestion des timers est la maniere plus direct, d'utiliser les timers windows (API). C'est ca qui est utiliser par le composant TTimer.
jlen100: il faut alors géré, en plus du temps d'execution de "OnTimer", les temps de Application.ProcessMessages et des differentes boucles, de la creation du thread... il y a pas mal de choses a changer, je vais voir cela.
Merci a tous
14 févr. 2006 à 14:58
"salut,pas mal ton code. Une petite chose tu n'as pas donné de priorité à la construction (si je ne trompe pas par défaut elle doit être à Priority := tpNormal)
pour les décalages j'ai eu le même probleme avec un thread et ce quelque soit la priorité donnée; le decalage pouvant atteindre 15ms en fait cela s'explique facilement : avec le Application.processmessages on indique au programme qu'il doit redonner la main à windows qui gère la file d'attente (et celà est préférable sous peine de blocage) résultat il faut bien qu'il traite aussi les autres threads et cela prend comme le refroidissement du fût du canon ... un certain temps.
en conclusion il est pratiquement impossible de garantir un timming précis en dessous de la milliseconde sans bloquer le processus (interdire à windows de traiter les threads).
Pour obtenir des timming plus petit il faut passer par des cartes d'extension qui génèrent le signal (avec ou sans bufferisation des données s'il faut les transmettre) une carte à microcontroleur fait génèralement l'affaire avec des horloge à 20 ou 50MHz on arrive facilement à des signaux precis à 50 à 100ns
Mais la persistance rétienienne étant ~100ms un timer standard réglé à 40/50 ms fait très bien l'affaire tu peux même descendre à 20ms en gardant un bonne reproductivité. Mais comme je ne connais pas ton application je ne fairais pas plus de commentaires"
j'espère que cela pourra t'être utile
@+
jlen
14 févr. 2006 à 13:34
dans private ajoute :
procedure OnTimer(var msg : Tmessage); message WM_TIMER;
//--------------------------------------------
procedure TForm1.OnTimer(var msg : Tmessage);
begin
// ici places les action à effecturer toutes les secondes
if Msg.wParam = 1234 then // si plusieurs timers une sellection
// est possible avec wParam
begin
end;
end;
//-------------------------------------------------
dans Procedure Tform1.Create(Sender: TObject); ajoute
setTimer(Handle,
1234, // identifiant du timer
1000, // temps en milliseconde (1 seconde dans ce cas)
nil); // voir aide (je ne suis pas trop copain avec l'anglais)
// pour stopper le timer utilies
Killtimer(Handle,
1234); //identifiant du timer
Toutes ces lignes peuvent t'éviter de creer un timer est peut être très simple d'utilisation (Quand on essaie l'emploie les <<message>>)
14 févr. 2006 à 12:01
Wolf ce qui est valable pour toi ne l'est pas forcément pour les autres.
Si aujourd'hui tu ne vois aucune utilité à un timer de haute précision, demain il en sera peut être autrement. C'est sur que pour afficher un message où fermer un rideau c'est pas utile d'être précis à la microseconde mais il n'y a pas que ça, je pense notamment au multimédia qui dans certaine circonstance demande une précision extrême mais il y a encore plein d'autres applications.
@+
Cirec
14 févr. 2006 à 09:12
Wolf691300
14 févr. 2006 à 06:43
procedure TForm1.FormCreate(Sender: TObject);
begin
LongTimeFormat := 'hh:nn:ss.zzz';
MicroTimer1 := MicroTimer.Create(nil);
MicroTimer1.OnTimer := MicroTimer1OnTimer;
end;
__________________________________________________________________
modification de OnTimer :
procedure TForm1.MicroTimer1OnTimer(Sender: TComponent);
var t : int64;
begin
QueryPerformanceCounter(t);
caption := format('%s || %d',[TimeToStr(now),t]);
end;
__________________________________________________________________
modification de Main() :
Procedure MicroTimer.Main();
var
Time_now, Time_memo, IntervalRecalc: Int64;
Ic : integer;
begin
Time_now := 0;
Time_memo := 0;
Ic := 0;
while FEnabled do begin
IntervalRecalc := FInterval - (Time_now - Time_memo) * 1000000 div FFrq_Base;
FThread:= MicroTimerTh.Create(FFrq_Base, IntervalRecalc);
while (not(FThread.ThreadTerminated)) and (FEnabled) do
if Ic = 1000 then begin
Application.ProcessMessages;
Ic := 0;
end;
Inc(Ic);
end;
QueryPerformanceCounter(Time_memo);
FOnTimer(Self);
QueryPerformanceCounter(Time_now);
end;
end;
__________________________________________________________________
Modification d'execute :
procedure MicroTimerTh.Execute;
var
Time_memo, Time_now, dif: Int64;
begin
QueryPerformanceCounter(Time_memo);
while dif <= FInterval do begin
QueryPerformanceCounter(Time_now);
dif := (Time_now - Time_memo) * 1000000 div FFrq_Base;
end;
end;
__________________________________________________________________
evite de balancer des données qui change tout le temps dans une liste ... utilise un label plutot ou un tstringlist (durant le calcul).