OVH Cloud OVH Cloud

Problème avec GetOpenFileName

15 réponses
Avatar
Roger
Bonjour,
J'ai un problème avec GetOpenFileName si et seulement si le fichier que
j'ouvre fait plus de 93Ko !!!! Si j'ai fait une erreur de programmation vous
allez pouvoir la trouver très vite car j'ai réécrit un programme élémentaire
très simple et très court qui reproduit exactement le phénomène et vous en
trouverez le code complet ci-dessous.
Ce programme est une simple fenêtre avec deux boutons (un bouton "Ouvrir" et
un bouton "Fermer") Le bouton "Ouvrir" (case 1 ) appelle la fonction
GetOpenFileName pour choisir un fichier quelconque, puis ouvre le fichier
avec CreateFile, puis lit un premier bloc de 1024 bytes avec ReadFile et
c'est tout. Le bouton "Fermer" (case 2) permet de fermer le fichier qui
vient d'être ouvert. Vous pouvez recopier ce code, le jeu consiste à faire
l'expérience en choisissant un premier fichier d'environ 75Ko, vous l'ouvrez
avec le bouton Ouvrir, puis vous le fermez avec le bouton "Fermer" et vous
recommencez plusieurs fois avec le même fichier : Ouvrir, Fermer, etc...
ceci sans jamais cliquer sur la croix pour fermer la fenêtre, vous
constaterez qu'il n'y a aucun problème, tout marche très bien. Puis vous
recommencez en choisissant cette fois-ci un fichier d'environ 1 Mo (>93Ko
c'est suffisant, mais avec 1Mo ça va plus vite), vous allez constater à un
moment (ou même souvent dès le premier essai) que le message 2 s'affiche
puis disparaît tout seul (très curieux alors que MessageBox est bloquant)en
même temps que la fenêtre. Je serais ravi que vous trouviez la faille car je
ne vois pas de rapport avec la taille du fichier puisque dans tous les cas
je ne lis que le 1er bloc, ci-dessous le petit programme :

#include <windows.h>
LRESULT CALLBACK processmainmess( HWND, UINT, WPARAM, LPARAM);
HINSTANCE n0instance;
MSG message;
OPENFILENAME ofn;
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 )
{
static HANDLE keyfile;
CHAR cheminfile[256];
static BOOL fileexist;
DWORD nbbytetoread=1024;
DWORD nbbyteread;
static CHAR Bloc[1025];
switch(IDMsg)
{
case WM_CREATE :
CreateWindow("BUTTON", "Ouvrir", WS_CHILD | WS_VISIBLE | WS_BORDER, 0, 0,
100, 35, winmainkey, (HMENU)1, n0instance, NULL);
CreateWindow("BUTTON", "Fermer", WS_CHILD | WS_VISIBLE | WS_BORDER, 110, 0,
100, 35, winmainkey, (HMENU)2, n0instance, NULL);
fileexist=false;
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case 1: // clic sur bouton ouvrir un fichier
if(fileexist) {MessageBox(winmainkey, "Fichier déjà ouvert", "test", MB_OK);
break;}
// *** choix du Fichier à ouvrir
ZeroMemory(&ofn, sizeof(OPENFILENAME));
*cheminfile=0x0;
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = winmainkey;
ofn.lpstrFile = cheminfile;
ofn.nMaxFile = 256;
ofn.lpstrFilter = "Tous les fichiers (*.*)\0*.*\0\0";
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)==false) break;
MessageBox(winmainkey, "2", "je passe", MB_OK); // ************* piège
message 2
//
keyfile = CreateFile(cheminfile, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL);
fileexist=true;
ReadFile(keyfile, Bloc, nbbytetoread, &nbbyteread, NULL);
MessageBox(winmainkey, "Fichier ouvert et 1er bloc lu OK", "test", MB_OK);
break;
case 2: // clic sur bouton fermer le fichier déjà ouvert
if(!fileexist) {MessageBox(winmainkey, "Il n'y a pas de fichier ouvert",
"test", MB_OK); break;}
CloseHandle(keyfile);
fileexist=false;
MessageBox(winmainkey, "Fichier fermé OK", "test", MB_OK);
break;
}
break;
case WM_CLOSE :
DestroyWindow( winmainkey );
break;
case WM_DESTROY :
if(fileexist) CloseHandle(keyfile);
PostQuitMessage(0);
break;
case WM_QUERYENDSESSION :
DestroyWindow( winmainkey );
break;
default :
return DefWindowProc( winmainkey, IDMsg, wParam, lParam );
};
return 0;
}

5 réponses

1 2
Avatar
CriCri
Roger a écrit :

...impossible d'envoyer quoi que ce soit, erreur 404 à chaque fois...



Ooops - content de le savoir, le suis-je - merci (y a pas grand monde
qui essaye de le faire donc je ne le savais pas et je ne l'ai pas testé
depuis sa mise en place il y a 6 ans - mais il faut bien que ça marche).
Je vais regarder ça dès demain - j'ai déjà une petite idée (histoire de
changement de serveurs...).

Peut-ête avec une simple adresse mail....



