Remplir tableau avec le contenu d'un CheckBoxList [Résolu]

Messages postés
236
Date d'inscription
jeudi 30 septembre 2004
Dernière intervention
26 juin 2011
- - Dernière réponse : cs_JackNUMBER
Messages postés
236
Date d'inscription
jeudi 30 septembre 2004
Dernière intervention
26 juin 2011
- 6 juin 2010 à 13:27
Bonsoir :)
Après beaucoup de recherche je n'ai pas réussi à trouver un exemple assez simple pour ce que je cherche à faire....

Je cherche simplement à remplir une colonne d'un tableau multidimensionnel par les ItemsIndex d'un CheckListBox et l'autre colonne par les Items de ce même CheckListBox. Le tout dans une fonction récursive.
Le script semble « correct » (il passe au compilateur) mais lors de l'exécution du script ça plante le prog.

Message d'erreur >> Violation d'accès à l'adresse 00404238 dans le module 'blabla.exe'. Ecriture de l'adresse 00000072.

var
  Form1: TForm1;
  c: Integer;
  b: Integer;
  Result : Integer;
  ResultTotal : Integer;
  StopProcess : Boolean;
  MonTableau: array of array of String;


function ListFiles(Chemin:String):Integer;
var
S : TSearchRec;

begin
 Chemin:=IncludeTrailingPathDelimiter(Chemin);
 Form1.Label1.Caption:='Recherche dans '+Chemin;
 Form1.CheckListBox1.Refresh;

 If FindFirst(Chemin+'*.*',faAnyFile,S)=0
 then begin
  repeat
   Application.ProcessMessages;
   if (StopProcess) then exit else
   if (S.Name<>'.')And(s.Name<>'..')
   then begin
    if (S.Attr And faDirectory)<>0
    then
     begin
     Result:=Result+ListFiles(Chemin+S.FindData.cFileName);
     Inc(ResultTotal);
     end
    else
     if MatchesMask(S.Name, 'TTTT*.*') then
      begin
       Form1.CheckListBox1.Items.Add(S.Name);
       Inc(Result);
       SetLength(MonTableau,1,Result-1);
       For b:=0 To Length(Form1.CheckListBox1.Items[b]) do //    c'est ici que ça pose problème
       MonTableau[1,b]:=Form1.CheckListBox1.Items[b];      //    c'est ici que ça pose problème
      end;
  end;
  Until FindNext(S) <> 0;
   FindClose(S);
  end;
end;



L'aide de Delphi m'a plus embrouillé qu'autre chose -_-
Merci de votre aide !
Afficher la suite 

Votre réponse

18 réponses

Meilleure réponse
Messages postés
260
Date d'inscription
lundi 27 octobre 2003
Dernière intervention
4 mars 2016
3
Merci
Salut,
ThWilliam a raison pourquoi un tableau 2D pour cette fonction .
Enfin ...
var
    Form1: TForm1;
    ResultFichier : Integer;
    ResultDossier : Integer;
    StopProcess   : Boolean;
    MonTableau    : array of array of String;

function ListFiles(Chemin, FindF:String; List:TStrings):Integer;
Var
    S : TSearchRec;
begin
    Chemin:=IncludeTrailingPathDelimiter(Chemin);
    Result:=0;
    If FindFirst(Chemin+'*.*',faAnyFile,S)=0 then
    begin
        repeat
            Application.ProcessMessages;
            if (StopProcess) then
                Exit
            else
            begin
                if (S.Name<>'.')And(s.Name<>'..')then
                begin
                    if (S.Attr And faDirectory)<>0 then
                    begin
                        ListFiles(Chemin+S.FindData.cFileName,FindF,List);
                        Inc(ResultDossier);
                    end
                    else
                    begin
                        if MatchesMask(S.Name, FindF) then
                        begin
                            Inc(ResultFichier);
                            List.Add(S.Name+' (Index '+IntTostr(ResultFichier-1)+')');
                            SetLength(MonTableau[0],ResultFichier);
                            SetLength(MonTableau[1],ResultFichier);
                            MonTableau[0,ResultFichier-1]:='Index '+IntTostr(ResultFichier-1);
                            MonTableau[1,ResultFichier-1]:=Chemin+S.Name;
                        end;
                    end;
                end;
            end;
        Until FindNext(S) <> 0;
        FindClose(S);
    end;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
    ResultFichier:=0;
    ResultDossier:=0;
    CheckListBox1.Clear;
    SetLength(MonTableau,2);
    Label1.Caption:='Recherche dans C:\Test';
    ListFiles('C:\Test','TTTT*.*',CheckListBox1.Items);
    Label2.Caption:=Format('Resultats : %d Dossiers et %d Fichiers',[ResultDossier,ResultFichier]);
end;

Dans le tableau : Index 0 | C:\Test\TTTTtest.jpg ...
Dans le CheckListBox : TTTTTest.jpg (Index 0) ...
Voilà courage
@+yanb

Merci cs_yanb 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources a aidé 98 internautes ce mois-ci

Commenter la réponse de cs_yanb
Messages postés
424
Date d'inscription
mardi 3 janvier 2006
Dernière intervention
26 novembre 2013
3
Merci
Re-bonjour.

"je n'ai pas réussi à déclarer lbOwnerDrawFixed" : tu as, je suppose, créer ton CheckListBox en mode designtime. Dans l'inspecteur d'objets, il suffit de modifier la propriété "Style". Puis dans les événements, double clic sur "OnDrawItem".

"Je souhaite supprimer certains des fichiers affichés, cette méthode le permet-elle ?"
Oui, sans aucun problème, puisque tes items du checkboxlist = chemin complet + nom de fichier.
Mais 2 remarques :
1) comme tu n'affiches pas le chemin, il est possible d'avoir à l'affichage deux ou plusieurs fichiers portant le même nom (pcq se trouvant dans des dossiers différents). Donc attention à choisir le bon !
2) remarque valable pour tout delete de plusieurs items dans une liste : toujours commencer par la fin de la liste :
for I:= CheckListBox1.Count - 1 downto 0 do...
en effet, à chaque delete d'un item, l'item suivant prend la place et l'indice de l'item effacé (et ainsi de suite...) + la propriété Count est réactualisée.

A +
Thierry

Merci ThWilliam 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources a aidé 98 internautes ce mois-ci

Commenter la réponse de ThWilliam
Messages postés
260
Date d'inscription
lundi 27 octobre 2003
Dernière intervention
4 mars 2016
3
Merci
Salut,
On a tout donné, où est la difficulté dans le code de ThWilliam.
Allez un effort pour la suppression.
var
  Form1: TForm1;
  StopProcess : Boolean;

function ListFiles(Chemin, FindF:String; List:TStrings):Integer;
var
    S : TSearchRec;
begin
    Chemin:=IncludeTrailingPathDelimiter(Chemin);
    Result:=0;
    If FindFirst(Chemin+'*.*',faAnyFile,S)=0 then
        repeat
            Application.ProcessMessages;
            if (StopProcess) then
                Exit
            else
                if (S.Name<>'.')And(s.Name<>'..')then
                    if (S.Attr And faDirectory)<>0 then
                        ListFiles(Chemin+S.FindData.cFileName,FindF,List)
                    else
                        if MatchesMask(S.Name, FindF) then
                            List.Add(Chemin+S.Name);
        Until FindNext(S) <> 0;
        FindClose(S);
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
    CheckListBox1.Style:=lbOwnerDrawFixed;
    CheckListBox1.Clear;
    Label1.Caption:='Recherche dans '+Direct;
    ListFiles('C:\Test','TTTT*.*',CheckListBox1.Items);
end;

procedure TForm1.CheckListBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
begin
    with CheckListBox1 do
        Canvas.TextRect(Rect,Rect.Left, Rect.Top,ExtractFileName(Items[Index]));
end;

@+ yanb

Merci cs_yanb 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources a aidé 98 internautes ce mois-ci

Commenter la réponse de cs_yanb
Messages postés
424
Date d'inscription
mardi 3 janvier 2006
Dernière intervention
26 novembre 2013
3
Merci
with CheckListBox1 do
Canvas.TextRect(Rect, Rect.Left
, Rect.Top, ExtractFileName(Items[Index]));

Merci ThWilliam 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources a aidé 98 internautes ce mois-ci

Commenter la réponse de ThWilliam
Messages postés
692
Date d'inscription
jeudi 17 avril 2008
Dernière intervention
14 septembre 2018
0
Merci
bonjour
For b:=0 To Length(Form1.CheckListBox1.Items[b])
je pense qu'il faut mettre " - 1 " car la longueur de la chaine est calculée de 1 à length, alors que le tableau est indicé à partir de 0
cordialement
Dubois77
Commenter la réponse de dubois77
Messages postés
260
Date d'inscription
lundi 27 octobre 2003
Dernière intervention
4 mars 2016
0
Merci
Salut,
Le dimensionnement tableau
Result à utiliser pour les fonctions pas en variable
etc ...
var
  Form1: TForm1;
  c: Integer;
  b: Integer;
  //Result : Integer;
  ResultTotal : Integer;
  StopProcess : Boolean;
  MonTableau: array of array of String;


function ListFiles(Chemin:String):Integer;
var
S : TSearchRec;

begin
 Chemin:=IncludeTrailingPathDelimiter(Chemin);
 Form1.Label1.Caption:='Recherche dans '+Chemin;
 Form1.CheckListBox1.Refresh;
 Result:=0;
 SetLength(MonTableau,2);
 If FindFirst(Chemin+'*.*',faAnyFile,S)=0
 then begin
  repeat
   Application.ProcessMessages;
   if (StopProcess) then exit else
   if (S.Name<>'.')And(s.Name<>'..')
   then begin
    if (S.Attr And faDirectory)<>0
    then
     begin
     Result:=Result+ListFiles(Chemin+S.FindData.cFileName);
     Inc(ResultTotal);
     end
    else
     if MatchesMask(S.Name, 'TTTT*.*') then
      begin
       Form1.CheckListBox1.Items.Add(S.Name);
       Inc(Result);       
       SetLength(MonTableau[0],Result);
       SetLength(MonTableau[1],Result);
       For b:=0 To Form1.CheckListBox1.Items.Count-1 do //    c'est ici que ça pose problème
       begin
         MonTableau[0,b]:=IntToStr(b+1);
         MonTableau[1,b]:=Form1.CheckListBox1.Items[b];      //    c'est ici que ça pose problème
       end;
      end;
  end;
  Until FindNext(S) <> 0;
   FindClose(S);
  end;
end;

Normalement ca devrait régler le pb
@+yanb
Commenter la réponse de cs_yanb
Messages postés
236
Date d'inscription
jeudi 30 septembre 2004
Dernière intervention
26 juin 2011
0
Merci
Et si je met autre chose à la place de Result ?
Une variable "blabla" ça marchera aussi ?

Merci de vos réponses, j'essaie ce soir.
Commenter la réponse de cs_JackNUMBER
Messages postés
236
Date d'inscription
jeudi 30 septembre 2004
Dernière intervention
26 juin 2011
0
Merci
J'ai essayé vos 2 méthodes : même erreur
Je ne sais pas d'où ça vient....
Commenter la réponse de cs_JackNUMBER
Messages postés
265
Date d'inscription
dimanche 7 décembre 2003
Dernière intervention
11 novembre 2016
0
Merci
Bonjour

Questions
1 pourquoi avoir un tableau a 2 dimension si c'est pour uniquement remplir la 2
MonTableau[1,b]:=Form1.CheckListBox1.Items[b]
2 a quoi sert cette boucle For b:=0 To Length(Form1.CheckListBox1.Items[b]) do
il serait mieux de faire
Form1.CheckListBox1.Items.Add(S.Name);
Inc(Result);
SetLength(MonTableau[1],Result);
MonTableau[1,Result -1]:=Form1.CheckListBox1.Items[Result -1]

