OVH Cloud OVH Cloud

Conception d'une "grid" avec les MFC

10 réponses
Avatar
TigrouMeow
Bonjour,

Je me pose une question d'ordre conceptuelle :)

Comme dans le démineur, je cherche à créer un logiciel qui réagit en
fonction
de zone où on clique. Par exemple dans ma zone de paint, j'aurais une grille
et
quand je clique sur un carré ça le colorie selon la couleur que j'aurais
choisi
(sachant que ça n'ira pas plus loin que ce coloriage par case).

Je ne sais pas comment concevoir cette "grille" au mieux, et récupérer
correctement la zone carrée qui a été cliquée. Ma première idée est de faire
une division par le nombre de carrés sur la longueur, et un modulo par le
nombre de carrés sur la largeur afin d'obtenir la position du vrai carré
(pour transformer les coordonées du clic en coordonées dans mon tableau).

N'y a t'il pas une meilleure technique plus puissante ?

Merci de m'éclairer :)

--
Meow

10 réponses

Avatar
ByB
TigrouMeow avait soumis l'idée :
Bonjour,

Je me pose une question d'ordre conceptuelle :)

Comme dans le démineur, je cherche à créer un logiciel qui réagit en fonction
de zone où on clique. Par exemple dans ma zone de paint, j'aurais une grille
et
quand je clique sur un carré ça le colorie selon la couleur que j'aurais
choisi
(sachant que ça n'ira pas plus loin que ce coloriage par case).

Je ne sais pas comment concevoir cette "grille" au mieux, et récupérer
correctement la zone carrée qui a été cliquée. Ma première idée est de faire
une division par le nombre de carrés sur la longueur, et un modulo par le
nombre de carrés sur la largeur afin d'obtenir la position du vrai carré
(pour transformer les coordonées du clic en coordonées dans mon tableau).

N'y a t'il pas une meilleure technique plus puissante ?

Merci de m'éclairer :)



Je suis curieux de savoir comment tu comptes représenter graphiquement
une telle grille avec les MFC ?
Compte-tu utiliser de simples boutons placés les uns à côté des autres
?

Merci.

--
Tout métier qui ne fait pas oublier le travail est un esclavage. [Henri
Jeanson]
Avatar
Christian ASTOR
TigrouMeow wrote:

Comme dans le démineur, je cherche à créer un logiciel qui réagit en
fonction
de zone où on clique. Par exemple dans ma zone de paint, j'aurais une grille
et
quand je clique sur un carré ça le colorie selon la couleur que j'aurais
choisi
(sachant que ça n'ira pas plus loin que ce coloriage par case).



Petzold => Checker
Avatar
Patrick Philippot
Bonjour,

Ma première idée est
de faire une division par le nombre de carrés sur la longueur, et un
modulo par le nombre de carrés sur la largeur afin d'obtenir la
position du vrai carré (pour transformer les coordonées du clic en
coordonées dans mon tableau).



C'est exactement ça. Comment faire autrement? La technique qui
consisterait à transformer chaque zone en une fenêtre et à récupérer les
messages souris au niveau de cette fenêtre est bien plus coûteuse.

Je dois avoir un TP MFC que j'utilise pendant mes cours qui est la
transposition en MFC du "Checker" de Petzold déjà cité. Je vous l'envoie
sur réception d'un e-mail.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
TigrouMeow
"Patrick Philippot" a écrit dans le
message de news: csiho6$2n01$
Bonjour,

Ma première idée est
de faire une division par le nombre de carrés sur la longueur, et un
modulo par le nombre de carrés sur la largeur afin d'obtenir la
position du vrai carré (pour transformer les coordonées du clic en
coordonées dans mon tableau).



C'est exactement ça. Comment faire autrement? La technique qui
consisterait à transformer chaque zone en une fenêtre et à récupérer les
messages souris au niveau de cette fenêtre est bien plus coûteuse.

Je dois avoir un TP MFC que j'utilise pendant mes cours qui est la
transposition en MFC du "Checker" de Petzold déjà cité. Je vous l'envoie
sur réception d'un e-mail.



Merci beaucoup j'ai bien reçu le fichier :)
En fait j'avais déjà commencer à implémenter cette gestion "gridoise"
et à priori le checker c'est la technique que j'ai employé.
Par contre il faut que je regarde un peu plus profondément le code
encore cela dit si vous pouvez m'apporter quelques élements de réponse
sur quelques points...

1. Quel est la différence entre OnDraw et OnPaint ?
(pour l'instant je n'utilise que OnDraw, et j'ai l'impression que les deux
sont appelés aux mêmes moments)

2. Dans la classe CDocument, quel est la différence entre le constructeur
et OnNewDocument ? Je pensais que quand on faisais un nouveau
document dans l'application il recréait un nouveau doc et une nouvelle
view... à savoir que pour l'instant je fais toutes mes allocations dans
OnNewDocument...

3. Dois-je faire une gestion de clic dans le Document ou dans la View ?
Je crois que c'est dans le Document, vu qu'on met notre structure
de données à jour, et on fait un UpdateAllView ensuite... j'ai besoin
d'une confirmation :)

4. Dans un ancien programme MFC que j'avais très mal fait, j'avais
un problème de scintillement... Je sais pas d'où ça vient en même
temps je veux pas trop regarder le code qui est mal foutu...
J'aimerais juste avoir quelques tips court pour me diriger, ensuite
je ferai les recherches nécéssaires par moi même :)

Je vous remercie, ce newsgroup m'aide beaucoup !

--
Meow
Avatar
Jacky Goyon
"TigrouMeow" a écrit dans le message de
news: 41ed031f$0$9950$

1. Quel est la différence entre OnDraw et OnPaint ?
(pour l'instant je n'utilise que OnDraw, et j'ai l'impression que les deux
sont appelés aux mêmes moments)



extrait du fichier source Microsoft visual studiovc98MfcsrcViewcore.cpp

// CView drawing support

void CView::OnPaint()
{
// standard paint routine
CPaintDC dc(this);
OnPrepareDC(&dc);
OnDraw(&dc);
}

tu as des heures de lecture en perspective...

Jacky
Avatar
Patrick Philippot
TigrouMeow wrote:
1. Quel est la différence entre OnDraw et OnPaint ?
(pour l'instant je n'utilise que OnDraw, et j'ai l'impression que les
deux sont appelés aux mêmes moments)



OnPaint traite le message WM_PAINT. Ce qui concerne donc directement
l'affichage dans une fenêtre. OnDraw est plus neutre et permet au
framework d'utiliser le même code que l'on dessine sur une fenêtre, une
imprimante ou n'importe quel autre device graphique. OnDraw est ce qui
permet la mise en oeuvre de la Print Preview, par exemple.

2. Dans la classe CDocument, quel est la différence entre le
constructeur et OnNewDocument ?



La différence est surtout importante pour les applications SDI. Dans ce
cas, le framework ne crée qu'un seul document qui est réutilisé en
permanence pour chaque nouveau document chargé ou créé. Le constructeur
n'est donc appelé qu'une fois pendant toute la vie du programme. Par
contre, OnNewDocument est appelé à chaque utilisation de la commande
"Nouveau Document" même si en réalité, on ne ré-instancie pas un nouveau
document.

Il vaut donc mieux mettre le code d'initialisation dans OnNewDocument
car si vous passez l'appli de MDI (ou d'un autre modèle) à SDI, vous
devrez revoir votre code si vous avez initialisé des données dans le
constructeur.

3. Dois-je faire une gestion de clic dans le Document ou dans la View
? Je crois que c'est dans le Document, vu qu'on met notre structure
de données à jour, et on fait un UpdateAllView ensuite... j'ai besoin
d'une confirmation :)



Éternel débat :-) . Le modèle document/vue est en fait un modèle
simplifié dérivé du modèle MVC (Model-View-Controller). S'il est plus
simple à gérer que le modèle MVC, il présente l'inconvénient de ne pas
définir clairement où l'on doit gérer l'interaction avec l'utilisateur.
D'où votre question qui est un grand classique. C'est une des carences
majeures des MFCs comparées à un framework comme OWL (Borland) par
exemple (sauf que OWL n'a pas été repris dans Delphi ce qui est une
bêtise regrettable).

Cependant, quelques règles de bon sens peuvent aider. Si l'action en
question n'a d'influence que sur l'état la vue courante, sans impact sur
le document, on peut envisager de la traiter directement au niveau de
cette vue. Si l'action utilisateur modifie l'état du document (et a donc
par conséquent un impact immédiat sur les autres vues connectées sur le
même document), votre raisonnement s'applique. Si l'action en question a
un impact sur l'état de l'application, on la traitera au niveau
application et pas au niveau document.

Tout cela ne vaut pas une bonne implémentation du modèle MVC. Il en
existe une, directement connectable sur les MFC: Objective Toolkit
inclus dans Stingray Studio. Les outils Stingray ont été rachetés par
Roguewave, ce qui est regrettable (par pour les fondateurs de Stingray
mais pour les clients). C'est du code de qualité mais pas très bon
marché. Et le support technique de Roguewave en France laisse à désirer
au moins pour certains produits comme Objective Views. Le code source
est fourni.

4. Dans un ancien programme MFC que j'avais très mal fait, j'avais
un problème de scintillement... Je sais pas d'où ça vient en même
temps je veux pas trop regarder le code qui est mal foutu...



Pour éviter le scintillement, effectuez toutes les manipulations
graphiques sur un DC en mémoire (MemoryDC) puis procédez à l'affichage
en une passe en copiant le MemoryDC sur le DC réel. Vous y gagnerez
également en performance.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
JM
Patrick Philippot a écrit :

