begin process at 2010 02 10 06:56:49
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Graphique

 > REALISER UN DEGRADE SUR PLUSIEURS COULEURS AVEC LES API WINDOWS

REALISER UN DEGRADE SUR PLUSIEURS COULEURS AVEC LES API WINDOWS


 Information sur la source

Note :
9,5 / 10 - par 2 personnes
9,50 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Graphique Classé sous :gradientfill, dégradé, multicolor, api Niveau :Initié Date de création :28/01/2006 Date de mise à jour :25/01/2010 17:44:47 Vu / téléchargé :7 196 / 989

Auteur : cirec

Ecrire un message privé
Commentaire sur cette source (44)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
Encore un dégradé me direz vous
Oui mais cette source utilise une procédure qui existe déjà dans l'unité Windows depuis au moins Delphi 4
et elle permet de réaliser un dégradé sur deux où plusieurs couleurs de votre choix que ce soit en horizontale en verticale
Et maintenant en triangle il y a également une gestion ludique des couleurs.

J'ai volontairement mis cette fonction dans une unité à part afin de vous faciliter son utilisation et son intégration dans vos applications

Son utilisation est des plus simple puisqu'elle se résume en deux fonctions.

Exemple :

GradientRect(Canvas.handle, // le canvas dans le quel le dégradé sera dessiné
             [clBlue, clGreen, clYellow, clRed], // les couleurs de votre choix
             ClientRect, // les coordonées et la taille du dégradé à réaliser
             GRADIENT_FILL_RECT_H // et la direction ici Horizontale et GRADIENT_FILL_RECT_V pour Verticale
             ); // si tout ce passe bien la fonction renvoie True


GradientTriangle(Canvas.handle, // le canvas dans le quel le dégradé sera dessiné
                [clBlue, clGreen, clYellow, clRed], // les couleurs de votre choix minimum 3 et 4 pour remplir un rectangle où carrée entièrement
                ClientRect, // les coordonées et la taille du dégradé à réaliser
                ); // si tout ce passe bien la fonction renvoie True


 Conclusion

Pour la gestion des couleurs je me suis légèrement inspiré de la source de WhiteHippo pour les Briques
//**************************************** ************************************************** ******//
L'unité Gradients.pas a été revue et corrigée par Maître F0xi
Un grand merci à lui je peux dire.
Efficace et précieuse sa collaboration à été.

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Historique

29 janvier 2006 12:29:43 :
Correction du défaut de compatibilité de version avec les Delphi inférieurs à Delphi2005. Retrait du composant XPManifest et ajout d'un fichier ressource qui fait la même chose. Merci à Nicolas__ et à Jlen
29 janvier 2006 12:51:09 :
J'ai déplacé les re-déclarations de type de la section Interface à la section implémentation ce qui et amplement suffisant.
30 janvier 2006 20:00:39 :
Ajout d'un DoubleBuffered := True dans l'évenement OnCreate et d'un Ivalidade dans l'évenement OnResize de la Form à la demande de Nicolas__ Merci
18 février 2006 03:14:07 :
Ajout de la fonction de dégrader en Triangle, Ajout de deux autres unités pour la gestion du tableau de couleurs, pour pouvoir changer les couleurs en Run Time de façon plus ludique avec possibilité de déplacement des couleurs en mode Drag & Drop. Mais tous ceci n'est la que pour le fun, le plus important étant l'implémentation de la fonction GradientTriangle. A ce propos si quelqu'un a une idée pour améliorer le code où une proposition de formule mathématique qui permettrait de calculer le nombre de triangles et leurs positions dans un rectangle donné en fonction du nombre de couleurs qu'il n'hésite pas, je suis ouvert à toutes propositions. Merci
19 février 2006 19:29:49 :
Voilà la première grande modification de cette source grâce à F0xi qui a réécrit la totalité de l'unité Gradients.pas. Mais j'ai laissé pour l'instant en commentaire les anciennes fonctions et procédures afin d'avoir un aperçu de l'étendue des modifications apportée par Maître F0xi ;-). Correction du problème soulevé par Jlen (Erreur lors de la suppression d'une couleur quand il n'y en a pas de sélectionnée) j'avais dans l'idée de modifier partie, ça viendra prochainement. Un grand merci à vous deux.
26 février 2006 19:48:56 :
Quelques petites modifications -- Ajout d'une propriété PopupMenu dans l'unité Briques ce qui corrige de manière plus élégante le problème soulevé par Jlen -- Ajout d'un Item dans le popupmenu pour pouvoir effacer toutes les Briques en une fois. -- Correction d'un bug dans la gestion des Briques par Drag&Drop (les positions visuels ne correspondaient pas à la réalité)
20 novembre 2008 16:04:26 :
Correction du problème lors de sélection d'une brique de couleurs noir
25 janvier 2010 11:32:09 :
Modification du code pour prendre en compte l'origine (Top/Left) du dégradé .. Merci à jderf
25 janvier 2010 17:44:47 :
Modification du code pour prendre en compte l'origine (Top/Left) du dégradé triangle ... Merci à jderf

 Sources du même auteur

