OnScroll Versus InvalidatRect

Résolu
shorzy Messages postés 94 Date d'inscription jeudi 23 novembre 2000 Statut Membre Dernière intervention 1 juin 2013 - 23 juil. 2009 à 22:30
ed73 Messages postés 276 Date d'inscription lundi 8 septembre 2008 Statut Membre Dernière intervention 15 avril 2013 - 28 juil. 2009 à 13:40
Bonjour.

Je voudrais me déplacer dans ma vue. (CView ou ScrollView)
J'ai 2 Possibilité :
1) OnScrollBy()
2) modifier le ViewPortOrg(), puis redessiner la fenêtre


Donnée.
-------
OnScrollBy déplace ma vue comme le ferais une modif du ViewPortOrg()
sauf que le déplacement est plus libre en modifiant le ViewPortOrg().

Problème.
---------
Je vais donc modifier le ViewPortOrg(), pour avoir des déplacements plus Libre.
MAIS
en redessinant la fenetre (Lors duInvalidatRect), j'ai un clignotement de celle-ci.
Chose que je n'est pas en faisant OnScrollBy()


QUESTION.
---------
Quelle est la méthode qu'utilise réellement OnScrollBy() que je pourrais utiliser directement au lieu de Déplacer la fenêtre puis la redessiner.


Merci de m'aider, je galère depuis plusieurs mois.....

Yeeh Baby

5 réponses

ed73 Messages postés 276 Date d'inscription lundi 8 septembre 2008 Statut Membre Dernière intervention 15 avril 2013 2
28 juil. 2009 à 13:40
Bonjour,

Ah oui, 60 000 pixels par 60 000 pixels, ça fait pas mal de mémoire

La première raison qui me vient à l'idée pour tes "lourdeurs" c'est que peut-être tu dessines plus de choses qu'il faudrait. Windows sait gérer ça car le dessin réel ne se fera que sur la fenêtre courante mais il peut y avoir des effets indésirables.

Tu peux commencer par vérifier :

- Le temps de calcul pour des objets qui n'ont pas besoin d'être dessinés
- Les coordonnées logiques sont limitées à l'intervale [-32768,+32767], en cas de fort zoom elles peuvent donc être dépassées dans tes calculs et là tu peux arriver à n'importe quoi comme par exemple des traits plus ou moins aléatoires sur ta fenêtre.

Avant de dessiner un objet tu dois donc vérifier qu'au moins une partie sera visible, une technique consiste à calculer le rectangle incluant ton objet et à vérifier qu'il possède une intersection avec le rectangle de la fenêtre à l'aide de la fonction IntersectRect.

Il n'y a ainsi pas de raison de limiter le niveau de zoom. Enfin, il faut rester raisonnable quand même sinon on finit par ne plus rien voir
3
ed73 Messages postés 276 Date d'inscription lundi 8 septembre 2008 Statut Membre Dernière intervention 15 avril 2013 2
27 juil. 2009 à 13:54
Bonjour,

Il s'agit en fait d'un effet visuel. OnScrollBy ne va invalider que la partie de la fenêtre qui devra être redessinnée, donc il est possible que tu ne vois pas le clignotement si la surface de cette zone est petite.

InvalidateRect invalide la totalité de la fenêtre en l'effaçant, ce qui donne cet effet de clignotement lorsque la fenêtre redessine son contenu.

Il y a plusieurs moyens pour l'éviter.

- InvalidateRect(NULL,FALSE); invalide toute la fenêtre sans effacer ce qui est présent.
- InvalidateRect(&Rect,TRUE ou FALSE); n'invalide que le rectangle spécifié.
- Tu peux intercepter le message WM_ERASEBKGND et retourner FALSE sans rien faire, ce qui fait que la fenêtre ne s'efface pas, ensuite tu effaces manuellement ce que tu veux et tu redessines.
- Enfin tu peux utiliser la technique du double buffer, c'est ce que je préconise car c'est eficace dans tous les cas et ça te permet de gérer plusieurs couches graphiques.

ed73
0
shorzy Messages postés 94 Date d'inscription jeudi 23 novembre 2000 Statut Membre Dernière intervention 1 juin 2013
27 juil. 2009 à 22:39
Merci de ta Réponse.
..Je connais tous ça....