Pour éviter le scintillement, effectuez toutes les manipulations
graphiques sur un DC en mémoire (MemoryDC) puis procédez à l'affichage
en une passe en copiant le MemoryDC sur le DC réel. Vous y gagnerez
également en performance.



A quels points de vue?
Avatar
Patrick Philippot
JM wrote:
Pour éviter le scintillement, effectuez toutes les manipulations
graphiques sur un DC en mémoire (MemoryDC) puis procédez à
l'affichage en une passe en copiant le MemoryDC sur le DC réel. Vous
y gagnerez également en performance.



A quels points de vue?



Touts les opérations réalisées sur un MemoryDC se font en mémoire et
n'ont pas de réprésentation physique à l'écran: on n'affiche rien. On va
donc nécessairement plus vite que si toutes ces modifications
intermédiaires étaient à chaque fois transmises au buffer d'écran. Ou
dit autrement, les opérations graphiques sur un MemoryDC sont plus
rapides que les mêmes opérations graphiques réalisées à l'écran.

En outre, vous gagnez également du temps parce qu'il n'y a qu'un seul
transfert réalisé à la fin des opérations quand le MemoryDC est prêt et
pas des transferts multiples réalisés à chaque opération.

C'est ce transfert unique qui permet d'éviter le scintillement.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
Loïc Joly
Patrick Philippot wrote:

JM wrote:

Pour éviter le scintillement, effectuez toutes les manipulations
graphiques sur un DC en mémoire (MemoryDC) puis procédez à
l'affichage en une passe en copiant le MemoryDC sur le DC réel. Vous
y gagnerez également en performance.



A quels points de vue?




Touts les opérations réalisées sur un MemoryDC se font en mémoire et
n'ont pas de réprésentation physique à l'écran: on n'affiche rien. On va
donc nécessairement plus vite que si toutes ces modifications
intermédiaires étaient à chaque fois transmises au buffer d'écran. Ou
dit autrement, les opérations graphiques sur un MemoryDC sont plus
rapides que les mêmes opérations graphiques réalisées à l'écran.



