begin process at 2010 02 10 05:58:05
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Delphi

 > 

Divers

 > 

Débutant(e)

 > 

Canvas sur des panels créés dynamiquement


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Canvas sur des panels créés dynamiquement

mercredi 1 octobre 2008 à 14:36:41 | Canvas sur des panels créés dynamiquement

RURUInc

Bonjour,

J'essai d'affecter une couleur dégrader sur un Panel, jusque là tout va bien si je place cela dans un evenement onmousedoxn du panel.
Mais lorsque je créer Un panel en dynamique je n'arrive pas à imposer cette couleur dégrader
voici le code complet sous delphi 7 qui fonctionne au clique sur un panel mais pas en dynamique

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, math, ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure PanelMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure PanelMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
  Procedure Degrader(Canevas : TCanvas;Rect : TRect;FStartColor:Tcolor;FEndColor:Tcolor);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

Procedure TForm1.Degrader(Canevas : TCanvas;Rect : TRect;FStartColor:Tcolor;FEndColor:Tcolor);
Var
  aBand : TRect;    { Bande rectangulaire de couleur courante        }
  i    : Integer;  { Compteur pour parcourir la hauteur de la fiche }
  FStartRGB  : Array[0..2] of Byte;    { RGB de la couleur de départ }
  FCurrentRGB : Array[0..2] of Byte;    { RGB de la couleur courante  }
  FDeltaRGB  : Array[0..2] of Integer; { RGB à ajouter à la couleur de départ pour atteindre la couleur de fin }
  nbtranches: integer;
Begin
  { Calcul des valeurs RGB pour la couleur courante }
  FStartRGB[0] := GetRValue( ColorToRGB( FStartColor ) );
  FStartRGB[1] := GetGValue( ColorToRGB( FStartColor ) );
  FStartRGB[2] := GetBValue( ColorToRGB( FStartColor ) );
  { Calcul des valeurs à ajouter pour atteindre la couleur de fin }
  FDeltaRGB[0] := GetRValue( ColorToRGB( FEndColor )) - FStartRGB[0] ;
  FDeltaRGB[1] := GetgValue( ColorToRGB( FEndColor )) - FStartRGB[1] ;
  FDeltaRGB[2] := GetbValue( ColorToRGB( FEndColor )) - FStartRGB[2] ;

  { Initialisation des dimensions de la bande de couleur }
  aBand.Left :=Rect.Left;
  aBand.Right:=Rect.Right;
  nbtranches:=min(256, Rect.Bottom-Rect.Top);
  { Boucle pour remplir la fiche courante en dégradé }
  With Canevas Do
  Begin
      Pen.Style:=psSolid;
      Pen.Mode:=pmCopy;
      For i:= 0 To nbtranches-1 Do
      Begin
          { Dimensions verticales de la bande }
          aBand.Left :=Rect.Left;
          aBand.Right:=Rect.Right;
          aBand.Top := Rect.Top+Round((Rect.Bottom-Rect.Top)/nbtranches*i);
          aBand.Bottom := Rect.Top+Round((Rect.Bottom-Rect.Top)/nbtranches*(i+1));

          { Calcul de la couleur courante }
          FCurrentRGB[0] := (FStartRGB[0] + MulDiv( i , FDeltaRGB[0] , nbtranches )) mod 256;


          FCurrentRGB[1] := (FStartRGB[1] + MulDiv( i , FDeltaRGB[1] , nbtranches )) mod 256;
          FCurrentRGB[2] := (FStartRGB[2] + MulDiv( i , FDeltaRGB[2] , nbtranches )) mod 256;
          { Affichage sur la fiche }
          Brush.color:=RGB(FCurrentRGB[0],FCurrentRGB[1],FCurrentRGB[2]);
          FillRect(aBand);
      End;
  End;
End;

procedure TForm1.FormCreate(Sender: TObject);
Var
  PanelCanvas: TControlCanvas;
  PanelRect : TRect;
  i: Integer;
  Panel: Tpanel;
begin
  for i := 1 To 10 do
  Begin
    Panel := TPanel.Create(Form1);
    Panel.Font.Size := 8;
    Panel.Font.Name := 'Tahoma';
    Panel.Name := 'PANEL' + inTtoStr(i);
    Panel.Caption := Panel.Name;
    Panel.Height := 20;
    Panel.Top := 30 * i;
    Panel.Parent := Form1;
    Panel.OnMouseDown := PanelMouseDown;
    Panel.OnMouseUp := PanelMouseUp;

    PanelCanvas:= TControlCanvas.Create;
    PanelCanvas.Control:= Panel;

    PanelRect.Left := 0;
    PanelRect.Top := 0;
    PanelRect.Right := Panel.width;
    PanelRect.Bottom := Panel.Height;

    Degrader(PanelCanvas,PanelRect,clblue,clwhite);
  end;
