Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 9 sur 9
  1. #1
    Membre du Club
    Inscrit en
    avril 2007
    Messages
    184
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 184
    Points : 52
    Points
    52

    Par défaut GetOpenFileName pour les sceptiques

    Bonjour,
    Pour ceux qui me disaient, il ne faut pas utiliser un buffer statique, utiliser une allocation dynamique de mémoire... ou à quoi sert un Generic_write ou un FILE_SHARE_READ etc...
    voilà ci-dessous un module de test épuré de tout, plus de CreateFile, plus de ReadFile, donc plus de buffer, simplement pour montrer que mon problème n'a rien à voir
    avec ces précédentes suspicions.
    Ce module ne fait qu'une seule chose: appel à la fonction GetOpenFileName et c'est tout, avec juste un message 1 avant l'appel et un message 2 après l'appel et le phénomène que je décrivais dans une autre discussion persiste. Lorsque je choisis un petit fichier jusqu'à 80Ko je n'ai aucun problème, si je choisis un fichier d'environ 1Mo le message 2 s'affiche puis disparaît tout seul ainsi que la fenêtre ceci parfois dès le premier essai ou au minimum 1 fois sur 3 ou 4 essais. Et je répète il n'y a plus aucune ouverture ni lecture de fichier donc, a priori, il ne devrait y avoir aucun rapport avec la taille du fichier.
    Précisions concernant les autres tests que j'ai pu faire, quand le message 2 disparaît je ne sors de ma fenêtre ni par le WM_CLOSE, ni par le WM_DESTROY, ni par le
    WM_QUERYENDSESSION, puisque j'ai mis des messages pour piéger ces sorties.
    Enfin, point important ce programme fonction correctement partout ailleurs que chez moi, ma copine a un micro au même niveau que le mien sur lequel ce programme fonctionne parfaitement, je l'ai passé à d'autres personnes à la fois le source à compiler chez eux ou bien l'exécutif directement et personne n'a rencontré le problème.
    Autre point important, ce module a été compilé chez moi avec Borland, une autre personne à qui j'avais passé le source l'a compilé chez elle avec vc++ et m'a envoyé le .exe et bien ce .exe compilé ailleurs avec un autre compilateur se comporte chez moi de manière identique (disparition du message 2 tout seul).
    J'ai essayé chez moi de lancer l'exécutable ailleurs que sur mon disque C, sur un disque externe ainsi que sur une clé USB sur lesquels j'avais aussi installé un fichier d'1Mo qui
    pose problème, le phénomène se reproduit toujours à l'identique.
    Ce qui est sûr c'est que le problème est bien chez moi.
    J'ai défragmenté mon disque dur, fait une analyse complète du disque par McAfee, rien n'y fait, j'ai toujours le problème.
    D'où ma question, c'est probablement un problème du Windows chez moi, quelqu'un aurait-il une idée, au vu des tests déjà effectués, de l'endroit où il faudrait que j'aille fouiller dans Windows ?
    Merci.
    Ci-dessous la version épurée:
    Code :
    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
    #include <windows.h>
    LRESULT CALLBACK processmainmess( HWND, UINT, WPARAM, LPARAM);
    HINSTANCE n0instance;
    MSG message;
    OPENFILENAME ofn;
    CHAR cheminfile[257];
    int APIENTRY WinMain( HINSTANCE W_n0inst, HINSTANCE W_n0precinst, LPTSTR W_CmdLine, int W_cdeaffich) // entier signé (32 bits)
    {
    	n0instance = W_n0inst;
    
    	WNDCLASS winclassmain;
    	winclassmain.hInstance =  n0instance;
    	winclassmain.lpszMenuName = NULL;
    	winclassmain.lpszClassName = "Essai";
    	winclassmain.hIcon = NULL;
    	winclassmain.hCursor = LoadCursor(NULL,IDC_ARROW);
    	winclassmain.hbrBackground =(HBRUSH)(COLOR_WINDOW+1);
    	winclassmain.style = CS_VREDRAW | CS_HREDRAW;
    	winclassmain.lpfnWndProc = (WNDPROC)processmainmess;
    	winclassmain.cbWndExtra = 0;
    	winclassmain.cbClsExtra = 0;
    	if ( !RegisterClass( &winclassmain ) )
    	return( FALSE );
    //
    	HWND Hdlgmain = CreateWindow("Essai", "test", WS_CAPTION | WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 250, 100, NULL, NULL, n0instance, NULL); 
    	if ( !Hdlgmain ) return( FALSE );
    	ShowWindow( Hdlgmain, W_cdeaffich ); // lancement manuel
    	UpdateWindow( Hdlgmain ); //
    	while(GetMessage( &message, NULL, 0, 0))
    	{
    		TranslateMessage( &message ); 
    		DispatchMessage( &message ); 
    	}
    	return message.wParam; 
    }
    LRESULT CALLBACK processmainmess( HWND winmainkey, UINT IDMsg, WPARAM wParam, LPARAM lParam )
    {
    	switch(IDMsg)
    	{
    		case WM_CREATE :
    			CreateWindow("BUTTON", "Choisir un fichier", WS_CHILD | WS_VISIBLE | WS_BORDER, 0, 0, 220, 35, winmainkey, (HMENU)1000, n0instance, NULL);
    			break;
    		case WM_COMMAND:
    			switch(LOWORD(wParam))
    			{
    				case 1000: // clic sur le bouton choisir un fichier
    					ZeroMemory(&ofn, sizeof(OPENFILENAME));
    					*cheminfile=0x0;
    					ofn.lStructSize = sizeof(OPENFILENAME);
    					ofn.hwndOwner = winmainkey;
    					//ofn.hInstance=n0instance;
    					ofn.lpstrFile = cheminfile;
    					ofn.nMaxFile = 256;
    					ofn.lpstrFilter = "Tous les fichiers (*.*)\0*.*\0\0";
    					ofn.nMaxCustFilter=60;
    					ofn.nFilterIndex = 1;
    					ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
    //
    					MessageBox(winmainkey, "1", "je passe", MB_OK); // ************************************************ piège message 1
    					if (!GetOpenFileName(&ofn)) break;
    					MessageBox(winmainkey, "2", "je passe", MB_OK); // ************************************************ piège message 2
    //
    					break;
    			}
    			break;
    		case WM_CLOSE :
    			MessageBox(winmainkey, "close", "Assistant", MB_OK);
    			DestroyWindow( winmainkey );
    			break;
    		case WM_DESTROY :
    			MessageBox(winmainkey, "destroy", "Assistant", MB_OK);
    			PostQuitMessage(0);
    			break;
    		case WM_QUERYENDSESSION :
    			MessageBox(winmainkey, "query", "Assistant", MB_OK);
    			DestroyWindow( winmainkey );
    			break;
    		default :
    			return DefWindowProc( winmainkey, IDMsg, wParam, lParam );
    	};
    	return 0;
    }

  2. #2
    Expert Confirmé Sénior
    Profil pro
    Développeur informatique
    Inscrit en
    novembre 2006
    Messages
    4 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : novembre 2006
    Messages : 4 874
    Points : 6 337
    Points
    6 337

    Par défaut

    cheminfile[257] doit être initialisé à 256 et non 257.
    Si tu regardes le MSDN on utilise fréquemment la constante MAX_PATH qui équivaut à 256 pour GetOpenFileName.

  3. #3
    Membre du Club
    Inscrit en
    avril 2007
    Messages
    184
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 184
    Points : 52
    Points
    52

    Par défaut Pour les sceptiques

    Bonjour,
    Merci pour la réponse, mais ça serait bien si c'était aussi simple que ça. 256 c'est ce que j'avais mis au départ, j'ai ensuite essayé 257 dans le buffer pour être sûr que le .nMaxFile (voir ce paramètre) avait ses 256 sans le 0x0. Mais Le fait de mettre 256 ou moins ou plus ne change malheureusement absolument rien au problème, je peux te le confirmer. Encore une fois, ce qui m'intéresse ça n'est pas de chercher la petite bête dans le programme, il n'y en a pas (sinon comment expliquer que le programme marche partout ailleurs que chez moi, facile à vérifier: suffit de recopier le code tel quel et de le compiler chez soi pour le vérifier), ce qui m'intéresse c'est de pouvoir localiser, au vu du phénomène, le module de Windows qui chez moi est vérolé (et évidemment sans avoir à réinstaller, car ça aussi, je sais très bien que ça marcherait).
    Merci

  4. #4
    Membre du Club
    Inscrit en
    avril 2007
    Messages
    184
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 184
    Points : 52
    Points
    52

    Par défaut Problème contourné

    Bon entretemps je me suis aperçu que mon programme de test dans lequel il n'y a plus que la fonction GetOpenFileName n'était pas le seul à se comporter ainsi. En voulant ouvrir un des fichiers qui pose problème avec le Bloc-notes, je me suis rendu compte que le Bloc-notes se comportait de manière identique: sa fenêtre disparaît toute seule de manière intempestive avec ce type de fichier alors qu'avec les petits fichiers le Bloc-notes se comporte correctement (exactement comme mon programme de test!!!). Mais en parallèle j'ai constaté que si j'ouvrais le même fichier avec d'autres progiciels comme: Word, Worpad, Excel et Acrobat le phénomène ne se produisait pas.
    Ceci m'a amené à la conclusion qu'il y avait certainement plusieurs manières de programmer la fonction GetOpenFileName et c'est ce que j'ai fait: j'ai tout simplement rajouté l'appel à une callback bidon au paramètre lpfnHook de OPENFILENAME, callback qui renvoie toujours false pour informer quelle ne traite pas les messages (seul message traité dans la callback: le WM_CLOSE) et depuis je n'ai plus aucun problème, plus du tout de disparition intempestive de fenêtre!!! Tout baigne.
    Je reconnais que je n'ai pas résolu le problème, mais le contournement permet au moins de débloquer mon développement.
    Peut-être qu'au vu de ces nouvelles infos, quelqu'un pourra-t-il me donner une explication à ce phénomène ????
    Merci

  5. #5
    Membre du Club
    Inscrit en
    avril 2007
    Messages
    184
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 184
    Points : 52
    Points
    52

    Par défaut GetOpenFileName enfin élucidé

    Je viens enfin d'élucider ce problème qui au vu des messages de ce site a beaucoup été lu, mais sur lequel je n'ai pas beaucoup eu de réponse. Voici ci-dessous le message que j'ai adressé à Adobe, je pense qu'il est suffisamment explicite:
    Message à Adobe:
    Ceci n'est pas une question, mais une signalisation de malfonctionnement de votre version Adobe Reader X (10.1.0) Français qui s'adresse à vos développeurs système (les autres langues n'ont pas été testées, mais a priori, il n'y a pas de raison que ce soit différent).
    Cette version induit sur les systèmes Windows XP SP3 un malfonctionnement de la fonction API Windows: GetOpenFileName qui est généralement utilisée dans toutes les applications pour le traitement du bouton "OUVRIR" (sous-entendu un fichier, en général Fichier>Ouvrir)
    Il faut deux conditions pour mettre en évidence le problème:
    1.- l'application qui utilise la fonction GetOpenFileName doit l'utiliser dans sa forme la plus simple, c'est à dire sans adresse de hook procédure.
    2.- l'utilisateur qui veut ouvrir un fichier doit choisir un fichier assez volumineux (environ 1Mo)
    Dans ce cas, de manière aléatoire, mais très fréquente (souvent dès le premier essai) la fenêtre de l'application qui utilise GetOpenFileName disparaît de manière intempestive ainsi que l'application elle-même.
    Ce qui m'a orienté vers votre logiciel c'est qu'à chaque fois que mon programme de test utilisait la fonction GetOpenFileName, je voyais apparaître dans le gestionnaire le processus AcroRd32.exe en double exemplaire ce qui m'a paru curieux !
    J'ai donc fait l'essai de désinstaller votre logiciel et le problème disparaît instantanément, je l'ai réinstallé, le problème revient.
    Si ça vous intéresse, je peux vous adresser un programme élémentaire de test, sinon le problème peut aussi être mis en évidence avec le Note-book et par n'importe quel développement qui utilise la fonction GetOpenFileName dans la forme que j'ai indiquée.
    Le problème ne peut pas être mis en évidence avec les progiciels qui utilisent la fonction GetOpenFileName dans sa forme plus sophistiquée (avec adresse de hook procédure) comme Word ou Excel ou même Acrobat.
    Je suis donc revenu à la version Acrobat Reader 9.4.0 qui ne pose aucun problème sur ce plan. A titre d'information (si ça peut aider vos ingénieurs système) le processus qui apparaît dans le gestionnaire avec Reader 9.4.0 pendant l'utilisation de GetOpenFileName sous sa forme simplifiée est: AcroRd32Info.exe
    Je me tiens à votre disposition si vous avez besoin d'informations complémentaires.

  6. #6
    Membre Expert
    Inscrit en
    juin 2006
    Messages
    768
    Détails du profil
    Informations forums :
    Inscription : juin 2006
    Messages : 768
    Points : 1 122
    Points
    1 122

    Par défaut

    Salut Arthur,

    content de voir que tu as pu trouver la source du problème, même si ça n'est pas encore très clair.
    Est-ce que tu pourrais lancer ton programme avec Dependency Walker (avec le Acrobat Reader foireux) pour éventuellement avoir plus de précisions sur le moment du crash ?

    C'est quand même très "intéressant" de voir que Acrobat Reader pose problème lors d'appel à une fonction aussi générique que ça.
    Qu'est-ce qu'ils peuvent bien faire pour déclencher ça ? Ils ont l'air d'être un peu curieux (si seulement ça pouvait se limiter qu'à ça...).
    Bref c'est pas clair, voir même très suspect.
    On dirait que t'as soulevelé un lièvre (ouais je sais je m'avance un peu mais je n'ai absolument aucune confiance en cette boite).

    Merci de nous avoir tenu au courant.
    Pourrais-tu nous faire suivre la(les) réponse(s), moi ça m'intéresse beaucoup et je ne dois pas être le seul.

    A plus et bonne continuation.

  7. #7
    Membre du Club
    Inscrit en
    avril 2007
    Messages
    184
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 184
    Points : 52
    Points
    52

    Par défaut Acrobat Reader X

    Pour faire les tests il faudrait que je revienne à la version 10.1.0 de Acrobat Reader X et ça me pose problème car comme je l'indique dans mon message je suis maintenant à la 9.4.0 et de ce fait j'ai remodifié toutes mes applis qui utilisent GetOpenFileName pour revenir à un appel standard puisque je n'ai pas de problème avec cette version. En effet, je préfère l'appel standard (sans la procédure de hook qui résout le problème), car bien que avec la procédure de hook ça marche dans tous les cas, le fait de l'utiliser nous fait passer par une boîte de dialogue différente de la procédure standard (sans hook), cette boîte est plus ancienne donc moins ergonomique (ou alors 3ème solution: il faut faire sa boîte de dialogue soi-même, mais ce n'était pas mon but). Je ferai par contre suivre si je reçois une réponse de chez Adobe, ils indiquent cependant explicitement sur leur site qu'ils ne répondent pas forcément, qu'ils recontactent par contre s'ils ont besoin d'infos complémentaires...
    A+

  8. #8
    Expert Confirmé Sénior Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    septembre 2005
    Messages
    24 040
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2005
    Messages : 24 040
    Points : 32 214
    Points
    32 214

    Par défaut

    Un crash par disparition brutale sans aucun message, pouf! comme ceci, c'est souvent un débordement de pile.

    Il est possible qu'Adobe installe une ShellExtension foireuse en effet. Tu devrais regarder ce qui se rapporte à Adobe dans HKEY_CLASS_ROOT...
    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
    Membre chevronné
    Homme Profil pro
    Auditeur informatique
    Inscrit en
    avril 2009
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Auditeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : avril 2009
    Messages : 120
    Points : 610
    Points
    610

    Par défaut Autre solution ...

    Confronté au même problème en 2009, j'avais trouvé la solution suivante, très simple :

    Il suffit au début de l'application de faire un appel à la fonction CoInitialize() - initialisation des fonctions de la librairie COM - déclarée dans objbase.h et incluse dans la librairie ole32.

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include <windows.h>
    #include <objbase.h>
     
    int APIENTRY WinMain(/** arguments **/)
    {
      /** déclaration et création de la fenêtre principale **/
     
      CoInitialize(NULL);
     
      /** boucle des messages **/
     
      CoUninitialize();
     
      /** retour **/
    }

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

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •