IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++Builder Discussion :

Mettre des image dans un TIMageList


Sujet :

C++Builder

  1. #21
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    219
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 219
    Par défaut
    Bonjour,
    j'ai deja toute ces option activées

    j'ai juste fait ce test sur uniquement une seule ligne de code et j'ai toujours cette violation d'acces

    Est ce que cette même ligne de code fait un violation d'acces
    sur votre machine ?

    Qui peut tester ce bout de code et me dire ?

    Je me demande si cela ne viens pas de mon compilateur ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void __fastcall TForm1::Button5Click(TObject *Sender)
    {
    TList *testListe=new TList[10];
    }
    ---------------------------
    Notification d'une exception du débogueur
    ---------------------------
    Le projet Tlist.exe a provoqué une classe d'exception EAccessViolation avec le message 'Violation d'accès à l'adresse 89C489C4. Lecture de l'adresse 89C489C4'. Processus stoppé. Utilisez Pas-à-pas ou Exécuter pour continuer.
    ---------------------------
    OK Aide
    ---------------------------
    merci

  2. #22
    Membre éclairé
    Homme Profil pro
    Consultant technique
    Inscrit en
    Juillet 2002
    Messages
    519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2002
    Messages : 519
    Par défaut
    Avec C++Builder 2006, j'ai le même problème mais le message d'erreur est différent (exception externe EEFFACE).

    De toute façon, il n'y a pas besoin de faire un tableau de TList, on peut les créer une à une et stocker leurs pointeurs dans le TList principal.

  3. #23
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2005
    Messages
    401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2005
    Messages : 401
    Par défaut
    Je me demande si cela ne viens pas de mon compilateur ?
    Oui, et non, en même temps...
    C'est une des joyeusetés de la VCL: les classes qui dérivent de TObject doivent être créées par un new, et on ne peut pas en créer un tableau !

    C'est clair quand tu faisLe compilo gueule tout de suite.

    Par contre il laisse passer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TList* listeDeListe=new TList[10];
    et tu le découvres à l'exécution...

    Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class TListX : public System::TObject
    {
    public:
    	__fastcall TListX(void) : System::TObject() { }
    };
     
    class TListY
    {
    public:
    	__fastcall TListY(void) { }
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void __fastcall TForm33::vBtn1Click(TObject *Sender)
    {
    TListY *testListeY=new TListY[10];
    TListX *testListeX=new TListX[10];
    }
    Pour TListY, ça passe.
    Pour TListX, violation d'accès....

    Pour terminer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    void __fastcall TForm33::vBtn1Click(TObject *Sender)
    {
      TPers *pPers=new TPers[6];
      pPers[0].Nom="Image1";   //liste 0 image 0    //colone ligne
      pPers[1].Nom="Image2";  // liste 1 image 1
      pPers[2].Nom="Image3";  // liste 2 image 2
      pPers[3].Nom="Image4";  // liste 0 image 3
      pPers[4].Nom="Image5";  // liste 1 image 5
      pPers[5].Nom="Image6";  // liste 2 image 6
     
      int NbListe=3;
       //const int NombreListe= NbListe;
     
      TList *TabList=new TList;
      for (int i=0; i<NbListe; i++)
        TabList->Add(new TList);
     
      // initilsation de liste
      TList* liste0 = (TList*)(TabList->Items[0]);
      TList* liste1 = (TList*)(TabList->Items[1]);
      TList* liste2 = (TList*)(TabList->Items[2]);
     
      liste0->Add(&pPers[0]);  //image1    liste0
      liste1->Add(&pPers[1]);  //image 2  liste1
      liste2->Add(&pPers[2]);  //image 3  liste  2
     
      liste0->Add(&pPers[3]);  //image 4  liste0
      liste1->Add(&pPers[4]);   //image 5 liste 1
      liste2->Add(&pPers[5]);   // image 6 liste 2
     
      AfficheListe2(TabList);
    }
    Allez, si tu veux vraiment utiliser des TList, y'a moyen de rendre la chose plus pratique:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class TPers
    {
      public:
      AnsiString Nom;
      TPers(AnsiString nom) : Nom(nom) {}
      TPers(void) {}
    };
     
    template <class T> class TListT : public TList
    {
    public:
    __property T* Items[int p_indice] = {read = LireItem, write=EcrireItem};
     
    private:
      T* __fastcall LireItem(int i) { return (T*)Get(i); }
      void __fastcall EcrireItem(int i, T* p) { Put(i, p); }
    };

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    void __fastcall TForm33::vBtn2Click(TObject *Sender)
    {
      int NbListe=3;
     
      TListT<TPers>* uneListe = new TListT<TPers>;
      uneListe->Add(new TPers("Im1"));
      uneListe->Add(new TPers("Im2"));
      TPers* pers = uneListe->Items[0];
      uneListe->Items[1]->Nom = "Im3";
      for (int i=0; i<uneListe->Count; i++)
        delete uneListe->Items[i];
      delete uneListe;
     
      TListT< TListT<TPers> > *TabList=new TListT< TListT<TPers> >;
      for (int i=0; i<NbListe; i++)
        TabList->Add(new TListT<TPers>);
     
      TabList->Items[0]->Add(new TPers("Image1"));  //image1    liste0
      TabList->Items[1]->Add(new TPers("Image2"));  //image 2  liste1
      TabList->Items[2]->Add(new TPers("Image3"));  //image 3  liste  2
     
      TabList->Items[0]->Add(new TPers("Image4"));  //image 4  liste0
      TabList->Items[1]->Add(new TPers("Image5"));   //image 5 liste 1
      TabList->Items[2]->Add(new TPers("Image6"));   // image 6 liste 2
     
      TabList->Items[2]->Items[0]->Nom = "Toto";
     
      AfficheListe2(TabList);
     
      for (int i=0; i<TabList->Count; i++)
      {
        TListT<TPers>* listeP = TabList->Items[i];
        for (int j=0; j<listeP->Count; j++)
          delete listeP->Items[j];
        delete listeP;
      }
      delete TabList;
    }

  4. #24
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    219
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 219
    Par défaut
    Merci totoche :merci :
    ton code est très pratique mais il va falloir que je rebosse le templates
    mais de loin c'est plus pratique

    tu ma donne un super idée créer une structure ou classe qui contiendrais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef struct TFlux
    {
    TMemoryStream *pMs;
    bool IsPicture  // sert a tester si le champ blob est une image ou du texte
    }TFlux;
    est ce possible ?
    est ce bien ?

    Par contre reste a savoir
    comment on teste la nature d'un flux blob pour savoir si c'est un flux qui contient de images ou soit du texte.....J'ai pas tout compris
    avez vous un exemple de code ?


    Je vais essayer de l'adapter pour le reste de ma fonction.

    pour le destruction actuellement je fais
    avez, vous de critique a faire a ce code ?

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    void _fastcall TForm1::FreeTABList(TList * TabList)
    {
            //On effcace tous toutes les listes 
    
            for( int i=0;i<TabList->Count;i++)    // parcours du tableau de liste
            {
               TList *ListeLu=(TList*)TabList->Items[i];
    
               for(int j=0 ;j<ListeLu->Count;j++) // parcours de la liste
               {
                 delete(TPers*)ListeLu->Items[j]; //on libere la memoire de l'objet
                 delete ListeLu->Items[j]; // on libère le pointeur dans la liste
               }
    
               delete ListeLu; // destruction d'une pointeur de liste
               ListeLu=NULL;
    
               delete TabList->Items[i]; // destruction du pointeur dans la liste
    
            }
            delete TabList;  // destruction de tableau de liste
            TabList=NULL;
    }

    J'avais un petite question j'aurais voulu en savoir plus
    Quant je compile sans codeguard et que j'exécute
    tous se passe bien

    Quand j'active codeguard cela s'exécute sans problème mais j'ai ces warning
    Dans la capture écran donnée ,et par rapport au code ce sont le 2 premières lignes en rouge . C'est au premier passage dans la boucle.

    j'aurais aimé en savoir plus......si vous pouvez m'expliquez

    encore merci a tous les deux pour votre aide précieuse
    Images attachées Images attachées  

  5. #25
    Membre éclairé
    Homme Profil pro
    Consultant technique
    Inscrit en
    Juillet 2002
    Messages
    519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2002
    Messages : 519
    Par défaut
    Vous pouvez enlever la ligne suivante :

    Vu que c'est une variable temporaire, sa durée de vie est limité à sa boucle. Et comme vous la videz juste avant qu'elle ne soit détruite, cela ne sert à rien.
    Mais ce n'est pas grave.
    Concernant votre problème de codeguard, je ne sais pas comment vous les avez créé mais la il vous dit que les fonctions que vous voulez supprimer ont été créée avec new[] et qu'il faut donc les libérer avec delete[] et non pas avec delete.
    Essayez :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
                 delete[] (TPers*)ListeLu->Items[j]; //on libere la memoire de l'objet
                 delete[] ListeLu->Items[j]; // on libère le pointeur dans la liste
    Concernant la détection des images, il me semble que chaque format d'image commence par une entête (‰PNG ou 8950AE47 en hexa pour un fichier PNG, GIF89a pour un GIF, BM6 pour un BMP, ...). J'ai trouvé ces valeurs avec un éditeur hexadécimal.

  6. #26
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2005
    Messages
    401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2005
    Messages : 401
    Par défaut
    En plus de ce que dit gandf, pourquoi supprimer 2 fois le même objet ??
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    void _fastcall TForm1::FreeTABList(TList * TabList)
    {
            //On effcace tous toutes les listes 
            for( int i=0;i<TabList->Count;i++)    // parcours du tableau de liste
            {
               TList *ListeLu=(TList*)TabList->Items[i];
               for(int j=0 ;j<ListeLu->Count;j++) // parcours de la liste
               {
                 delete (TPers*)(ListeLu->Items[j]); //on libere la memoire de l'objet
                 // delete ListeLu->Items[j]; // idem que précédent
               }
               delete ListeLu; // destruction d'une pointeur de liste
               // ListeLu=NULL; // Inutile
               // delete TabList->Items[i]; // déjà fait
     
            }
            delete TabList;  // destruction de tableau de liste
            // TabList=NULL; // Inutile
    }

  7. #27
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    219
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 219
    Par défaut
    Bonjour j'ai essayé ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
       for(int j=0 ;j<ListeLu->Count;j++){ // parcours de la liste
               delete [] (TPers*)(ListeLu->Items[j])
       }
    effectivement code guard ne broche plus mais au second passage dans ma boucle j'ai un violation d'acces "indice en dehors de limites"

    J'ai créée mes listes comme ceci avec mon ancien code mais je compte bien utiliser le troisième solution de Totoche 76 il va falloir que je prevois de l'aspirine......

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    void __fastcall TForm1::Button4Click(TObject *Sender)
    {
    TPers *pPers=new TPers[6];
    pPers[0].Nom="Image1";   //liste 0 image 0    //colone ligne
    pPers[1].Nom="Image2";  // liste 1 image 1
    pPers[2].Nom="Image3";  // liste 2 image 2
    pPers[3].Nom="Image4";  // liste 0 image 3
    pPers[4].Nom="Image5";  // liste 1 image 5
    pPers[5].Nom="Image6";  // liste 2 image 6
     
    int NbListe=3;
     //const int NombreListe= NbListe;
     
    TList *TabList=new  TList;
    /* code ok */
    TList *liste[10];// un liste
     
    //TList *liste;
          if(NbListe>1)   // redimensionement de liste
          {
     
            for (int i=0;i<NbListe;i++)
            {
              liste[i]=new TList;
              TabList->Add(liste[i]);
                // ajout des liste dans les liste
            }
     
     
          }
         // ShowMessage(TabList->Count);
     
     
          // initilsation de liste
          liste[0]->Add(&pPers[0]);  //image1    liste0
          liste[1]->Add(&pPers[1]);  //image 2  liste1
          liste[2]->Add(&pPers[2]);  //image 3  liste  2
     
          liste[0]->Add(&pPers[3]);  //image 4  liste0
          liste[1]->Add(&pPers[4]);   //image 5 liste 1
          liste[2]->Add(&pPers[5]);   // image 6 liste 2
     
         AfficheListe2(TabList);
         FreeTABList(TabList);
     
    }
    Concernant la détection des images, il me semble que chaque format d'image commence par une entête (‰PNG ou 8950AE47 en hexa pour un fichier PNG, GIF89a pour un GIF, BM6 pour un BMP, ...). J'ai trouvé ces valeurs avec un éditeur hexadécimal.
    Comment lire une entête de flux ? je ne sais pas faire du tout
    avez vous un exemple ?


    merci

  8. #28
    Membre éclairé
    Homme Profil pro
    Consultant technique
    Inscrit en
    Juillet 2002
    Messages
    519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2002
    Messages : 519
    Par défaut
    Tout d'abord pour le bug d'indice hors limite :
    Vous avez fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TPers *pPers=new TPers[6];
    Et si je ne me trompe pas, la ligne qui vous pose problème est celle qui libère cette mémoire.

    Hors, le bon pointeur est stocké dans le 1er item de votre liste et un delete[] supprime déja tout le tableau. Donc quand vous passer à l'élément suivant, il est déja détruit.

    Concernant le flux, vous avez toutes les fonctions pour le faire via votre TMemoryStream.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    pMs->Position; // la position en cours sur le flux, les données lues le seront depuis cette position
    pMs->Size; // la taille total du flux en octet
    pMs->Read (void * Buffer, int Count); // lit au maximum Count octet depuis Position et l'envoie à l'adresse Buffer que l'on a choisi. Cette fonction renvoie le nombre d'octets réellement lues. Cette fonction met à jour Position pour le positionner à la fin de ce qui vient d'être lu.

  9. #29
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    219
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 219
    Par défaut
    Bonjour et bonne fetes
    encore un grand merci a ceux qui m'ont aider

    Je me suis inspiré du code de Totoche 76

    j'ai une fonction qui a ce prototype

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    bool __fastcall ToCache2(TIBClientDataSet * pCache, TIBQuery * pQuery,TListList<TListList<TFlux> >*pListList )  ;

    Quand je veux recuperer le ppointeur pListList pour m'en servir ailleur
    j'ai une message d'erreur de code guard "method called on invalid object"

    je fais ceci , je prcise , j'ai un liste et une image dans mon jeu d'essais

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    IbSgbd->IBQuery1->Close();
    IbSgbd->IBQuery1->SQL->Clear();
    IbSgbd->IBQuery1->SQL->Add(" select IMAGE from articles");
     
     
    TListList<TListList<TFlux> >*pListList;
     
    IbSgbd->ToCache2(IbSgbd->IBClientDataSet,IbSgbd->IBQuery1,pListList);
    // on affiche dans dbgrid2
    DBGrid2->DataSource=IbSgbd->DataSource3;
     
    TMemoryStream *pTestMen =new TMemoryStream;
    pTestMen->LoadFromStream((TStream *)pListList->Items[0]->Items[0]->pMsLu); // violation d'acces
    pTestMen->SaveToFile("SUPER_TEST1.bmp");

    en changeant le prototype de ma fonction

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     TListList<TListList<TFlux> >* __fastcall ToCache3(TIBClientDataSet * pCache, TIBQuery * pQuery/*,TListList<TListList<TFlux> >*pListList */)  ;

    J'arrive a recupere mon pointeur et a afficher mon image issus d'un flux blob

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    IbSgbd->IBQuery1->SQL->Clear();
     
    IbSgbd->IBQuery1->SQL->Add(" select IMAGE from articles");
     
    TListList<TListList<TFlux> >*pListList;
     
    pListList=IbSgbd->ToCache3(IbSgbd->IBClientDataSet,IbSgbd->IBQuery1/*,pListList*/);
    // on affiche dans dbgrid2
    DBGrid2->DataSource=IbSgbd->DataSource3;
     
     
     
      TMemoryStream *pTestMen =new TMemoryStream;
      pTestMen->LoadFromStream((TStream *)pListList->Items[0]->Items[0]->pMsLu);
     DBImage1->Picture->Bitmap->LoadFromStream(pTestMen);


    Ma question est comment faire pour que dans le premier cas je puise récupérer mon pointeur en entrée /sortie afin de l'utiliser ailleurs ?

    merci encore et bonne fêtes

Discussions similaires

  1. [D6] Mettre des PNG dans un TImageList
    Par fab56 dans le forum Delphi
    Réponses: 4
    Dernier message: 02/03/2007, 19h12
  2. Mettre des images dans une liste déroulante
    Par PrinceMaster77 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 1
    Dernier message: 01/12/2006, 15h35
  3. Mettre des images dans une base
    Par ecarbill dans le forum Access
    Réponses: 4
    Dernier message: 22/08/2006, 15h59
  4. [Debutant] Mettre des images dans une Toolbar
    Par Beleim dans le forum Windows
    Réponses: 11
    Dernier message: 02/03/2006, 23h31
  5. Possibilité de mettre des images dans un DrawGrid?
    Par tactical dans le forum C++Builder
    Réponses: 8
    Dernier message: 11/07/2005, 17h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo