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

Windows Discussion :

créer une zone graphique dans une fenetre


Sujet :

Windows

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2011
    Messages : 22
    Points : 14
    Points
    14
    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

  2. #2
    Membre éclairé
    Inscrit en
    Décembre 2010
    Messages
    290
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 290
    Points : 719
    Points
    719
    Par défaut
    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.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2011
    Messages : 22
    Points : 14
    Points
    14
    Par défaut
    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?

  4. #4
    Membre éclairé
    Inscrit en
    Décembre 2010
    Messages
    290
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 290
    Points : 719
    Points
    719
    Par défaut
    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.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2011
    Messages : 22
    Points : 14
    Points
    14
    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...

  6. #6
    Membre éclairé
    Inscrit en
    Décembre 2010
    Messages
    290
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 290
    Points : 719
    Points
    719
    Par défaut
    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 ?

  7. #7
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2011
    Messages : 22
    Points : 14
    Points
    14
    Par défaut
    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.

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 581
    Points
    41 581
    Par défaut
    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()).

  9. #9
    Membre éclairé
    Inscrit en
    Décembre 2010
    Messages
    290
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 290
    Points : 719
    Points
    719
    Par défaut
    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.

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 581
    Points
    41 581
    Par défaut
    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).

  11. #11
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2011
    Messages : 22
    Points : 14
    Points
    14
    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?

  12. #12
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 581
    Points
    41 581
    Par défaut
    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.

  13. #13
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2011
    Messages : 22
    Points : 14
    Points
    14
    Par défaut
    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 : 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
    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;

Discussions similaires

  1. [XL-2003] Extraction d'une zone ovale d'une photo insérée dans une feuille
    Par bolide7 dans le forum Excel
    Réponses: 4
    Dernier message: 21/04/2011, 18h45
  2. Réponses: 3
    Dernier message: 07/04/2011, 14h38
  3. Réponses: 6
    Dernier message: 13/11/2009, 16h06
  4. Intégrer une zone cachée dans une zone de texte
    Par beegees dans le forum Balisage (X)HTML et validation W3C
    Réponses: 6
    Dernier message: 20/10/2008, 16h20
  5. Réponses: 3
    Dernier message: 29/06/2007, 15h29

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