TABLEAU DE VOYANTS CLIGNOTANTS

f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 - 19 déc. 2006 à 08:42
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 - 20 déc. 2006 à 09:01
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/40775-tableau-de-voyants-clignotants

cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
20 déc. 2006 à 09:01
Autant pour Moi!

La procédur Timer1Timer fonctionne, j'avais résolu le Pb!

:)
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
20 déc. 2006 à 08:44
Oui, merci Francky

OK pour tout.

1. Pour la gestion de mes sources,j'ai perdu des mois de boulot sur certains codes suite à un Pb de hard! Je suis en train d'installer un disque de sauvegarde externe.

2. j'ai testé ton code,c'est OK. Je suis en train de l'adapter. Je pense que je vais procéder en plusieurs étapes. La création d'un composant suggérée par Florenth est une bonne idée que j'exploiterai plus tard. Voilà pour l'heure les types que j'ai créés pour l'instant :

{fiche----------------------------------}
TFormBlinker = class(TForm)
Timer1: TTimer;
ImageList1: TImageList;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Déclarations privées }
procedure DoImageClick(Sender : TObject);
procedure Libere_Les_Leds;
public
{ Déclarations publiques }
end;

{Voyant ----------------------------------}
TBlinker = record
Image : TImage;
State : boolean;
Enabled : boolean;
Frequency : integer;
Tick : integer;
end;

{Classe Led -----------------------------}
TLedBlink = class(TImage) // classe héritant de TPaintBox
public
constructor Create(aLed : TComponent); override;
procedure aLedClick(Sender : TObject);
end;

Const
NledProcess = 7;
NProcess = 4;
Var
FormBlinker : TFormBlinker;
BlinkColors : array[boolean] of Integer = (clGreen, clLime);
Blinkers : array of TBlinker;
NbreLeds : Integer; // compte les voyants créés
aLedblink : TLedBlink;

3. J'ai préféré un TImage pour Image, car je n'arrive pas à affecter une image bmp existente de manière dynamique à un PaintBox.

4. D'ailleurs ça bug toujours dans la procédure Timer1Timer. Les images ne clignotent pas et s'effacent. Je vais m'y pencher un peu aujourd'hui.

if Tick >= Frequency then
begin
State := not State;
if State then
begin
ImageList1.GetBitmap(0,TImage(FindComponent('Image'+IntToStr(N+1))).Picture.Bitmap);
TImage(FindComponent('Image'+IntToStr(N+1))).Refresh;
end else
begin
ImageList1.GetBitmap(1,TImage(FindComponent('Image'+IntToStr(N+1))).Picture.Bitmap);
TImage(FindComponent('Image'+IntToStr(N+1))).Refresh;
end;
...
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
20 déc. 2006 à 00:27
salut les zoulous!

@francky :

mon but premier n'etait pas de dynamisé les compos de la fiche mais de montrer ce qu'on pouvait faire avec 3 procedure et un seul timer (toute les paintbox clignote a leurs propre frequence).

@jeanjean :

pour les compos, y'a que l'embaras du choix, soit on part d'une classe TGraphicControl, soit d'un RadioButton ou encore un TRadioGroup etc....
comme je disais a je sais plus qui y'a pas longtemps, quand on commence a avoir des tonnes de lignes de codes redondante ... il faut se demander si il n'y a pas un chemin plus cours.

Pour ce qui est des pertes de compos, y'a une astuce simple, tu crée un dossier "delphi" sur une partition ou disque different du C:.
avec comme sous repertoire : Delphi\Lib et Delphi\Projects
ce qui permet, en cas de reinstallation de Delphi ou du systeme ou de formatage du disque C: de ne rien perdre.
on peu d'ailleur faire pareil avec le dossier "mes documents", on peu le placer ailleur que sur C: (click droit sur "Mes documents" > propriétés > onglet cible > deplacer)
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
19 déc. 2006 à 23:57
Ha oui, merci Japee!

Bonne idée. Je corrige tout de suite.
j'étais justement en train d'adapter ton code sur la création dynamique à l'appli

:)@+
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
19 déc. 2006 à 22:41
Salut Jean_Jean,

Ben c'est plutôt sympa, pour un premier envoi.
Il est certain qu'il y a moyen d'optimiser, et je vais y aller moi aussi de ma petite suggestion.
Tiens, comme ça, par exemple, pourquoi ne pas l'écrire ainsi :