Source avec Zip Source avec une capture BITMAP 32BITS INTÉGRÉ À LA VCL (TIMAGE, TPICTURE, TBITMAP, T...
Source avec Zip Source avec une capture [ASTUCE] COMMENT VOIR UN ITEM, D'UNE LISTBOX, TRONQUÉ DANS U...
Source avec Zip Source avec une capture TEXTE GRAPHIQUE AVEC CONTOUR, OMBRE ET TEXTURE EN API VERSIO...
Source avec Zip Source avec une capture TEXTE GRAPHIQUE AVEC CONTOUR, OMBRE ET TEXTURE EN API
Source avec Zip Source avec une capture ROTATION (RAPIDE) DE BITMAP (À 360°) EN PUR GDI

 Sources de la même categorie

Source avec Zip Source avec une capture EFFET VITRE ET THUMBNAILS SOUS VISTA par Bacterius
Source avec Zip Source avec une capture ANAGLYPHEUR OU COMMENT VOIR EN RELIEF LES STÉRÉOSCOPES ANCES... par jfs59
Source avec Zip Source avec une capture DÉFORMER UNE IMAGE AUX DIMENSIONS D'UN QUADRANGLE QUELCONQUE... par FFCAST
Source avec Zip Source avec une capture THREAD ET BITMAP (DESSIN AU CRAYON) par barbichette
Source avec Zip Source avec une capture ÉCRAN DE VEILLE FEU D'ARTIFICE par barbichette

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture UN JOLI BOUTON ! par Bacterius
Source avec Zip OBTENIR LE PROPRIÉTAIRE D'UN FICHIER (WIN32;NTFS) par ILP
Source avec Zip Source avec une capture AUTO-COMPLÉTION D'UN CONTRÔLE DE SAISIE par Bacterius
Source avec Zip Source avec une capture TANGENT PACK [COMPOSANTS] par Bacterius
Source avec Zip Source avec une capture PACKAGE MICROSOFT par blueperfect

Commentaires et avis

Commentaire de Nicolas___ le 28/01/2006 16:29:34

[Erreur] Gradients.pas(78): Les types des paramètres VAR originaux et formels doivent être identiques
[Erreur fatale] UGradient_Demo.pas(30): Impossible de compiler l'unité utilisée 'Gradients.pas'

Dommage ca pouvait etre bien pratique ...

Ps:J ai delphi7 et winXP

Ciao
Nico

Commentaire de jlen100 le 28/01/2006 16:34:58

salut cirec,
intéressant.
pas mal l'effet toutefois 2/3 petites choses pas trop grave:
sous D7 cela ne se compile pas :
[Erreur] Gradients.pas(78): Les types des paramètres VAR originaux et formels doivent être identiques
alors que cela ne pose pas de probleme sous D2005 (je n'est pas testé sous D6 entreprise qui n'est pas installé sur ce PC et non raccordé au réseau)
evite de mettre un XPman qui n'est pas supporté par les version<D7 je crois (j'ai trouvé la "ruse" : mettre un fichier ressources du genre XPManifest.res et mettre :{$R XPManifest.res}
) l'effet est identique et supporté par toute les versions.
une petite remarque dans le fonctionnement de la demo (peut être du à mon PC) l'effet n'est pas instantanné quand on change de mode( qqs secondes pour avoir une stabilisation complète des couleurs).
à+
jlen

Commentaire de jlen100 le 28/01/2006 16:37:24

--> nicolas je viens de faire la même remarque apparement il faut D2005 avec la version perso ça marche!!
@+
jlen

Commentaire de cirec le 28/01/2006 16:58:29 administrateur CS

@ Jlen chez moi c'est instantané et le XPManifest je l'ai juste mis pour montrer que ça le prenait aussi en compte (je ferais ce qu'il faut bientôt promis)
Pour le reste je vais essayer de voir ce que ça donne avec Delphi4
désolé je n'ai pas D7 pour faire les testes, j'ai ma petite idée sur le problème.
Par contre pour aujourd'hui ce ne sera peut être plus possible je dois me sauver
mais dès que je revient je me penche dessus et posterai une mise à jour

Commentaire de jlen100 le 28/01/2006 17:16:15

pour l'effet c'est presque instantanné et ne joue que sur des nuances ( mais cela vient aussi peut-être de l'oeil du peintre: je suis certainement un peu plus sensible à une plus grande variétés de nuances).
l'inconvénientdu composant XPman c'est que quand il n'est pas supporté par la version il te fait une superbe erreur de compilation du genre unité pas trouvée!! ce qui n'est pas du meilleur effet.
@+
jlen

Commentaire de cirec le 29/01/2006 12:42:58 administrateur CS

@ Nicolas et Jlen,
Les modifications sont faites merci à vous deux

Il semblerait que les Dev de chez Borland aient fait des modifications sur certain type :
Color16 était déclaré comme Shortint alors que maintenant il semblerait qu'il soit de type Word.

Je l'ai testé Ok sur Delphi4.
Testez et tenez moi informé.
@+
Cirec

Commentaire de jlen100 le 29/01/2006 12:59:41

--cirec ça fonctionne sous D7 c'est parfait je testerais aussi sur un autre PC pour vérifier si c'est le PC ou ma vue qui me joue des tours!!
@+
jlen

Commentaire de cirec le 29/01/2006 13:07:06 administrateur CS

Merci Jlen, je ne sais pas si tu as vu mais j'ai refait une mise à jour les re-déclaration de type sont maintenant dans la section Implémentation
Chez moi sur un P4 HT 3Ghz je ne remarque rien c'est immédiat ce qui ma un peut surpris je m'attendais justement à voir le rafraîchissement mais non c'est impeccable.

@+
Cirec

Commentaire de jlen100 le 29/01/2006 13:27:16

c'est dommage que l'on ne puisse pas tarnsmettre d'image car ce n'est pas facile à expliquer:
si tu veux le rafraichissement est instantané mais il persiste deux zones qui sont en retard (genre ~ moirage) mais je viens de tester sur un autre pc ou l'effet n'est partiquement persetible et sur le vieux compaq ce n'est plus perceptible.
je crois savoir la cause le PC sur internet est éqipé d'un écran TFT ancienne génération (~5ans) tandis que le compaq est équipé d'un CRT .
Conclusion : cela constitue un bon test sur la qualité de l'écran et/ou de la carte graphique!
@+
jlen

Commentaire de Nicolas___ le 30/01/2006 18:53:43

Ah ,
Merci Cirec pour avoir transforme le code pour qu il soit compatible Delphi7.
Et ben en tt cas vraiment excellente cette fonction  

Par contre tu peux mettre,

procedure TForm1.FormCreate(Sender: TObject);
begin
doublebuffered:=true;
end;

et

procedure TForm1.FormResize(Sender: TObject);
begin
Direction := TRadioButton(Sender).Tag;
Invalidate;
    GradientRect(Canvas.Handle,[cllime, clblack, clYellow, clRed], ClientRect, Direction);

end;

Ca permet comme on le voit tres bien de pouvoir modifier la taille de la form en faisant tjs le degrader

Le doublebuffered c est pr le scintillement

J ai une ATIRadeon 9600 pro et un athlon 1800+(donc pas terrible) et ya pas de prob

Commentaire de cirec le 30/01/2006 20:11:31 administrateur CS

Salut Nicolas,
pour le DoubleBuffered je suis entièrement d'accord avec toi (c'est fait) mais pour la suite seulement à moitié :
Le paramètre Sender ne peut pas être utiliser ici puisqu'il sera forcement Form1 et non un radiobutton et l'appel a la fonction GradientRect est ici inutile puisque l'appel a Invalidate envoie WM_Paint à la Form donc l'évènement OnPaint est déclanché

Voici ce que j'ai mis et ça fonctionne bien.

procedure TForm1.FormCreate(Sender: TObject);
begin
  DoubleBuffered := True;
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  Invalidate;
end;

Teste le et dis moi.

@+
Cirec

Commentaire de Nicolas___ le 30/01/2006 20:23:06

procedure TForm1.FormResize(Sender: TObject);
begin
  Invalidate;
end;
------> Oui Oui tt a fait d acc av toi je pense que j ai ete un peu trop vite ...
Allez, Ciao et Re-Merci !

Nico

Commentaire de cirec le 30/01/2006 20:27:46 administrateur CS

ps : j'ai oublié le plus important honte à moi
Merci à toi Nicolas__ pour ton commentaire et pour tes informations qui m'ont permis de faire les modifications nécessaires

pour info Ati redeon pro 9200 à 128 Mb DDR pour la carte vidéo
et comme elle a deux sortie j'ai deux écrans branchés dessus un crt et un lcd 19 pouces les deux et la qualité du dégradé je la trouve meilleur sur le vieux crt je m'explique
le fondu entre les couleurs et mieux fait plus doux.
@+
Cirec

Commentaire de jlen100 le 30/01/2006 20:34:52

c'est ce que j'ai constaté le fondu est meilleurs sur un  crt
que sur un TFT Remarque aussi que le photos ont bien souvent un meilleurs rendu sur un crt (saturation des couleurs moins importante)
@+
jlen

Commentaire de cirec le 30/01/2006 20:50:08 administrateur CS

Oui c'est limite décevant bon remarque j'ai l'impression que les pixels sont plus gros.
Mais bon d'un autre coté sur la vidéo c'est génial la j'ai rien n'a dire où re-dire, il faut peut être passer à une qualité supérieur si c'est possible dans Delphi au niveau du mode d'affichage mais la ça me dépasse

@+
Cirec

Commentaire de jlen100 le 30/01/2006 21:09:39

en fait je pense que çà vient du mode de reproduction des couleurs:
sur un crt chaque pixel posséde 3 lumiphores exités par le flux d'électrons et en fait ce flux ou plutot le flux secondaire emis exite les lumiphores adjacents ce qui produit une sorte de "flou"
alors de dans les TFT ou les LCD chaque pixel est activé par la matrice.
tout ce passe comme si dans une image on passait directement d'une couleur à une autre sans zone de transition (exemple d'une image détourée mise sur un fond uni: l'effet n'est pas naturel) c'est pour cela que les logiciel de retouche photo procede à un dégradé de la zone de transition.
comme quoi le mieux est l'ennemi du bien!!
@+
jlen

Commentaire de cirec le 18/02/2006 03:21:07 administrateur CS

Salut,
J’ai réalisé l'implémentation de la fonction GradientTriange plus quelques petites modifications voir plus haut. A ce propos j'en appel à vos lumières si vous avez une idée pour rationaliser le code, parce que la je sèche un peut ;-) Pour plus d'informations voir l'historique des mises à jour. D'avance Merci.

@+
Cirec

Commentaire de f0xi le 19/02/2006 14:23:06 administrateur CS

unit GRADIENT.PAS

modification de la structure _TRIVERTEX :

  _TRIVERTEX = Packed Record
    X,Y : Longint;
    Red, Green, Blue, Alpha: COLOR16;
  End;

on aurait egalement pus faire :

  _TRIVERTEX = Record
    Coord : TPoint;
    Red, Green, Blue, Alpha: COLOR16;
  End;
_________________________________________

Ajout de methodes pour le type TTRIVERTEX :