end;

procedure TForm1.PanelMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
Var
  PanelCanvas: TControlCanvas;
  PanelRect : TRect;
begin

  // On remet la structure graphic du Panel comme initial
    PanelCanvas:= TControlCanvas.Create;
    PanelCanvas.Control:= Tpanel(sender);
    PanelRect.Left := 0;
    PanelRect.Top := 0;
    PanelRect.Right := Tpanel(sender).Width;
    PanelRect.Bottom := Tpanel(sender).Height;

    Degrader(PanelCanvas,PanelRect,clwhite,clblue);
end;

procedure TForm1.PanelMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
Var
  PanelCanvas: TControlCanvas;
  PanelRect : TRect;
begin
  // On remet la structure graphic du Panel comme initial
    PanelCanvas:= TControlCanvas.Create;
    PanelCanvas.Control:= Tpanel(sender);
    PanelCanvas.Brush.Style := bsClear;
    PanelCanvas.Font.Name := 'Tahoma';
    PanelCanvas.Font.Size := 8;
    PanelRect.Left := 0;
    PanelRect.Top := 0;
    PanelRect.Right := Tpanel(sender).Width;
    PanelRect.Bottom := Tpanel(sender).Height;

    DrawText(PanelCanvas.Handle, PChar(Tpanel(Sender).Caption) , -1, PanelRect, DT_CENTER or DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE);

end;

end.

Je pense que le problème se situe dans la procedure oncreate de la form à :

Panelcanvas.Control = Panel;

Mais je vois pas quoi mettre d'autre, auriez vous une idée ?

mercredi 1 octobre 2008 à 14:49:35 | Re : Canvas sur des panels créés dynamiquement

Bacterius

Membre Club
Il y a des composants sur le site, des panels avec des dégradés dessus. Et aussi des sources, des trucs et des astuces. Tape dans le moteur de recherche du site, "Panel Degradé" tu vas comprendre.

Cordialement, Bacterius !
jeudi 2 octobre 2008 à 00:15:42 | Re : Canvas sur des panels créés dynamiquement

RURUInc

J'ai regarder, analyser ton lien, et je vois pas comment cela peux m'aider. D'ailleur les proposition ne sont pas adaptable à mon cas.
A moins que je sois un gros nigo... (je crois lolo)

Bref, en fait si je place dans OnActivate de ma form la procedure OnCreate (j'inverse en fait) et bien il dessine bien les panels en 1 fraction de seconde il les remts en classique.
Cela redessine mes panels en fait.

Et je reste persuadé que cela viens du control de PAnelCanvas.Control := Panel

De plus dans mon projet si dessus, je le sort du context de mon programme. En effet je créer des panel dynamiquement mais le dégradé en réalité est différent pour chaque panel.

Je pensais trouvé un specialiste des canvas et autre TcontrolGraphic ici.

Si vous pouvez m'aider ou me diriger vers une autre solution. MErci a vous

jeudi 2 octobre 2008 à 13:20:08 | Re : Canvas sur des panels créés dynamiquement

f0xi

Membre Club Administrateur CodeS-SourceS

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  { Declaration d'un nouvel evenement pour TPanel }
  TPaintEvent = procedure(Sender: TObject; ACanvas: TCanvas; ARect: TRect) of object;

  { Surcharge de la classe TPanel
    TPanel contient une propriété Canvas protégée, il suffit de la publiée,
    nous en profitont pour ajouter des evenements et surcharger la methode Paint
    pour appeler ces derniers, afin que TPanel gere seul son dessin et son
    rafraichissement.
    Si l'image "clignote" lors du dessin, surtout si le TPanel recouvre une grande
    partie de l'ecran, il faudrat mettre la propriété DoubleBuffered des TPanels
    concernés ou encore celui de la fiche principale a True.
  }

  TPanel = class(ExtCtrls.TPanel)
  private
    fOnBeforePaint: TPaintEvent; // Dessiner avant
    fOnAfterPaint: TPaintEvent;  // Dessiner aprés
  protected
    procedure Paint; override;   // surcharge de la methode de dessin de TPanel
  public
    property Canvas;             // TPanel contient un canvas qu'il faut publié!
    property OnBeforePaint: TPaintEvent read fOnBeforePaint write fOnBeforePaint;
    property OnAfterPaint : TPaintEvent read fOnAfterPaint write fOnAfterPaint;
  end;

  { TForm1 }
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);  // Creation
    procedure FormDestroy(Sender: TObject); // Liberation
  private
    fStartColor, fEndColor : TColor;         // couleurs du dégradé
    fGradientPanels : array[0..9] of TPanel; // Les Panels dynamiques
  public
    procedure PanelPaint(Sender: TObject; ACanvas: TCanvas; AClientRect: TRect);
    // Methode de dessin pour les Panels.
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ nécessite l'unité Gradients.pas, téléchargeable a cette adresse :
  http://www.delphifr.com/codes/REALISER-DEGRADE-SUR-PLUSIEURS-COULEURS-AVEC-API-WINDOWS_35784.aspx
}

