Bonjour,
Y a-t-il une solution pour corriger les effets de scintillement observés sur un composant TPainBox ?
Merci![]()
Discussion :
Bonjour,
Y a-t-il une solution pour corriger les effets de scintillement observés sur un composant TPainBox ?
Merci![]()
On ne peut pas faire confiance à un code qu'on n'a pas entièrement écrit soi‑même, et encore moins à celui qu'on a écrit entièrement. :aie:
Réponse bête: DoubleBuffered ?
Ou alors, ceci:
Ton prog, c’est du pro ou open source, car le sujet m’intéresse ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part paintbox1.controlstyle := paintbox1.controlstyle + [csopaque];
On ne peut pas faire confiance à un code qu'on n'a pas entièrement écrit soi‑même, et encore moins à celui qu'on a écrit entièrement. :aie:
Tient cela me rappelle un truc écrit pour le forum : https://www.developpez.net/forums/d1...i/#post8056103
Un exercice classique !
Pour un outil de dessin de plan, c'était aussi de control plutôt qu'une PaintBox c'était au final plus simple pour le scrolling dans une ScrollBox que gérer soit même le fenêtrage
Regarde aussi si tu peux déterminer un clipRect pour limiter la zone dessinée
Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !![]()
Attention Troll Méchant !
"Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
L'ignorance n'excuse pas la médiocrité !
L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
Il faut avoir le courage de se tromper et d'apprendre de ses erreurs
@xeGregory: pour tes liens, tu devrais définir des zones d’ancrages pour les liaisons, par exemple au milieu de chaque côté de tes formes voir même au 4 coins![]()
Merci der§en
Actuellement, Les points d’ancrage sont placés au centre de chaque côté de l’objet.
Je vais effectivement définir des zones d’ancrage pour les liaisons. Je pensais placer un point au milieu de chaque côté des formes, et éventuellement ajouter aussi les quatre coins pour offrir plus de flexibilité dans le positionnement des liens.
On ne peut pas faire confiance à un code qu'on n'a pas entièrement écrit soi‑même, et encore moins à celui qu'on a écrit entièrement. :aie:
Je viens de mettre en place cette fonctionnalité. Cela permet d'éviter de placer des formes à l'extérieur de la zone.
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 procedure TFlowChart.ConstrainRectToBounds(var R: TRect); var W, H: Integer; begin NormalizeRect(R); W := R.Right - R.Left; H := R.Bottom - R.Top; if W > (FBounds.Right - FBounds.Left) then W := FBounds.Right - FBounds.Left; if H > (FBounds.Bottom - FBounds.Top) then H := FBounds.Bottom - FBounds.Top; if R.Left < FBounds.Left then R.Left := FBounds.Left; if R.Top < FBounds.Top then R.Top := FBounds.Top; R.Right := R.Left + W; R.Bottom := R.Top + H; if R.Right > FBounds.Right then begin R.Right := FBounds.Right; R.Left := R.Right - W; if R.Left < FBounds.Left then R.Left := FBounds.Left; end; if R.Bottom > FBounds.Bottom then begin R.Bottom := FBounds.Bottom; R.Top := R.Bottom - H; if R.Top < FBounds.Top then R.Top := FBounds.Top; end; NormalizeRect(R); end;
Merci ShaiLeTroll![]()
On ne peut pas faire confiance à un code qu'on n'a pas entièrement écrit soi‑même, et encore moins à celui qu'on a écrit entièrement. :aie:
Si tu dessines dans un Bitmap puis tu reportes dans le PaintBox c'est mieux le clipping ?
Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !![]()
Attention Troll Méchant !
"Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
L'ignorance n'excuse pas la médiocrité !
L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
Il faut avoir le courage de se tromper et d'apprendre de ses erreurs
Il a quand même un petit soucis de rafraîchissement sur les objets pas concernés pas le déplacement, je trouve
Tu dessines directement dans le PaintBox, ou bien tu passes par un bitmap de travail ?
Plutôt que tout recalculer à chaque déplacement, n'aurait-il pas mieux valu calculer le clipping une fois pour toute au mouse down et limiter le mouvement de la souris par ClipCursor ?
Si le diagramme est sauvé et rechargé sur une machine avec une résolution inférieure, y a-t-il mise à l'échelle ? Sinon ce clipping est plus gênant qu'autre chose.
A tester aussi ce genre d’approche:
https://delphi-bar.blogspot.com/2012...lickering.html
Oui, je dessine directement dans la PaintBox.
J’ai testé l’option Bitmap : C’est toute la PaintBox qui scintille à chaque rafraîchissement.
À choisir, je préfère que ce soient uniquement les objets qui scintillent.
En effet, je n’avais pas envisagé cette solution. ClipCursor s’avère plus efficace que de recalculer en permanence, je vais donc approfondir le sujet.
Non je n'est pas de mise a l'échelle, pour le moment.
Je vais regarder ça.
Merci![]()
On ne peut pas faire confiance à un code qu'on n'a pas entièrement écrit soi‑même, et encore moins à celui qu'on a écrit entièrement. :aie:
Regarde du côté des fenêtres layered, pas de scintillement puisque plus de messages WM_PAINT\WM_ERASEBKGND.
Un bitmap en mémoire et un flush par UpdateLayeredWindow.
(pense aussi à Direct2D plutôt que GDI)
Je pense qu'il y a une confusion, TPaintBox est un TGraphicControl n'a pas de handle et qui dessine directement sur le canvas du parent donc l'astuce pointée par der§en ou le remarque sur WM_ERASEBKGND ne changent rien, la première chose à faire c'est mettre DoubleBuffred du parent à True, et changer la méthode de rafraîchissement entre Invalidate et Repaint.
l'idéal c'est de remplacer Paintbox par un TCustumControl pour profiter des fonctionnalités de dessin windows et aussi pour pouvoir géré les srcollbas si le dessin dépasse la fenêtre. et avec un TWincontrol on peut faire des rafraîchissements doux avec invalidateRect, UpdateWindow
Sur le principe je suis d'accord avec toi mais on peut supposer que le code est plus ou moins comme ceci :
Invalidate (Repaint même combat) demande une repainture (du parent ici) qui sera d'office précédée d'un WM_ERASEBKGND.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 procedure TForm23.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if ssLeft in Shift then begin ... Invalidate; // ou PaintBox1.Invalidate; end; end;
Soit on ignore ce message (Message.Result := 1), soit on ne demande pas de rafraichissement en appelant directement PaintBox1.OnPaint(PaintBox1). Il ne disparaitra peut-être pas complétement mais le flicker sera déjà grandement réduit.
Mais un bitmap en mémoire serait mieux puisqu'il pourrait même être utilisé pour l'effacement par WM_ERASEBKGND (on a le DC), Paint ne se chargeant plus que de l'objet en mouvement.
Sinon, une fenêtre layered...
Solution simple et efficace : J'ai activer le double buffering sur le formulaire
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 procedure TFFlowChart.DrawPaintMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if Assigned(FlowChart) then begin DrawPaint.Cursor := FlowChart.CursorForPoint(Point(X, Y)); if (ssLeft in Shift) or (ssRight in Shift) then begin FlowChart.MouseMove(Point(X, Y)); DrawPaint.Invalidate; end; end; end;
Code : Sélectionner tout - Visualiser dans une fenêtre à part DoubleBuffered := True
DoubleBuffered := True a réglé mon problème de scintillement lors du déplacement des objets dans un PaintBox.
![]()
On ne peut pas faire confiance à un code qu'on n'a pas entièrement écrit soi‑même, et encore moins à celui qu'on a écrit entièrement. :aie:
Le doublebuffered, c’est un peu utiliser une masse pour enfoncer une punaise, et puis cela augmente ta consommation CPU…
Partager