procedure PointTVX(out TVX : TTriVertex; const aX,aY : LongInt); forward;
Procedure ColorTVX(out TVX : TTriVertex; const aRed,aGreen,aBlue : COLOR16; const aAlpha : COLOR16 = 0); overload; forward;
Procedure ColorTVX(out TVX : TTriVertex; const aCol : TColor; const aAlpha : COLOR16 = 0); overload; forward;
procedure TriVertexP(out TVX : TTriVertex; const aX,aY : LongInt;const aRed,aGreen,aBlue : COLOR16; const aAlpha : COLOR16 = 0); overload; forward;
procedure TriVertexP(out TVX : TTriVertex; const aX,aY : LongInt;const aCol : Tcolor; const aAlpha : COLOR16 = 0); overload; forward;
function TriVertexF(const aX,aY : LongInt;const aRed,aGreen,aBlue : COLOR16; const aAlpha : COLOR16 = 0) : TTriVertex; overload; forward;
function TriVertexF(const aX,aY : LongInt;const aCol : Tcolor; const aAlpha : COLOR16 = 0) : TTriVertex; overload; forward;

// permet de definir rapidement les coordonées
procedure PointTVX(out TVX : TTriVertex; const aX,aY : LongInt);
begin
  TVX.X := aX;
  TVX.Y := aY;
end;

// permet de definir rapidement la couleur
Procedure ColorTVX(out TVX : TTriVertex; const aRed,aGreen,aBlue : COLOR16; const aAlpha : COLOR16 = 0);
begin
  With TVX do begin
    Red   := aRed;
    Green := aGreen;
    Blue  := aBlue;
    Alpha := aAlpha
  end;
end;

// en incluant les traitements
Procedure ColorTVX(out TVX : TTriVertex; const aCol : TColor; const aAlpha : COLOR16 = 0);
begin
  With TVX do begin
    Red   := GetRValue(aCol) Shl 8;
    Green := GetGValue(aCol) Shl 8;
    Blue  := GetBValue(aCol) Shl 8;
    Alpha := aAlpha
  end;
end;

// permet de definir rapidement un element TTriVertex

procedure TriVertexP(out TVX : TTriVertex; const aX,aY : LongInt;const aRed,aGreen,aBlue : COLOR16; const aAlpha : COLOR16 = 0);
begin
  PointTVX(TVX,aX,aY);
  ColorTVX(TVX,aRed,aGreen,aBlue,aAlpha);
end;

procedure TriVertexP(out TVX : TTriVertex; const aX,aY : LongInt;const aCol : TColor; const aAlpha : COLOR16 = 0);
begin
  PointTVX(TVX,aX,aY);
  ColorTVX(TVX,aCol,aAlpha);
end;

function TriVertexF(const aX,aY : LongInt;const aRed,aGreen,aBlue : COLOR16; const aAlpha : COLOR16 = 0) : TTriVertex;
begin
  PointTVX(result,aX,aY);
  ColorTVX(result,aRed,aGreen,aBlue,aAlpha);
end;

function TriVertexF(const aX,aY : LongInt;const aCol : TColor; const aAlpha : COLOR16 = 0) : TTriVertex;
begin
  PointTVX(result,aX,aY);
  ColorTVX(result,aCol,aAlpha);
end;
_________________________________________

ajout de methode pour TGRADIENTTRIANGLE :

procedure GradientTriP(out aGT : TGRADIENTTRIANGLE; const Vx1, Vx2, Vx3 : cardinal);
begin
  aGT.Vertex1 := Vx1;
  aGT.Vertex2 := Vx2;
  aGT.Vertex3 := Vx3;
end;

function GradientTriF(const Vx1, Vx2, Vx3 : cardinal) : TGRADIENTTRIANGLE;
begin
  result.Vertex1 := Vx1;
  result.Vertex2 := Vx2;
  result.Vertex3 := Vx3;
end;
_________________________________________

Ajout de methodes pour le type TGRADIENTRECT :

procedure GradientRect(out aGR : TGRADIENTRECT; const aUL,aLR : cardinal);
begin
  aGR.UpperLeft := aUL;
  aGR.LowerRight:= aLR;
end;
_________________________________________

Modifications en consequence :

{ **** }

Function GradientRect(Dc: THandle; ColorArray: Array Of TColor; aRect: TRect; Direction: Integer): Boolean;
Var Idx, aHeight, aWidth, nbCycle,pX,pY : Integer;
  Vert  : Array Of TTrivertEx;
  gRect : Array Of TGRADIENTRECT;
Begin
  nbCycle := Length(ColorArray);
  SetLength(Vert, nbCycle);
  SetLength(gRect, nbCycle - 1);
  aHeight := GetRectHeight(aRect);
  aWidth  := GetRectWidth(aRect);
  PX := 0;
  PY := 0;
  For Idx := 0 To High(Vert) Do begin
      Case Direction Of
        GRADIENT_FILL_RECT_V : Begin
           If Idx Mod 2 = 0 Then pX := 0 Else pX := aWidth;
           pY := Round(aHeight / (nbCycle - 1) * Idx);
        End;
        GRADIENT_FILL_RECT_H : Begin
           If Idx Mod 2 = 0 Then pY := 0 Else pY := aHeight;
           pX := Round(aWidth / (nbCycle - 1) * Idx);
        End;
      End;
      TriVertexP(Vert[Idx],PX,PY, ColorArray[Idx]);
  End;

  For Idx := 0 To High(gRect) Do
      GradientRect(gRect[Idx],Idx,Idx + 1);

  Result := GradientFill( Dc, PTRIVERTEX(vert), nbCycle, PGradientRect(gRect), nbCycle-1, Direction);