procedure TForm1.Eteint_Voyants(aNumThrd : Byte);
Var i : Byte;
begin
FicVoy := Rep+'LEDoff.bmp';
for i := ((aNumThrd - 1) * 7) + 1 to aNumThrd * 7 do
if Assigned(FindComponent('Image' + IntToStr(i))) then
TImage(FindComponent('Image' + IntToStr(i))).Picture.LoadFromFile(FicVoy);
end;

On gagne quelques lignes de code, et c'est plus rigolo.
Car la programmation, faut que ça reste rigolo, telle est ma devise.

Florenth a dit :
"Qu'est ce qu'on s'embetterait si tous les codes du site étaient de la pure merveille, prêt-à-l-emploi ou encore z-avez-qu-a-le-déposer-sur-la-fiche ..."

Je suis entièrement d'accord avec lui.
Et, oserai-je ajouter, on s'emmerderait grave...

Bonne continuation à tous.

japee
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
19 déc. 2006 à 18:08
Merci Florenth :)
J'ai d'autres priorités! il faut que je clarifie chez Borland. En fermant mon entreprise, je suis passé de 4 à 1 ordinateur. ça pas été sans problème!
Je remettrai tout nickel un peu plus tard!

Mais ça fait plaisir de voir que je fais un peu parti de la communauté des delphim'ans et qu'elle vit bien au travers de ce site. J'ai plein de choses à donner, mais faut pas pousser mémé, sinon, je panique!!!

Je connais la procédure pour créer 1 Compo... On verra plus tard! Je travaille sur un compte utilisateur. c'est peut-être ça le bug car j'ai installé D7 sur le Compte Admi.

Pour l'appli,
Je vais essayer de créer un Objet Led et tenir compte de vos remarques. après réflexion, ça pourrait être intéressant. Je posterai une nouvelle version, quand je sentirai que je suis bloqué pour optimiser plus!

A +
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
19 déc. 2006 à 13:14
Vive la jeunesse!
J'aimerai avoir 20 ans de moins et avoir plus de temps. Changer d'activité et reprendre une spécialisation de 3ème cycle à 50 balais!?Pas évident, mais j'ai l'enthousiasme d'un jeune de 20 ans dans tout ce que je fais. Alors merci à tous!

Je me doutai bien que mon code ferait bondir les pros ! J'ai un tas de code en attente, mais si je ne publie pas, je ne vais pas progresser. Par exemple, j'étais gêné d'utiliser 2 timers pour 1 clignotant, mais mon souci 1er était ailleurs!

Délibérément, je n'ai pas voulu me lancer dans la conception d'un composant car je n'arrive pas à les installer. De plus, avec la migration de D5 à D7, j'ai perdu tout le travail que j'avais fait en composants !?. Borland ne m?a pas renvoyé mon code d'utilisateur de delphi 7 (je leur ai envoyé pourtant le n° de série). Donc, j'attends de normaliser et clarifier mon installation de Delphi, avant de gérer à nouveau : Composants et Bases de données.

Florenth, OK. Je vais peut-être créé un Objet Clignotant plutot qu'un composant ? ça reviendra au même, non ?
Foxi, OK. Je vais tester ta solution. Y a t-il une raison pour que tu choisisses PaintBox au lieu de Image ?
Francky, OK!

Bien à vous !
Francky23012301 Messages postés 400 Date d'inscription samedi 6 août 2005 Statut Membre Dernière intervention 11 février 2016 1
19 déc. 2006 à 12:54
@f0xi : quitte à utiliser 20 TPainBox autant les créer dynamiquement (idem pour le timer) non ?
Euh f0xi, quitte à revoir le code, autant tout revoir ...
Et faire de beaux composants réutilisables, non ?

Sinon, c'est vrai que j'ai oublié de préciser que le code est un peu fouillis.

[mode-hs on]
Mais c'est bien que les codes ne soient pas parfaits ! ça laisse des choses à dire et à améliorer !
Qu'est ce qu'on s'embetterait si tous les codesdu site étaient de la pure merveille, prêt-à-l-emploi ou encore z-avez-qu-a-le-déposer-sur-la-fiche ...

Bon ok, je sors ... ^^
[mode-hs off]
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
19 déc. 2006 à 09:39
pfiuuu que de code pour ça ...

tu pourrais optimiser tout cela avec des tableaux, des inverseurs booléens ect... ect...

exemple avec des paintbox :

