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

Composants VCL Delphi Discussion :

TLabel masqué ou pas transparent après dégradé


Sujet :

Composants VCL Delphi

  1. #1
    Membre averti Avatar de zemeilleurofgreg
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    515
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2006
    Messages : 515
    Points : 346
    Points
    346
    Par défaut TLabel masqué ou pas transparent après dégradé
    Bonjour à tous,

    je me concocte une application de gestion de photos et un petit problème graphique me contrarie.

    Je place chaque objets TImage dans un container TPanel ainsi qu'un TLabel utilisé pour le nom de fichier.
    Lorsque les miniatures des photos sont affichées, j'ai évidemment la possibilité de les sélectionner ce qui engendre l'appel de la procédure de coloriage du TPanel afin de lui donner un aspect de dégradé (comme dans windows 7).

    Mon problème est que après coloriage, je fais un refresh de l'objet TImage pour le rendre visible (sans cela, le dégradé masque le TImage), et ça fonctionne très bien mais impossible de faire la même chose avec le TLabel qui reste soit masqué par le dégradé quand je ne refresh pas le TLabel ou qui perd sa transparence lorsque je le refresh.

    voici le code de création du TLabel :

    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
    MyLabel:=TLabel.Create(self);
        MyLabel.AutoSize:=false;
        //MyLabel.AutoSize:=true;
        MyLabel.Caption:='  '+MyArray[i].FileName+' ';
        MyLabel.Font.Name:='Verdana';
        MyLabel.Height:=50;
        MyLabel.Width:=MyMainPanel.Width-2;
        MyLabel.Left:=round((MyMainPanel.Width-MyLabel.Width)/2);
        MyLabel.Top:=MyMainPanel.Height-MyLabel.Height-1;
        //MyLabel.Align:=alBottom;
        MyLabel.WordWrap:=true;
        MyLabel.Alignment:=taCenter;
        //MyLabel.Layout:=tlCenter;
        MyLabel.Layout:=tlBottom;
        MyLabel.Name:='MyLabel'+inttostr(i);
        MyLabel.Transparent:=true;
        MyLabel.Tag:=i;
        MyLabel.OnClick:=MyComponentClick;
        MyLabel.OnMouseMove:=MyComponentMouseMove;
        MyLabel.Parent:=MyMainPanel;
    voici l'appel de la procédure du dégradé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    MyComponent:=FindComponent('MyMainPanel'+inttostr(TComponent(Sender).Tag));
     
      PanelCanvas:=TControlCanvas.Create;
      PanelCanvas.Control:=MyComponent as TPanel;
     
      Application.ProcessMessages;
     
      MyDegradeOnPaint(PanelCanvas,BorderSizeSelected,MyPanelHeight-BorderSizeSelected,1,StartColorPanel,EndColorPanel);
     
      MyComponent:=FindComponent('MyImage'+inttostr(TComponent(Sender).Tag));
      (MyComponent as TImage).Refresh;
     
      MyComponent:=FindComponent('MyLabel'+inttostr(TComponent(Sender).Tag));
      (MyComponent as TLabel).Refresh;
    et voici enfin la procédure du dégradé :

    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
    procedure TfrmMain.MyDegradeOnPaint(MyCanvas : TCanvas;StartTop, EndBottom : integer; ReverseDegrad : integer ; StartColor, EndColor: TColor);
    var
    aBand : TRect;    { Bande rectangulaire de couleur courante        }
    i, nbDgrad   : integer;  { Compteur pour parcourir la hauteur de l'objet }
    Arr_StartRGB : Array[0..2] of Byte;     { RGB de la couleur de départ }
    Arr_DifRGB   : Array[0..2] of integer;  { RGB à ajouter à la couleur de départ pour atteindre la couleur de fin }
    Arr_CurRGB   : Array[0..2] of Byte;     { RGB de la couleur courante  }
    Reverse,j : integer;
    MyArray : Array of integer;
    begin
     
        //Calcul des valeurs RGB pour la couleur courante
        Arr_StartRGB[0] := GetRValue( ColorToRGB( StartColor ) );
        Arr_StartRGB[1] := GetGValue( ColorToRGB( StartColor ) );
        Arr_StartRGB[2] := GetBValue( ColorToRGB( StartColor ) );
     
        // Calcul des valeurs à ajouter pour atteindre la couleur de fin
        Arr_DifRGB[0] := GetRValue( ColorToRGB( EndColor )) - Arr_StartRGB[0] ;
        Arr_DifRGB[1] := GetGValue( ColorToRGB( EndColor )) - Arr_StartRGB[1] ;
        Arr_DifRGB[2] := GetBValue( ColorToRGB( EndColor )) - Arr_StartRGB[2] ;
     
      With MyCanvas do
      begin
        Pen.Style := psSolid;
        Pen.Mode  := pmCopy;
        Pen.Width := 1;
        nbDgrad   := 255;
     
        aBand.Left   := ClientRect.Left+BorderSizeSelected;
        aBand.Right := ClientRect.Left+MyPanelWidth-BorderSizeSelected;
     
        case ReverseDegrad of
            0: Reverse:=EndBottom; //pas de renversement du dégradé
     	      1: Reverse:=Round(EndBottom/2); //renversement du dégradé à la moitié de l'objet
    	      2: Reverse:=Round(EndBottom/3)*2; //renversement du dégradé aux 2/3 de l'objet
    	      3: Reverse:=Round(EndBottom/4)*3; //renversement du dégradé aux 3/4 de l'objet
        end;
     
        if Reverse - StartTop < 255
            then nbDgrad := Reverse - StartTop;
     
        j:=0;
     
        for i:= StartTop to Reverse-1 do
        begin
     
          aBand.Top:=i;
          aBand.Bottom:=i+1;
     
           // Calcul de la couleur courante
          Arr_CurRGB[0] := (Arr_StartRGB[0] + MulDiv( i, Arr_DifRGB[0] , nbDgrad ));
          Arr_CurRGB[1] := (Arr_StartRGB[1] + MulDiv( i, Arr_DifRGB[1] , nbDgrad ));
          Arr_CurRGB[2] := (Arr_StartRGB[2] + MulDiv( i, Arr_DifRGB[2] , nbDgrad ));
     
          Brush.color:=RGB(Arr_CurRGB[0], Arr_CurRGB[1], Arr_CurRGB[2]);
          FillRect(aBand);
     
          if i>=Reverse-(EndBottom-Reverse)-1 then
          begin
            setLength(MyArray,j+1);
            MyArray[j]:=Brush.color;
            inc(j);
          end;
     
        end;
     
        if ReverseDegrad > 0 then // dégradé dans l'autre sens
        begin
     
        	for i:=Reverse to EndBottom-1 do
        	begin
     
          	   aBand.Top:=i;
          	   aBand.Bottom:=i+1;
     
               Brush.Color:=MyArray[j-1];
               dec(j);
               FillRect(aBand);
     
        	end;
          setlength(MyArray,0);
        end;
     
     
      end;
     
    end;
    avez-vous une idée de comment résoudre ce problème ?
    Merci beaucoup.
    Je joint 3 captures d'écran afin que vous compreniez.

    avant dégradé :
    Nom : Avant dégradé.jpg
Affichages : 91
Taille : 48,6 Ko
    après dégradé sans refresh :
    Nom : après dégradé.jpg
Affichages : 93
Taille : 32,9 Ko
    après dégradé avec refresh :
    Nom : après refresh TLabel.png
Affichages : 87
Taille : 87,1 Ko

  2. #2
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    tant qu'à empiler des composants pourquoi ne pas mettre une TPainBox en fond sur le TPanel pour y dessiner le dégradé ?

    d'ailleurs à quel moment dessines-tu ton dégradé ?

  3. #3
    Membre averti Avatar de zemeilleurofgreg
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    515
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2006
    Messages : 515
    Points : 346
    Points
    346
    Par défaut
    d'ailleurs à quel moment dessines-tu ton dégradé ?
    Bonjour Paul,

    la procédure de dégradé est appelée lors du clique sur le TPanel.

    tant qu'à empiler des composants pourquoi ne pas mettre une TPainBox en fond sur le TPanel pour y dessiner le dégradé ?
    Tu parles d'une TPainBox en tant qu'enfant du TPanel ?

  4. #4
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    Citation Envoyé par zemeilleurofgreg Voir le message
    Bonjour Paul,

    la procédure de dégradé est appelée lors du clique sur le TPanel.
    alors ça fonctionne, mais forcer un affichage sur un clic n'est pas la méthode recommandée sous Windows, tu es supposé appeler TPanel.Invalidate() pour indiquer à Windows que le contenu du Panel doit être redessiner et s'est lors de son "paint" que le dégradé doit être dessiné. Sinon tu perds ton dégradé si tu passes une fenêtre devant ton appli par exemple.

    Citation Envoyé par zemeilleurofgreg Voir le message

    Tu parles d'une TPainBox en tant qu'enfant du TPanel ?
    oui puisque TPanel n'a ni canvas ni onPaint, sinon il faut dériver TPanel et intercepter le message WM_ERASEBKGND

  5. #5
    Membre averti Avatar de zemeilleurofgreg
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    515
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2006
    Messages : 515
    Points : 346
    Points
    346
    Par défaut
    alors ça fonctionne, mais forcer un affichage sur un clic n'est pas la méthode recommandée sous Windows, tu es supposé appeler TPanel.Invalidate() pour indiquer à Windows que le contenu du Panel doit être redessiner et s'est lors de son "paint" que le dégradé doit être dessiné. Sinon tu perds ton dégradé si tu passes une fenêtre devant ton appli par exemple.
    effectivement, je perd le dégradé
    Je dois donc surcharger la méthode onPaint ?
    Concrètement, à quoi cela doit-il ressembler ?

    Merci pour tes bons conseils

  6. #6
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    Citation Envoyé par zemeilleurofgreg Voir le message
    effectivement, je perd le dégradé
    Je dois donc surcharger la méthode onPaint ?
    Concrètement, à quoi cela doit-il ressembler ?

    Merci pour tes bons conseils
    je te l'ai dit, le plus simple est de placer un TPaintBox dans ton panel, soit un alClient, soit aux dimensions du TPanel avec tous les Anchors actif et dans son évènement OnPaint tu dessines un dégradé sur son Canvas.

    assure-toi ensuite que l'image et le label soient au dessus du TPaintBox pour qu'ils soient dessinés par dessus et non en dessous.

  7. #7
    Membre averti Avatar de zemeilleurofgreg
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    515
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2006
    Messages : 515
    Points : 346
    Points
    346
    Par défaut
    voila voila, j'ai testé tout ça et ça fonctionne nikel
    Et en plus, j'ai l'impression que c'est moins gourmand en ressource que ma technique précédente.

    Un grand merci à toi Paul

    @+

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 19/02/2008, 12h45
  2. TLabel masqué par TGroupBox
    Par Felipe_ dans le forum C++Builder
    Réponses: 10
    Dernier message: 28/10/2007, 12h09
  3. Réponses: 4
    Dernier message: 28/09/2006, 15h50
  4. Réponses: 2
    Dernier message: 27/07/2006, 10h30
  5. savoir si une table est masquée ou pas
    Par scully2501 dans le forum Access
    Réponses: 13
    Dernier message: 22/09/2005, 13h19

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