Le n°1) Parais bien, mais on dirais que "l'Encre Coule" quand on bouge la fenêtre
le n°2 est bien mais ne convient pas ici (...)
Et le n°3 est bien (MAIS...)
(voir un Exemple ici)
http://www.cppfrance.com/codes/DOUBLE-BUFFERING-MFC_48812.aspx

Cette méthode est bien, MAIS l'Implémentation utilisé (sur le Lien) n'est peut etre pas la meilleur car les ressources consommés sont importantes.
(j'ai implémenté un Zoom sur la Fenêtre et les Ressources utilisés sont Enooorme : Pross 100% Ram +100Mo
(Tous ça pour une Vue quoisiment Vide !!!)


+++
0
ed73 Messages postés 276 Date d'inscription lundi 8 septembre 2008 Statut Membre Dernière intervention 15 avril 2013 2
27 juil. 2009 à 23:06
Bonsoir,

Il est bien évident que la méthode d'implémentation du double buffer dans le lien que tu cites n'est pas la bonne.

Il n'est pas raisonnable de créer les ressources nécessaires au double buffer dans le traitement du message WM_PAINT car non seulement cela consomme de la mémoire mais aussi du temps.

Il reste cependant que c'est la seule et unique méthode te permettant d'éviter le clignotement de ta fenêtre, encore faut-il le gérer correctement.

Quelques pistes :

- Maintenir un objet gérant le double buffer durant le temps d'existence de ta fenêtre.
- Ne créer le bitmap associé que lors d'un redimensionnement de la fenêtre ou encore un créer un une fois pour toute de la taille maximale de l'écran.
- Si le WM_PAINT est généré suite à une action involontaire de ta part, comme par exemple la fermeture d'une popup qui était par dessus ta fenêtre alors ne faire que recopier le contenu su bitmap à l'écran puisque tu l'as déjà dans l'objet qui gère le double buffer.

J'utilise ces techniques depuis des années, en particulier dans des logiciels de cartographie avec des double buffer à plusieurs couches pour par exemple déplacer des objets ou encore pour ne pas recalculer des images complexes à chaque réaffichage et je peux affirmer que ça fonctionne parfaitement sans consommer plus de ressources que nécessaire si on sait les gérer.

Je ne sais pas comment tu as implémenté ton zoom mais il n'y a aucune raison valable pour que ça comsomme plus de ressources. Car finalement, qu'est-ce qu'un zoom ? Ce n'est jamais qu'une différence d'échelle entre les données affichées et la taille de la fenêtre. Une fois que tu connais les coordonnées logiques des données à représenter il te suffit de ne dessiner que les objets dont au moins une partie rentre dans la fenêtre.

ed73
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
shorzy Messages postés 94 Date d'inscription jeudi 23 novembre 2000 Statut Membre Dernière intervention 1 juin 2013
28 juil. 2009 à 13:05
Salut,
Hé ben... Tu es mon seul amis sur ce Post ...
Mais apparement de Qualité Lol

Ok. J'ai Vu hier pourquoi mon PC Rotait du sang lorsque je dézoomais
(Je construisait mon BitMap de la Taille des Coordonnées Logique, et Non Coord Device)

Donc en Dézoomant, je construissais eenvirons une Image de 60 000 x 60 000 Pixels (Argl...)
J'ai Corrigé tous ça Hier, je suis bien content !!!
Le Pross. reste à 3% et la Ram ne bouge plus !!!!


* Je vais regarder les Messages à Traiter (Lors des Fermeture de Popup etc...)

Au fait,
Quand Je faisait 'Zoom Out' j'avais un grand nbr de Pts Logique donc :
(comme je m'était planté dans la construction de mon image, elle était Très Grande)
Je comprend le Plantage (Il ne m'arrive plus maintenant!!!)

Par contre maintenant quand je fait Zoom In (jusqu'a avoir ~5x5 Pts Logique pour 1680x1500 Pxl)
Là des 'Lourdeurs' se font sentir !!! (ces Lourdeurs n'existe plus au dela de 10x10 pts pour 1680x1500 pxl logiques)
Je peux contourner le Problème en Interdisant de Zoomer trop, mais... as tu une Explication

MerCi++
0
Rejoignez-nous