Files
SignauxComplexes/UnitCompteur.pas
2026-02-14 10:24:01 +01:00

1067 lines
31 KiB
ObjectPascal

unit UnitCompteur;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, math, ComCtrls, Menus, Unitprinc ;
const
pisur180=pi/180;
NbreCompteurs=1;
type
TFormCompteur = class(TForm)
ImageCompteur: TImage;
TrackBarC: TTrackBar;
PopupMenuC: TPopupMenu;
Verrouillerdevant1: TMenuItem;
Dverrouiller1: TMenuItem;
N1: TMenuItem;
Compteurdevitesse11: TMenuItem;
Compteurdevitesse21: TMenuItem;
Compteurtachro1: TMenuItem;
Labeltrain: TLabel;
Button0: TButton;
ImageTprov: TImage;
N2: TMenuItem;
Affichericonedutrain1: TMenuItem;
ImageTrain: TImage;
N3: TMenuItem;
Vitesseencrans1: TMenuItem;
Vitesserelle1: TMenuItem;
procedure FormActivate(Sender: TObject);
procedure Dverrouiller1Click(Sender: TObject);
procedure Verrouillerdevant1Click(Sender: TObject);
procedure Compteurdevitesse11Click(Sender: TObject);
procedure Compteurdevitesse21Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Compteurtachro1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure TrackBarCChange(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure Button0Click(Sender: TObject);
procedure Affichericonedutrain1Click(Sender: TObject);
procedure Vitesseencrans1Click(Sender: TObject);
procedure Vitesserelle1Click(Sender: TObject);
procedure PopupMenuCPopup(Sender: TObject);
private
{ Déclarations privées }
protected
procedure WMExitSizeMove(var Message: TMessage); message WM_EXITSIZEMOVE; // détecte fin de redimensionnement fenêtre
//procedure WMNCPaint(var Mes : TWMNCPaint); message WM_NCPAINT;
public
{ Déclarations publiques }
end;
type
typ=(Trien,fen,gb,im); // indique où se situe le compteur : dans la fenetre 'formCompteur' (fen), un des groupBox de la fenetre principale (gb) ou d'une image (onglet compteurs formConfig)
TTcompteur=array[1..1] of record
FcBitMap : Tbitmap;
paramcompt : TparamCompt;
end;
var
formCompteur : array[1..1] of TformCompteur; // il y a 10 fenetres mais on utilise qu'un compteur.
Scompteur : TTCompteur; // Scompteur : associé à grande fenetre compteur
ParamCompteur : array[1..3] of record
coulAig,coulGrad,CoulNum,CoulFond,CoulArc : tcolor;
increment : integer; // incrément rapide
end;
VerrouilleCompteur,affTrainCompteur,VitCrans : boolean;
LargeurCompteurs,HauteurCompteurs,LargComptC,HautComptC : integer;
couleurTete : tcolor;
Procedure Init_compteur(i : integer;c : Tcomponent);
procedure aiguille_compteur(c,idTrain : integer;comp : Tcomponent);
procedure dessin_fond_compteur(var param : TparamCompt;i: integer ; Im : tbitmap;typCompt : integer);
procedure position_compteur;
procedure affiche_train_compteur(c : integer);
procedure init_compteurs;
function Vr_kmh(v : integer) : integer;
implementation
uses UnitTCO, UnitClock , UnitConfig, UnitDebug;
{$R *.dfm}
// ne pas utiliser - essai
procedure affiche_caption(s : string);
var
ACanvas : TCanvas;
l,h : integer;
begin
l:=formCompteur[1].Width-40;
h:=30;
ACanvas:=TCanvas.Create;
try
ACanvas.Handle:=GetWindowDC(FormCompteur[1].Handle);
with ACanvas do
begin
// Brush.Color := couleurTete;
Font.Name:='Arial';
Font.Size:=12;
Font.Color:=clCaptionText;
Font.Style:=[fsBold];
FillRect(rect(2,2,l,h));
Textout(8,6,s);
end;
finally
ReleaseDC(FormCompteur[1].Handle, ACanvas.Handle);
ACanvas.Free;
ACanvas:=nil;
end;
end;
// affiche le nom du train dans le compteur
procedure affiche_train_compteur(c : integer);
var s : string;
larg,haut : integer;
begin
if idTrainClic<0 then exit;
s:=trains[IdTrainClic].nom_train;
with FormCompteur[c] do
begin
caption:=s;
if affTrainCompteur then
begin
//Affiche(intToSTR(Imagetrain.Picture.Width),clYellow);
larg:=Maj_icone_train(ImageTProv,IdTrainClic,clWhite);
haut:=ImageTProv.height;
ImageTrain.Width:=larg;
ImageTrain.Height:=haut;
ImageTrain.canvas.copyrect(rect(0,0,larg,haut),ImageTprov.canvas,rect(0,0,larg,haut));
//Affiche(intToSTR(larg)+'x'+intToSTR(haut),clYellow);
ImageTrain.left:=ImageCompteur.Picture.Width-larg;
end;
LabelTrain.caption:=s;
end;
end;
// event fin de redimensionnement
procedure TFormCompteur.WMExitSizeMove(var Message: TMessage);
begin
inherited;
//Affiche('ExitSizeMove '+IntToSTR(Message.Msg)+' '+inTtOstr(message.WParam)+' '+intToSTR(message.LParam)+' '+intToSTR(message.WParamLo),clred);
LargeurCompteurs:=formCompteur[1].Width; // nouvelle largeur
init_compteur(1,formcompteur[1]);
affiche_train_compteur(1);
end;
// convertit une vitesse en cm/s en km/h suivant l'échelle
function Vr_kmh(v : integer) : integer;
begin
case echelle of
0 : result:=(v*87*36) div 1000; // H0
1 : result:=(v*160*36) div 1000; // N
2 : result:=(v*220*36) div 1000; // Z
end;
end;
// change l'aiguille du compteur "c" en fonction de la vitesse du train "idTrain" dans le composant "comp"
// c : n° de fenetre du compteur idTrain : index du train comp : composant dans lequel se trouve le compteur (form, groupbox ou image)
procedure aiguille_compteur(c,idTrain : integer ; comp : Tcomponent);
var ComptLoc,x1,y1,x2,y2,x3,y3,x4,y4,vitesse,vitesseFin,lim,him : integer;
angleDeb,AngleFinLoc,sinD,cosD,sinF,cosF : extended ;
canvDest :tcanvas;
param : Tparamcompt;
typDest : typ;
begin
if compteur<1 then exit;
typDest:=Trien;
if comp is tform then typDest:=fen;
if comp is tgroupBox then typDest:=gb;
if comp is tImage then typDest:=im;
if TypDest=Trien then
begin
Affiche('Anomalie 47 c='+intToSTR(c)+' i='+intToSTR(idTrain),clred);
exit;
end;
if idTrain<>0 then
begin
// détermine début et fin de l'arc vert
vitesse:=abs(trains[idTrain].VitesseCompteur); // vitesse en cours
vitesseFin:=abs(trains[idTrain].vitesseCons); // vitesse consigne
end
else
begin
Vitesse:=0;
VitesseFin:=0;
end;
// convertir les vitesses instantanées et fin en angles par
// la formule angle=A.vitesse+b
if typdest=fen then
begin
ComptLoc:=compteur; // type de compteur 1 2 ou 3
param:=Scompteur[c].paramcompt;
canvDest:=formCompteur[c].ImageCompteur.Canvas;
end;
if typdest=gb then
begin
ComptLoc:=compteur;
param:=CompteurT[c].paramcompt;
canvDest:=compteurT[c].Img.Canvas;
end;
if typdest=im then
begin
ComptLoc:=formconfig.ComboBoxCompt.ItemIndex+1;
param:=paramcomptIm;
canvDest:=formconfig.ImageCtC.Canvas;
end;
if not(VitCrans) then
begin
if trains[idTrain].CoeffV1<>0 then // si le train est étalonné
begin
vitesse:=round(crans_to_Vrcms(vitesse,idTrain)); // vitesse en cm/s
vitesseFin:=round(crans_to_Vrcms(vitesseFin,idTrain)); // vitesse en cms/s
vitesse:=vr_kmh(vitesse);
VitesseFin:=vr_kmh(vitesseFin);
if vitesse>param.AngleFin then vitesse:=param.AngleFin;
if vitesseFin>param.AngleFin then VitesseFin:=param.AngleFin;
end;
end;
with param do
begin
angleDeb:=ComptA*vitesse+comptB;
angleFinLoc:=ComptA*vitesseFin+comptB;
lim:=imgL;
Him:=imgH;
end;
sincos(AngleDeb*pisur180,sinD,cosD); // arc vitesse de début
sincos(AngleFinLoc*pisur180,sinF,cosF); // arc vitesse de fin
with canvDest do
begin
// copie le fond du compteur
if typdest=fen then copyrect(rect(0,0,lim,him),Scompteur[c].FcBitMap.canvas,rect(0,0,lim,him));
if typdest=gb then copyrect(rect(0,0,lim,him),compteurT[c].FcBitMap.canvas,rect(0,0,lim,him));
if typdest=im then copyrect(rect(0,0,lim,him),FbmcompC.canvas,rect(0,0,lim,him));
// afficher l'arc vert
with param do
begin
pen.mode:=pmCopy;
pen.width:=round(4*redX);
if (vitesse<>0) and (angleDeb<>angleFinLoc) then
begin
x1:=AigCX - rav;
y1:=AigCY - rav;
x2:=AigCX + rav;
y2:=AigCY + rav;
x3:=AigCX + Round(rav*sinD);
y3:=AigCY - Round(rav*cosD);
x4:=AigCX + Round(rav*sinF);
y4:=AigCY - Round(rav*cosF);
pen.color:=ParamCompteur[comptloc].coulArc;
if angleDeb>=angleFinLoc then setArcDirection(Handle,AD_COUNTERCLOCKWISE) else setArcDirection(Handle,AD_CLOCKWISE) ;
Arc(x1,y1,x2,y2,x3,y3,x4,y4);
end;
// Afficher l'aiguille (angleDeb)
pen.color:=ParamCompteur[comptloc].coulAig;
MoveTo(AigCX,AigCY);
LineTo(round(rAig*sinD)+AigCX,round(-rAig*cosD)+AigCY);
end;
end;
end;
// dessine le fond du compteur 2 (graduations et chiffres)
procedure compteur_2(c : integer;bm : tbitmap;var param : tparamcompt);
var n,v,rayon2,rayon3,rayon4,x1,y1,x2,y2,xt,yt,lim,him,rg : integer;
angle,incr,r : single;
s : string;
begin
angle:=10; // angle début des graduations
incr:=2.5; // incrément d'angle en ° des graduations
n:=0;
v:=0;
lim:=bm.Width;
him:=bm.height;
with param do
begin
AngleFin:=170; // 170 angle fin des graduations
r:=redx; // facteur réduction de la fenetre du compteur
rg:=round(AigCX/1.05); // rayon des graduations
rayon2:=Rg-round(10*r); // rayon de fin des graduations
rayon3:=Rg-round(20*r);
rayon4:=Rg-round(20*r); // chiffres
with bm.Canvas do
begin
pen.width:=1;
pen.Color:=ParamCompteur[2].coulGrad;
Brush.Color:=ParamCompteur[2].coulFond;
brush.style:=bssolid; // pour effacer
FillRect(Rect(0,0,lim,him));
Brush.Color:=ParamCompteur[2].coulFond;
Cercle(bm.canvas,AigCX,AigCY,round(10*r),clBlack,clBlack);
font.Name:='Arial';;
font.color:=ParamCompteur[2].CoulNum;
font.style:=[fsbold];
font.size:=round(r*15*RedFonte);
{$IF CompilerVersion >= 28.0}
font.orientation:=0;
{$IFEND}
end;
// dessine le cadran
repeat
// affiche les chiffres
if n mod 10=0 then
begin
// pour centrer le chiffre de vitesse sur l'axe de la graduation
// affiche les chiffres
case v of
0 : begin xt:=round(30*r);yt:=round(160*r);s:='0';end;
1 : begin xt:=round(60*r);yt:=round(100*r);s:='20';end;
2 : begin xt:=round(110*r);yt:=round(55*r);s:='40';end;
3 : begin xt:=round(170*r);yt:=round(35*r);s:='60';end;
4 : begin xt:=round(240*r);yt:=round(40*r);s:='80';end;
5 : begin xt:=round(280*r);yt:=round(80*r);s:='100';end;
6 : begin xt:=round(310*r);yt:=round(130*r);s:='120';end;
//7 : begin xt:=round(300*r);yt:=round(100*r);s:='140';end;
end;
//bm.Canvas.brush.Style:=bsClear;
bm.canvas.Brush.Style:=bsclear; // pour transparent de la fonte
bm.canvas.Textout(xt,yt,s);
inc(v);
end;
x1:=round(cos((angle+180)*pisur180)*Rg)+AigCX;
y1:=round(sin((angle+180)*pisur180)*Rg)+AigCY;
// gros traits
if n mod 5 = 0 then
begin
bm.canvas.pen.Width:=round(4*r);
x2:=round(cos((angle+180)*pisur180)*rayon3)+AigCX;
y2:=round(sin((angle+180)*pisur180)*rayon3)+AigCY;
end
else
begin
// traits fins
bm.canvas.pen.Width:=round(2*r);
x2:=round(cos((angle+180)*pisur180)*rayon2)+AigCX;
y2:=round(sin((angle+180)*pisur180)*rayon2)+AigCY;
end;
with bm.canvas do
begin
Brush.Style:=bsSolid;
pen.color:=ParamCompteur[2].coulGrad;
MoveTo(x1,y1);
lineTo(x2,y2);
end;
inc(n);
angle:=angle+incr; // 18
until angle>param.AngleFin+incr;
AngleFin:=130; // en fait vitesse maxi compteur
end;
end;
// dessine le fond du compteur tachro
procedure compteur_tachro(c : integer;bm : tbitmap;var param : tparamcompt);
var l,av,n,v,rayon2,rayon3,rayon4,x1,y1,x2,y2,xt,yt,lim,him,rg : integer;
angle,incr,r,a,sinA,cosA : single;
s : string;
begin
angle:=-40; // angle début des graduations
incr:=2.5; // incrément d'angle en ° des graduations
n:=0;
v:=0;
with param do
begin
angleFin:=220; // angle fin des graduations en km/h
lim:=ImgL;
him:=ImgH;
AigCX:=lim div 2; // centre aiguille
AigCY:=round(200*redY);
r:=lim/400; // réduction
rg:=round(AigCX/1.07); // rayon des graduations
rayon2:=Rg-round(10*r); // rayon de fin des graduations
rayon3:=Rg-round(20*r); // rayon des grands traits
rayon4:=Rg-round(16*r); // chiffres
with Bm.Canvas do
begin
pen.width:=1;
pen.Color:=ParamCompteur[3].coulfond;
Brush.Color:=ParamCompteur[3].coulfond;
Brush.Style:=bsSolid;
FillRect(Rect(0,0,lim,him));
end;
Cercle(bm.Canvas,AigCX,AigCY,round(125*r),clGray,ParamCompteur[3].CoulFond);
Cercle(bm.Canvas,AigCX,AigCY,round(10*r),clwhite,clWhite);
with bm.Canvas do
begin
font.Name:='Arial';
brush.color:=clBlack;
pen.color:=ParamCompteur[3].coulgrad;
font.color:=ParamCompteur[3].CoulNum;
font.size:=round(r*20*RedFonte); // taille de la fonte constante même si changement % affichage windows
//Affiche(intToSTR(font.size),clred);
font.style:=[];
end;
// dessine le cadran
repeat
// affiche les chiffres
if n mod 10=0 then
begin
s:=intToSTR(round(v));
// pour centrer le chiffre de vitesse sur l'axe de la graduation
a:=(bm.Canvas.TextWidth(s) div 2)/rayon4;
if abs(a)>1 then a:=1;
a:=arcSin(a);
l:=round(a*180/pi);
//Affiche(intToSTR(l),clYellow);
xt:=round(cos((angle+180-l)*pisur180)*rayon4)+AigCX;
yt:=round(sin((angle+180-l)*pisur180)*rayon4)+AigCY;
// affiche les chiffres avec un angle
{$IF CompilerVersion >= 28.0}
av:=round(90-angle)*10;
bm.canvas.font.orientation:=av;
bm.canvas.Textout(xt,yt,s);
{$ELSE}
av:=10+round(90-angle)*10;
AffTexteIncliBordeTexture(bm.Canvas,xt,yt,bm.Canvas.font,clYellow,0,pmcopy,s,av);
{$IFEND}
inc(v,20);
end;
cosA:=cos((angle+180)*pisur180);
sinA:=sin((angle+180)*pisur180);
x1:=round(cosA*Rg)+AigCX;
y1:=round(SinA*Rg)+AigCY;
// gros traits
if n mod 5 = 0 then
begin
bm.Canvas.pen.Width:=round(4*r);
x2:=round(cosA*rayon3)+AigCX;
y2:=round(sinA*rayon3)+AigCY;
end
else
begin
// traits fins
bm.Canvas.pen.Width:=round(2*r);
x2:=round(cosA*rayon2)+AigCX;
y2:=round(sinA*rayon2)+AigCY;
end;
with bm.Canvas do
begin
MoveTo(x1,y1);
lineTo(x2,y2);
end;
inc(n);
angle:=angle+incr;
until angle>param.AngleFin+incr;
end;
// copie l'image du texte "tachro" mise à l'échelle
StretchBlt(bm.Canvas.Handle,round(145*r),round(90*r),round(lim*r),round(him*r),
FormPrinc.ImageTachro.canvas.Handle,0,0,lim,him,srcCopy);
param.AngleFin:=220; // en fait vitesse maxi compteur
end;
// dessine le fond du compteur pour tous les compteurs dans le FbitMap
// le var est obligatoire
// typecompt : type du compteur 1 2 ou 3
procedure dessin_fond_compteur(var param : TparamCompt;i: integer ; Im : tbitmap;typCompt : integer);
var lim,him : integer;
begin
lim:=param.ImgL;
him:=param.ImgH;
with Im.Canvas do
begin
Brush.Style:=bsSolid;
Brush.Color:=$141414;
font.name:='arial';
font.Style:=[fsBold];
// le compteurs 1 provient de bitmaps
// le compteur 2 et 3 sont dessinés par
with param do
begin
case typCompt of
1 : begin
// le compteur 1 provient d'une image
StretchDraw(rect(0,0,Lim,Him),Formprinc.ImageCompteur1.Picture.Bitmap);
Brush.Style:=bsSolid;
Brush.Color:=$1F1A17;
font.color:=ParamCompteur[1].CoulNum;
{$IF CompilerVersion >= 28.0}
font.orientation:=0;
// centre de l'aiguille
AigCX:=round(97*redX); // le centre de l'aiguille est en 97 97
AigCY:=round(97*redY);
{$ELSE}
// centre de l'aiguille
AigCX:=round(97*redX*RedFonte); // le centre de l'aiguille est en 97 97
AigCY:=round(97*redY*RedFonte);
{$IFEND}
font.size:=round(redx*10*RedFonte);
TextOut(round(50*redX),round(128*redY),'0');
TextOut(round(40*redX),round(92*redY),'20');
TextOut(round(56*redX),round(56*redY),'40');
TextOut(round(94*redX),round(36*redY),'60');
TextOut(round(129*redX),round(53*redY),'80');
TextOut(round(137*redX),round(91*redY),'100');
TextOut(round(124*redX),round(130*redY),'120');
rAig:=round(AigCX / 1.5);
angleFin:=127; // en fait vitesse maxi compteur
end;
2 : begin
// centre de l'aiguille et longueur
AigCX:=lim div 2;
AigCY:=round(200*redY);
rAig:=round(AigCX/1.07);
// le compteur 2 est dessiné
compteur_2(i,im,param);
end;
3 : begin // tachro
// centre de l'aiguille et longueur
AigCX:=lim div 2;
AigCY:=round(200*redY);
rAig:=round(AigCX/1.1);
// le compteur tachro est dessiné
compteur_tachro(i,im,param);
end;
end;
end;
end;
end;
procedure init_compteurs;
var i : integer;
begin
for i:=1 to ntrains do
begin
init_compteur(i,CompteurT[i].gb);
end;
init_compteur(1,FormCompteur[1]);
end;
// initialise le compteur
// i = rang du compteur
// c : composant de destination
Procedure Init_compteur(i : integer;c : Tcomponent);
const ofs=30; // décalage entre la taille de l'image et de la fenetre
// compteurs fenetre principale
HautTb=10; // hauteur trackbar
ofsGBH=15; // marge haut du groupbox
ofsGBB=8; // marge bas du groupbox
var comptLoc,l,h,lim,him,hfen,mini,maxi,vmax : integer;
typDest : typ;
r : single;
image : timage;
canv : tcanvas;
begin
if (i<1) or (hautComptC=0) then exit;
if ProcPrinc then Affiche('Init compteur de vitesse '+intToSTR(i)+' composant '+c.name,clYellow);
typDest:=Trien;
if c is tform then typDest:=fen; // si le compteur est la fenetre unique
if c is tGroupBox then typDest:=gb; // si le compteur est le groupBox de la fenetre principale
if c is tImage then typDest:=im; // si le compteur est l'image de l'onglet config compteurs
if typDest=Trien then
begin
Affiche('Anomalie 48 i='+intToSTR(i),clred);
exit;
end;
if (typDest=fen) or (typDest=gb) then ComptLoc:=compteur; // compteur est une variable globale qui désigne le type de compteur de la grande fenetre de compteur
if typDest=im then ComptLoc:=formconfig.ComboBoxCompt.ItemIndex+1;
case ComptLoc of // 1=compteur 1, 2=compteur 2 , 3=compteur tachro
1 :
begin
mini:=-135;
maxi:=152;
vmax:=127;
l:=formPrinc.ImageCompteur1.width;
h:=formPrinc.ImageCompteur1.height;
end;
2 :
begin
mini:=-80; // le 0 est à mini degrés
maxi:=120; // le vmax est à max degrés
vmax:=160; // vmax du compteur
l:=400;
h:=215;
end;
3 :
begin
mini:=-130; // le 0 est à mini degrés
maxi:=132; // le vmax est à max degrés
vmax:=210; // vmax du compteur
l:=400;
h:=340;
end;
end;
// fixer la largeur de la fenêtre
if typDest=fen then
begin
Lim:=LargeurCompteurs-ofs;
formCompteur[i].Width:=LargeurCompteurs;
Scompteur[i].paramcompt.ComptA:=(maxi-mini)/vmax; // pente de conversion vitesse en degrés compteur
Scompteur[i].paramcompt.ComptB:=mini; // coordonnées origine conversion
end;
if typDest=gb then
begin
compteurT[i].paramcompt.ComptA:=(maxi-mini)/vmax;
compteurT[i].paramcompt.ComptB:=mini;
end;
if typDest=im then
begin
paramcomptIm.ComptA:=(maxi-mini)/vmax;
paramcomptIm.ComptB:=mini;
end;
r:=h/l;
if l>=h then
begin
him:=round(lim*r); // hauteur image
//Affiche('Lim him = '+IntToSTR(lim)+' '+intToSTR(him),clLime);
//Affiche('L h = '+IntToSTR(l)+' '+intToSTR(h),clLime);
end
else
begin
him:=round(h*largeurCompteurs/l); // a revoir
Affiche('non traité 6',clred);
end;
// --- traitement par type de compteur
if typDest=gb then // GroupBox de l'onglet compteurs de la page principale
begin
if l>h then
begin
lim:=LargComptC-10;
him:=round(lim*r);
end
else
begin
him:=HautComptC-ofsGBH-CompteurT[i].tb.Height-ofsGBB;
lim:=round(him/r);
end;
with CompteurT[i] do
begin
tb.Height:=15;
gb.Width:=LargComptC;
gb.height:=ofsGBH+him+CompteurT[i].tb.Height+ofsGBB;
gb.Top:=(gb.Height+5)*((i-1) div NbreCompteursPLigne);
gb.left:=(LargComptC+5)*((i-1) mod (NbreCompteursPLigne));
Img.height:=HautComptC;
paramCompt.ImgL:=lim;
paramCompt.imgH:=him; //HautCompt-HautTb-ofsGBH-ofsGBB;
Img.picture.Bitmap.Width:=lim;
Img.picture.Bitmap.Height:=him; //HautCompt-HautTb-ofsGBH-ofsGBB;
if ComptLoc=1 then
begin
paramcompt.redX:=Lim/l/RedFonte; // pour le compteur 1; il faut intégrer le facteur de réduction
paramcompt.redY:=Him/h/RedFonte;
end
else
begin
paramcompt.redX:=Lim/l;
paramcompt.redY:=Him/h;
end;
paramcompt.ImgL:=Lim;
paramcompt.ImgH:=Him;
tb.Top:=him+ofsGBH; // position de la trackbar
tb.Width:=lim;
bouton.Top:=tb.Top-12;
bouton.left:=(lim div 2)-6;
bouton.Width:=16;
end;
case compteur of
1 : compteurT[i].paramcompt.rav:=round(70*compteurT[i].paramcompt.redx); // rayon de l'arc vert
2 : compteurT[i].paramcompt.rav:=round(100*compteurT[i].paramcompt.redx);
3 : compteurT[i].paramcompt.rav:=round(115*compteurT[i].paramcompt.redx);
end;
//ne pas faire compteurT[i].FCBitMap.Free çà fait une exception si il est déja en nil, contrairement à D13.
compteurT[i].fcBitMap:=tbitmap.Create;
with compteurT[i].FCBitMap do
begin
Width:=lim;
Height:=him;
end;
dessin_fond_compteur(compteurT[i].paramcompt,i,compteurT[i].fcBitmap,compteur);
Aiguille_compteur(i,i,compteurT[i].gb);
end;
// fenetre compteur unique
if typDest=fen then
begin
formCompteur[i].ImageCompteur.width:=Lim;
if ComptLoc=1 then
begin
Scompteur[i].paramcompt.redX:=Lim/l/RedFonte;
Scompteur[i].paramcompt.redY:=Him/h/RedFonte;
end
else
begin
Scompteur[i].paramcompt.redX:=Lim/l;
Scompteur[i].paramcompt.redY:=Him/h;
end;
Scompteur[i].paramcompt.ImgL:=Lim;
Scompteur[i].paramcompt.ImgH:=Him;
case compteur of
1 : Scompteur[i].paramcompt.rav:=round(70*Scompteur[i].paramcompt.redx); // rayon de l'arc vert
2 : Scompteur[i].paramcompt.rav:=round(100*Scompteur[i].paramcompt.redx);
3 : Scompteur[i].paramcompt.rav:=round(115*Scompteur[i].paramcompt.redx);
end;
with formCompteur[i] do
begin
if VerrouilleCompteur then Left:=formprinc.Left+formprinc.Width-width;
// ajuster hauteur de la fenetre
Hfen:=him+trackBarC.height;
if affTrainCompteur then Hfen:=Hfen+ImageTrain.Height+45 else
Hfen:=Hfen+LabelTrain.Height+40;
height:=hfen;
Scompteur[i].paramcompt.ImgL:=Lim;
Scompteur[i].paramcompt.ImgH:=Him;
with ImageCompteur do
begin
Width:=Lim;
Height:=Him;
Picture.Bitmap.Width:=Lim;
Picture.Bitmap.Height:=Him;
end;
with trackbarC do
begin
top:=him+ImageCompteur.Top;
width:=lim-2;
Left:=0;
visible:=true;
end;
with labelTrain do
begin
top:=trackbarC.Top+TrackBarC.Height;
left:=0;
end;
with button0 do
begin
top:=ImageCompteur.height-button0.height;//trackbarC.Top+TrackBarC.Height;
left:=(lim div 2)-(width div 2);
end;
With ImageTprov do
begin
left:=0;
width:=lim-2;
end;
With ImageTrain do
begin
top:=trackbarC.Top+TrackBarC.Height;
left:=2;
visible:=affTrainCompteur;
end;
// imageC <-- FCBitMap (on écrit les vitesses) <- ImageCompteur (grande)
// créer un bitmap réduit qui sert de référence
Scompteur[i].FCBitMap.Free;
Scompteur[i].fcBitMap:=tbitmap.Create;
with Scompteur[i].FCBitMap do
begin
Width:=lim;
Height:=him;
end;
end;
dessin_fond_compteur(Scompteur[i].paramcompt,i,Scompteur[i].FcBitmap,compteur);
Aiguille_compteur(i,IdTrainClic,formCompteur[i]);
Affiche_train_compteur(i);
end;
// image onglet config compteur
if typdest=im then
begin
image:=c as tImage;
lim:=Image.Width;
if l>h then
begin
him:=round(lim*r);
end
else
begin
him:=round(lim*r);
lim:=round(him/r);
end;
Image.Width:=lim;
Image.Height:=him;
if ComptLoc=1 then
begin
paramcomptIm.redX:=Lim/l/RedFonte;
paramcomptIm.redY:=Him/h/RedFonte;
end
else
begin
paramcomptIm.redX:=Lim/l;
paramcomptIm.redY:=Him/h;
end;
paramcomptIm.ImgL:=Lim;
paramcomptIm.ImgH:=Him;
i:=formconfig.ComboBoxCompt.Itemindex+1;
case i of
1 : paramcomptIm.rav:=round(70*paramcomptIm.redx); // rayon de l'arc vert
2 : paramcomptIm.rav:=round(100*paramcomptIm.redx);
3 : paramcomptIm.rav:=round(122*paramcomptIm.redx);
end;
FbmcompC.Width:=lim;
FbmcompC.height:=him;
canv:=formconfig.ImageCtC.Canvas;// Picture.Bitmap.Canvas;
dessin_fond_compteur(paramcomptIm,1,FbmcompC,i);
//Aiguille_compteur(1,1,formconfig.ImageCTC);
Aiguille_compteur(i,i,formconfig.ImageCTC);
end;
end;
// repositionne le compteur principal
procedure position_compteur;
begin
if not(Verrouillecompteur) then exit;
if formCompteur[1]=nil then exit;
with formCompteur[1] do
begin
Left:=formprinc.Left+formprinc.Width-width-2;
end;
if (formClock<>nil) and not(fermeSC) then
begin
if FormClock.Showing then
formCompteur[1].top:=formclock.top-formCompteur[1].height
else
formCompteur[1].top:=FormPrinc.top+formprinc.PageControl.top+100;
end;
//Affiche(intToSTR(formCompteur[1].top),clYellow);
end;
procedure TFormCompteur.FormActivate(Sender: TObject);
begin
//Affiche('FormCompteur activate',clyellow);
if VerrouilleCompteur then position_compteur;
end;
procedure TFormCompteur.Dverrouiller1Click(Sender: TObject);
begin
SetWindowPos(Handle,HWND_NOTOPMOST,0,0,0,0,SWP_NoMove or SWP_NoSize);
Verrouillerdevant1.Checked:=false;
Dverrouiller1.Checked:=true;
VerrouilleCompteur:=false;
end;
procedure TFormCompteur.Verrouillerdevant1Click(Sender: TObject);
begin
SetWindowPos(Handle,HWND_TOPMOST,0,0,0,0,SWP_NoMove or SWP_NoSize);
Verrouillerdevant1.Checked:=true;
Dverrouiller1.Checked:=false;
VerrouilleCompteur:=true;
end;
procedure TFormCompteur.Compteurdevitesse11Click(Sender: TObject);
begin
Compteurdevitesse11.checked:=true;
Compteurdevitesse21.checked:=false;
Compteurtachro1.checked:=false;
compteur:=1;
init_compteurs;
affiche_train_compteur(1);
aiguille_compteur(1,idTrainClic,formCOmpteur[1]);
end;
procedure TFormCompteur.Compteurdevitesse21Click(Sender: TObject);
begin
Compteurdevitesse11.checked:=false;
Compteurdevitesse21.checked:=true;
Compteurtachro1.checked:=false;
compteur:=2;
init_compteurs;
affiche_train_compteur(1);
aiguille_compteur(1,idTrainClic,formCompteur[1]);
end;
procedure TFormCompteur.Compteurtachro1Click(Sender: TObject);
begin
Compteurdevitesse11.checked:=false;
Compteurdevitesse21.checked:=false;
Compteurtachro1.checked:=true;
compteur:=3;
init_compteurs;
affiche_train_compteur(1);
aiguille_compteur(1,idTrainClic,formCompteur[1]);
end;
procedure TFormCompteur.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
AffCompteur:=false;
end;
procedure TFormCompteur.FormCreate(Sender: TObject);
begin
//LargComptC:=150;HautCompTC:=150;
// valeurs mini et maxi de la fenetre
with constraints do
begin
MaxWidth:=400;
MinWidth:=200;
MaxHeight:=450;
MinHeight:=100;
end;
if (Largeurcompteurs<=0) or (LargeurCompteurs>400) then LargeurCompteurs:=200;
HauteurCompteurs:=200;
ImageTrain.Height:=30; // les deux images doivent avoir la même hauteur
ImageTProv.height:=ImageTrain.Height;
// pour pouvoir redimensionner ImageTtrain, la première écriture de width doit etre au maxi possible et
// dessiner dedans sinon on ne peut plus l'agrandir au dela du maxi
with ImageTrain do
begin
Width:=400;
canvas.fillrect(rect(0,0,400,30));
end;
LabelTrain.Font.Size:=round(14*RedFonte);
end;
procedure TFormCompteur.TrackBarCChange(Sender: TObject);
var s : string;
i,vit : integer;
tt : ttrackbar;
f : tform;
begin
if clicTBtrain or clicTBGB then exit;
clicTBFen:=true;
tt:=sender as TTrackBar;
f:=tt.Parent as tform;
s:=f.caption; // nom du train=caption de la fenêtre
i:=index_train_nom(s);
vit:=TrackBarC.position;
//If affevt then Affiche('Changement TrackBarcc Vit='+intToSTR(vit),clyellow);
compteurT[i].tb.Position:=vit;
vitesse_loco(s,i,trains[i].adresse,vit,10,0);
clicTBFen:=false;
end;
procedure TFormCompteur.FormResize(Sender: TObject);
begin
refresh;
end;
procedure TFormCompteur.Button0Click(Sender: TObject);
var i : integer;
tt : tbutton;
f : Tform;
s : string;
begin
clicTBFen:=true;
tt:=sender as TButton;
f:=tt.Parent as tform;
s:=f.caption; // nom du train=caption de la fenêtre
i:=index_train_nom(s);
trains[i].vitesseCons:=0;
compteurT[i].tb.Position:=0;
trackBarC.Position:=0;
//vitesse_loco(s,i,trains[i].adresse,0,10,0);
clicTBFen:=false;
end;
procedure TFormCompteur.Affichericonedutrain1Click(Sender: TObject);
begin
affTrainCompteur:=not(affTrainCompteur);
afficherIconeDuTrain1.Checked:=affTrainCompteur;
init_compteur(1,formcompteur[1]);
affiche_train_compteur(1);
end;
procedure TFormCompteur.Vitesseencrans1Click(Sender: TObject);
begin
Vitesseencrans1.Checked:=true;
Vitesserelle1.checked:=false;
VitCrans:=true;
end;
procedure TFormCompteur.Vitesserelle1Click(Sender: TObject);
begin
Vitesserelle1.Checked:=true;
Vitesseencrans1.Checked:=false;
VitCrans:=false;
end;
procedure TFormCompteur.PopupMenuCPopup(Sender: TObject);
var c : tcomponent;
f : tform;
s : string;
i : integer;
begin
c:=popupmenuC.PopupComponent; // trouver la form parente du popup
c:=c.GetParentComponent;
if c is tform then
begin
f:=c as tform;
s:=f.caption; // train
i:=index_train_nom(s);
if trains[i].CoeffV3=0 then
begin
Vitesseencrans1.enabled:=false;
Vitesserelle1.enabled:=false;
end
else
begin
Vitesseencrans1.enabled:=true;
Vitesserelle1.enabled:=true;
end;
end;
end;
end.