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 :

Contrôles statiques qui ne se rafraîchissent pas


Sujet :

Windows

  1. #1
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut Contrôles statiques qui ne se rafraîchissent pas
    Bonjour

    Dans le cadre d'une application graphique temps réel, j'ai développé une petite classe qui gère le rendu du moteur graphique dans un contrôle Win32 statique.

    Tout fonctionne à merveille, seulement voilà, si je crée plusieurs de ces contrôles seul le premier semble recevoir tous ses messages ; les autres ne reçoivent WM_PAINT que lorsque je déplace la fenêtre parent.

    Voici mon code.

    Création du contrôle statique contenant le rendu graphique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myHandle = CreateWindow("STATIC", NULL, Style | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, Left, Top, Width, Height, Parent, NULL, Instance, NULL);
    Subclassement du contrôle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myCallback = SetWindowLongPtr(myHandle, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&Win32Canvas::OnEvent));
    Interceptage de l'évènement WM_PAINT :

    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
    LRESULT CALLBACK Win32Canvas::OnEvent(HWND Handle, UINT Message, WPARAM WParam, LPARAM LParam)
    {
        switch (Message)
        {
            case WM_PAINT :
            {
                PAINTSTRUCT Paint;
                HDC Hdc = BeginPaint(Handle, &Paint);
    
                // ... rendu moteur graphique
    
                EndPaint(Handle, &Paint);
                InvalidateRect(Handle, NULL, true);
                return 0;
            }
        }
    
        return CallWindowProc(myCallback, Handle, Message, WParam, LParam);
    }
    Comme vous le voyez j'invalide mon contrôle après chaque rafraîchissement, ainsi il devrait se redessiner continuellement.

    Tout ceci fonctionne donc pour le premier contrôle créé, mais visiblement pas pour les suivants. Si je n'intercepte pas WM_PAINT pour le premier contrôle, alors le second se rafraîchit correctement cette fois. Comme si le fait de gérer le premier bloquait tous les suivants, ou quelque chose comme ça.

    Dernière précision : le reste du code ou la logique d'affichage ne sont pas mis en cause, car la même chose programmée avec wxWidgets ne souffre pas de ce problème.

    Une idée ?


  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Je pense que Windows rafraichit les contrôles dans un ordre précis, et qu'il se tient à cet ordre : "tant qu'un contrôle est invalide, on ne redessine pas les suivants".

    Pour contrer cela, tu devrais essayer en les invalidant tous (ou peut-être en invalidant la fenêtre mère) après avoir repeint le dernier...
    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.

  3. #3
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Merci pour la réponse.

    Pour contrer cela, tu devrais essayer en les invalidant tous (ou peut-être en invalidant la fenêtre mère) après avoir repeint le dernier...
    Aucun résultat avec l'une ou l'autre méthode

  4. #4
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Pour ceux qui voudraient bidouiller, voici un exemple complet minimal qui reproduit le problème :

    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    #include <stdio.h>
    #include <windows.h>
    
    LRESULT CALLBACK OnStaticEvent(HWND Handle, UINT Message, WPARAM WParam, LPARAM LParam)
    {
        LONG_PTR Callback;
        PAINTSTRUCT Paint;
        HDC Hdc;
        char DebugStr[255];
    
        Callback = GetWindowLongPtr(Handle, GWLP_USERDATA);
    
        if (Message == WM_PAINT)
        {
            Hdc = BeginPaint(Handle, &Paint);
            sprintf(DebugStr, "%d", GetTickCount());
            TextOut(Hdc, 10, 10, DebugStr, strlen(DebugStr));
            EndPaint(Handle, &Paint);
            InvalidateRect(Handle, NULL, true);
    
            return 0;
        }
    
        return CallWindowProc((WNDPROC)Callback, Handle, Message, WParam, LParam);
    }
    
    LRESULT CALLBACK OnEvent(HWND Handle, UINT Message, WPARAM WParam, LPARAM LParam)
    {
        if ((Message == WM_CLOSE) || ((Message == WM_KEYDOWN) && (LOWORD(WParam) == VK_ESCAPE)))
        {
            PostQuitMessage(0);
            return 0;
        }
    
        return DefWindowProc(Handle, Message, WParam, LParam);
    }
    
    INT WINAPI WinMain(HINSTANCE Instance, HINSTANCE, LPSTR, INT)
    {
        WNDCLASS WindowClass;
        MSG Message;
        HWND Window;
        HWND View1;
        HWND View2;
        LONG_PTR Callback1;
        LONG_PTR Callback2;
    
        WindowClass.style         = 0;
        WindowClass.lpfnWndProc   = &OnEvent;
        WindowClass.cbClsExtra    = 0;
        WindowClass.cbWndExtra    = 0;
        WindowClass.hInstance     = Instance;
        WindowClass.hIcon         = NULL;
        WindowClass.hCursor       = 0;
        WindowClass.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
        WindowClass.lpszMenuName  = NULL;
        WindowClass.lpszClassName = "App";
        RegisterClass(&WindowClass);
    
        Window = CreateWindow("App", "App", WS_SYSMENU | WS_VISIBLE, 0, 0, 800, 600, NULL, NULL, Instance, NULL);
    
        View1 = CreateWindow("STATIC", NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, 100, 100, 250, 400, Window, NULL, Instance, NULL);
        Callback1 = SetWindowLongPtr(View1, GWLP_WNDPROC, (LONG_PTR)&OnStaticEvent);
        SetWindowLongPtr(View1, GWLP_USERDATA, Callback1);
        UpdateWindow(View1);
    
        View2 = CreateWindow("STATIC", NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, 450, 100, 250, 400, Window, NULL, Instance, NULL);
        Callback2 = SetWindowLongPtr(View2, GWLP_WNDPROC, (LONG_PTR)&OnStaticEvent);
        SetWindowLongPtr(View2, GWLP_USERDATA, Callback2);
        UpdateWindow(View2);
    
        while (GetMessage(&Message, NULL, 0, 0))
        {
            TranslateMessage(&Message);
            DispatchMessage(&Message);
        }
    
        return EXIT_SUCCESS;
    }
    (il devrait compiler en C si je n'ai pas fait de bêtise)

  5. #5
    CGi
    CGi est déconnecté
    Expert éminent
    Avatar de CGi
    Inscrit en
    Mars 2002
    Messages
    1 030
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 1 030
    Points : 8 202
    Points
    8 202
    Par défaut
    En mettant un UpdateWindow dans traitement du message WM_PAINT
    de la fenêtre mère.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if (Message == WM_PAINT)
        {
           UpdateWindow(Handle);
           return 0;
        }
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  6. #6
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    En effet ça résoud le problème

    Merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 16/04/2010, 12h02
  2. Contrôle dynamique qui ne s'affiche pas
    Par gta126 dans le forum VB.NET
    Réponses: 2
    Dernier message: 01/11/2009, 11h05
  3. Contrôle qui ne s'affiche pas
    Par jason69 dans le forum AWT/Swing
    Réponses: 13
    Dernier message: 25/07/2007, 19h18
  4. [VB.NET]Contrôle qui ne s'affiche pas
    Par Bleuarff dans le forum Windows Forms
    Réponses: 4
    Dernier message: 23/08/2006, 20h07
  5. Réponses: 4
    Dernier message: 11/07/2006, 21h43

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