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 :

TListBox au fond transparent


Sujet :

C++Builder

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 145
    Par défaut TListBox au fond transparent
    Bonjour,

    Je souhaite rendre le fond d'un TListBox transparent, mais impossible de trouver un problème semblable sur google où le forum...

    J'espère que c'est possible..

    Merci à tous,
    FluidBlow

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    Je pense que le sujet a déjà été abordé sur ce forum mais je n'ai pas réussi à le retrouver.

    En fait, ça dépend de ce qu'il y a sous l'objet.

    Sans doute à l'aide de la méthode OnDrawItem... sinon créer un nouveau composant...

    A plus !

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 145
    Par défaut
    Bonjour,

    Sous le TListBox, il y a un TImage...


    Si il n'est pas possible de mettre un fondd transparent, serait-il possible de mettre une image 32 bits en fond alors ?

    Merci d'avance.
    FluidBlow

  4. #4
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    Si le ListBox se dessine sur l'image (sans déborder) il est possible de récupérer l'image en arrière plan, bouts par bouts et de dessiner chaque bout dans le ListBox lors des OnDrawItem.
    Par contre... ça doit être assez délicat à cause des couleurs de l'image qui pourraient perturber la lisibilité du texte.
    Dès que j'en aurai le temps je ferai un test.
    En attendant, tu as tout pour dessiner sur le Listbox grace aux paramètres de la méthode OnDrawItem.
    Il faut juste calculer les coordonnées des bouts d'images sur l'image d'arrière plan.
    Faire une recherche sur le forum BCB : OnDrawItem sinon voir l'aide.

    A plus !

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 145
    Par défaut
    Bonsoir,

    Merci beacoup de cotre aide qui m'est très précieuse.
    Pour ce qui est de voir lisiblement les items, pas de problèmes, c'est prévu pour, un fond clair, léger dégradé.

    Mais je vais me mettre au boulot pour essayer de faire ce que tu m'as dit.

    Encore merci pour tout!
    Cordialement,
    FluidBlow

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 145
    Par défaut
    Bonjour,

    Je n'ai pas réussi à trouver ce qui pourrait me permettre de découper une partie de l'image et de la remettre en fond du TList Box, mais peut etre qu'il faudrait utiliser ceci pour assigner l'image non ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ListBox1->Canvas->Brush->Bitmap->
    Et plus précisement un truck du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ListBox1->Canvas->Brush->Bitmap->LoadFromClipboardFormat();
    Mais je ne vois pas très bien ce que je peux faire sinon.

    Cordialement,
    FluidBlow

  7. #7
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    Avec un TListBox, ça ne fonctionne bien que si on affiche un nombre d'items tel que le cadre soit comlètement rempli.
    Je n'ai pas réussi à trouver le moyen de remplir le bas du cadre.
    Je pense que le mieux est de développer un objet dédié, soit à partir d'un TPaintBox soit à partir d'un TCustomControl, les items étant stockés dans un TStringList.
    Ca représente quand même pas mal de travail pour simuler une transparence très localisée.
    Il ne faut donc pas trop en demander pour ce qui en sera de la transparence.
    Il existe aussi une autre possibilité, à l'aide de labels... rafraichis lors du OnChange d'un ScrollBar placé à gauche des labels...
    Sinon, j'ai développé une classe en dérivant de TCustomControl.

    A plus !

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 145
    Par défaut
    Bonjour,

    Merci encore de votre aide, mais j'ai peur de ne pas avoir tout compris
    Donc il faudrait que j'utilise un autre élèment qu'un TListBox ?
    Pas de problèmes mais alors qu'est ce que vous me proposez pour que ça soit la plus facile à gérer ?
    Sachant que ma liste est mise à jour dynamiquement par cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if(OpenDialog1->Execute())
    {
           ListBox1->Items->Assign(OpenDialog1->Files);
    }
    Merci encore !
    FluidBlow

  9. #9
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    Je ne sais pas si ce qui suit peut te convenir :

    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
    class jListBox : public TCustomControl
    {
    private:
    TScrollBar *ScrollBar; //pour le défilement des items
    int MaxItems; //nombre d'items dessinés
    int FItemIndex; //Item sélectionné
    int FTopIndex; //code du premier item affiché (== ScrollBar->Position)
     
    protected:
        //Méthodes permettant de fixer la valeur des propriétés afin
        //d'associer le rafraîchissement de l'objet à chaque modification
        void __fastcall SetItemIndex(int Value);
        void __fastcall SetTopIndex(int Value);
     
    public:
    TImage *BackGround; //l'image en arrière plan
    TStringList *Items; //la liste des chaines
     
        __fastcall jListBox(TComponent *Owner, TImage *BG);
        __fastcall ~jListBox();
     
        //Surcharge de la méthode Paint
        void __fastcall Paint();
     
        //Pour ajouter un item à la stringlist
        void __fastcall Add(AnsiString N);
     
        //Pour assigner un ensemble de chaines
        void __fastcall AssignItems(TStrings *Source);
     
        //Pour le défilement des items (OnChange de la ScrollBar)
        void __fastcall WhenScroll(TObject *Sender);
     
        //Pour la sélection d'un item (OnMouseDown de l'objet)
        void __fastcall WhenMouseDown(TObject *Sender, TMouseButton Button,
                                    TShiftState Shift, int X, int Y);
     
        //Propriétés
        __property int ItemIndex = {read=FItemIndex, write=SetItemIndex};
        __property int TopIndex = {read=FTopIndex, write=SetTopIndex};
    };

    Les méthodes :

    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    __fastcall jListBox::jListBox(TComponent *Owner, TImage *BG)
        : TCustomControl(Owner)
    {
    if(Owner->InheritsFrom(__classid(TWinControl)))
        {
        Parent = (TWinControl*)Owner;
        BringToFront();
        }
    //Lien vers l'image d'arrière plan
    BackGround = BG;
     
    //Création d'un scrollbar pour le défilement des items
    ScrollBar = new TScrollBar(this);
    ScrollBar->Kind = sbVertical;
    ScrollBar->Align = alRight;
    ScrollBar->Max = 0;
    ScrollBar->OnChange = WhenScroll;
    ScrollBar->Parent = this;
     
    FItemIndex = -1;
     
    Items = new TStringList;
     
    OnMouseDown = WhenMouseDown;
    }
    //--
     
    __fastcall jListBox::~jListBox()
    {
    Items->Clear();
    delete Items;
    }
    //--
     
    void __fastcall jListBox::Paint()
    {
    Canvas->Brush->Style = bsClear;
    //Quelques variables
    int we = ScrollBar->Left;
    int he = Height;
    TRect Dest = Rect(0,0,we,he);
    TRect Srce;
     
    //Calcul des coordonnées de la portion d'image en arrière plan
    Srce.Left = Left - BackGround->Left;
    Srce.Top = Top - BackGround->Top;
    Srce.Right = Srce.Left + we;
    Srce.Bottom = Srce.Top + he;
     
    //Copie du fond
    Canvas->CopyRect(Dest, BackGround->Picture->Bitmap->Canvas, Srce);
    Canvas->Font->Color = clBlack; //<<< Ici ça dépend !
     
    //Ecriture des items
    MaxItems = he / 16;
    int item;
    for(int j = 0; j < MaxItems; j++)
        {
        item = j + FTopIndex;
        if(item < Items->Count)
            {
            if(item == FItemIndex)Canvas->Font->Style = Canvas->Font->Style << fsBold;
            else Canvas->Font->Style = Canvas->Font->Style >> fsBold;
            Canvas->TextOut(4, j * 16, Items->Strings[item]);
            }
        }
    //Contour 3D
    Canvas->Pen->Color = clWhite;
    Canvas->MoveTo(0,he); Canvas->LineTo(0,0); Canvas->LineTo(we,0);
    Canvas->Pen->Color = clBlack;
    we--; he--;
    Canvas->MoveTo(0,he); Canvas->LineTo(we,he); Canvas->LineTo(we,0);
    }
     
    void __fastcall jListBox::Add(AnsiString N)
    {
    Items->Add(N);
    ScrollBar->Max = Items->Count-1;
    Repaint();
    }
     
    void __fastcall jListBox::AssignItems(TStrings *Source)
    {
    Items->Assign(Source);
    ScrollBar->Max = Items->Count-1;
    Repaint();
    }
     
    void __fastcall jListBox::WhenScroll(TObject *Sender)
    {
    FTopIndex = ScrollBar->Position;
    Repaint();
    }
     
    void __fastcall jListBox::WhenMouseDown(TObject *Sender, TMouseButton Button,
                                    TShiftState Shift, int X, int Y)
    {
    int n = Y / 16;
    if(n < MaxItems)
        {
        n = n + FTopIndex;
        if(n < Items->Count)
            {
            ItemIndex = n;
            }
        }
    }
    Les méthodes Set pour les deux propriétés

    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
    void __fastcall jListBox::SetItemIndex(int Value)
    {
    FItemIndex = Value;
    Repaint();
    }
     
    void __fastcall jListBox::SetTopIndex(int Value)
    {
    if((Value >= 0) && Value < (Items->Count-1))
        {
        ScrollBar->Position = Value;
        FTopIndex = Value;
        Repaint();
        }
    }

    Tel que je l'ai testé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    jListBox *ListBox;
     
    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
    ListBox = new jListBox(this, Image1);
    ListBox->SetBounds(Image1->Left + 50, Image1->Top + 70, 192, 120);
    }
    Et pour reprendre ce que tu fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
    {
    if(OpenDialog1->Execute())
        {
        ListBox->AssignItems(OpenDialog1->Files);
        }
    La transparence est simulée par rapport à une image en arrière plan et ne fonctionne que dans ce contexte précis.
    J'ai passé outre certains tests dans les méthodes, car j'ai supposé que tout est valide.

    A plus !

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 145
    Par défaut
    Bonjour,

    Tout d'abord, merci pour tes ces efforts pour moi

    Mais j'ai quelques petits problèmes pour cette partie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     if(OpenDialog1->Execute())
    {
           jListBox->Items->Assign(OpenDialog1->FileName);
    }
    Il me dit : " [C++ Erreur ] Unit1.cpp(37): E2108 Utilisation impropre de typedef 'jListBox'


    Et aussi, lors de la compilation (sans cette ligne de code), L'image de ma fiche n'apparait plus, ni dans le fond, ni dans le jListBox

    Ce serait trop bête d'échouer si près du but

    Merci beaucoup encore !
    FluidBlow

  11. #11
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    jListBox... c'est le nom de la classe... !!!

    Donc, en fonction du nom donné au pointeur sur l'instance :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    jListBox *ListBox;
     
    ListBox->Items->Add(OpenDialog1->FileName);//<<< envisageable
    Mais surtout pour ajouter un item isolé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ListBox->Add(OpenDialog1->FileName);
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ListBox->AssignItems(OpenDialog1->Files);
    Mes méthodes ( Add et AssignItems) permettent d'assigner les chaînes mais surtout de redessine le resultat !

    A plus !

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 145
    Par défaut
    Bonsoir,

    Malheureusement, ça ne fonctionne pas mieux, mis à part que je peux compiler sans erreurs.
    Le problème survient à ce momment,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ListBox->SetBounds(Image1->Left + 50, Image1->Top + 70, 192, 120);
    J'ai mis cette ligne de code après ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    TForm1 *Form1;
    jListBox *ListBox;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    Voici les images :

    Sans la ligne de code :



    Avec la ligne de code, sans fichiers dans la ListBox :



    Avec la ligne de code, avec fichiers dans la ListBox :



    Dans la dernière image, on peux voir qu'il y a des items vides à chaques fois...


    Alors voilà, j'espère qu'une solution existe

    En tout cas, merci pour tout ce que tu as déjà fait !
    Cordialement,
    FluidBlow

  13. #13
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    L'exemple que j'ai donné ne vaut que pour un contexte simple où une jListBox s'affiche par dessus une TImage en simulant une transparence.

    Si l'image, telle qu'on la voit sans la listbox, est un agglomérat d'objets, dans ce cas, la simulation de la transparence ne peut pas fonctionner.

    A noter que j'ai utilisé l'image que tu as donné, sans aucun problème donc...

    A plus !

  14. #14
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    Avec la version BCB6, c'est peut-être une question de double buffering de la form ?

    A plus !

  15. #15
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 145
    Par défaut
    Bonjour,

    Je viens d'essayer en rajoutant cette ligne juste avant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    //Création dynamique de l'objet
    ListBox = new jListBox(this, Image1);
    //son positionnement sur la form
    ListBox->SetBounds(Image1->Left + 50, Image1->Top + 70, 192, 120);
    Mais ça ne change rien

    Cordialement,
    FluidBlow

  16. #16
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 145
    Par défaut
    Salut !

    Je viens de trouver d'où venait mon problème !
    Il ne supporte pas les images JPG !!
    Tout simplement, il fallait que je mette une image BMP !

    Merci beaucoup pour tout ce que tu as fait !!
    Enfin résolu ! ^^

    Encore merci,
    FluidBlow

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 14
    Dernier message: 13/10/2005, 15h00
  2. Image avec fond transparent
    Par Virgile59 dans le forum Access
    Réponses: 3
    Dernier message: 16/09/2005, 11h48
  3. Rendre le fond transparent dans une picturebox
    Par fun31 dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 20/01/2005, 18h17
  4. Image GIF a fond transparent dans un formulaire ?
    Par Coquelicot dans le forum IHM
    Réponses: 4
    Dernier message: 25/10/2004, 12h08
  5. [JButton] avec un fond transparent
    Par Tiercel dans le forum Composants
    Réponses: 6
    Dernier message: 23/09/2004, 09h19

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