Précédent   Forum des professionnels en informatique > Général Développement > Programmation système > Windows
Windows Forum d'entraide sur la programmation Windows. Tutoriel API Windows
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 07/01/2012, 17h48   #1
Invité de passage
 
Homme jean-luc GIORGETTA
Inscription : avril 2011
Messages : 7
Détails du profil
Informations personnelles :
Nom : Homme jean-luc GIORGETTA
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : avril 2011
Messages : 7
Points : 0
Points : 0
Par défaut créer une zone graphique dans une fenetre

Bonjour,
Je fais du dessin avec l'API sur la zone client de ma fenetre principale, occupée partiellement par des toolbars en partie haute de la zc. Je souhaite limiter la zone de dessin à un rectangle, pas de pb pour la souris, je fais un test avec PtInRect pour interdire le dessin ailleurs, mais par exemple un cercle déborde de ce rectangle. J'ai essayé une fenetre child "static", ça dessine mais ça buggue à mort au resize au bout d'un moment (apparemment le "static" gère mal les messages). J'ai testé avec une "clipping region" rectangulaire...ça clippe toute la fenetre y compris les menus! Au final quel type de child utiliser pour le dédier uniquement au dessin? (l'équivalent d'un PaintBox en Delphi par ex). Faut-il sous-classer obligatoirement?
Merci d'avance
jlg75 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2012, 18h31   #2
Membre confirmé
 
Inscription : décembre 2010
Messages : 99
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 99
Points : 203
Points : 203
Si ton message concerne Win32, perso, moi je creerais une classe de fenetre a moi, (probablement avec un attribut CS_SAVEBITS pour eviter d'avoir a redessiner a chaque fois, mais a voir), et je creerais une instance de cette classe en child de la fenetre principale.

Si tu dessines directement dans la fenetre principale en faisant un GetDC() sur le handle de la fenetre, fatalement, tu vas perturber les elements qui se trouvent deja a l'interieur, comme les autres boutons, ou bien c'est eux qui vont perturber ta zone de dessin.
phi1981 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 07/01/2012, 18h49   #3
Invité de passage
 
Homme jean-luc GIORGETTA
Inscription : avril 2011
Messages : 7
Détails du profil
Informations personnelles :
Nom : Homme jean-luc GIORGETTA
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : avril 2011
Messages : 7
Points : 0
Points : 0
Ok merci, je vais créer une classe spéciale. Mais je suppose qu'il faut attacher à cette fenetre un WndProc spécial différent de celui de la fenetre principale? (ce qu'on appelle ss-classement??). Il devra contenir le switch de traitement des messages souris (entre autre) je suppose?
jlg75 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2012, 20h00   #4
Membre confirmé
 
Inscription : décembre 2010
Messages : 99
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 99
Points : 203
Points : 203
Chaque classe de fenetre a un WndProc, generalement distinct.

Mais un ss-classement consiste a remplacer la wndproc d'une fenetre par une autre wndproc DURANT SON EXISTANCE (technique qui permet de modifier le comportement d'une fenetre ou d'un controle sans necessairement modifier son code source). La fonction generalement utilisee pour ca c'est SetWindowLong (via le selecteur GWL_WNDPROC ou qqchose comme ca).

Le cas present il ne s'agit donc pas d'un sous-classement, simplement de la definition d'une nouvelle classe (donc via RegisterClass). L'avantage, c'est que si demain tu le souhaites, tu peux reutiliser ta classe "ZoneDeDessin" dans une autre fenetre sans rien modifier a ton code.
phi1981 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 09/01/2012, 20h03   #5
Invité de passage
 
Homme jean-luc GIORGETTA
Inscription : avril 2011
Messages : 7
Détails du profil
Informations personnelles :
Nom : Homme jean-luc GIORGETTA
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : avril 2011
Messages : 7
Points : 0
Points : 0
Par défaut fenetre graphique

J'ai modifié le code avec une classe de fenetre CHILD dédiée au dessin, ça a l'air de fonctionner correctement. Les WndProc respectifs traitent les fonctions générales (MainWinProc), l'autre les fonctions de tracé pur sur le DC (GraphWinProc). Par contre j'ai du passer pas mal de variables en "global" pour pouvoir faire dialoguer les 2 WndProc (par exemple mémoriser le curseur en cours, la commande active, le facteur de zoom, les pointeurs sur les LIST stockant les objets graphiques...etc). Peut-on faire autrement ? Si j'en crois les règles de "bonne prog" il faut éviter les variables globales...
jlg75 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/01/2012, 08h25   #6
Membre confirmé
 
Inscription : décembre 2010
Messages : 99
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 99
Points : 203
Points : 203
Tu peux utiliser le champ cbWndExtra de la structure WNDCLASS pour demander à Windows d'allouer un certain nombre d'octets (qu'il initialisera à 0) associés à chaque fenêtre de cette classe.
Ensuite, tu peux utiliser GetWindowLong et SetWindowLong pour récupérer/modifier ces octets.
Rien ne t'empeche d'y stocker un pointeur vers une structure qui contiendra les données que tu associes à ta fenêtre. Il faut juste penser à allouer cette structure au moment du WM_CREATE et à libérer l'espace au moment du WM_DESTROY.
Cette technique te permet d'éviter que ta classe de fenêtre n'utilise des globales, ce qui serait très ennuyeux pour sa réutilisabilité : imagine l'horreur si tu voulais avoir deux zones de dessin en même temps dans ton programme ? pire : deux zones de dessin dans deux modes différents ?
phi1981 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/01/2012, 11h48   #7
Invité de passage
 
Homme jean-luc GIORGETTA
Inscription : avril 2011
Messages : 7
Détails du profil
Informations personnelles :
Nom : Homme jean-luc GIORGETTA
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : avril 2011
Messages : 7
Points : 0
Points : 0
Merci beaucoup pour tous ces conseils, cela me permet d'utiliser les bonnes méthodes et d'éviter de galérer. Je fais de la prog en amateur et je me familiarise peu à peu avec C++ et l'API Windows.
jlg75 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/01/2012, 10h26   #8
Expert Confirmé Sénior
 
Avatar de Médinoc
 
Homme
Développeur informatique
Inscription : septembre 2005
Messages : 21 481
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 28
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : septembre 2005
Messages : 21 481
Points : 28 760
Points : 28 760
Envoyer un message via MSN à Médinoc
L'autre moyen, c'est de juste mémoriser un pointeur de structure dans le slot GWLP_USERDATA.

Voir ceci pour un exemple d'utilisation (plus le lien sur SetWindowLongPtr()).
__________________
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone.
-- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Médinoc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/01/2012, 11h34   #9
Membre confirmé
 
Inscription : décembre 2010
Messages : 99
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 99
Points : 203
Points : 203
Citation:
Envoyé par Médinoc Voir le message
L'autre moyen, c'est de juste mémoriser un pointeur de structure dans le slot GWLP_USERDATA.

Voir ceci pour un exemple d'utilisation (plus le lien sur SetWindowLongPtr()).
Exact, de nos jours, c'est bien mieux d'utiliser le SetWindowLongPtr(). Je n'y pense jamais vu que je compile pour des machines archaiques.
phi1981 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/01/2012, 16h15   #10
Expert Confirmé Sénior
 
Avatar de Médinoc
 
Homme
Développeur informatique
Inscription : septembre 2005
Messages : 21 481
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 28
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : septembre 2005
Messages : 21 481
Points : 28 760
Points : 28 760
Envoyer un message via MSN à Médinoc
Et si on utilise un Visual Studio 2008 ou supérieur, on n'a pas besoin de macros bizarres pour utiliser SetWindowLongPtr() sans warning: Sans le mode hybride de VS 2005, on peut utiliser la fonction directement.

(À noter que le morceau de code pour en-tête que j'ai posté en tient compte).
__________________
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone.
-- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Médinoc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/01/2012, 16h53   #11
Invité de passage
 
Homme jean-luc GIORGETTA
Inscription : avril 2011
Messages : 7
Détails du profil
Informations personnelles :
Nom : Homme jean-luc GIORGETTA
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : avril 2011
Messages : 7
Points : 0
Points : 0
Par défaut traitement message clavier

Bonjour,

La gestion de la fenetre graphique fonctionne bien, mais je tombe sur un autre problème: le CHILD ne réagit pas aux messages clavier. Qd j'appuie sur "echap" je dois désactiver la toolBar graphique de la fenetre principale et simultanément effacer le tracé en cours. La fenetre principale récupère correctement le message mais le WinProc de la fenetre CHILD ne voit rien. Je n'ai pas trouvé de réponse sur MSDN. Je pense bêtement transferer le message par un SendMessage vers le CHILD, ou utiliser le fameux SetWindowLong. Cela ne me semble pas très élégant, y a-t-il une astuce simple?
jlg75 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/01/2012, 22h30   #12
Expert Confirmé Sénior
 
Avatar de Médinoc
 
Homme
Développeur informatique
Inscription : septembre 2005
Messages : 21 481
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 28
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : septembre 2005
Messages : 21 481
Points : 28 760
Points : 28 760
Envoyer un message via MSN à Médinoc
Je pense que c'est la fenêtre principale qui commande, donc pour moi ce serait à elle d'envoyer un message "efface-toi" au CHILD.
__________________
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone.
-- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Médinoc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/01/2012, 00h04   #13
Invité de passage
 
Homme jean-luc GIORGETTA
Inscription : avril 2011
Messages : 7
Détails du profil
Informations personnelles :
Nom : Homme jean-luc GIORGETTA
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : avril 2011
Messages : 7
Points : 0
Points : 0
J'ai fait un SetForegroundWindow(hwnd du CHILD), et là je récupère correctement le code clavier. J'agis sur la ToolBar avec un SendMessage. Voici le switch concerné dans le WndProc de la fenetre CHILD:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
case WM_CHAR:
            keyCode=wParam;
            switch (keyCode)
            {
             case 27:    //........ECHAP

                if (cmdActive==IDM_HELP)
                    {
                    cmdActive=cmdPreced;    // restaure la commande
                    SetCursor(hCurPrev);    // et le curseur en cours
                    break;
                    }
                SendMessage(hDrawBar, TB_CHECKBUTTON, cmdActive, (LPARAM) FALSE); // désactive le bouton de cmde actuel
                cmdActive=IDM_SELECT; // repasse en mode selection par défaut
                cmdName="Cmde=SELECTION";
                if (dynStart==true)
                    {
                    dynStart=false;
                    DynLine(hGraph, dynStart, clicPix, curPix); // efface le ruban en cours
                    }
                break;
            }
            break;
jlg75 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 08h49.


 
 
 
 
Partenaires

Hébergement Web