uses Gradients;

{ TPanel }

procedure TPanel.Paint;
begin
  // Declanchement de la methode de dessin "avant"
  if Assigned(fOnBeforePaint) then
    fOnBeforePaint(Self, Canvas, ClientRect);

  // Methode de dessin originale de TPanel
  inherited Paint;

  // Declanchement de la methode de dessin "aprés"
  if Assigned(fOnAfterPaint) then
    fOnAfterPaint(Self, Canvas, ClientRect);
end;

{ TForm1 }

{ remarque importante :
  Il ne faut jamais appeler la variable FormX (Form1, Form2...)
  dans l'implementation de la classe TFormX (Tform1, TForm2...)
 
  Pour appeler l'instance en cours de la classe TFormX, il faut
  utiliser le mot clef "SELF", mais cela reste facultatif et doit
  etre utiliser uniquement pour appeler les methodes ou propriétés
  de TFormX dans les bloc With ... do n'englobant pas TFormX.

  exemple a ne pas faire :
   
   Form1.Width := 10;

  exemple a ne pas faire :
  
   Self.Width := 10;

  exemple de la bonne utilisation de "Self" a l'interieur d'une classe :

   ObjectQuelconque := TTruc.Create(Self);
   with ObjetQuelconque do
   begin
     Parent := Self; 
     SetBounds(Self.ClientOrigin.X+10, Self.ClientOrigin.Y+10, Self.Width, Self.Height);
   end;
}



procedure TForm1.FormCreate(Sender: TObject);
Var
  N: Integer;
begin
  fStartColor := clBlue;
  fEndColor   := clWhite;

  for N := Low(fGradientPanels) To High(fGradientPanels) do
  Begin
    fGradientPanels[N] := TPanel.Create(Self);
    with fGradientPanels[N] do
    begin
      Font.Size     := 8;
      Font.Name     := 'Tahoma';
      Name          := 'PANEL' + IntToStr(N);
      Caption       := Name;
      Height        := 20;
      Top           := 30 * (N+1);
      Parent        := Self;

      //OnMouseDown   := PanelMouseDown; // obsolete
      //OnMouseUp     := PanelMouseUp;   // obsolete

      OnBeforePaint := PanelPaint;  // le dégradé sera en arriere plan du Panel
      // ou
      //OnAfterPaint  := PanelPaint; // sinon ici, il serait en premier plan
    end;
  end;
end;


procedure TForm1.FormDestroy(Sender: TObject);
var N : integer;
begin
  { on oublis pas de detruire les Panels créer dynamiquement
    on preferera ne jamais laisser les "Parents" se charger de la destruction
    des "enfants", toutes les classes ne le font pas et on s'assure de ne pas
    avoir de fuites de memoire.

    On detruit toujours a l'envers (dernier créé, premier detruit).
  }

  for N := Low(fGradientPanels) downto High(fGradientPanels) do
    fGradientPanels[N].Free;
end;

procedure TForm1.PanelPaint(Sender: TObject; ACanvas: TCanvas; AClientRect: TRect);
begin
  { le resultat est le même, on peu même facilement modifier les couleurs
    et l'aspect du dégradé en faisant des dégradé sur plusieurs couleurs...

    Les performances sont egalements meilleures :
    ~130cycles cpu contre  ~210cycles cpu pour l'ancienne methode.

    l'API Windows possedent de sympathique fonctions, il suffit de les connaitres
    mais surtout de les chercher.
  }
  Gradients.GradientRect(ACanvas.Handle, [fStartColor, fEndColor], AClientRect, GRADIENT_FILL_RECT_V);
end;


end.





vendredi 3 octobre 2008 à 16:54:53 | Re : Canvas sur des panels créés dynamiquement

RURUInc

C'est énorme ce que tu à fait. Apparement superbe.
Alors entre temps voilà ce que l'on à pu me proposé.

Est-ce que tu pense que c'est mieux ou pas ?

.....

