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 :

Fermer la fenêtre ne stoppe pas le processus


Sujet :

Windows

  1. #1
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut Fermer la fenêtre ne stoppe pas le processus
    Salut !

    Je me mets un peu à la programmation Windows, que je trouve bien compliquée. (J'ai passé ma vie à programmer en C en mode console...)
    J'ai fait un petit code qui crée une fenêtre avec un menu. Lorsqu'on clique sur le menu, une seconde fenêtre s'ouvre. Le soucis, c'est qu'une fois les deux fenêtres fermées, le processus continue de tourner dans le vide (j'ai vérifié dans le gestionnaire de tâches). Comment cela se fait ?

    J'ai une seconde question : comment empêcher l'accès à la première fenêtre (menu ou autre) lorsque la seconde fenêtre s'ouvre ?

    Voici le code :
    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
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    #include <windows.h>
    #include <stdio.h>
    
    #define IDM_NOUVELLEFENETRE 101
    
    HINSTANCE hinst;
    
    LRESULT CALLBACK ProcedureFenetre2 (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
            case WM_CREATE:
                break;
            case WM_COMMAND:
    			break;
    		case WM_DESTROY:
    			break;
            default:
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
    	return 0;
    }
    int WINAPI Fenetre2(HWND hwnd_parent)
    {
        HWND hwnd;
        MSG messages;
        static WNDCLASSEX wincl;
        static unsigned int classe_deja_enregistree=0; /* 'static' pour ne pas enregistrer la classe plusieurs fois en cas d'ouvertures successives de la fenêtre */
    	
    	if (!classe_deja_enregistree)
    	{
    		classe_deja_enregistree=1;
    		wincl.hInstance = hinst;
    		wincl.lpszClassName = "ClasseFenetre2";
    		wincl.lpfnWndProc = ProcedureFenetre2;
    		wincl.style = CS_DBLCLKS;
    		wincl.cbSize = sizeof (WNDCLASSEX);
    		wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    		wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    		wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    		wincl.lpszMenuName = NULL;
    		wincl.cbClsExtra = 0;
    		wincl.cbWndExtra = 0;
    		wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    		if (!RegisterClassEx (&wincl)) return 0;
    	}
        hwnd = CreateWindowEx (0,"ClasseFenetre2","Fenetre 2",WS_BORDER | WS_CAPTION | WS_SYSMENU,150,150,900,500,hwnd_parent,NULL,hinst,NULL);
        ShowWindow (hwnd, SW_SHOWNORMAL);
    	UpdateWindow(hwnd);
    	
        while (GetMessage (&messages, NULL, 0, 0))
        {
            TranslateMessage(&messages);
            DispatchMessage(&messages);
        }
    	return messages.wParam;
    }
    LRESULT CALLBACK ProcedureFenetrePrincipale(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
            case WM_COMMAND:
    			switch (LOWORD(wParam))
    			{
    				case IDM_NOUVELLEFENETRE:
    					(void)Fenetre2(hwnd); /* Passage en paramètre du HWND de la fenêtre parent */
    					break;
    			}
    			break;
            case WM_DESTROY:
                PostQuitMessage(0);
                break;
            default:
                return DefWindowProc (hwnd, message, wParam, lParam);
    	}
    	return 0;
    }
    int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument,int nCmdShow)
    {
        HWND hwnd;
        MSG messages;
        WNDCLASSEX wincl;
    	HMENU hMenu;
    
    	hinst=hThisInstance;
    
        hMenu = CreateMenu();
        AppendMenu(hMenu, MF_STRING, IDM_NOUVELLEFENETRE, "Ouverture fenetre 2");
    
        wincl.hInstance = hinst;
        wincl.lpszClassName = "ClassFenetrePrincipale";
        wincl.lpfnWndProc = ProcedureFenetrePrincipale;
        wincl.style = CS_DBLCLKS;
        wincl.cbSize = sizeof (WNDCLASSEX);
        wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
        wincl.lpszMenuName = NULL;
        wincl.cbClsExtra = 0;
        wincl.cbWndExtra = 0;
        wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    
        if (!RegisterClassEx (&wincl)) return 0;
    
        hwnd = CreateWindowEx (0,"ClassFenetrePrincipale","Fenetre principale",WS_OVERLAPPEDWINDOW,50,50,900,500,HWND_DESKTOP,hMenu,hinst,NULL);
        ShowWindow (hwnd, nCmdShow);
    	UpdateWindow(hwnd);
    	
        while (GetMessage (&messages, NULL, 0, 0))
        {
            TranslateMessage(&messages);
            DispatchMessage(&messages);
        }
        return messages.wParam;
    }
    Merci !

  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 518
    Points
    41 518
    Par défaut
    Tu as deux boucles de messages imbriquées et un seul PostQuitMessage()...
    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
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Merci. Effectivement, ça règle le problème.

    Il y a quelque chose que je ne comprends pas par contre. Si j'ai bien compris, la fonction "PostQuitMessage" envoie un message WM_QUIT à la file de message, qui est censé provoquer la sortie de la boucle ?

    When the thread retrieves the WM_QUIT message from its message queue, it should exit its message loop and return control to the system. The exit value returned to the system must be the wParam parameter of the WM_QUIT message.
    Or, j'ai constaté, en me servant de la fonction "GetCurrentThreadId", qu'en ouvrant deux fenêtres à partir du menu "Ouverture fenetre 2", le code qui crée les deux fenêtres et celui qui gère les messages tournent dans le même thread (le thread ID est le même).

    J'ai alors voulu mieux comprendre le topo. J'ai donc rajouté un "MessageBox" juste après la boucle qui gère les messages (à la fin de la fonction "Fenetre2", juste avant le "return"), pour vérifier si on sort bien de la boucle. Lorsque je ferme les deux fenêtres, l'une après l'autre, une boîte de message apparait bien pour chacune d'elles... comme si ce même code tournait dans deux threads différents.
    Ce que je comprends pas c'est : Si la boucle de messages, qui gère les deux fenêtres, tourne dans le même thread, comment se fait-il que la fermeture d'une fenêtre (=sortie de la boucle) permet à l'autre de rester en vie alors qu'on est censé être sorti de la boucle ? Si on sort de la boucle, pourquoi l'exécution se comporte comme si on était encore dedans, vu que ça tourne dans le même thread ?

    Je ne sais pas si j'ai bien formulé mes interrogations.

    En tout cas, j'ai beau essayer de comprendre comment fonctionne tout ce système, mais je dois reconnaître que je suis complètement largué.

  4. #4
    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 518
    Points
    41 518
    Par défaut
    Tu n'as qu'un seul thread, mais deux boucles imbriquées quand tu ouvres la seconde fenêtre.

    Les MessageBox() créent également une boucle de messages imbriquées.
    http://blogs.msdn.com/oldnewthing/ar...22/378018.aspx
    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.

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Merci pour tes infos, je commence maintenant à mieux comprendre le fonctionnement de ces boucles.

    EDIT:

    Est-ce que l'imbrication de boucles comme dans ce code est une manière correcte de programmer, ou est-il préférable de passer par un autre système de gestion de messages ?

  6. #6
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par jeroman Voir le message
    Est-ce que l'imbrication de boucles comme dans ce code est une manière correcte de programmer, ou est-il préférable de passer par un autre système de gestion de messages ?
    Le souci d'avoir un seul thread, c'est que si une des fenêtres est "gelée" pour une raison X, l'autre le sera aussi...
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  7. #7
    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 518
    Points
    41 518
    Par défaut
    @jeroman: Ça dépend de ce que tu fais.
    Généralement, pour une boîte de dialogue modale (genre Ouvrir ou Options), c'est là chose à faire. Pour d'autres choses (genre une barre d'outils flottante), il vaut mieux avoir tout sur la même boucle de messages.
    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.

Discussions similaires

  1. fermer une fenêtre et ne pas quitter l'application
    Par win_ubuntu dans le forum JavaFX
    Réponses: 3
    Dernier message: 28/10/2014, 08h48
  2. Fermer une fenêtre et pas toutes les fenêtres ouvertes
    Par Sinakhine dans le forum Général Java
    Réponses: 4
    Dernier message: 29/10/2012, 13h06
  3. Ne pas fermer une fenêtre DIV
    Par BRUNO71 dans le forum Général JavaScript
    Réponses: 14
    Dernier message: 28/10/2012, 10h25
  4. Problème de fenêtre modal qui ne stoppe pas le code en arrière plan
    Par Sebcaen dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 25/09/2006, 13h43
  5. Maximiser fenêtre ne marche pas
    Par sandrinec dans le forum Composants VCL
    Réponses: 2
    Dernier message: 12/06/2003, 12h02

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