seba31stien
Messages postés51Date d'inscriptionlundi 13 juin 2005StatutMembreDernière intervention25 juillet 2006
-
17 mai 2006 à 11:49
seba31stien
Messages postés51Date d'inscriptionlundi 13 juin 2005StatutMembreDernière intervention25 juillet 2006
-
18 mai 2006 à 09:16
Bonjour,
lorsque je compile ou construit mon soft, delphi indique "erreur interne L594". sur la FAQ, l'erreur interne L signifie "Linker". Dois je m'en inquiéter ? Est-ce que ça vous parle ?
merci
Seb
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202235 17 mai 2006 à 16:24
oui tu peu en effet mettre le tableau en statique si le nombre d'element ne depasse pas une certaine limite fixe.
de toute façon je ne vois aucune erreur la dedans ... peut etre utilise tu un thread ? auquel cas on peu en effet avoir des probleme si on essaye d'ajuster la taille du tableau tout en le lisant d'un autre coté.
vus que ton enregistrement fait 76 octets ... tu peu meme si tu veux faire un array[0..99] of TSite. (760 octets)
quand je pense que j'ai fait des tableaux dynamique beaucoup plus lourd que ça ...
petit conseil, tu pourrait faire comme cela :
TMatrix10B = array[0..9] of boolean;
TMatrix4i = array[0..3] of integer;
TSite = record
Drawing : boolean;
RR,RRO : TRect;
Center : TPoint;
Bond : TMatrix10B;
MonSite : String;
TypeRelais : TMatrix4i;
Numero : integer;
end;
TCC = Array of TSite;
procedure AddSite(var CC: TCC; const Site : TSite);
begin
SetLength(CC, Length(CC)+1);
CC[High(CC)] := Site;
end;
en sachant que l'indice de CC vas de 0 a N
evite, si tu l'a fait de faire :
CC[Length(CC)-1] car si length = 0 tu vas chercher l'indice -1 donc ... probleme
et toujours faire quelque controls preliminaire comme :
if Length(CC) = 0 then exit;
tu peu egalement te faire une Classe et placer TSite en TCollectionItem ... ça demande un peu plus de code mais au final l'utilisation est hyper simplifiée et securisée.
seba31stien
Messages postés51Date d'inscriptionlundi 13 juin 2005StatutMembreDernière intervention25 juillet 20061 17 mai 2006 à 12:40
Quand je mets cette ligne en commentaire, je n'ai plus le message d'erreur.c'est pour ça que je pense que celle ci est la cause du message.
concernant le code, je ne sais pas quoi mettre. pour info, CC est un tableau de données de type record.
Vous n’avez pas trouvé la réponse que vous recherchez ?
seba31stien
Messages postés51Date d'inscriptionlundi 13 juin 2005StatutMembreDernière intervention25 juillet 20061 17 mai 2006 à 16:07
type TSite = record
drawing : boolean; // en cours de déplacement
rr : trect; // rectangle position courante
rro : trect; // ancien ancienne position
centre : Tpoint;
bond : array[1..10] of boolean ;
nom_site : string;
type_relais : array[1..4] of integer;
numero : integer;
end;
SetLength(CC,x) vient après le click sur un bouton confirmant la création d'une image sur une carte. je ne sais pas quoi t'indiquer de plus.
mon appli : je place des triangles (polyline) sur une carte (paintbox).cc[x] correspond à un triangle. je crée un tableau de CC que j'initialise sur le formcreate.puis j'incrémente la taille de cc[] à chaque fois que l'on rajoutera un triangle sur la carte.
le nombre maxi de triangles sur la carte ne devrait pas dépasser 20, je pourrais peut être me passer d'un tableau dynamique et utiliser un statique.
Seb
seba31stien
Messages postés51Date d'inscriptionlundi 13 juin 2005StatutMembreDernière intervention25 juillet 20061 17 mai 2006 à 16:43
merci pour toutes ces infos & conseils.je débutes en programmation et tout ceci m'intéresse car mon but est de faire du "code" dont "l'utilisation est hyper simplifiée et securisée.."
je pars donc avec un tableau statique.
peux tu m'en dire plus sur les classes ? je regardes du côté de ce tutoriel :
http://sjrd.developpez.com/delphi/delphitutoriels/composants/graphiques/?page=collections
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202235 17 mai 2006 à 18:42
aller je suis de bonne humeur aujourd'hui et comme je sais que l'elaboration d'une classe est une chose peu evidente au debut je te donne la classe TSitesManager complete...
libre a toi ensuite de chercher a ajouter des evenements, methodes, propriétés ect... ect...
recopis tout cela dans une unité vierge et enregistre la dans le repertoire LIB de delphi.
ensuite installe ce nouveau composant que tu trouveras dans l'onglet "Exemple".
place le sur ta fiche et hop ... tu n'a plus qu'a ecrire ton programme avec la classe TSitesManager qui gereras tout pour toi.
Remarque que les evenements sont facile a créer, un evenements se decompose de la maniere suivante :
interface
type
{ type procedure of object qui permet de determiné une procedure type }
TNamedEvent = procedure(Sender : TObject [;Arguments]) of object;
TClasse = class
private
{ la variable qui pointeras sur le gestionnaire d'evenement }
fOnNamedEvent : TNamedEvent;
protected
{ le caller, permet d'appeler l'evenement a l'interieur de la classe
doit etre virtual pour permettre la derivation de la methode }
procedure NamedEventQuery([Arguments]); virtual;
published
{ la propriété qui s'afficherat dans l'onglet evenement de l'inspecteur d'objet }
property OnNamedEvent : TNamedEvent read fOnNamedEvent write fOnNamedEvent;
public
end;
implementation
procedure TClasse.NamedEventQuery([Arguments]);
begin
{ on doit appeler l'evenement uniquement si un gestionnaire y est attaché,
c'est une convention unique qui doit etre absoluement respectée.
il est interdit d'appeler un gestionnaire de remplacement si aucun
gestionnaire n'est associé. il ne faut pas non plus declancher d'exceptions
si c'est le cas. L'utilisateur doit etre libre de declarer un gestionnaire
ou non. }
if Assigned(fOnNamedEvent) then
fOnNamedEvent(Self [,Arguments]);
end;
et on appeleras NamedEventQuery dans la methode qui doit declancher l'evenement.
simple non ?
Il existe un type d'evenement predefinie qui se nome TNotifyEvent. c'est une evenement simple qui ne retourne que le Sender (Self) de l'evenement.
Mais il existe egalement d'autre type d'evenements ... pas besoin de les cités tous.
<hr size="2" width="100%" />
unit SitesMan;
INTERFACE
uses Windows, SysUtils, Classes, Types;
type
TMatrix10B = array[0..9] of boolean;
TMatrix4i = array[0..3] of integer;
{ forwarding des classes, declarer des classes pas encore definient pour pouvoir
y acceder a partir de classes declarée plus haut dans l'unité }
TSitesCollection = class;
TSitesManager = class;
{ TSiteItem ---------------------------------------------------------------------------------- }
{ TSiteItem correspond a l'ancien type record TSite, il ne contient que les données et
quelques routine de gestion }
{ TSitesCollection ------------------------------------------------------------------------ }
{ TSitesCollection correspond a l'ancien tableau dynamique array of TSite
c'est lui qui a la lourde charge de gerer la creation/liberation des TSiteItem,
il ne sert qu'a cela }
TSitesCollection = class(TCollection)
private
fSitesManager : TSitesManager;
function GetItem(Index: Integer): TSiteItem;
procedure SetItem(Index: Integer; Value: TSiteItem);
protected
function GetOwner: TPersistent; override;
public
constructor Create(SitesManager: TSitesManager);
function Add : TSiteItem;
property Items[Index: Integer]: TSiteItem read GetItem write SetItem; default;
end;
{ TSitesManager --------------------------------------------------------------------------- }
{ TSiteManager correspond aux anciennes routines externe utlisées dans le programme pour
traiter les données de TSite et le tableau array of TSite. C'est lui qui vas donc
jouer le chef d'orchestre entre les items et la collection. }
TSitesManager = class(TComponent)
private
fSitesCollection : TSitesCollection;
procedure SetSites(Val : TSitesCollection);
procedure SetItem(index : integer; val : TSiteItem);
function GetItem(index : integer) : TSiteItem;
protected
published
property Sites : TSitesCollection read fSitesCollection write SetSites;
public
property Items[index : integer] : TSiteItem read GetItem write SetItem;
function Add(const Item : TSiteItem) : integer;
procedure Delete(const index : integer);
function Count : integer;
{ enregistrement du composant dans la palette }
procedure Register;
IMPLEMENTATION
procedure Register;
begin
RegisterComponents(
'Exemples', { on definit la palette ou l'on vas installer le composant }
[TSitesManager]); { le nom de la classe du composant a installer }
end;
{ comparaison de deux variable TPoint }
function ComparePoint(const P1,P2 : TPoint) : boolean;
begin result :(P1.X P2.X) and (P1.Y = P2.Y);
end;
{ comparaison de deux variable TRect }
function CompareRect(const R1,R2 : TRect) : boolean;
begin result :(r1.Left r2.Left) and
(r1.Top = r2.Top) and
(r1.Right = r2.Right) and
(r1.Bottom = r2.Bottom);
end;
{ TSiteItem ------------------------------------------------------------------------------- }
constructor TSiteItem.Create(Collection: TCollection);
var N : integer;
begin
fCollection := (Collection as TSitesCollection);
fDrawing := false;
fRR := Rect(0,0,0,0);
fRRO := Rect(0,0,0,0);
fCenter := Point(0,0);
fMonSite := 'unnamed';
Self.MakeBond([False]);
Self.MakeTypeRelais([0]);
fNumero := fCollection.Count;
inherited Create(Collection);
end;
{ permet d'afficher une information descriptive de l'item dans l'inspecteur d'objet }
function TSiteItem.GetDisplayName: string;
begin
Result := format('Site %d : %s',[fNumero,fMonSite]);
end;
procedure TSiteItem.SetDrawing(val : boolean);
begin
if fDrawing <> Val then begin
fDrawing := Val;
Changed(false);
end;
end;
procedure TSiteItem.SetRect(index : integer; val : TRect);
begin
case index of
0 : if not CompareRect(fRR,Val) then begin
fRR := Val;
Changed(false);
end;
1 : if not CompareRect(fRRO,Val) then begin
fRRO := Val;
Changed(false);
end;
end;
end;
procedure TSiteItem.SetPoint(val : tpoint);
begin
if not ComparePoint(fCenter,Val) then begin
fCenter := Val;
Changed(false);
end;
end;
procedure TSiteItem.SetBond(index : integer; val : boolean);
begin
if (index >= 0) and (index <= 9) then
if fBond[index] <> Val then begin
fBond[index] := Val;
Changed(false);
end;
end;
function TSiteItem.GetBond(index : integer) : boolean;
begin
result := fBond[index]
end;
procedure TSiteItem.SetString(val : string);
begin
if fMonSite <> Val then begin
fMonSite := Val;
Changed(false);
end;
end;
procedure TSiteItem.SetRelais(index : integer; val : integer);
begin
if (index >= 0) and (index <= 3) then
if fTypeRelais[index] <> Val then begin
fTypeRelais[index] := Val;
Changed(false);
end;
end;
function TSiteItem.GetRelais(index : integer) : integer;
begin
result := fTypeRelais[index];
end;
procedure TSiteItem.SetInt(val : integer);
begin
if fNumero <> Val then begin
fNumero := Val;
Changed(false);
end;
end;
procedure TSiteItem.Assign(Source : TPersistent);
begin
if source is TSiteItem then begin
with TSiteItem(Source) do begin
Self.fDrawing := Drawing;
Self.fRR := RR;
Self.fRRO := RRO;
Self.fCenter := Center;
Self.fBond := fBond;
Self.fMonSite := MonSite;
Self.fTypeRelais := fTypeRelais;
Self.fNumero := Numero;
end;
end else
inherited Assign(source);
end;
{ Crée un tableau a partir des arguments on peu placer 1 ou 9 arguments
1 seul argument, le tableau est remplit avec cette valeur.
9 arguments, le tableau est remplit dans l'ordre avec les 9 valeurs }
procedure TSiteItem.MakeBond(const Args : array of boolean);
var N : integer;
begin
if length(Args) = 9 then
for N := 0 to 9 do
fBond[N] := Args[N]
else
if length(Args) = 1 then
for N := 0 to 9 do
fBond[N] := Args[0];
end;
{ fonctionnement identique a MakeBond ... sauf qu'ici nous auront 1 ou 4 arguments }
procedure TSiteItem.MakeTypeRelais(const Args : array of integer);
var N : integer;
begin
if length(Args) = 4 then
for N := 0 to 3 do
fTypeRelais[N] := Args[N]
else
if length(Args) = 1 then
for N := 0 to 3 do
fTypeRelais[N] := Args[0]
else
for N := 0 to 3 do
fTypeRelais[N] := 0;
end;
destructor TSitesManager.Destroy;
begin
fSitesCollection.Free;
inherited Destroy;
end;
procedure TSitesManager.SetSites(Val : TSitesCollection);
begin
fSitesCollection.Assign(Val);
end;
procedure TSitesManager.SetItem(index : integer; val : TSiteItem);
begin
fSitesCollection.SetItem(index,val);
end;
function TSitesManager.GetItem(index : integer) : TSiteItem;
begin
result := fSitesCollection.GetItem(index);
end;
{ crée un item et renvois son index dans la collection }
function TSitesManager.Add(const Item : TSiteItem) : integer;
begin
with fSitesCollection.Add do begin
Assign(item);
result := index;
end;
end;
procedure TSitesManager.Delete(const index : integer);
begin
fSitesCollection.Delete(index);
end;
function TSitesManager.Count : integer;
begin
result := fSitesCollection.Count;
end;
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 202250 17 mai 2006 à 19:34
Salut,
pour revenir à ton problème de départ (après le code de F0xi c'est pas évident )
type TSite = record
drawing : boolean; // en cours de déplacement
rr : trect; // rectangle position courante
rro : trect; // ancien ancienne position
centre : Tpoint;
bond : array[1..10] of boolean ;
nom_site : string[80]; // Une erreur se produit si aucune limite n'est donné à un String
type_relais : array[1..4] of integer;
numero : integer;
end;
Var cc : Arrayof TSite;
procedure TForm1.Button11Click(Sender: TObject);
begin SetLength(CC,1);
With cc[0] do Begin drawing : = True;
rr := Rect(0,0,100,100);
rro := Rect(100,100,500,500);
centre := Point(200,200);
bond[1] := True;
nom_site := 'DelphiFr';
type_relais[1] := 2;
numero := 15;
End;
End;
Ce code a été testé et il fonctionne
Bien sur la méthode de F0xi est bien plus propre mais c'était juste pour comprendre le pourquoi du comment
seba31stien
Messages postés51Date d'inscriptionlundi 13 juin 2005StatutMembreDernière intervention25 juillet 20061 18 mai 2006 à 09:16
Salut Cirec, j'ai limité la taille des strings mais l'erreur se produit toujours.
Salut f0xi, merci d'avoir pris le temps pour ajouter cette réponse. je vais travailler dessus pour comprendre et l'utiliser correctement. je posterai de nouveaux sujets lorsque je rencontrerai des difficultés de compréhension
Seb