Je me demande si avec les cartes modernes qui comprennent directement
des ordres assez haut niveau, on ne va pas inverser la tendance, où il
vaudra mieux laisser la carte faire directement le boulot. On a déjà
presque déjà ça, quand on dessine de la 2D en 3D, il arrive d'avoir des
meilleurs perfs que quand on dessine en 2D directement...

--
Loïc
Avatar
TigrouMeow
"Patrick Philippot" a écrit dans le
message de news: csl6sj$lpd$
TigrouMeow wrote:
1. Quel est la différence entre OnDraw et OnPaint ?
(pour l'instant je n'utilise que OnDraw, et j'ai l'impression que les
deux sont appelés aux mêmes moments)



OnPaint traite le message WM_PAINT. Ce qui concerne donc directement
l'affichage dans une fenêtre. OnDraw est plus neutre et permet au
framework d'utiliser le même code que l'on dessine sur une fenêtre, une
imprimante ou n'importe quel autre device graphique. OnDraw est ce qui
permet la mise en oeuvre de la Print Preview, par exemple.

2. Dans la classe CDocument, quel est la différence entre le
constructeur et OnNewDocument ?



La différence est surtout importante pour les applications SDI. Dans ce
cas, le framework ne crée qu'un seul document qui est réutilisé en
permanence pour chaque nouveau document chargé ou créé. Le constructeur
n'est donc appelé qu'une fois pendant toute la vie du programme. Par
contre, OnNewDocument est appelé à chaque utilisation de la commande
"Nouveau Document" même si en réalité, on ne ré-instancie pas un nouveau
document.

Il vaut donc mieux mettre le code d'initialisation dans OnNewDocument car
si vous passez l'appli de MDI (ou d'un autre modèle) à SDI, vous devrez
revoir votre code si vous avez initialisé des données dans le
constructeur.

3. Dois-je faire une gestion de clic dans le Document ou dans la View
? Je crois que c'est dans le Document, vu qu'on met notre structure
de données à jour, et on fait un UpdateAllView ensuite... j'ai besoin
d'une confirmation :)



Éternel débat :-) . Le modèle document/vue est en fait un modèle simplifié
dérivé du modèle MVC (Model-View-Controller). S'il est plus simple à gérer
que le modèle MVC, il présente l'inconvénient de ne pas définir clairement
où l'on doit gérer l'interaction avec l'utilisateur. D'où votre question
qui est un grand classique. C'est une des carences majeures des MFCs
comparées à un framework comme OWL (Borland) par exemple (sauf que OWL n'a
pas été repris dans Delphi ce qui est une bêtise regrettable).

Cependant, quelques règles de bon sens peuvent aider. Si l'action en
question n'a d'influence que sur l'état la vue courante, sans impact sur
le document, on peut envisager de la traiter directement au niveau de
cette vue. Si l'action utilisateur modifie l'état du document (et a donc
par conséquent un impact immédiat sur les autres vues connectées sur le
même document), votre raisonnement s'applique. Si l'action en question a
un impact sur l'état de l'application, on la traitera au niveau
application et pas au niveau document.

Tout cela ne vaut pas une bonne implémentation du modèle MVC. Il en existe
une, directement connectable sur les MFC: Objective Toolkit inclus dans
Stingray Studio. Les outils Stingray ont été rachetés par Roguewave, ce
qui est regrettable (par pour les fondateurs de Stingray mais pour les
clients). C'est du code de qualité mais pas très bon marché. Et le support
technique de Roguewave en France laisse à désirer au moins pour certains
produits comme Objective Views. Le code source est fourni.

4. Dans un ancien programme MFC que j'avais très mal fait, j'avais
un problème de scintillement... Je sais pas d'où ça vient en même
temps je veux pas trop regarder le code qui est mal foutu...



Pour éviter le scintillement, effectuez toutes les manipulations
graphiques sur un DC en mémoire (MemoryDC) puis procédez à l'affichage en
une passe en copiant le MemoryDC sur le DC réel. Vous y gagnerez également
en performance.



Je remercie avec un peu de retard, mais je me suis laissé le temps de faire
le programme avec ces conseils :)