type

  TMyPanel = class(TPanel)
   private
     FStartColor:Tcolor;
     FEndColor:Tcolor ;
   protected
    procedure Paint;override;
   published
    property StartColor : Tcolor read fStartColor write fStartColor ;
    property EndColor : Tcolor read FEndColor write FEndColor ;
   end;

.....(Suite)

procedure TMyPanel.Paint;

  Procedure Degrader;
  Var
    aBand : TRect;    { Bande rectangulaire de couleur courante        }
    i    : Integer;  { Compteur pour parcourir la hauteur de la fiche }
    FStartRGB  : Array[0..2] of Byte;    { RGB de la couleur de départ }
    FCurrentRGB : Array[0..2] of Byte;    { RGB de la couleur courante  }
    FDeltaRGB  : Array[0..2] of Integer; { RGB à ajouter à la couleur de départ pour atteindre la couleur de fin }
    nbtranches: integer;
    Canevas:TControlCanvas;
    Rect:TRect;
  Begin
    Rect.Left := 0;
    Rect.Top := 0;
    Rect.Right := Self.Width;
    Rect.Bottom := Self.Height;
    self.ParentColor := false;
    Canevas:= TControlCanvas.Create;
    Canevas.Control:= self;
    { Calcul des valeurs RGB pour la couleur courante }
    FStartRGB[0] := GetRValue( ColorToRGB( StartColor ) );
    FStartRGB[1] := GetGValue( ColorToRGB( StartColor ) );
    FStartRGB[2] := GetBValue( ColorToRGB( StartColor ) );
    { Calcul des valeurs à ajouter pour atteindre la couleur de fin }
    FDeltaRGB[0] := GetRValue( ColorToRGB( EndColor )) - FStartRGB[0] ;
    FDeltaRGB[1] := GetgValue( ColorToRGB( EndColor )) - FStartRGB[1] ;
    FDeltaRGB[2] := GetbValue( ColorToRGB( EndColor )) - FStartRGB[2] ;
 
    { Initialisation des dimensions de la bande de couleur }
    aBand.Left :=Rect.Left;
    aBand.Right:=Rect.Right;
    nbtranches:=min(256, Rect.Bottom-Rect.Top);
    { Boucle pour remplir la fiche courante en dégradé }
    With Canevas Do
    Begin
        Pen.Style:=psSolid;
        Pen.Mode:=pmCopy;
        For i:= 0 To nbtranches-1 Do
        Begin
            { Dimensions verticales de la bande }
            aBand.Left :=Rect.Left;
            aBand.Right:=Rect.Right;
            aBand.Top := Rect.Top+Round((Rect.Bottom-Rect.Top)/nbtranches*i);
            aBand.Bottom := Rect.Top+Round((Rect.Bottom-Rect.Top)/nbtranches*(i+1));

            { Calcul de la couleur courante }
            FCurrentRGB[0] := (FStartRGB[0] + MulDiv( i , FDeltaRGB[0] , nbtranches )) mod 256;
            FCurrentRGB[1] := (FStartRGB[1] + MulDiv( i , FDeltaRGB[1] , nbtranches )) mod 256;
            FCurrentRGB[2] := (FStartRGB[2] + MulDiv( i , FDeltaRGB[2] , nbtranches )) mod 256;
            { Affichage sur la fiche }
            Brush.color:=RGB(FCurrentRGB[0],FCurrentRGB[1],FCurrentRGB[2]);
            FillRect(aBand);
        End;
      Font.Name := self.Font.Name;
      Font.Size := self.Font.Size;
      Brush.Style := bsClear;
      DrawText(Canevas.Handle, PChar(Self.Caption) , -1, Rect, DT_CENTER or DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE);
    End;
   Canevas.Free; // Libérer le canevas après usage !
  End;
 
begin
 inherited Paint;
 Degrader;
end;

...... (suite)
Procedure TFormPrincipal.MiseEnPlaceDesTPanelDejaExistant;
Var 
   Panel: TMyPanel;
begin
      With ModuleDeDonneeSecondaire do
      Begin
        while not ADOCalendrier.Eof do
        Begin
          Panel := TMyPanel.Create(FormPrincipal);  <== la tu est sur qu'il faut mettre SELF ?
          Panel.Font.Size := 8;
          Panel.Font.Name := 'Tahoma';
          Panel.Name := 'PANEL' + ADOCalendrier.Fields.Fields[31].AsString;
          Panel.Caption := ADOCalendrier.Fields.Fields[45].AsString;
          Panel.Top := StrToInt(ADOCalendrier.Fields.Fields[28].AsString);
          Panel.left := StrToInt(ADOCalendrier.Fields.Fields[25].AsString);
          Panel.Height := StrToInt(ADOCalendrier.Fields.Fields[22].AsString);