End;

{ **** }

Procedure InitTriSequence;
Var I : Integer;
Begin
  For I := 1 To High(TriSequence) Do Begin
      SetLength(TriSequence[I], I);
  End;

  For I := 1 To 8 Do Begin
      if I in [1..8]    then GradientTriP(TriSequence[I][0],0,1,2);
      if I in [2,6..8]  then GradientTriP(TriSequence[I][1],0,2,3);
      if I in [3..5]    then GradientTriP(TriSequence[I][1],1,2,3);
      if I in [4..8]    then GradientTriP(TriSequence[I][2],2,3,4);
      if I in [5..8]    then GradientTriP(TriSequence[I][3],2,4,5);
      if I in [6..8]    then GradientTriP(TriSequence[I][4],2,5,6);
      if I in [7,8]     then GradientTriP(TriSequence[I][5],2,6,7);
      if I in [3,4]     then GradientTriP(TriSequence[I][I-1],0,2,4);
      if I in [5..8]    then GradientTriP(TriSequence[I][I-1],0,2,I);
  End;
  GradientTriP(TriSequence[8][6],2,7,8);
End;

{ **** }

Procedure GetVertPos(Var Vert: Array Of TTrivertEx; aRect: TRect);
Var nbCycle, aHeight, aWidth: Integer;
Begin
  aHeight := GetRectHeight(aRect);
  aWidth  := GetRectWidth(aRect);
  nbCycle := Length(Vert);

  PointTVX(Vert[0],aRect.Left,aRect.Top);

  if nbCycle IN [3..5] then begin
     PointTVX(Vert[1],aRect.Right,aRect.Top);
  end;

  if nbCycle IN [3..4] then begin
     PointTVX(Vert[2],aRect.Right,aRect.Bottom);
  end;

  if nbCycle IN [5..9] then begin
     PointTVX(Vert[2],aWidth Div 2,aHeight Div 2);
  end;

  if nbCycle IN [6..9] then begin
     PointTVX(Vert[1],aWidth Div 2,aRect.Top);
     PointTVX(Vert[3],aRect.Right,aRect.Top);
  end;

  if nbCycle IN [7..9] then begin
     PointTVX(Vert[4],aRect.Right,aHeight Div 2);
     PointTVX(Vert[5],aRect.Right,aRect.Bottom);
  end;

  if nbCycle IN [8..9] then begin
     PointTVX(Vert[6],aWidth Div 2,aRect.Bottom);
     PointTVX(Vert[7],aRect.Left,aRect.Bottom);
  end;

  if nbCycle = 4 then
     PointTVX(Vert[3],aRect.Left,aRect.Bottom);

  if nbCycle = 5 then begin
     PointTVX(Vert[3],aRect.Right,aRect.Bottom);
     PointTVX(Vert[4],aRect.Left,aRect.Bottom);
  End;

  if nbCycle = 6 then begin
        PointTVX(Vert[4],aRect.Right,aRect.Bottom);
        PointTVX(Vert[5],aRect.Left,aRect.Bottom);
  End;

  if nbCycle = 7 then
     PointTVX(Vert[6],aRect.Left,aRect.Bottom);

  if nbCycle = 9 then begin
     PointTVX(Vert[6],aWidth Div 2,aRect.Bottom);
     PointTVX(Vert[8],aRect.Left,aHeight Div 2);
  End;
End;

{ **** }

Function GradientTriangle(Dc: THandle; ColorArray: Array Of TColor; aRect: TRect): Boolean;
Var Idx, nbCycle, NbTriCycle: Integer;
    Vert : Array Of TTrivertEx;
Begin
  nbCycle := Length(ColorArray);
  If NbCycle > 9 Then NbCycle := 9;
  SetLength(Vert, nbCycle);
  GetVertPos(Vert, aRect);
  For Idx := 0 To High(Vert) Do
      ColorTVX(Vert[Idx],ColorArray[Idx]);

  If NbCycle > 4 Then
     NbTriCycle := NbCycle - 1
  Else
     NbTriCycle := NbCycle - 2;

  GradientFill(dc, PTRIVERTEX(vert), NbCycle,
  PGRADIENTTRIANGLE(TriSequence[NbTriCycle]), NbTriCycle, GRADIENT_FILL_TRIANGLE);
End;



voila pour celle ci au niveau optimisation / completion, tu remarqueras que tous les ajouts de methodes ne sont pas utilisés.
je les ais laissés juste a titre d'exemple.

d'ailleur je conseil a tout le monde qui voudrais créer une petite ou grande structure "record"
de creer egalement les fonctions/procedure permettant d'ameliorer et optimiser le code, exemple :

TIdentity = record
  nom,prenom : string;
  DdN : tdatetime;
end;

procedure Identity(out aID : TIdentity; const aNom,aPrenom : string; cont aDdN : TDateTime);
begin
  aID.nom := aNom;
  aID.prenom := aPrenom;
  aID.DdN := aDdN;
end;

cela permet d'augementer la rapiditée d'ecriture de code et egalement d'alleger celui ci.

Commentaire de f0xi le 19/02/2006 14:33:30 administrateur CS

petit bug :



procedure GRect(out aGR : TGRADIENTRECT; const aUL,aLR : cardinal);
begin
  aGR.UpperLeft := aUL;
  aGR.LowerRight:= aLR;
end;

Function GradientRect(Dc: THandle; ColorArray: Array Of TColor; aRect: TRect; Direction: Integer): Boolean;
Var Idx, aHeight, aWidth, nbCycle,pX,pY : Integer;
  Vert  : Array Of TTrivertEx;
  gRect : Array Of TGRADIENTRECT;

Begin
  nbCycle := Length(ColorArray);

  SetLength(Vert, nbCycle);
  SetLength(gRect, nbCycle - 1);

  aHeight := GetRectHeight(aRect);
  aWidth  := GetRectWidth(aRect);
  PX := 0;
  PY := 0;

  For Idx := 0 To High(Vert) Do begin
      Case Direction Of
        GRADIENT_FILL_RECT_V : Begin
           If Idx Mod 2 = 0 Then pX := 0 Else pX := aWidth;
           pY := Round(aHeight / (nbCycle - 1) * Idx);
        End;
        GRADIENT_FILL_RECT_H : Begin
           If Idx Mod 2 = 0 Then pY := 0 Else pY := aHeight;
           pX := Round(aWidth / (nbCycle - 1) * Idx);
        End;
      End;
      TriVertexP(Vert[Idx],PX,PY, ColorArray[Idx]);
  End;

  For Idx := 0 To High(gRect) Do
      GRect(gRect[Idx],Idx,Idx + 1);

  Result := GradientFill( Dc, PTRIVERTEX(vert), nbCycle, PGradientRect(gRect), nbCycle-1, Direction);
End;

Commentaire de cirec le 19/02/2006 15:02:53 administrateur CS

Salut F0xi,
Merci de t'être penché sur ma source.
Que dire ?  wouaou ça fait beaucoup de changements d'un coup pour ma petite tête ;-)
je vais de ce pas tester le tout et dès que c'est fait je te tiens au courant.
une petite question toute fois :
Jlen ma signalé un problème dans la gestion des briques de couleurs sous D7, lors de la suppression d'une où plusieurs de ces briques (non mise à jour de l'affichage) et en retirant le fichier WinXP.res le problème serait résolue.
alors as-tu également ce genre de problème parce que moi j'ai aucun soucis à ce niveau
ni sous D4 ni sous D9 ?

@+
Cirec

Commentaire de jlen100 le 19/02/2006 15:30:40

salut,
pour l'erreur lors de la suppression cela ce produit aussi sous toutes version (enfin sous lesquelles j'ai pu tester : D6, D7,D9) quand on fait un click droit en dehors des carrés et que l'on fait "supprimer" le debugger renvoie à la ligne:
  TriShape[NBrique].Free;

@+
jlen

Commentaire de cirec le 19/02/2006 16:40:41 administrateur CS

@ Jlen
je vais verifier tout ça et je te tiens au courrant.

@ F0xi
premiere modification testé j'ai été obligé d'apporté un petit changement si non il refusait de compiler :
// le nom de cette procedure est passé de GRect à GrdRect
// puisqu'il y avait confusion par le compilateur dans la procedure GradientRect avec
// le tableau dynamique gRect
procedure GrdRect(out aGR : TGRADIENTRECT; const aUL,aLR : cardinal);
begin
  aGR.UpperLeft := aUL;
  aGR.LowerRight:= aLR;
end;

Function GradientRect(Dc: THandle; ColorArray: Array Of TColor; aRect: TRect; Direction: Integer): Boolean;
Var Idx, aHeight, aWidth, nbCycle,pX,pY : Integer;
  Vert  : Array Of TTrivertEx;
  gRect : Array Of TGRADIENTRECT;

Begin
  nbCycle := Length(ColorArray);

  SetLength(Vert, nbCycle);
  SetLength(gRect, nbCycle - 1);

  aHeight := GetRectHeight(aRect);
  aWidth  := GetRectWidth(aRect);
  PX := 0;
  PY := 0;

  For Idx := 0 To High(Vert) Do begin
      Case Direction Of
        GRADIENT_FILL_RECT_V : Begin
           If Idx Mod 2 = 0 Then pX := 0 Else pX := aWidth;
           pY := Round(aHeight / (nbCycle - 1) * Idx);
        End;
        GRADIENT_FILL_RECT_H : Begin
           If Idx Mod 2 = 0 Then pY := 0 Else pY := aHeight;
           pX := Round(aWidth / (nbCycle - 1) * Idx);
        End;
      End;
      TriVertexP(Vert[Idx],PX,PY, ColorArray[Idx]);
  End;

  For Idx := 0 To High(gRect) Do
      GrdRect(gRect[Idx],Idx,Idx + 1);

  Result := GradientFill( Dc, PTRIVERTEX(vert), nbCycle, PGradientRect(gRect), nbCycle-1, Direction);
End;

et les deux fonctions : GetRectHeight et GetRectWidth sont inconue mais bon c'est pas un problème c'est fait et ça fonctionne.

Je teste la suite et je reviens vous en dire plus

@+
Cirec

Commentaire de cirec le 19/02/2006 16:49:34 administrateur CS

Bon pour le problème de suppression c'est règlé :
  If Length(TriShape) = 0 Then Exit;

  NBrique := -1;  // Ajouté

  For I := 0 To High(TriShape) Do
    If TriShape[I].Selected Then NBrique := I;
  If nBrique = -1 Then Exit;  // et ajouté
  TriShape[NBrique].Free;

et le problème à disparue

dès que tout serat au point je posterai une nouvelle mise à jour
je retourne aux testes sur les propositions de F0xi.
@+
Cirec

Commentaire de cirec le 19/02/2006 19:41:28 administrateur CS

