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 :

[API windows] RegisterClassEx échoue et marche !


Sujet :

Windows

  1. #1
    Nouveau membre du Club
    Inscrit en
    Juin 2004
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 42
    Points : 31
    Points
    31
    Par défaut [API windows] RegisterClassEx échoue et marche !
    Bonjour !


    C'est un étrange problème que je soumets aujourd'hui à votre perspicacité. Dans une application, j'utilise RegisterClassEx. Cette méthode échoue (0 est renvoyé).

    Pourtant, si je m'en fiche (pas de if (RegisterClassEx(..)==0) return 0; ), l'application fonctionne apparemment parfaitement, la fenêtre est crée comme je le souhaite, et il n'y a pas de problème.

    Je voudrais savoir pourquoi, car malgré tout je préfererais une valeur de retour non nulle.

    Merci d'avance

  2. #2
    Membre actif Avatar de Twindruff
    Inscrit en
    Janvier 2005
    Messages
    216
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 216
    Points : 237
    Points
    237
    Par défaut
    Utilise GetLastError et FormatMessage pour avoir plus de détails sur l'échec.
    Peut-être que la classe est déjà enregistrée et c'est pour ça que ça marche ? (avec GetClassInfo tu peux savoir si une classe est déjà enregistrée)

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Points : 121
    Points
    121
    Par défaut
    Effectivement, nous avions pensé au fait que la classe puisse être déjà enregistrée. Mais nous ne la voyons pas sur spy++ . De plus, 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
    if( GetClassInfoEx(NULL,szClassName,&wc) )
    		g_CLogM->AddEvent("Application déjà enregistrée");
    	else
    	{ 
    (construction de wc)
    
    f(!RegisterClassEx(&wc))
    		{
    			g_CLogM->AddEvent("Méthode RegisterClassEx échouée");
    			return 0;
    		}
    
    		g_CLogM->AddEvent("Application enregistrée");
    }
    nous renvoie une fois sur deux un échec, et l'autre "Application Enregistrée", sans jamais passer par "Application déjà enregistreé"... Ce qui tend à nous faire penser que la classe n'est pas déjà enregistrée (et ce ne serait donc pas lié à une mauvaise fermeture du programme).

    Pourriez-vous nous indiquer quelques pistes supplémentaires ?

    Merci

    Cordialement
    OS : WinXP
    Outils : VC++ 8 (Visual Studio 2005)

  4. #4
    Membre actif Avatar de Twindruff
    Inscrit en
    Janvier 2005
    Messages
    216
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 216
    Points : 237
    Points
    237
    Par défaut
    Eh ben déjà utiliser GetLastError et FormatMessage pour avoir plus de détails sur l'erreur

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Points : 121
    Points
    121
    Par défaut
    Ca m'a complétement échappé !

    Je fais ça tout de suite.

    Merci
    OS : WinXP
    Outils : VC++ 8 (Visual Studio 2005)

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Points : 121
    Points
    121
    Par défaut
    C'est fait. j'ai modifié mon code pour obtenir le suivant :

    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
    if(!RegisterClassEx(&wc))
    		{
    	#ifndef _DEBUG
    			CSplashScreen::Exit();
    	#endif
    			LPVOID lpMsgBuf;
    			
    			FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
    						  FORMAT_MESSAGE_FROM_SYSTEM |
    						  FORMAT_MESSAGE_IGNORE_INSERTS,
    						  NULL,
    						  GetLastError(),
    						  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    						  (LPTSTR) &lpMsgBuf,
    						  0,
    						  NULL);
    			MessageBox(g_hDlg,(LPTSTR)lpMsgBuf,"",0);
    
    
    			g_CLogM->AddEvent("Méthode RegisterClassEx échouée");
    			
    			return 0;
    		}

    La plupart du temps, ça passe. Et quand RegisterClassEx rate, il m'envoie un "La classe n'existe pas." . Y'a pas à dire, je suis très avancé !

    Alors, pour quelles raisons RegisterClasseEx peut-il échouer ?

    Merci

    Cordialement
    OS : WinXP
    Outils : VC++ 8 (Visual Studio 2005)

  7. #7
    Nouveau membre du Club
    Inscrit en
    Juin 2004
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 42
    Points : 31
    Points
    31
    Par défaut
    J'ai utilisé cette fonction. Mais même si la classe n'existe pas, registerclassex échoue de toute manière, l'application pouvant cependant marcher par la suite. Une suggestion ?

  8. #8
    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
    Bonjour,
    1. Pour commencer, je ne suis pas sûr de ce que fait ton CSplashScreen(), mais tu devrais appeler GetLastError() AVANT pour être sûr.
    2. Ensuite, tu oublies de libérer la mémoire de ton buffer.
    3. Et pour finir, on peut voir la définition précise de ta classe de fenêtre ?

    PS: Pense à regarder aussi sur les forums Microsoft : Peut-être quelqu'un a-t-il déjà eu ton problème...
    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.

  9. #9
    Nouveau membre du Club
    Inscrit en
    Juin 2004
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 42
    Points : 31
    Points
    31
    Par défaut
    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
    //------Création de la classe de fenêtre
    wc.hInstance = hInstance;
    wc.lpszClassName = szClassName;     //pointeur vers une chaîne constante
    wc.lpfnWndProc = WindowProcedure;
    wc.style = 0;
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_MYICON));
    wc.hIconSm = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_MYICON));
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.lpszMenuName = NULL;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
    
    if(!RegisterClassEx(&wc))
    {
    	LPVOID lpMsgBuf;
    	
    	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
    				  FORMAT_MESSAGE_FROM_SYSTEM |
    				  FORMAT_MESSAGE_IGNORE_INSERTS,
    				  NULL,
    				  GetLastError(),
    				  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    				  (LPTSTR) &lpMsgBuf,
    				  0,
    				  NULL);
    	
    	//on écrit des événements dans un fichier log
    	g_CLogM->AddEvent((LPTSTR)lpMsgBuf);
    	g_CLogM->AddEvent("Méthode RegisterClassEx échouée");
    	
    #ifndef _DEBUG
    	CSplashScreen::Exit();   //pas de problème avec cette fonction !
    #endif
    	return 0;
    }
    Pour info : la fenêtre est destinée à ne recevoir "que du DirectX", elle est volontairement rudimentaire.

    Pour la mémoire à libérer, faut-il comprendre que formatmessage alloue de la mémoire ?

  10. #10
    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
    Eh bien, je ne vois pas grand-chose de bizarre dans la WNDCLASSEX, à part peut-être le GetStockObject() (j'ignore si c'est OK de le mettre dans une classe ou si c'est nuisible comme pour GetSysColorBrush()).
    Citation Envoyé par Heliopraetor
    Pour la mémoire à libérer, faut-il comprendre que formatmessage alloue de la mémoire ?
    À quoi crois-tu que sert le flag FORMAT_MESSAGE_ALLOCATE_BUFFER ?
    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.

  11. #11
    Membre actif Avatar de Twindruff
    Inscrit en
    Janvier 2005
    Messages
    216
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 216
    Points : 237
    Points
    237
    Par défaut
    Parfois le RegisterClass échoue si la MessageProc n'est pas bien formée aussi.
    Edit: ah non c'est la CreateWindow qui peut échouer si la MessageProc n'est pas bien formée

Discussions similaires

  1. Réponses: 29
    Dernier message: 14/01/2013, 10h40
  2. tutoriel : La programmation de l'API Windows en C++ par Bob
    Par Aurelien.Regat-Barrel dans le forum Windows
    Réponses: 19
    Dernier message: 21/06/2008, 14h34
  3. Documentation gratuite sur l'API Windows, COM, DCOM, OLE, etc.
    Par Community Management dans le forum Windows
    Réponses: 1
    Dernier message: 16/11/2006, 15h28
  4. [API Windows] Polices de caractères disponibles
    Par bebeours dans le forum C++Builder
    Réponses: 3
    Dernier message: 05/11/2003, 08h28
  5. Utilisation de Pointeurs dans API windows
    Par Drooxy dans le forum API, COM et SDKs
    Réponses: 4
    Dernier message: 13/03/2003, 22h39

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