type
TForm1 = class(TForm)
Timer1: TTimer;
PaintBox1: TPaintBox;
PaintBox2: TPaintBox;
PaintBox3: TPaintBox;
PaintBox4: TPaintBox;
PaintBox5: TPaintBox;
PaintBox6: TPaintBox;
PaintBox7: TPaintBox;
PaintBox8: TPaintBox;
PaintBox9: TPaintBox;
PaintBox10: TPaintBox;
PaintBox11: TPaintBox;
PaintBox12: TPaintBox;
PaintBox13: TPaintBox;
PaintBox14: TPaintBox;
PaintBox15: TPaintBox;
PaintBox16: TPaintBox;
PaintBox17: TPaintBox;
PaintBox18: TPaintBox;
PaintBox19: TPaintBox;
PaintBox20: TPaintBox;
procedure Timer1Timer(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Déclarations privées }
procedure DoImageClick(Sender : TObject);
public
{ Déclarations publiques }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

type
TBlinker = record
Image : TPaintBox;
State : boolean;
Enabled : boolean;
Frequency : integer;
Tick : integer;
end;

var
BlinkColors : array[boolean] of Integer = (clGreen, clLime);
Blinkers : array of TBlinker;

procedure TForm1.FormCreate(Sender: TObject);
var N : integer;
begin
Randomize;
SetLength(Blinkers, 20);
For N := 0 to high(Blinkers) do
with Blinkers[N] do begin
state := false;
enabled := true;
Frequency := (N+1) shl 1;
Tick := 0;
Image := TPaintBox(FindComponent('PaintBox'+IntToStr(N+1)));
Image.Tag := N;
Image.OnClick := DoImageClick;
Image.Hint :'F '+inttostr(Frequency*Timer1.Interval)+' ms';
end;
Timer1.Interval := 10;
end;

procedure TForm1.DoImageClick(Sender : TObject);
begin
with Blinkers[(sender as TPaintBox).Tag] do begin
Enabled := not Enabled;
State := false;
Tick := 0;
Image.Canvas.Brush.Color := BlinkColors[state];
Image.Canvas.FillRect(Image.ClientRect);
end;
end;


procedure TForm1.Timer1Timer(Sender: TObject);
var N : integer;
begin
for N := 0 to High(Blinkers) do
with Blinkers[N] do
if Enabled then begin
inc(Tick);
if Tick >= Frequency then begin
State := not State;
Image.Canvas.Brush.Color := BlinkColors[state];
Image.Canvas.FillRect(Image.ClientRect);
Tick := 0;
end;
end;
end;


end.
Pas mal du tout !
Par contre, j'aurais eu une approche complètement différente. Je pense que ça vaut le coup que le la décrive.

Explication:

Créer un composant "TLedClignotante" avec comme propriétés:
- Une référence vers un TImageList
- Deux index pour les images allumées et éteintes (relative au ImageList)
- Une propriété "Clignote: Boolean" (pour savoir si la led doit clignoter)
- Une propriété "Allumé: Boolean" (indique l'état de la led)
- Une référence vers un "TLedManager". (voir plus bas)

Donc, pour chaque led, il y aurait un composant. La gestion des états "allumé/éteint/clignotant" se ferait par des gestionnaires OnClick (un seul pour chaque processus, on teste le Sender pour savoir le nouvel état)

Deuxième composant "TLedManager" (non-visuel) se composerait tout simplement:
- D'un Timer déclanchant les clignotements (Intervalle réglable depuis l'extérieur bien sûr)
- D'une liste (non propriétaire) de TLedClignotante.

A chaque intervalle du timer, il changerait l'état des leds si leur propriété "Clignote" est à True. Comme ça, le clignotement est synchronisé (parmi toutes les leds qui lui sont reliées), et il est possible d'arrèter tous les clignotements en une seule ligne.

L'idée étant de séparer complètement l'aspect visuel (clignotements) et l'action de l'utilisateur (click pour changer les priorités des processus).

On pourrait même envisager un composant, "TLedRadioBox" qui regroupperait une liste de leds sous forme d'un dérivé de TStrings, qui les positionnerait à l'intérieur de lui même, qui s'assurerait qu'une seule led doit cochée (il serait aussi possible de rajouter une propriété pour en allumer plusieurs) et qui gérerait le clignotement (grâce, bien sûr, au TLedManager).

Je ne sais pas ce que tu en penses, fais le moi savoir stp. C'est sûr que ça fait plus de code, mais je pense que l'aspect réutilisable que prendrait ce genre de projet rentabiliserait largement le temps passé à le coder. En plus, non seulement ce serait utile, mais aussi joli et pratique.
*Vous ne vous imaginez pas tout ce que Citroën (euh... un composant) peut faire pour vous !* ^^

A+
Florent
Rejoignez-nous