Voilà, la mise à jour est faite sur les propositions de F0xi,
du coup toute l'unité a été réécrite mais je vous laisse
pour l'instant l'ancienne version en commentaire pour pouvoir voir et comprendre
ce qui a été fait.
Le bug découvert par Jlen est également corrigé.

J'ai l'impression que les performances d'affichage sont meilleurs, a vous de juger.
Dites moi ce que vous en pensez.

@+
Cirec

Commentaire de cirec le 24/03/2006 20:51:43 administrateur CS

Où tu le fais exprès où tu n'as rien compris à la programmation.
Quand tu utilises un TImage pour afficher un Bmp, tu es au courant qu'il y a des dizaines de lignes de codes derrière et que même si tu les as pas écrite elles sont quand même "embarquées" dans ton application.

Ici c'est la même chose :
Tu déclares l'unité "Gradients" une fois pour toute dans les "Uses" et la fonction s'utilise en une seule ligne.

En faite l'unité "Gradients" à été crée pour réduire l'utilisation de la fonction "GradientFill" à un seule ligne de commande (à l'origine elle demande au minimum une dizaine de lignes)
Il n'y a pas plus simple que ça! Les autres unités ne sont la que pour l'exemple.

Maintenant si tu arrives à faire la même chose ("Dégradé, vertical, horizontal, triangulaire sur plusieurs couleurs avec fondu entre les couleurs") et le tout avec moins de code alors je te tire mon chapeau. Mais je demande à voir d'abord.

Je pense également que si tu avais pris la peine de regarder le fonctionnement de la fonction "GragientFill" tu aurais eu un autre avis sur le sujet.

@+
Cirec

Commentaire de jlen100 le 24/03/2006 21:07:48

salut Cirec,
Wolf a encore fait des siennes (son commentaire a été supprimé mais j'ai eu le temps de le lire) C'est le spécialiste des posts hors sujet : celà ne mérite même pas la peine d'y répondre. Un jour peut-être il comprendra que les commentaires ou critiques ont pour but d'améliorer les sources et que les critiques sans fondements n'apportent rien

@+
jlen

Commentaire de cirec le 24/03/2006 21:35:57 administrateur CS

Salut Jlen,
tu me rassures je commençais à penser que je l'avais rêvé ce post.
En effet il a remis le couvert, peut être qu'un jour il comprendra le but des commentaires sur CS.
En tout cas c'est allé vite cette fois (compte tenu que je n'ai pas fait de demande de suppression et je ne pense pas qu'il y ait eu une).

Du coup mon précédent post est un peut perdu sans réel raison d'être :)
Enfin bon c'est pas grave.

@+
Cirec

Commentaire de jlen100 le 24/03/2006 21:44:41

oui sans la notification automatique je l'aurais surement loupé
@+
jlen

Commentaire de jlen100 le 22/04/2006 10:32:16

michèle le code cirec n'a du tout la même fonction qu'un Timage et tu aurais du liretouts les posts
il y a déjà la réponse à ta remarque je cite:
" Quand tu utilises un TImage pour afficher un Bmp, tu es au courant qu'il y a des dizaines
de lignes de codes derrière et que même si tu les as pas écrite elles sont quand
même "embarquées" dans ton application."
ensuite essaye de faire la même chose en dynamique avec un TImage et reviens nous dire le résultat

@+
jlen

Commentaire de jlen100 le 22/04/2006 10:51:01

ce n'est pas la même fonction avec un composant TImage tu n'as qu'un dégradé sinon il te faudra autant de Timage que de dégradé avec la fonction de cirec tu fais varier ton dégradé en dymanique avec un Timage c'est impossible
ce n'est pas plus difficile que de charger une image dans le picture puisqu'il te suffit d'appeler la procédure avec les bons paramètres

@+
jlen

Commentaire de Idefix57 le 02/05/2006 14:07:18

Merci Cirec et les correcteurs
que ferions nous sans une équipe soudée...

super le programe ,

Idefix

Commentaire de Toya78 le 04/01/2007 19:09:20

Une seule chose à dire : MA-GNI-FIQUE !

Superbe source ! J'applaudis des 2 mains et des 2 pieds !

Bravo ! :)

Commentaire de Bacterius le 03/05/2008 21:17:56

Bonjour,
je voulais juste dire que depuis que j'ai Delphi 6, je me suis souvenu de cette source, et j'étais loin de penser que c'était aussi BEAU ^^
Je vais essayer d'en faire un composant, ca peut être bien joli :)

Cordialement, Bacterius !

Commentaire de Bacterius le 03/05/2008 22:10:31

Bon, j'ai laissé tomber le composant, trop dur à faire, quelqu'un pourrait-t-il m'expliquer les grandes lignes "conception d'un composant" car j'y comprends rien, à chaque fois j'ai 20 messages d'erreur :x

Sinon j'en ai fait une unité, que j'ai mis dans le dossier delphi, je peux facilement faire des bôs dégradés maintenant merci beaucoup Cirec pour ce joli code :)

Cordialement, Bacterius !

Commentaire de cirec le 04/05/2008 16:44:33 administrateur CS

Merci pour l'appréciation.

