Win Api : redessiner une fenêtre

Résolu
Messages postés
33
Date d'inscription
dimanche 14 mai 2006
Statut
Membre
Dernière intervention
16 décembre 2006
-
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Membre
Dernière intervention
22 août 2010
-
Bonjour déjà

Bon voilà mon problème et je seche depuis quelques heures dessus. Ce serait sympa de m'aider .

Je fais un petit programme en API windows . J'ai dessiné une fenêtre, une image de fond, quelques boutons... J'aimerais pouvoir redessiner cette fenêtre quand je presse sur un bouton.

Les notifications des boutons sont testées dans "case WM_COMMAND" par une fonction de mon cru dans laquelle une structure de deux termes(  BOOL)  est mise à jour et qui est retournée par cette fonction..... ok ? ( En fait leurs valeurs sont inversée. )

J'ai vérifié, sous WM_COMMAND la structure est bien modifiée en passant pas la fonction en question.
Alors j' utilise la fonction InvalidateRect comme ceci pour forcer le message WM_PAINT.

if (temoins.liste) InvalidateRect(hwnd, 0, TRUE);

Passons au code de case WM_PAINT :

 case WM_PAINT:
            {
                HDC hdc =NULL;
                PAINTSTRUCT ps;
                hdc = BeginPaint(hwnd,&ps);
                if(temoins.couv) dessinerCouverture (hwnd,hdc,ps, "Carnet                                              d'adresses",hBouton); // la fonction
                if(temoins.liste) exit(0);  //pour voir si ça passe ...et non ! :(
                EndPaint(hwnd, &ps);
                return 0;
            }
        return 0;
Comme vous l'avez compris,  ma fenêtre ne se ferme pas quand temoins.liste =TRUE. Pourquoi ??
J'aimerais bien pouvoir dessiner ma fenêtre avec une autre fonction quand temoins.liste =TRUE.

Merci pour votre réponse.

45 réponses

Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Membre
Dernière intervention
22 août 2010
10
Erreur bête qu'on aurait jamais trouvée sans que tu donne tout le code.
Dans la fonction Procedure, tu as la ligne temoins.liste=FALSE; qui est exécutée à chaque fois que la fonction est appelée. Donc à chaque Wm_PAINT (entre autre), temoins.liste est mis a FALSE. Normal donc que la fenêtre ne se ferme pas

_____________________________________
Un éditeur de ressources gratuit pour Windows
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Membre
Dernière intervention
22 août 2010
10
Tu le fais dans le WM_CREATE par exemple.
temoins est a mettre en static.

Tu peux aussi faire ca:
TEMOINS temoins={TRUE};
ce qui va mettre couv a TRUE et liste à FALSE

_____________________________________
Un éditeur de ressources gratuit pour Windows
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Membre
Dernière intervention
22 août 2010
10
if (temoins.liste)
{
  InvalidateRect(hwnd, 0, TRUE);
  UpdateWindow(hwnd);
}

Comme ca tu es sur que la valeur de temoins.liste ne changera pas entre temps

_____________________________________
Un éditeur de ressources gratuit pour Windows
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
13
Salut,
Comment est déclarée ta structure? en global ou en static dans la procédure de la fenêtre?
Messages postés
33
Date d'inscription
dimanche 14 mai 2006
Statut
Membre
Dernière intervention
16 décembre 2006

Je viens d'essayer ta solution mais la fenêtre reste ouverte .
Bon ça m'évite déjà de prendre le risque que le message change effectivement.

Voici ma fonction au cazou...

TEMOINS messagesBoutonsCouv( HWND hwnd,HWND *hBouton, UINT uMsg ,
                            WPARAM wParam, LPARAM lParam, TEMOINS temoins)
{
      static long i=0,j=0;
        for(i=0;i<27;i++)
           {
            if(HIWORD(wParam)== BN_CLICKED)
            {
              if(lParam== (LPARAM)hBouton[i])
               {
                   for(j=0;j<27;j++) {DestroyWindow(hBouton[j]); }
                   //les boutons s'effacent pour ça pas de problème
                   temoins.couv=FALSE;
                   temoins.liste=TRUE;
               }
            }
           }
           return temoins;
  }
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Membre
Dernière intervention
22 août 2010
10
La structure TEMOINS est passée par valeur, donc les changement sont pas pris en compte dans la fonction originale. Passe un pointeur de la structure, ou mets la en variable globale

_____________________________________
Un éditeur de ressources gratuit pour Windows
Messages postés
33
Date d'inscription
dimanche 14 mai 2006
Statut
Membre
Dernière intervention
16 décembre 2006

La structure est  en static et ça marche pas ...
Messages postés
33
Date d'inscription
dimanche 14 mai 2006
Statut
Membre
Dernière intervention
16 décembre 2006

Je vais esayer mais ça va me prendre un peu de temps... moi les pointeurs j'aime pas ça lol et le variables globales j'essaie d'éviter...

à plus pour les nouvelles :!

et surtout merci pour vos réponses... c'est hyper rapide !
Messages postés
33
Date d'inscription
dimanche 14 mai 2006
Statut
Membre
Dernière intervention
16 décembre 2006

J'ai essayé en globale et en pointeur et ni l'un ni l'autre ne fonctionnent !!
Quel casse tête !
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Membre
Dernière intervention
22 août 2010
10
void messagesBoutonsCouv( HWND hwnd,HWND *hBouton, UINT uMsg ,
                            WPARAM wParam, LPARAM lParam, TEMOINS* temoins)
{
  remplacer tous les temoins. par des temoins->
  rien a retourner
}

Mais j'ai un doute, je vois que ta fonction retourne une structure TEMOINS donc si tu l'affectais à la variable d'origine, ce devrait peut être marcher. Par contre utiliser un pointeur est plus performant

_____________________________________
Un éditeur de ressources gratuit pour Windows
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
13
Pour les variables globales, on doit les éviter tant que possible. Les pointeurs sont au contraire indispensables en programmation C/C++. Ta fonction messagesBoutonsCouv() prend un pointeur comme 2ème paramètre.
Tu sais ce n'est pas toujours facile de trouver une erreur à partir d'un morceau de code. Il faut voir la totalité du code si c'est possible.
Messages postés
33
Date d'inscription
dimanche 14 mai 2006
Statut
Membre
Dernière intervention
16 décembre 2006

Oui oui je sais que les pointeurs sont indispensables... ça commence à venir mais c'est pas tjrs évident.... j'ai peut être ré^pondu un peu vite tout à l'heure, je reprends mon code ..(avec les pointeurs ) à++
et encore merci !
Messages postés
33
Date d'inscription
dimanche 14 mai 2006
Statut
Membre
Dernière intervention
16 décembre 2006

Bon désolée mais ça ne marche pas...
J'ai bien transformé le code pour utiliser les pointeurs.

Le message WM_COMMAND :

     case WM_COMMAND:
            //Traiter les messages du menu
            messagesMenu (hwnd, hBouton,WM_COMMAND, wParam,lParam);
            //Traiter les messages des boutons des lettres de la couverture
            messagesBoutonsCouv (hwnd, hBouton,WM_COMMAND, wParam,lParam,&temoins);
             if (temoins.liste)
                    {
                      InvalidateRect(hwnd, 0, TRUE);
                      UpdateWindow(hwnd);
                     // exit(0); // ici la fenêtre se ferme pour TRUE
                    }
        return 0;

Le message WM_PAINT :
        case WM_PAINT:
            {
                   HDC hdc = NULL;
                PAINTSTRUCT ps;
                hdc = BeginPaint(hwnd,&ps);
                if(temoins.couv) dessinerCouverture (hwnd,hdc,ps,
                                    "Carnet d'adresses",hBouton);
                if(temoins.liste) exit(0); // ça ne marche pas !
                EndPaint(hwnd, &ps);
            }
        return 0;

La fonction concernée  :
void messagesBoutonsCouv( HWND hwnd,HWND *hBouton, UINT uMsg ,
                            WPARAM wParam, LPARAM lParam, TEMOINS* temoins)
{
      static long i =0,j=0;
        for(i=0;i<27;i++)
           {
            if(HIWORD(wParam)== BN_CLICKED)
            {
              if(lParam== (LPARAM)hBouton[i])
               {
                   for(j=0;j<27;j++) {DestroyWindow(hBouton[j]); }
                   //les boutons s'effacent pour ça pas de problème
                   temoins->couv=FALSE;
                   temoins->liste=TRUE;
               }
            }
           }
}
Voilà je pense que tout y est. J'ai déclaré la structure une fois en static une fois sans rien... ça ne change pas.
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Membre
Dernière intervention
22 août 2010
10
Je ne vois aucune erreur, le problème se situe peut être ailleurs. Comme le dit racpp, un code complet sera plus utile (avec le debugger on trouve l'erreur en deux minutes)

_____________________________________
Un éditeur de ressources gratuit pour Windows
Messages postés
33
Date d'inscription
dimanche 14 mai 2006
Statut
Membre
Dernière intervention
16 décembre 2006

Je l'envoie ? ... et comment ?
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Membre
Dernière intervention
22 août 2010
10
Tu peux coller le code ici, ou bien mettre un lien vers l'endroit de ton choix (http://www.nomorepasting.com/paste.php par exemple)

_____________________________________
Un éditeur de ressources gratuit pour Windows
Messages postés
33
Date d'inscription
dimanche 14 mai 2006
Statut
Membre
Dernière intervention
16 décembre 2006

http://mapage.noos.fr/site1/carnet.rar



Voilà ce n'est que le code, je n'ai pas mis les images !
Messages postés
33
Date d'inscription
dimanche 14 mai 2006
Statut
Membre
Dernière intervention
16 décembre 2006

J'vaoue il y a pas mal de globales ...parce que j'aimerais les mettre plus tard dans un fichier de configuration....
Je vais essayer de changer ça plus tard !
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Membre
Dernière intervention
22 août 2010
10
Autre chose, j'ai vu une chose bizarre dans ton code:
MessageBox(hwnd,(LPCWSTR)"Ce fichier n'existe pas !  ", (LPCWSTR)"Attention !", MB_ICONWARNING|MB_OK);

Si tu pense faire de l'unicode avec ca, tu te trompes. Si tu veux le faire (en l'occurence ca ne sert a rien puisque ca marche en ANSI), voila comme il faut faire:
MessageBoxW(hwnd,L"Ce fichier n'existe pas !  ", L"Attention !", MB_ICONWARNING|MB_OK);
Les chaines unicode sont à précéder d'un L, ne par caster directement en WCHAR*

_____________________________________
Un éditeur de ressources gratuit pour Windows
Messages postés
33
Date d'inscription
dimanche 14 mai 2006
Statut
Membre
Dernière intervention
16 décembre 2006

Ah ! ok, je me demandais justement si le programme passait toujours par là ?

Mais je fais comment pour mettre  temoins.couv  à  TRUE et temoins.liste à FALSE au début ?