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

C++ Discussion :

[Windows 11] Fenêtre impossible à détruire ? Problème de rafraichissement ?


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    208
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 208
    Par défaut [Windows 11] Fenêtre impossible à détruire ? Problème de rafraichissement ?
    Bonjour à tous,

    Nostalgique du temps où il était possible d'avoir du contenu HTML en fond d'écran du bureau Windows, je cherche à reproduire ce comportement en créant une application affichant une fenêtre entre le fond d'écran et les icônes du bureau.
    Je programme en C++ (bon sang, bien 15 ans que j'y ai pas touché 🤪 ) sous Windows 11 avec Visual Studio Code.

    Pour créer cette fenêtre, j'utilise cette technique de ninja : https://www.codeproject.com/Articles...n-Windows-plus.
    Le handle retourné (wallpaper_hwnd) sert de parent à la fenêtre de mon application, créée grâce à la ligne suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    HWND hwnd = CreateWindowEx( 0, CLASS_NAME, L"Ma fenêtre",  WS_CHILD | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, wallpaper_hwnd, NULL, hInstance, NULL );
    J'ai aussi ajouté une icône dans la zone de notification avec un menu me permettant de quitter l'appli.
    Lorsque je clique sur 'Quitter', j'appelle la fermeture de ma fenêtre grâce au message suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PostMessage(hwnd, WM_CLOSE, 0, 0);
    La réception du message de fermeture 'WM_CLOSE' entraine l'exécution du code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    case WM_CLOSE:
    {
        WriteToLog(L"Fenêtre en train de se fermer.");
        BOOL windowDestroyed = DestroyWindow(hwnd);
        if (windowDestroyed) {
            WriteToLog(L"\tFenêtre enfant correctement détruite");
        } else {
            WriteToLog(L"\tFenêtre enfant non détruite");
        }
        break;
    }
    Puis l'on passe dans le code lors de la réception du message de destruction de la fenêtre 'WM_DESTROY' :

    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
    case WM_DESTROY:
    {
        WriteToLog(L"Je suis dans Destroy de la fenêtre fille");
     
        // Supprimer l'icône de la zone de notification
        Shell_NotifyIcon(NIM_DELETE, &g_nid);
     
        // Détruire et libérer la fenêtre parente wallpaper_hwnd si elle existe
        HWND wallpaper_hwnd = GetParent(hwnd);
        if (wallpaper_hwnd != NULL)
        {
            WriteToLog(L"J'ai trouvé une fenêtre parente, je cherche à la détruire");
            BOOL wallPaperDestroyed = DestroyWindow(wallpaper_hwnd);
            if (wallPaperDestroyed) {
                WriteToLog(L"\tFenêtre parente correctement détruite");
            } else {
                WriteToLog(L"\tFenêtre parente non détruite");
            }
        }
     
        // Changer la couleur de fond de la fenêtre
        HBRUSH hbrBackground = CreateSolidBrush(RGB(255, 0, 0)); // Rouge
        SetClassLongPtr(hwnd, GCLP_HBRBACKGROUND, (LONG_PTR)hbrBackground);
     
        // Forcer le rafraichissement de la fenêtre enfant
        InvalidateRect(hwnd, NULL, TRUE);
     
        // Forcer le rafraichissement de la fenêtre parent
        InvalidateRect(wallpaper_hwnd, NULL, TRUE);
     
        PostQuitMessage(0);
        break;
    }
    Et c'est là que le bas blesse.
    Le retour dans le terminal m'indique que mon application c'est quittée normalement, mais je vois toujours un carré blanc dégueulasse entre mon fond d'écran et les icônes du bureau.
    Les retours dans le fichier de log m'indiquent :

    • Que 'Fenêtre parente non détruite'. Je m'y attendais, c'est 'ProgMan' qui la créé je ne dois pas pouvoir la détruire comme ça.
    • Que 'Fenêtre enfant correctement détruite'.

    La tentative de changement de couleur du fond de la fenêtre enfant dans 'WM_DESTROY' échoue, alors qu'il fonctionne avant la réception du message de fermeture de la fenêtre 'WM_CLOSE'.
    Est-ce là une preuve supplémentaire que ma fenêtre fille est bien détruite ?

    Est-ce un problème de rafraichissement de la fenêtre parent ?
    Une piste pour me permettre de me retrouver avec un espace tout propre et tout vide entre mon arrière plan de bureau et mes icônes ?

    Merci d'avance 😙

  2. #2
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 446
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 446
    Par défaut
    Je comprends pas trop la logique de votre programme.

    Vous créez une fenêtre selon un procédé (SendMessage vers un autre "applicatif"), alors pourquoi tenté de la détruire via un "DestroyWindow" bien sale ?
    Espionnez encore un peu, via Spy++, pour voir comment l'application de changement de fond d'écran fait le taf et faites pareil.

    Est-ce là une preuve supplémentaire que ma fenêtre fille est bien détruite ?
    Pas forcément, mais comme vous testez la valeur de retour de "DestroyWindow" ligne 4 du code "case WM_CLOSE:", pourquoi en douter ?
    Testez systématiquement les valeurs de retour et utiliser GetLastError pour avoir des explications aux éventuelles problèmes (quitte à utiliser des MACRO type SUCCEEDED)

    Avec 1 ou 2 copies d'écran, ça serait plus explicite pour nous.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    208
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 208
    Par défaut
    Bonjour bacelar et merci pour cette réponse,

    Citation Envoyé par bacelar Voir le message
    Espionnez encore un peu, via Spy++, pour voir comment l'application de changement de fond d'écran fait le taf et faites pareil...
    Il semblerait que Spy++ ne soit pas pris en compte par Visual Studio Code.

    Citation Envoyé par bacelar Voir le message
    pourquoi tenté de la détruire via un "DestroyWindow" bien sale ?
    Tout est dit : c'est une tentative bien sale, non fonctionnelle, pour résoudre mon problème.
    Ça ne coûtait pas bien cher de tenter.

    Après avoir relu attentivement le tuto originel posté plus haut, j'ai remarqué ceci :

    Note: Everything you draw onto this layer will stay there until you paint over it, invalidate it, or reset your wallpaper.
    J'ai donc récupéré le chemin vers l'image utilisé comme arrière plan en début de mon application grâce à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    WCHAR wallpaperPath[MAX_PATH];
    SystemParametersInfo(SPI_GETDESKWALLPAPER, MAX_PATH, wallpaperPath, 0);
    Et je remets cette image en tant que fond d'écran avant de quitter l'application :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, wallpaperPath, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
    Je ne sais pas si c'est le plus propre, mais ça fonctionne 🤷
    J'ai tenté de rafraichir la fenêtre parente grâce à InvalidateRect et UpdateWindow après la destruction de la fenêtre fille, sans succès.

  4. #4
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 750
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 750
    Par défaut
    Citation Envoyé par themoye Voir le message
    J'ai tenté de rafraichir la fenêtre parente grâce à InvalidateRect et UpdateWindow après la destruction de la fenêtre fille, sans succès.
    Après on parle d'1 API qui a 30 ans (1992) et qui a été supplantée/ surcouchée plusieurs fois (MFC > WTL > WinForms > WPF, UWP) et donc il y a eu beaucoup de changements

    Mais il me semble que c'est normal ces 2 fonctions ne doivent pas être appelées directement (elles sont appelés en interne) et il me semble (et en lisant la documentation), il faut envoyer 1 message WM_PAINT.
    Après si tu veux forcer (en regardant vite fait sur Internet), il faut utiliser la fonction RedrawWindow (<- lien vers MSDN)


    Édit: on m'a mis -1 alors que personne ne peut expliquer pourquoi InvalidateRect et UpdateWindow ne fonctionnent pas.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    208
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 208
    Par défaut
    Hello foetus !

    Citation Envoyé par foetus Voir le message
    Ces 2 fonctions ne doivent pas être appelées directement (elles sont appelés en interne) et il me semble (et en lisant la documentation), il faut envoyer 1 message WM_PAINT.
    Ce n'est pas l'inverse ? 🤔
    Si je fais le test sur une fenêtre que j'ai créé, un appel à 'UpdateWindow' envoi le message 'WM_PAINT'.
    De la même manière qu'un appel à 'DestroyWindow' envoi le message 'WM_DESTROY' etc

  6. #6
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 750
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 750
    Par défaut
    Citation Envoyé par themoye Voir le message
    Ce n'est pas l'inverse ? 🤔
    Voici 1 commentaire sur stackoverflow qui reprend la documentation
    InvalidateRect() merely marks a window for repainting. The window is not actually repainted by the OS until the parent thread's message queue, or an explicit call to UpdateWindow() or RedrawWindow(), generates a new WM_PAINT to paint the window. At which time, anything that was on the window gets erased and redrawn. This is basic Win32 GDI stuff
    Donc voila, le fonctionnement est assez simple. Mais il y a 1 histoire de file de messages qui fait que ta fenêtre ignore "tes messages" tant qu'on ne lui pas dit de les traiter (en l'occurrence réception d'1 message WM_PAINT)


    Édit: Après il y a peut-être d'autres messages que WM_PAINT, comme WM_ERASEBKGND.
    Et ensuite, c'est peut-être 1 ""paramètrage"" du clipping fenêtre fille/ fenêtre mère J'ai vu cela sur stackoverflow:
    You can prevent redraw of child windows by setting WS_CLIPCHILDREN to parent window, or by invalidating redraw with the use of RedrawWindow function with RDW_NOCHILDREN flag

  7. #7
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 446
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 446
    Par défaut
    Il semblerait que Spy++ ne soit pas pris en compte par Visual Studio Code.
    Visual Studio Code, c'est, au départ une version très light de Visual Studio.
    Visual Studio est gratuit pour les hobbyistes, les petites structures et les projets OpenSource.

    Donc, à moins d'avoir des problèmes sur la quantité de données à télécharger et à stocker sur les HD, installer Visual Studio n'a pas trop d'inconvénients.
    Récupérer un Spy++ isolé n'est pas impossible, mais à quoi bon ? (à part les dizaines de Giga du pestio : VS, parce que Spy++, ça doit faire dans les quelques dizaines ou centaines de ko)

    Ça ne coûtait pas bien cher de tenter.
    Comme de télécharger Visual Studio.

    Je ne sais pas si c'est le plus propre, mais ça fonctionne 🤷
    Je trouve même votre solution assez élégante.
    Mais un petit espionnage pour voir comment les cocos de M$ ont implémenté la chose, via Spy++, permettrait de voir s'il y a des cas qu'on n'a pas pris en compte.

    J'ai tenté de rafraichir la fenêtre parente grâce à InvalidateRect et UpdateWindow après la destruction de la fenêtre fille, sans succès.
    On est clairement pas dans le cas "standard" de ce type d'API, car ces fenêtres n'ont pas été créées par le thread qui utilise l'API.
    Les valeurs de retour devrait indiquer ce "petit" problème.
    Mantra n°1 d'un utilisateur d'une API C : "TOUJOURS vérifier les valeurs de retour, TOUJOURS".

    Même si les valeurs de retours "sont bonnes", il faut bien voir que la gestion de l'affichage est asynchrone et que seul le thread créateur de la fenêtre a, par défaut, un accès "directe" avec les structures de la fenêtre (via les API Kernel).
    S'il y a un dialogue avec le processus "Progman" à suivre, Spy++ sera ton ami.

    Après on parle d'1 API qui a 30 ans (1992) et qui a été supplantée/ surcouchée plusieurs fois (MFC > WTL > WinForms > WPF, UWP) et donc il y a eu beaucoup de changements
    @foetus, heu, je crois que tu t'es gouré.
    1992, c'est la sortie de la technologie NT, et ces API C des enfers, elles existaient bien avant ; en tout cas on les avait déjà sous Win3.
    Et ces API n'ont pas été "supplantées" depuis, elles ont bien été "carrossées" avec des trucs bien plus ergonomiques, je te l'accorde.
    Mais la seul API que support le sous-système "window" de Windows, c'est Win32, donc ces "cochonneries" à base de "InvalidateRect et UpdateWindow".
    Et là, clairement, le cas d'utilisation de @themoye explose les principes de conceptions des librairies graphiques que tu cites ; aucune n'a été pensée pour dialoguer avec un autre programme "propriétaire" d'une fenêtre.
    Pour ce genre d’acrobaties visuelles, il faut plutôt regarder du côté des antiques DDE et autres COM/ActiveX.
    Mais c'est toujours des surcouches à Win16/Win32 et Spy++ ne permet d'espionner qu'à ce niveau "bas" : "Win16/Win32".

    Mais tes remarques, @foetus, sur les peaux de bananes que cachent ces API sont très pertinentes.

    Mais il me semble que c'est normal ces 2 fonctions ne doivent pas être appelées directement (elles sont appelés en interne)
    Interne à quoi ?
    Oui, si on utilise les APIs/librairies graphiques que tu as mentionné, c'est à elles, normalement de se démerder avec tous ces bidules.
    Mais quand on fait de l'API "bas niveau", c'est au programmeur de faire "correctement" tourner le machin, "InvalidateRect et UpdateWindow" compris.

    Mais je le répète, je trouve la solution de @themoye particulièrement simple et élégante. A moins d'effet de bord non prévues, je pense qu'elle fait très bien le taf.

    Ce n'est pas l'inverse ? 🤔
    Oulà, vous êtes prêt pour un voyage sous Doliprane ?
    WM_PAINT, c'est un message "bouchon", qui n'est lu que si c'est le seul et dernier de la file (c'est un espèce de bouchon à la surface de la file de message, qu'on écoperait pas le fond de la colonne).
    Faire un "UpdateWindow" sur une fenêtre créée par le thread appelant l'API fait apparaître un WM_PAINT dans la file du thread, oui, mais dans le cas où la fenêtre n'a pas été créée par le thread, je suis nettement plus dubitatif.
    Si c'est bien le thread créateur de la fenêtre (donc dans le processus "Progman") qui reçoit le WM_PAINT, encore faut-il qu'il pompe et qu'il atteigne la fin de la file de message pour qu'il le traite "correctement" (gestion de fenêtre filles, etc...).

    De la même manière qu'un appel à 'DestroyWindow' envoi le message 'WM_DESTROY' etc
    Même si WM_DESTROY n'est pas un message "bouchon", je ne suis pas sûr que l’enchaînement soit si simple dans le cas d'un thread demandant non créateur de la susdite fenêtre.

    Édit: Après il y a peut-être d'autres messages que WM_PAINT, comme WM_ERASEBKGND.
    Si, bien sûr, et bien d'autres, d'où mon insistance sur le fait de faire une petite session d'espionnage avec Spy++.

    Ici, on est largement en dehors du périmètre habituel de ces API et donc l'utilisation d'autres appels pour compenser des effets de bord est assez probable.

  8. #8
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 750
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 750
    Par défaut
    Citation Envoyé par bacelar Voir le message
    Interne à quoi ?
    Ma dernière expérience (2014-2017), c'était avec la VCL (Embarcadero Xe 10), autre surcouche objet C++/ Delphi.
    Donc pas forcément précis

    Mais ce que je voulais dire c'est que la WinApi impose 1 ""cadre"" pour surcharger tel message, telle action.
    L'exemple typique c'est le BeginPaint/ EndPaint qu'on doit utiliser dans la surcharge du message WM_PAINT

    Donc voilà, la documentation est exhaustive mais ne dit pas le où le dev doit appeler les fonctions. Par exemple:
    *) SendMessage, PostMessage et RedrawWindow n'ont pas vocation à être appelées dans 1 surcharge de message
    *) à contrario InvalidateRect, UpdateRect, BeginPaint/ EndPaint ont vocation d'être en *interne* dans la surcharge des messages ou autres, et des fois des messages précis (comme le WM_PAINT)

    Et c'est pour cela qu'il faut te farder des bouquins sur les arcanes de la WinApi pour comprendre les ""diagramme séquences""
    Avec la VCL je m'étais penché sur la gestion clavier

    Donc voilà je me méfie, mais je n'ai pas vu sur Internet que InvalidateRect doit être obligatoirement utiliser dans la surcharge du message WM_PAINT


    Citation Envoyé par bacelar Voir le message
    1992, c'est la sortie de la technologie NT
    Je n'ai pas été précis sur la date (et je n'avais pas vérifié) mais pour le développeur c'est la différence entre le paléothique et la préhistoire
    Et en lisant ta réponse, dans la WinApi il manque : les threads, l'Unicode (USC-2 à l'époque si je dis pas de bêtises)

  9. #9
    CGi
    CGi est déconnecté
    Expert confirmé
    Avatar de CGi
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 061
    Détails du profil
    Informations personnelles :
    Localisation : France, Allier (Auvergne)

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 061
    Par défaut
    Sans entrer dans les détails, InvalidateRect est probablement une des fonctions les plus utilisée pour demander de redessiner une zone client (ou partie d'une zone client) d'une fenêtre. Elle rend invalide la zone, quand une zone est invalide, le systeme va poster un message WM_PAINT dans la file d'attente. Donc mettre cette fonction dans le traitement d'un message WM_PAINT provoquerait une boucle sans fin.
    Site : http://chgi.developpez.com

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

  10. #10
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 446
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 446
    Par défaut
    c'est la différence entre le paléothique et la préhistoire
    Ayant connu DOS, je suis bien un tricératops du Crétacé de l'informatique.

    Et en lisant ta réponse, dans la WinApi il manque : les threads, l'Unicode (USC-2 à l'époque si je dis pas de bêtises)
    On parle de quelle WinApi ?
    Win16, elle n'a pas de thread car on est dans un conteste multitâche "coopératif" et non préemptif, donc on utilise des "fibres" et pas des threads.
    Pour Win32, c'est la faite à la saucisse des versions et les threads font leur apparition dans la première version (WinNT3.5 ou Win95).
    Pour USC-2, ça n'existait pas (=>MBSM), c'est compliqué pour des raisons de rétrocompatibilité.

    @CGi, tout à fait !!!

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    208
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 208
    Par défaut
    Par Saint Sylvain Durif, je n'ai pas vu toutes ces nouvelles réponses 😱😱
    On ne reçoit plus de mail lorsque le sujet est passé en Résolu ?

    Un grand merci à vous, bacelar et foetus pour vos explications supplémentaires !

    Comme de télécharger Visual Studio.
    J'ai craqué, j'ai depuis installé Visual Studio.
    Obligé, il semblerait qu'on ne puisse pas utiliser WebView2 dans VS Code.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Citation Envoyé par CGi Voir le message
    Sans entrer dans les détails, InvalidateRect est probablement une des fonctions les plus utilisée pour demander de redessiner une zone client (ou partie d'une zone client) d'une fenêtre. Elle rend invalide la zone, quand une zone est invalide, le systeme va poster un message WM_PAINT dans la file d'attente. Donc mettre cette fonction dans le traitement d'un message WM_PAINT provoquerait une boucle sans fin.
    Une boucle sans fin, mais qui a la décence de rendre le processeur entre chaque itération (et s'interrompre si la fenêtre est réduite).
    Cela peut être utile dans certains cas où l'on veut un affichage mis à jour "aussi souvent que possible" mais en temps normal on n'a pas besoin de ça et/ou on peut trouver de meilleures façons de le faire.
    (et en plus, cela bloque aussi les messages WM_TIMER qui sont encore plus "bouchon" que WM_PAINT)
    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.

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

Discussions similaires

  1. Problème de rafraichissement de ma fenêtre
    Par kafiristanica dans le forum AWT/Swing
    Réponses: 2
    Dernier message: 13/05/2012, 16h17
  2. Fenêtre noire, problème de rafraichissement.
    Par Froyok dans le forum Ogre
    Réponses: 6
    Dernier message: 12/10/2009, 20h26
  3. Réponses: 16
    Dernier message: 18/03/2007, 13h30
  4. [JTree]problème de rafraichissement
    Par peppena dans le forum Composants
    Réponses: 9
    Dernier message: 20/01/2004, 14h06
  5. Toujours un problème de rafraichissement de DBGrid
    Par tripper.dim dans le forum C++Builder
    Réponses: 4
    Dernier message: 09/12/2002, 13h15

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