je suis curieux de savoir ce que tu as mis dans ton unité ?
envoie moi le code sur ma boite Mail (tu as l'adresse)

ensuite faire un composant ne me parait pas être utile ...

En ce concerne la création de composants regarde les tutoriels.
Mais je pense que c'est encore trop tôt pour toi .. il te faut d'abord acquérir certaine bases avant de te lancer dans la création de composant.

Commentaire de Bacterius le 04/05/2008 17:02:39

Bonjour,
j'ai juste un peu arrangé le code, qui beugeait un petit peu pour moi. Et puis j'ai bloqué les dégradés horizon/vertical avec 1 seule couleur, et les dégradés triangulaires avec moins de 4 couleurs (il est coupé).
C'est tout pour l'unité.
Et j'ai essayé de faire une application autour de ca aussi.
C'est dommage qu'on puisse pas faire de dégradé polygonal, et circulaire ... Il doit exister un moyen de le faire, je vais me renseigner :)

Ce code m'a redonné le gout de la programmation graphique :)

Cordialement, Bacterius !

Commentaire de cirec le 04/05/2008 17:25:07 administrateur CS

je ne comprend pas ...

Normalement tout est dans l'unité Gradients.pas il n'y a rien d'autre à déclarer ... et le code a été testé Ok sous D4 D7 D9 D10(Turbo Delphi)

c'est pour ça que je te demande de m'envoyer l'unité à coup sûr tu as fait ça pour rien ^^

l'intérêt du code était justement de pouvoir réaliser des dégradés sur plusieurs couleurs mais tu peux aussi en "sélectionner" que deux

Commentaire de ThWilliam le 08/05/2008 19:21:04

Salut Cirec.

Je n'ai pas encore eu le temps de regarder le code, mais le résultat est magnifique. Je sens que cela va me servir...
Bravo.

Commentaire de cincap le 19/11/2008 17:34:48

Bonjour à toutes et à tous,

@ Cirec, avec Delphi 6 c'est correct, génial et le code bien structuré.

Après test, en ajoutant une brique de couleur noire, la brique apparaît en blanc, il faut choisir une brique d'une autre couleur puis modifier la couleur en noir avec le click droit et cela fonctionne.

Voila voilou, il y a peut être une raison.

@+,

Cincap

Commentaire de cincap le 20/11/2008 07:38:36

Bonjour à toutes et à tous,

@ Cirec, bon c'est OK, j'ai trouvé une parade qui fonctionne correctement.

@+,

Cincap

Commentaire de cirec le 20/11/2008 15:20:03 administrateur CS

Il faut tout simplement jouter ceci dans le constructeur de TBrique:
  FCouleur := -1;  

voilà c'est tout

Commentaire de cincap le 20/11/2008 15:45:35

Bonjour à toutes et à tous,

@Cirec, merci d'avoir répondu, j'avais ajouté cette ligne ce qui me semble quif quif.

Procedure Tfrm_Color.AddBrique(Value: TColor);
Begin
  
  if value = $00000000 then value := value + 1 ;

  @+,

Cincap

Commentaire de cirec le 20/11/2008 16:11:11 administrateur CS

c'est pas tout à fait la même chose

j'ai mis le Zip à jour (il y a encore d'autres petites corrections ;))

en fait FCouleur est initialisé à 0

donc quand tu choisis une brique de couleur noir (0) le code n'est pas executé puisqu'il n'y a pas de différence entre Value et FCouleur :
  if FCouleur <> Value then
  begin
    FCouleur := Value;
    Brush.Color := Value;
    Invalidate;
  end;

Commentaire de cincap le 20/11/2008 16:22:10

Pourtant cela fonctionnait correctement (sans mettre ton code), mais j'ai quand même modifié l'unité Brique avec ta solution.

Merci,

@+,

Cincap

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Les Api Windows [ par twoupy ] Est-ce que quelqu'un possède ou sait où je pourrais trouver l'aide sur les Api Windows (win32.hlp) en français. ce serait bien cool, parce que l'angl documentation API [ par Noureddine ] Bonjour,je cherche la documentation pour comprendre L'API, si vous avez une adresse ou je peut télécharger une documentation en français SVPMerci. problème avec une api [ par fabiin ] SalutEst-ce que kelk'un rencontre un problème lors de l'utilisation desetDCbrushcoloren Delphi 6Merci par avance@+Fabse Comment utiliser une API avec Delphi 5? [ par Manthis ] Salut,Je débute tout juste en Delphi 5. J'avais commencer par le VB. Et donc voila j'ai un problème comment utiliser une API avec Delphi?Ou doit-on la API sndPlaySoundA [ par jlg75 ] j'utilise l'API 'sndPlaySoundA' tirée de 'winmm.dll' pour lire des .wav dans un prog DELPHI. Je déclare explicitement cet API comme fonction 'external CHERCHE TUT DELPHI API [ par golum ] Salut je suis a la recherche d'un tut Delphi et API un peu comme EstDev pour VBAuriez vous quelque chose ? des adresses ? Winsock [ par SMoG ] Yop... Je desespere de trouver un jour de la doc sur l'api winsock avec des exemples delphi...Si qqn pouvait m'expliquer comment deux machines se con API msn messenger [ par achovovich ] BonjourJe voudrai creer un add on pour msn messenger. Je sais ke ceci es faisable en VB et bcp d'exemples existent mais en delphi, rien. Je ne sais me fenetres bizzarres [ par ak47 ] bonjour a tous,J'ai lu dans un article qu'on pouvait faire des fenetres "bizarres" (de part leurs formes) grace a une api de windows. Malheureusement, Fonction API GetOpenFileName ??? [ par PhGORMAND ] Salut à tous.Je cherche à utiliser la fonction API GetOpenFileName, mais je ne parvient pas à l'utiliser.Dans le code ci dessous, je fais appel à la f


Nos sponsors


Sondage...

Comparez les prix

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,655 sec (3)

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