//          Panel.Color := ADOCalendrier.Fields.Fields[20].AsInteger;
          Panel.Width := StrToInt(ADOCalendrier.Fields.Fields[30].AsString);
          Panel.Parent := FormPrincipal.StringGridSemaine; <== tu penses que c'est bon comme cela ?
          Panel.PopupMenu := FormPrincipal.PopupMenu1;
          Panel.OnDblClick := FormPrincipal.PanelDblClick;
          Panel.OnMouseDown := FormPrincipal.PanelMouseDown;
          Panel.OnMouseMove := FormPrincipal.PanelMouseMove;
          Panel.OnMouseUp := FormPrincipal.PanelMouseUp;
          Panel.ParentBackground := False;
          Panel.Hint := ADOCalendrier.Fields.Fields[23].AsString;
          Panel.ShowHint := True;
          Panel.StartColor := clCream;
          Panel.EndColor := ADOCalendrier.Fields.Fields[20].AsInteger;
          ProgressBarPrincipal.Position := ProgressBarPrincipal.Position + 1;

          ADOCalendrier.Next;
        end;
end;



J'attends vraiement ton avis de professionel.

N'hesite pas à me dire ce que tu en pense.

vendredi 3 octobre 2008 à 17:06:52 | Re : Canvas sur des panels créés dynamiquement

Bacterius

Membre Club
Bonjour,
je me permets de simplifier la réponse de f0xi, pour ta première remarque en rouge.

Self définit le type actif dans une unité. Dans les unités fiches, il désignera la fiche.

Pour toute création de composant dynamique, il vaut mieux utiliser Self pour Create, cela spécifie à la fiche qu'elle devra se charger de la destruction du composant lorsqu'elle se détruira.

Cordialement, Bacterius !
samedi 4 octobre 2008 à 02:22:12 | Re : Canvas sur des panels créés dynamiquement

f0xi

Membre Club Administrateur CodeS-SourceS

utilise la procedure de dégradé que j'ai mis, elle est mieux!

ensuite, oui Self et pas autre chose.

Self pour create et Self.StringGridSemaine






Cette discussion est classée dans : sender, rect, panel, panelrect, panelcanvas


Répondre à ce message

Sujets en rapport avec ce message

dbgrid,couleur.... [ par exyacc ] salut, j'utilise ce code pour changer la couleur de selection d'un dbgrid. procedure TForm1.RxDBGrid3DrawColumnCell(Sender:TObject;const Rect:TRect;D Une source liée à MsDos qui ne fonctionne pas [ par Francky23012301 ] Salut à tous j'avais lancé le débat sur la possibilité d'ouvrir une invite MsDos et de l'incruster dans une FORM. Divers solutions m'avaient été propo Réinitialiser un panel. [ par Becracker ] Salut les gras, Juste une ptite kestion. J'ai un panel qui contient plusieurs labels et edit dont les valeurs changent. Je voudrais en clickant sur u Scrollbar dans un panel [ par josswel ] Bonjour je voudrai savoir si quelqun porrai me donner un exemple de code s'il es possible de combine un Tpanel avec un scrollebar ou un simple scrolle afficher une fiche dans une fiche [ par develomagaly ] bonjour,J'ai besoin d'un petit coup de main. J'ai une fiche MdiChild qui contient en panel, Je voudrait afficher une fiche dans ce panel. Je ne souhai Erreur de type asynchrone [ par Francky23012301 ] Salut à tous,j'ai voulu faire un petit test de transfert de fichiers transfert client->serveur :La connection du client au serveur s'effectue correcte Mettre une fiche dans un panel [ par develomagaly ] bonjour, J'ai un petit probleme pour mettre une fiche dans un panel.J'ouvre une fentre FrmSimulation qui contient a panel PnlDonneesJe met dans PnlDon Affichage des composants et de leur fils [ par anisb ] Salut tout le monde,Voilà je suis débutant en Delphi et j'ai forcément un petit probleme...J'ai une classe qui dérive de TCustomPanel dans lequel la r Comment bouger un form avec un Panel [ par skrypterz ] salut !!!!Il y a une facon de faire bouger le form en cliquan sur un panel ????mon form : BorderStyle := bsNoneSkrypterZ Affichage dans un Combobox [ par yannba ] J'utilise un Affichage couleur dans un Combobox.Tout est paramétrée en police 8 (font.size:=8). Tout marche mais lorsque l'utilisateur change la taill


Nos sponsors


Sondage...

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,312 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales