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 :

Passage de paramètres à un callback de fenêtre ?


Sujet :

Windows

  1. #1
    Membre du Club
    Profil pro
    Développeur Web
    Inscrit en
    Mai 2007
    Messages
    67
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 67
    Points : 48
    Points
    48
    Par défaut Passage de paramètres à un callback de fenêtre ?
    Bonjour,

    Voilà mon problème :

    J'ai une application qui doit libérer toutes ses ressources à la réception d'un message window envoyé par une autre appli. Le seul moyen que j'ai trouvé de le récupérer est de créer une fenêtre et d'entrer dans une boucle de réception des messages, comme décrit ici.

    Ca donne quelque chose comme :
    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
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
    {
    
      Lancement de threads qui utilisent des ressources qui devront être libérées;
    
      HWND hwnd;
      MSG msg;
      WNDCLASS wc;
    
      ulMessageFinVie=RegisterWindowMessage(_T("FinAppli"));
    
      hinst = hInstance;
    
      wc.style = 0 ;
      wc.lpfnWndProc = MainWndProc;
      wc.cbClsExtra = 0;
      wc.cbWndExtra = 0;
      wc.hInstance = hInstance;
      wc.hIcon = NULL;
      wc.hCursor = LoadCursor(NULL, IDC_ARROW);
      wc.hbrBackground = NULL;
      wc.lpszMenuName =  NULL;
      wc.lpszClassName = _T("ClassName");
    
      if(!RegisterClass(&wc)) return FALSE;
    
      hwnd = CreateWindow(_T("Name1"), _T("Name2"), WS_VISIBLE | WS_CAPTION | WS_SYSMENU,
                                     700, 700, 20, 20, NULL, NULL, hInstance, NULL);
      if (!hwnd)  return FALSE;
    
      ShowWindow(hwnd, nCmdShow);
    
      while (GetMessage(&msg, NULL, 0, 0))
      {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
      }
    
      return msg.wParam;
    }
    Ceci pour le main, et pour le callback :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    LRESULT CALLBACK MainWndProc(HWND hWnd,UINT wMsg,WPARAM wParam,LPARAM lParam)
    {
      Libérer les ressources;
    }
    Le seul petit soucis : Jusque là je n'utilise aucune variable globale (c'est bien !), mais les ressources que je dois libérer sont donc inaccessibles depuis la fonction callback de la fenêtre que j'ai créée, vu que MainWndProc ne prend pas de paramètre utilisateur... ou alors j'ai raté quelque chose !

    Je veux paaaas céder aux variables globales ! Aidez-moi !

  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
    Le dernier paramètre de CreateWindow() est transmis en paramètre du message WM_CREATE.

    Après, tu peux mémoriser cela dans la fenêtre avec SetWindowLongPtr()...
    Voici un petit exemple C++ d'utilisation de SetWindowLongPtr().
    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 du Club
    Profil pro
    Développeur Web
    Inscrit en
    Mai 2007
    Messages
    67
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 67
    Points : 48
    Points
    48
    Par défaut
    D'abord merci de la réponse, c'est exactement ce sur quoi j'espérais tomber (encapsulation de la fenêtre dans une classe).

    J'ai écrit le code de ma classe. La fonction callback donne :

    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
    LRESULT CALLBACK WindowClass::WindowProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
    {
    	LRESULT lrRet = 0;
    	WindowClass* pObj = reinterpret_cast< WindowClass* >(GetWindowLongPtr(hWnd, GWL_USERDATA));
    
    
    	if(pObj)
    	{
    		if (wMsg == pObj->m_message)
    		{
    			PostQuitMessage(0);
    			return lrRet;
    		}
    	}
       
    	switch(wMsg)
    	{
    		case WM_CREATE:
    			{
    				// Retrieves the pointer on the WindowClass object
    				LPCREATESTRUCT pCs = reinterpret_cast< LPCREATESTRUCT >(lParam);
    				pObj = static_cast< WindowClass* >(pCs->lpCreateParams);
    				SetWindowLongPtr(hWnd, GWL_USERDATA, reinterpret_cast< LONG_PTR >(pObj));
    			}
    			break;
    
    		case WM_DESTROY:
    			PostQuitMessage(0);
    			break;
    
    		default:
    			lrRet = DefWindowProc(hWnd, wMsg, wParam, lParam);
    			break;
    	}
    	return lrRet;
    }
    Tout va bien pour ma fenêtre (je me fiche de ce qu'elle affiche pour l'instant) si j'appuie sur la croix, elle se ferme et libère les ressources (elle reçoit bien et traîte bien le message WM_DESTROY donc).

    En revanche, j'ai lancé une autre appli console toute simple qui ressemble à ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int main()
    {
    
    	Sleep(5000);
    	cout << "Sending message" << endl;
    	unsigned long testMessage = RegisterWindowMessage(_T("TestMessage"));
    	PostMessage(HWND_BROADCAST, testMessage, NULL, NULL);
    	Sleep(5000);
    	return 0;
    }
    Mais là, c'est le drame, la fenêtre ne se ferme pas au bout des 5 secondes (alors que Sending message s'affiche sur la console). J'ai l'impression que le test :
    n'est jamais juste, et donc que lors du traitement du message WM_CREATE, il y a un problème qui fait que la fonction "SetWindowLongPtr" n'enregistre pas le pointeur comme elle le devrait, ou bien que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    LPCREATESTRUCT pCs = reinterpret_cast< LPCREATESTRUCT >(lParam);
    pObj = static_cast< WindowClass* >(pCs->lpCreateParams);
    ne fonctionne pas. Qu'en est-il à votre avis ?

    EDIT : J'ai trouvé la solution en postant le message... J'avais oublié l'essentiel : dans ma méthode CreateWindow(), je n'avais pas mis le pointeur vers l'objet à récupérer... Et là ça marche tout de suite mieux !

  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 519
    Points
    41 519
    Par défaut
    Au passage: Utilise GWLP_USERDATA, pour la compatibilité.
    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 du Club
    Profil pro
    Développeur Web
    Inscrit en
    Mai 2007
    Messages
    67
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 67
    Points : 48
    Points
    48
    Par défaut
    Ok

    Et merci pour tout !!

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

Discussions similaires

  1. Passage de paramètres entre deux fenêtres
    Par mosaique dans le forum WinDev
    Réponses: 8
    Dernier message: 21/01/2010, 00h28
  2. Réponses: 5
    Dernier message: 23/01/2009, 16h22
  3. Passage de paramètres à une nouvelle fenêtre
    Par rohstev dans le forum ASP.NET
    Réponses: 3
    Dernier message: 21/10/2008, 17h54
  4. Réponses: 5
    Dernier message: 17/12/2007, 12h07
  5. Passage de paramètre fenêtre mère --> popup fill
    Par senacle dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 03/10/2005, 15h48

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