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

Langage Delphi Discussion :

[Composant dynamique] Paint en boucle [FAQ]


Sujet :

Langage Delphi

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 72
    Points : 38
    Points
    38
    Par défaut [Composant dynamique] Paint en boucle
    Bonjour,

    Je créé dynamiquement un composant(TImage) qui surcharge la méthode Paint.

    Le problème est que le Paint tounre en boucle. Je peux utilisé mon programme normalement mais le bouton de création reste enfoncé par ex... C'est pas terrible et j'aimerais faire ça proprement

    Voilé le code pour la création sur le clic
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    inc(Nombre);
      SetLength(ListeCompos, Nombre+1);
      ListeCompos[Nombre] := Compo.Create(Self);
      with ListeCompos[Nombre] do
      begin
        Parent := Self;
        PopupMenu := PopupMenu1;
        Name := 'Compo'+IntToStr(Nombre);
        Tag := Nombre;
        Backcolor := clInfoBk;
        OnMouseDown := CompoMouseDown;
        OnDragOver := CompoDragOver;
        OnEndDrag := CompoEndDrag;
      end;
    Vous n'auriez pas une idée ?

    Merci

  2. #2
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 72
    Points : 38
    Points
    38
    Par défaut
    Visiblement, c'est un porblème dans mon Paint.

    J'utilise les méthodes Rectangle() et Polygon() de Canvas et il apprécie pas trop.

    Pour résoudre le problème, je ne fais pas d'override et j'appelle Paint(public) dès que j'en ai besoin... mais je trouve ça pas très élégant.

    Vous n'auriez pas une solution ?

  3. #3
    Membre expert
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Points : 3 575
    Points
    3 575
    Par défaut
    Le bouton de création
    peux-tu préciser stp ?
    C'est un bouton standard ou c'est le résultat de ta création, un TImage avec ton evt OnPaint ?

    Peux-tu donner le code de ton .OnPaint ?
    Section Delphi
    La mine d'or: La FAQ, les Sources

    Un développement compliqué paraitra simple pour l'utilisateur, frustrant non ?
    Notre revanche ? l'inverse est aussi vrai ;-)

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 72
    Points : 38
    Points
    38
    Par défaut
    Citation Envoyé par TicTacToe
    Le bouton de création
    peux-tu préciser stp ?
    C'est un bouton standard ou c'est le résultat de ta création, un TImage avec ton evt OnPaint ?

    Peux-tu donner le code de ton .OnPaint ?
    Je tiens à préciser que ce n'est pas un événement...

    C'est bouton dans une toolbox qui envoie le code donné plus haut.

    Voici un bout de mon paint :
    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
     
    procedure Paint;override;
     
    procedure Paint;
    begin
      inherited Paint;
     
      With Canvas do
      begin
        Pen.Color := clRed;
        Brush.Color := clRed;
        Rectangle(0,0,Width,Height);
      end;
     
    end;
    C'est qu'un petit extrait, mais en ne mettant que ça, ça tourne en boucle... alors que si j'enlève la fonction rectangle, c'est ok.

    Ça veut dire que ces fonctions du Canvas font un refresh....

    Est-ce possible de l'empêcher sans devoir gérer soi-même tous les appels à Paint ?

  5. #5
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par maredami
    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
     
    procedure Paint;override;
     
    procedure Paint;
    begin
      inherited Paint;
     
      With Canvas do
      begin
        Pen.Color := clRed;
        Brush.Color := clRed;
        Rectangle(0,0,Width,Height);
      end;
     
    end;
    Ce code m'a l'air bon Pour moi, le problème est ailleurs
    Note: C'est pas plutot TMachin.Paint ?

    Citation Envoyé par maredami
    Ça veut dire que ces fonctions du Canvas font un refresh....
    Non absolument pas... Sinon il serait impossible de dessiner un composant
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

  6. #6
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    C'est quoi l'ancêtre de "TMachin" (comme le dit si bien pedro), c'est TImage, ou TButton ?

    Sinon je subodore quelque chose du côté de CompoDragOver;

    Tu peux nous en dire plus STP ?

    Bidouilleuse Delphi

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 72
    Points : 38
    Points
    38
    Par défaut
    Citation Envoyé par waskol
    C'est quoi l'ancêtre de "TMachin" (comme le dit si bien pedro), c'est TImage, ou TButton ?

    Sinon je subodore quelque chose du côté de CompoDragOver;

    Tu peux nous en dire plus STP ?

    L'ancêtre un TImage.

    Je (essaie)gère effectivement le Drag&Drop à l'aide de MousDown, DragOver et EndDrag. Bien vu

    Mais je ne vois pas en quoi ça peut redessiner mes composants en boucle...

  8. #8
    Membre expert
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Points : 3 575
    Points
    3 575
    Par défaut
    Moi aussi je subodore la même chose au vu des post.

    Est-ce que dans les evts MouseMouve et Dragxxx il n'y a pas quelque chose qui provoque le Paint ? (un refresh, update ... )

    Sinon c'est du code normal pour un paint...
    Section Delphi
    La mine d'or: La FAQ, les Sources

    Un développement compliqué paraitra simple pour l'utilisateur, frustrant non ?
    Notre revanche ? l'inverse est aussi vrai ;-)

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 72
    Points : 38
    Points
    38
    Par défaut
    Aucune de ces fonctions ne devrait déranger puisqu'elles agissent en fonctions de certains événements (clic, glisser...).

    Dans le doute, j'ai enlevé tout le contenu de ces fonctions qui me servent à faire un Drag&Drop et aussi une sélection à l'aide d'un rectangle.

    Le problème est toujours présent.

    Je n'y comprends rien !

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 72
    Points : 38
    Points
    38
    Par défaut
    J'ai fait une nouvelle application avec un bouton.

    Lors du clic sur ce bouton :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    var
      f: MonCompo;
    begin
      f := MonCompo.Create(self);
      f.Parent := Self;
    end;
    En mettant un point d'arrêt, surprise ! Une magnifique boucle sur Paint dès que je retourne sur la Form.(comme avant quoi)

    Donc, je ne sais plus que faire si ce n'est gérer moi-même tous les appels à Paint. Ce qui est franchement peu glorieux...

  11. #11
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Tu peux nous envoyer tout ton code ou bien c'est Top Secret ?
    On va faire le tri...
    parce que là je ne comprend pas du tout ce que tu fait...
    Bidouilleuse Delphi

  12. #12
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par maredami
    En mettant un point d'arrêt, surprise ! Une magnifique boucle sur Paint dès que je retourne sur la Form.(comme avant quoi)
    Ben c'est normal tu mets la fenêtre de code de Delphi devant ton appli (et donc ton compo). Donc lorsque tu retournes vers ton appli (tu la remets en avant plan), il faut redessiner... D'où le Paint... Enfin il me semble...
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 72
    Points : 38
    Points
    38
    Par défaut
    Citation Envoyé par Pedro
    Citation Envoyé par maredami
    En mettant un point d'arrêt, surprise ! Une magnifique boucle sur Paint dès que je retourne sur la Form.(comme avant quoi)
    Ben c'est normal tu mets la fenêtre de code de Delphi devant ton appli (et donc ton compo). Donc lorsque tu retournes vers ton appli (tu la remets en avant plan), il faut redessiner... D'où le Paint... Enfin il me semble...
    Oui, ça c'est clair.

    Ce qui l'est moins, c'est que la boucle est toujours là en mode exécution (j'ai affiché un compteur pour vérification).

    Serait-ce dû à l'override ? Aurais-je ommis de mettre une property à true ou false ?

    Ce dont je suis sûr, c'est que, le simple fait d'utiliser Rectangle, Polygon LineTo..., créé une boucle sur la méthode Paint de TImage... enfin je crois !

  14. #14
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 72
    Points : 38
    Points
    38
    Par défaut
    J'ai une petite question subsidiaire :

    Pourquoi sur ce tutoriel, il fait un override de Paint mais il n'appelle pas inherited Paint ?

    Si dans mon code je ne le mets pas, rien ne se dessine.

    Est-ce un oubli ?

  15. #15
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Citation Envoyé par maredami
    J'ai une petite question subsidiaire :

    Pourquoi sur ce tutoriel, il fait un override de Paint mais il n'appelle pas inherited Paint ?

    Si dans mon code je ne le mets pas, rien ne se dessine.

    Est-ce un oubli ?
    Bonne remarque.
    Non, il n'y a ni erreur ni oubli.

    Quand tu écris :
    en fait tu appelle le code Paint de la classe ancètre.
    Bref, le code que tu ajoute après cet appel, va dessiner par dessus ce qui à déjà été dessiné par Delphi via le code du Paint de l'ancètre

    sjrd, lui, redessine complêtement l'objet dans son Paint et et il n'a donc pas besoin d'appeler le dessin de l'ancètre (qui lui, dessine peut-être un triangle).
    Bidouilleuse Delphi

  16. #16
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 865
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 865
    Points : 11 333
    Points
    11 333
    Billets dans le blog
    6
    Par défaut
    le TImage n'est pas conçu pour dessiner sur son image, mais pour l'afficher et la repeindre si besoin.

    si tu dois modifier l'image, pê serait-il judicieux de le faire en dehors, puis de réaffecter au TImage ?
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  17. #17
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Personnellement j'utilise toujours un TPaintBox, couplé si besoin est à un TBitmap. Une fois qu'on y a pris goût...
    Bidouilleuse Delphi

  18. #18
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Ca y'est !!!!!!!

    Dans ton paint, quand tu dessines sur le Canvas du TImage, en fait, tu dessines sur le Bitmap sous-jascent. Modifiant le ce bitmap sous-jascent, crac, tu redéclenches le paint de ton TImage.

    Si tu regarde bien comment est codé le PAint de TImage, tu remarqueras qu'il est fait appel à inherited Canvas, qui lui EST le véritable canvas du Timage (en fait celui de l'ancètre TGraphicControl). Bref, il va falloir que tu fasses pareil.

    Donc au lieu d'écrire ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    procedure Paint;
    begin
      inherited Paint;
     
      With Canvas do
      begin
        Pen.Color := clRed;
        Brush.Color := clRed;
        Rectangle(0,0,Width,Height);
      end;
     
    end;
    Tu vas écrire ceci, qui devrait faire l'affaire :

    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
     
    type TPublicGraphicControl=class(TGraphicControl);
     
    procedure TTonCompo.Paint;
    begin
      inherited Paint;
      //utilise le canvas du TGraphicControl (le vrai Canvas du TImage)
      With TPublicGraphicControl(Self).Canvas do 
      begin
        Pen.Color := clRed;
        Brush.Color := clRed;
        Rectangle(0,0,Width,Height);
      end;
     
    end;
    Bidouilleuse Delphi

  19. #19
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 72
    Points : 38
    Points
    38
    Par défaut
    And the winner is : waskol !!!

    Merci infiniment !

    Si tu regarde bien comment est codé le PAint de TImage
    Comment je peux voir ça ?

    Tu penses quand même qu'il serait plus judicieux d'utiliser un composant hérité de TPaintBox ? Je vais avoir pleins de composants graphiques différents (pour dessiner un schéma) qui seront ajoutés avec la toolbar.

  20. #20
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Haaaaaaa....

    Comment je peux voir ça ?
    Dans ton code, dans ton éditeur Delphi :
    1. tu cliques sur le mot TImage (simple clic pour se positionner dessus)
    2. Tu cliques avec le bouton droit de la souris (une fois)
    3. Dans le menu Contextuel, tu choisis "Chercher la déclaration" (tout en haut du menu) -->Delphi ouvre l'unité ExtCtrls
    4. Dans l'explorateur de code, tu cherches et déroules "TImage-->Protégées-->Paint", sur lequel tu cliques et tu obtiens ceci :

      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
      procedure TImage.Paint;
      var
        Save: Boolean;
      begin
        if csDesigning in ComponentState then
      	with inherited Canvas do
      	begin
      	  Pen.Style := psDash;
      	  Brush.Style := bsClear;
      	  Rectangle(0, 0, Width, Height);
      	end;
        Save := FDrawing;
        FDrawing := True;
        try
      	with inherited Canvas do
      	  StretchDraw(DestRect, Picture.Graphic);
        finally
      	FDrawing := Save;
        end;
      end;
      Tu remarques alors le "inherited Canvas" qui appelle la propriété Canvas de la classe ancètre, c'est-à-dire TGraphicControl, qui est une propriété protégée, pour ne rien arranger ... CQFD


    Tu penses quand même qu'il serait plus judicieux d'utiliser un composant hérité de TPaintBox ? Je vais avoir pleins de composants graphiques différents (pour dessiner un schéma) qui seront ajoutés avec la toolbar.
    En fait, pour dessiner quelque part en direct, c'est ce que j'utilise, (il y ajuste à codé l'évènement OnPaint.
    Par contre pour faire un composant visuel, la plupart du temps, je suis un poil brutus :
    - si il mon composant doit contenir des contrôles : je dérive de TWinControl et j'écris tout..
    - sinon je dérive de TGraphicControl.

    En tout cas, écrire un descendant de TImage, non, je ne le fait jamais. A la rigueur un descendant de TPaintBox, avec un TBitmap qui me sert à dessiner en BackGround fait toujours l'affaire. C'est moins lourd que TImage, je trouve.

    Celà reste bien sur un point de vue, chacun doit trouver son style : il n'y a pas UNE solution universelle pour chaque réalisation spécifique.

    Voilà, voilà.
    Bidouilleuse Delphi

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

Discussions similaires

  1. Composant dynamique
    Par leycho dans le forum Composants VCL
    Réponses: 1
    Dernier message: 29/12/2005, 16h14
  2. problème de destruction de composants dynamique
    Par gandf dans le forum C++Builder
    Réponses: 4
    Dernier message: 23/08/2005, 10h39
  3. [FLASH MX] Nom de composant dynamique
    Par bobgeldof7 dans le forum Flash
    Réponses: 2
    Dernier message: 12/11/2004, 23h07
  4. [THandle][DLL] Composant dynamique et THandle
    Par el_diablos dans le forum Langage
    Réponses: 10
    Dernier message: 01/07/2004, 15h01
  5. [JTabbedPane] Accès à des composants dynamiques
    Par SamRay1024 dans le forum Composants
    Réponses: 8
    Dernier message: 26/05/2004, 13h04

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