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 :

RegisterClass qui plante mais ne renvoit pas l'erreur directement quand manifest


Sujet :

Windows

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

    Informations forums :
    Inscription : Août 2006
    Messages : 256
    Points : 91
    Points
    91
    Par défaut RegisterClass qui plante mais ne renvoit pas l'erreur directement quand manifest
    Bonsoir,

    J'ai un problème bien corriace que je n'arrive pas à résoudre :

    J'ai eut initialement ce problème sur un programme quasiment fini, mais pour simplifier la recherche du bug, j'ai refait un programme beaucoup plus simple.
    Il faut savoir que ce problème est reproductible sur environ la moitié des PC, j'ai 4 PCs chez moi, ça bug sur 2 et ça marche très bien sur les 2 autres.

    J'ai donc fait un programme qui affiche une simple fenêtre avec un bouton dedans, ça marche.
    Si j'ajoute à coté de l'exe un fichier manifest (qui marche, testé sur d'autre programmes), le bouton ne s'affiche plus.

    RegisterClass ne renvoit pas zéro, donc, en théorie il enregistre bien la classe, mais juste après lui, GetLastError renvoit 2.

    Ensuite, le CreateWindow du bouton renvoit 1411 soit ERROR_CLASS_DOES_NOT_EXIST, ce qui confirme bien que RegisterClass a planté ...




    C'est ici que mes compétences en programmation s'arrètent ...

    Je ne comprend pas, le code est normalement bon, parce que c'est celui donné par l'IDE CodeBlocks, et de toute façon, il marche sans fichier manifest.

    Le fichier manifest est correcte puisqu'il marche avec d'autres programmes sur les PCs ou le mien plante.

    Le problème ne viens pas des PCs puisque tout les autres programmes marchent très bien dessus, et 2 PCs chez moi plus un autre chez un collègue qui reproduisent le problème, ça ferait un peu gros.


    En recherchant, j'ai trouvé quelqu'un qui a eut apparament un problème qui pourait ressembler au mien, mais je ne voit pas le rapport de sa conclusion avec le problème : par ici.


    Voilà, si un de vous a une idée de génie ...

    Merci.
    Pierre.

    PS : Le code qui m'a servis pour les tests, compilé avec MinGW :

    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
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    #include <windows.h>
    #include <stdio.h>
    
    /*  Declare Windows procedure  */
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
    
    /*  Make the class name into a global variable  */
    char szClassName[ ] = "CodeBlocksWindowsApp";
    
    // J'en fait une global pour pouvoir "prendre" une erreur dans WinMain et l'affichcher dans la procedure windows
    int erreur1;
    
    // encore le même problème de portée
    HINSTANCE instance;
    
    int WINAPI WinMain (HINSTANCE hThisInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR lpszArgument,
                         int nCmdShow)
    {
        SetLastError(0);
    
        instance=hThisInstance;
    
        WNDCLASSEX wincl;        /* Data structure for the windowclass */
        HWND hwnd;               /* This is the handle for our window */
        MSG messages;            /* Here messages to the application are saved */
    
    
        /* The Window structure */
        wincl.hInstance = hThisInstance;
        wincl.lpszClassName = szClassName;
        wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
        wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
        wincl.cbSize = sizeof (WNDCLASSEX);
    
        /* Use default icon and mouse-pointer */
        wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
        wincl.lpszMenuName = NULL;                 /* No menu */
        wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
        wincl.cbWndExtra = 0;                      /* structure or the window instance */
        /* Use Windows's default colour as the background of the window */
        wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    
        /* Register the window class, and if it fails quit the program */
        if (!RegisterClassEx (&wincl))
            return 0;
        // Ici, GetLastError renvoit 2
        erreur1=GetLastError();
    
        /* The class is registered, let's create the program*/
        hwnd = CreateWindowEx (
               0,                   /* Extended possibilites for variation */
               szClassName,         /* Classname */
               "Code::Blocks Template Windows App",       /* Title Text */
               WS_OVERLAPPEDWINDOW, /* default window */
               CW_USEDEFAULT,       /* Windows decides the position */
               CW_USEDEFAULT,       /* where the window ends up on the screen */
               544,                 /* The programs width */
               375,                 /* and height in pixels */
               HWND_DESKTOP,        /* The window is a child-window to desktop */
               NULL,                /* No menu */
               hThisInstance,       /* Program Instance handler */
               NULL                 /* No Window Creation data */
               );
    
        /* Make the window visible on the screen */
        ShowWindow (hwnd, nCmdShow);
    
        /* Run the message loop. It will run until GetMessage() returns 0 */
        while (GetMessage (&messages, NULL, 0, 0))
        {
            /* Translate virtual-key messages into character messages */
            TranslateMessage(&messages);
            /* Send message to WindowProcedure */
            DispatchMessage(&messages);
        }
    
        /* The program return-value is 0 - The value that PostQuitMessage() gave */
        return messages.wParam;
    }
    
    
    /*  This function is called by the Windows function DispatchMessage()  */
    
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        static HWND handle=NULL;
    
        switch (message)                  /* handle the messages */
        {
            case WM_CREATE:
            {
                int erreurAvCW=GetLastError();
                SetLastError(0);
    
                /// Renvoit class does not exist
                handle=CreateWindow("BUTTON",
                             "test",
                             WS_CHILD | WS_VISIBLE,
                             5,
                             5,
                             383,
                             30,
                             hwnd,
                             NULL,
                             instance,
                             NULL);
    
                int erreurApCW=GetLastError();
                SetLastError(0);
    
                FILE *fichierErreur=NULL;
                fichierErreur=fopen("Débugage.txt", "a");
                if (GetLastError() == ERROR_ALREADY_EXISTS) SetLastError(0);
                if (fichierErreur==NULL)
                {
                    MessageBox(NULL, "Impossible de créer ou d'ouvrir le fichier de débugage", "Erreur", MB_ICONERROR);
                    exit(0);
                }
    
                fprintf(fichierErreur, "Erreur 1 : %u\n", erreur1);
                fprintf(fichierErreur, "Erreur au début du WM_CREATE, avant le CreateWindow du bouton : %u\n", erreurAvCW);
                fprintf(fichierErreur, "Handle renvoyé par CreateWindow : %u\n", handle);
                fprintf(fichierErreur, "Erreur après le CreateWindow du bouton : %u\n", erreurApCW);
                fclose(fichierErreur);
            }
                break;
    
            case WM_DESTROY:
                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                break;
    
            default:                      /* for messages that we don't deal with */
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
    
        return 0;
    }
    Le fichier que me génère mon programe de test avec le manifest :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Erreur 1 : 2
    Erreur au début du WM_CREATE, avant le CreateWindow du bouton : 0
    Handle renvoyé par CreateWindow : 0
    Erreur après le CreateWindow du bouton : 1411

    Le fichier que me génère mon programe de test sans le manifest :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Erreur 1 : 2
    Erreur au début du WM_CREATE, avant le CreateWindow du bouton : 0
    Handle renvoyé par CreateWindow : 1311738
    Erreur après le CreateWindow du bouton : 0
    Le fichier manifest (qui marche avec d'autres programmes) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
    <dependency>
    <dependentAssembly>
    <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df">
    </assemblyIdentity>
    </dependentAssembly>
    </dependency>
    </assembly>

  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
    La classe non-trouvée n'est à mon avis pas celle de ta fenêtre, mais celle d'un Common Control (le bouton notamment).
    Avec ce genre d'erreur, même les MessageBox() ne marchent pas.

    Tu as du bol, j'ai eu ce problème il n'y a pas une semaine, qui se manifestait aussi bien en trifouillant moi-même avec le manifest qu'en utilsant le pragma recommandé sur Visual Studio.
    Le problème s'est résolu en appelant InitCommonControls() ou InitCommonControlsEx() au début du programme.

    (le problème se produit avec le manifest et pas sans, parce qu'avec, les contrôles simples (bouton, edit) sont ceux de comctl32.dll au lieu de ceux de user32.dll)
    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 régulier
    Profil pro
    Inscrit en
    Août 2006
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 256
    Points : 91
    Points
    91
    Par défaut
    T'es mon dieu Médioc !

    Salut et un gros merci, ça marche, depuis le temps que ça me fesait ch*** ...

    J'avais déjà essayé InitCommonControls, mais tout seul, sans le manifest, et ça ne marchait pas.

    Encore merci et à la prochaine.

    Pierre.

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 13/08/2014, 17h57
  2. Macro qui plante, mais pas en pas à pas
    Par alacoume dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 29/11/2011, 15h18
  3. Réponses: 3
    Dernier message: 09/02/2010, 20h15
  4. Carte réseau qui émet mais ne reçoit pas
    Par vg-matrix dans le forum Windows XP
    Réponses: 12
    Dernier message: 13/12/2009, 19h13
  5. Une interface qui envoie mais ne reçoit pas
    Par Eusebius dans le forum Développement
    Réponses: 1
    Dernier message: 21/03/2008, 09h27

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