- Delphi / Pascal : Make cab + checklistbox - CodeS SourceS
- Commande make linux
- Driver class 'org.gjt.mm.mysql.driver' could not be found, make sure the 'mysql' driver (jar file) is installed. org.gjt.mm.mysq
- Gérer les cases à cocher des Checklistbox : récupérer seulement les lignes coché
- Assignment makes integer from pointer without a cast
29 juin 2006 à 19:53
type
IStrings=interface
function GetCount:Integer;
property Count:Integer read GetCount;
function GetItem(const Index:Integer):string;
procedure SetItem(const Index:Integer;const Value:string);
property Item[Index:Integer]:string read GetItem write SetItem;
end;
TStringsImplementation=class(TInterfacedObject,IStrings)
function GetCount:Integer;
function GetItem(const Index:Integer):string;
procedure SetItem(const Index:Integer;const Value:string);
destructor Destroy;override;
end;
...faire l'implémentation de l'objet TStringsImplementation...
On pourrait alors déclarer la fonction qui renvoie une liste de chaînes de la fonction suivante:
function TCheckListBox.GetChecks:IStrings;
begin
Result:=TStringsImplementation.Create;
Result.Add(...);
end;
Lorsque quelqu'un utilise la fonction ainsi:
with CheckListBox1.GetChecks do begin
ShowMessage('Il y a '+IntToStr(Count)+' items sélecionnés');
end;
la mémoire sera libérée, car il y a des appels implicites à _AddRef et _Release qui font -avec le mécanisme de comptage de référence des interfaces- qu'à l'issue de cet appel, l'objet TStringsImplementation est détruit. C'est une solution propre et élégante, mais qui nécessite toutefois d'écrire un peu plus de code (ceci dit écrire l'implémentation de TStringsImplementation ne me paraît pas très difficile...).
29 juin 2006 à 19:44
begin
List.BeginUpdate;
try
List.Add(...);
finally
List.EndUpdate;
end;
end;
"AddToList" a l'avantage d'être un nom explicite. BeginUpdate...EndUpdate permet de ne pas dégrader les performances avec des TStrings associés à des contrôles par exemple.
23 avril 2006 à 22:04
en fait je parler de rendre disponible le retour de la fonction pour l'utiliser comme control ou comme information.
pour ce que tu dis :
La création est inutile ici.
procedure SetList(List : TStrings);
begin
list.Clear
List.Add(...);
end;
attention, toute fois, si il s'agit d'une liste non visuelle, pas de probleme, par contre si il s'agit d'un composant visuel, le fait de faire des ADD vas rafraichir le compo et degradé les preformance d'ou le buffer de type TStringList pour d'abord créer la liste puis envoyer la liste a l'objet en argument.
21 avril 2006 à 22:10
Regarde ma solution de près et tu veras que le code Repeat Until n'est appelé que si le If est vrai. Le traitement ne seront donc bien effectué que sur le premier élément.
Pour ta solution
procedure SetList(List : TStrings);
var TMPLIST : TStringList;
begin
try
TMPLIST := TStringList.Create;
...
TMPLIST.Add(...);
...
List.Assign(TMPLIST);
finally
TMPLIST.Free;
end;
end;
La création est inutile ici.
procedure SetList(List : TStrings);
begin
list.Clear
List.Add(...);
end;
Pour répondre à un point au dessus aussi, tu dis que le résultat est libéré car c'est une variable locale. C'est FAUX. Seules les chaines et les tableaux dynamiques sont dans ce cas, dans tous les autres c'est à toi de le gérer.
21 avril 2006 à 11:02
Erreur que j'ai répétée et que nono a corrigée, c'est qu'un retour de ce type ne serat jamais libéré durant l'execution, soit, pas liberée en memoire.
donc si la liste pese 15Koctet et qu'on appel 100 fois la fonction, on provoque une fuite de memoire de 1500 Ko (1.5Mo)
donc il faut faire comme on vient de te le dire, passer la List dans les arguments et non dans le retour de fonction.
soit :
procedure TCheckListBox.GetSelection(OutList : TStrings);
var
i : Integer;
TPL : TStringList;
begin
try
TPL : TStringList;
For i := 0 to Items.Count - 1 do
if Checked[i] then TPL.Add(Items.Strings[i]);
OutList.Assign(TPL);
finally
TPL.free;
end;
end;
>> J'ai mis le sender sur le CheckAll pour pouvoir l'appeler directement avec le click sur le menuitem "Tout cocher" mais peut etre qu'il y a un autre moyen ?
pas besoin, Tu crée la methode "TouCocher1Click" et tu place le code CheckList.CheckAll;
dedans.
ce serat plus propre car comme je te l'ai dis, ce sont des methodes et non des evenements. nuance.
en plus, cela permet de ne pas passer un argument inutile aux methodes ...
car un il ne faut pas oublier qu'un argument inutile prend de la place pour rien en memoire.
donc tu auras :
procedure TForm1.ToutCocher1Click(Sender : TObject);
begin
CheckList.CheckAll;
end;
et non dans l'inspecteur d'objet :
OnClick >> CheckList.CheckAll