Ben tu peux utiliser celui qui figure dans mes posts, moyennant la
petite manip' évidente. Jusqu'à 5MO par message ça devrait passer (même
10, peut-être, j'ai pas fait attention).

Cdlt, CC

--
bitwyse [PGP KeyID 0xA79C8F2C]
http://www.le-maquis.net
C'est comme au CNRS: des chercheurs qui cherchent on en trouve
mais des chercheurs qui trouvent on en cherche.
Avatar
Roger

Ben tu peux utiliser celui qui figure dans mes posts, moyennant la
petite manip' évidente. Jusqu'à 5MO par message ça devrait passer (même
10, peut-être, j'ai pas fait attention).

Cdlt, CC

--
bitwyse [PGP KeyID 0xA79C8F2C]
http://www.le-maquis.net
C'est comme au CNRS: des chercheurs qui cherchent on en trouve
mais des chercheurs qui trouvent on en cherche.



Faut croire que ça n'est pas évident pour tout le monde... Je dois faire
parti de ceux qui cherchent. Alors peut-être plus facile, si c'est toi qui
m'envoies quelque chose avec un objet que je puisse facilement reconnaître
du genre "Cricri des news" pour éviter que par mégarde je mette à la
poubelle (plus de 50 indésirables par jour), alors je pourrais répondre.
Pour ça:
http://rwebeasy.free.fr/ninabel/
ne pas cliquer sur entrer, afficher le code de la page source et voir dans
les meta deux lignes sous l'auteur.
Merci
Avatar
Roger
Avancement sur le sujet (pour ceux qui seraient intéressés):
1.- Le programme de test a été réduit à sa plus simple expression, il ne
contient plus que la fonction GetOpenFileName, plus de buffer, plus de
CreateFile, plus de ReadFile ce qui a permis de mettre hors de cause un
problème de buffer, de CreateFile ou de ReadFile car avec les gros fichiers
le phénomène se produit toujours: disparition intempestive de la fenêtre du
programme pendant l'exécution de GetOpenFileName.
2.- Je m'aperçois que le Bloc-notes (tout au moins chez moi) se comporte
exactement de la même manière que le programme de test avec le fichier qui
pose problème (disparition intempestive de la fenêtre du Bloc-notes).
3.- Je constate que le fichier qui pose problème, n'en pose aucun si je
l'ouvre avec les progiciels tels que: Word, Wordpad, Excel, Acrobat.
4.- J'en conclus qu'il y a plusieurs manières d'utiliser GetOpenFileName,
une manière qui chez moi pose problème, une autre qui n'en pose pas et ceci
est conforté par le fait que la boîte de dialogue que j'obtiens avec le
Bloc-notes lorsque j'ouvre un fichier n'est pas strictement la même qu'avec
les autres progiciels.
5.- En conclusion, j'ai simplement rajouté l'appel à une callback bidon dans
le paramètre: lpfnHook de OPENFILENAME de mon programme de test, callback
qui répond toujours false pour signifier qu'elle ne traitera pas le message
(seul message traité par la callback: WM_CLOSE) et le phénomène a disparu:
plus de disparition intempestive de fenêtre quelle que soit la taille du
fichier!!!

En conclusion, le problème initial n'est pas expliqué, mais contourné ce qui
permet de me débloquer.
Je tiens à remercier Cricri pour tous les tests qu'il a bien voulu faire
chez lui, pour ces suggestions et surtout pour sa patience...

R.G.
Avatar
Laurent
"Roger" a écrit dans le message de news:
4e0379b4$0$25259$
5.- En conclusion, j'ai simplement rajouté l'appel à une callback bidon
dans le paramètre: lpfnHook de OPENFILENAME de mon programme de test,
callback qui répond toujours false pour signifier qu'elle ne traitera pas
le message (seul message traité par la callback: WM_CLOSE) et le phénomène
a disparu: plus de disparition intempestive de fenêtre quelle que soit la
taille du fichier!!!

En conclusion, le problème initial n'est pas expliqué, mais contourné ce
qui permet de me débloquer.
Je tiens à remercier Cricri pour tous les tests qu'il a bien voulu faire
chez lui, pour ces suggestions et surtout pour sa patience...



Merci du retour,
mais ça reste bizarre, vu qu'il y a forcément toujours une explicaton
logique...
Avatar
Roger
Merci du retour,
mais ça reste bizarre, vu qu'il y a forcément toujours une explicaton
logique...


J'en conviens et si quelqu'un peut me la donner je suis preneur car la
solution de contournement du problème que j'ai adoptée a un petit
inconvénient c'est que dans ce cas GetOpenFileName utilise une boîte de
dialogue différente (plus ancienne) de celle qui est normalement utilisée
lorsqu'il n'y a pas d'adresse de procédure de hook.

Si vous voulez voir il vous suffit de recopier le programme ci-dessous et de
le recompiler:
**********************************************************************************
#include <windows.h>
LRESULT CALLBACK processmainmess( HWND, UINT, WPARAM, LPARAM);
HINSTANCE n0instance;
MSG message;
OPENFILENAME ofn;
CHAR cheminfile[257];
INT i=1;
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;
}
UINT CALLBACK hookprocess(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM
lParam)
{
switch(uiMsg)
{
case WM_CLOSE:
PostMessage(hdlg, WM_COMMAND, (WPARAM)IDABORT, (LPARAM)0);
break;
}
return false;
}
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 (*.*)*.*";
ofn.nMaxCustFilter`;
ofn.nFilterIndex = 1;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY |
OFN_ENABLEHOOK;
ofn.lpfnHook = (LPOFNHOOKPROC)hookprocess;
//
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;
}
*******************************************************************************
1 2