A+
Commenter la réponse de fbalien
Messages postés
236
Date d'inscription
jeudi 30 septembre 2004
Dernière intervention
26 juin 2011
0
Merci
Et bien en fait je comptais remplir la première colonne après :s (mon script est incomplet, c'est vrai).
Et la boucle c'est parce que je n'ai pas réussi à pondre quelque chose de plus "cohérent"....

Merci pour ton aide fbalien mais ça ne marche pas...
En gros, je cherche à remplir comme ceci :

tableau :
[0|dossier/TTTT01.jpg]
[1|TTTThdfhdd.mpg]
[2|dossier/blabla/TTTTblabla.rtf]
[3|dossier/bla/TTTTjjjjjjjjj.jpg]
[4|..........]

checklistbox :
[]TTTT01.jpg (index:0)
[]TTTThdfhdd.jmpg (index:1)
[]TTTTblabla.rtf (index:2)
[]TTTTjjjjjjjjj.jpg (index:3)
[]TTTT............ (index:4)




J'ai essayé ceci :
Form1.CheckListBox1.Items.Add(S.Name);
Inc(Result);
SetLength(MonTableau[1],Result-1);
MonTableau[0,Result -1]:=IntToStr(Result-1);
MonTableau[1,Result -1]:=Chemin+S.Name;

sans succès :/

Merci de votre aide !
Commenter la réponse de cs_JackNUMBER
Messages postés
260
Date d'inscription
lundi 27 octobre 2003
Dernière intervention
4 mars 2016
0
Merci
Salut,
surprenant que le message soit toujours présent...
je vais le tester, mais le pb vient bien du dimensionnement du tableau,
tu essaye de mettre des valeur dans un tableau ou les tailles ne sont pas ou mal fixés.
@+yanb
Commenter la réponse de cs_yanb
Messages postés
424
Date d'inscription
mardi 3 janvier 2006
Dernière intervention
26 novembre 2013
0
Merci
Salut,

Si je comprends bien, tu utilises un tableau 2D pour stocker :
- index du fichier trouvé
- chemin + nom fichier

A quoi te sert ce tableau !?
- comme tu ajoutes à chaque fichier trouvé son nom dans un checklistbox, l'index du fichier = index de l'item du checklistbox.
- tu utilises la 2° dimension pour stocker le chemin complet. Mais tu peux très bien assigner à l'item du checklistbox le chemin + le nom. Si tu ne veux voir affiché que le nom, tu "dessines" toi-même le texte à afficher.

Propriété Style du checklistbox = lbOwnerDrawFixed

puis événement OnDrawItem, avec un code du genre :

procedure TForm1.CheckListBox1DrawItem(Control: TWinControl;
Index: Integer; Rect: TRect; State: TOwnerDrawState);
begin
with CheckListBox1 do
Canvas.TextRect(Rect,Rect.Left, Rect.Top,ExtractFileName(Items[Index]));
end;

A +
Thierry
Commenter la réponse de ThWilliam
Messages postés
236
Date d'inscription
jeudi 30 septembre 2004
Dernière intervention
26 juin 2011
0
Merci
@ ThWilliam > je ne pensais pas que l'on pouvait faire une telle chose !!
C'est un ami qui m'a conseillé de passer par un tableau, je suis issu des BDD, ça m'a paru être une bonne idée.
Cette idée m'intéresse beaucoup !
Peux-tu m'en dire plus, je n'ai pas réussi à déclarer lbOwnerDrawFixed.

Je souhaite supprimer certains des fichiers affichés, cette méthode le permet-elle ?



@ yanb > merci mais je vais me concentrer sur la méthode de ThWilliam.
Commenter la réponse de cs_JackNUMBER
Messages postés
236
Date d'inscription
jeudi 30 septembre 2004
Dernière intervention
26 juin 2011
0
Merci
Et après plusieurs essais je n'ai pas réussi à faire fonctionner
Canvas.TextRect(Rect,Rect.Left, Rect.Top,ExtractFileName(Items[Index]));

Je suis vraiment nul --'
j'ai déclaré Form1.CheckListBox1.Style:=lbOwnerDrawFixed; avant la fonction récursive....
Commenter la réponse de cs_JackNUMBER
Messages postés
260
Date d'inscription
lundi 27 octobre 2003
Dernière intervention
4 mars 2016
0
Merci
oups erreur il faut supprimer la ligne :
Label1.Caption:='Recherche dans '+Direct;
ou la remplacer par Label1.Caption:='Recherche dans C:\Test';
@+yanb
Commenter la réponse de cs_yanb
Messages postés
236
Date d'inscription
jeudi 30 septembre 2004
Dernière intervention
26 juin 2011
0
Merci
[b]with CheckListBox1 do
Canvas.TextRect(Rect,Rect.right, Rect.Top,ExtractFileName(Items[Index]));/b
n'a aucun effet je me retrouve avec les chemins+noms de fichiers dans le CHL.

Merci pour le script pour la suppression !
Commenter la réponse de cs_JackNUMBER
Messages postés
236
Date d'inscription
jeudi 30 septembre 2004
Dernière intervention
26 juin 2011
0
Merci
Encore mieux... le OnDrawItem vide les items, j'ai toutes les cases à cocher mais plus le contenu (nom de fichier ou chemin).... je suis perdu.
Commenter la réponse de cs_JackNUMBER
Messages postés
236
Date d'inscription
jeudi 30 septembre 2004
Dernière intervention
26 juin 2011
0
Merci
Parfait !!!
Comme prévu CheckListBox1.Items[i] affiche le chemin + nom du fichier !

Je vous aime les gars
Commenter la réponse de cs_JackNUMBER

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.