API Win32, problème de variable

cs_bouba Messages postés 518 Date d'inscription dimanche 2 décembre 2001 Statut Membre Dernière intervention 10 novembre 2007 - 17 févr. 2003 à 21:54
cs_bouba Messages postés 518 Date d'inscription dimanche 2 décembre 2001 Statut Membre Dernière intervention 10 novembre 2007 - 18 févr. 2003 à 11:55
Salut a tous, j'ai un blem de variable dans mon programme. Voici mon code source.

LPSTR Path="";

LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CREATE:
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case FICHIER_NOUVEAU:
SetDlgItemText(hWnd, 0, "");
break;
case FICHIER_OUVRIR:
Path = OuvrirFichier(hWnd);
break;
case FICHIER_SAVE:
SauverFichier(hWnd,Path);
MessageBoxEx(NULL,Path,"Error",MB_OK,0x040c);
break;
case FICHIER_SAVEAS:
MessageBoxEx(NULL,Path,"Error",MB_OK,0x040c);
Path = SauverSousFichier(hWnd);
MessageBoxEx(NULL,Path,"Error",MB_OK,0x040c);
break;
case FICHIER_PRINT:
break;
case FICHIER_QUITTER:
PostQuitMessage(0);
break;
case AIDE_PROPOS:
DialogBox(GetModuleHandle(NULL),"AIDEDIALOG",hWnd,AideDialogProc);
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_SIZE:
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return (0L);
}

Bon, voila le problème est dans la variblale Path, a ce niveau

case FICHIER_SAVEAS:
MessageBoxEx(NULL,Path,"Error",MB_OK,0x040c);
Path = SauverSousFichier(hWnd);
MessageBoxEx(NULL,Path,"Error",MB_OK,0x040c);

J'utilise deux messageBox pour tester, la première m'affiche donc une chaine vide et la deuxième le résultat retourné par la fonction SauverSousFichier. Jusqu'ici tout va bien mais lorsque je repasse par le même code:

case FICHIER_SAVEAS:
MessageBoxEx(NULL,Path,"Error",MB_OK,0x040c);
Path = SauverSousFichier(hWnd);
MessageBoxEx(NULL,Path,"Error",MB_OK,0x040c);

La première messageBox me réaffiche une chaine vide alors que je souhaiterais quelle m'affiche la chaine quelle m'avais affiché au passage précédent.
Je ne comprends pas, c'est comme si la variable Path était vidé après chaque appel de la fonction WndProc.
Comment faire pour que le contenu de cette variable ne se vide pas après chaque passage dans cette fonction?

3 réponses

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
17 févr. 2003 à 22:28
Salut,
Path = SauverSousFichier(hWnd);
comment veux-tu que retourne quoi que ce soit.
Faudrait que to Path soir char *Path; et que ta func SauverSousFichier alloue la memoire et fasse pointer Path dessus. Toi tu as defini une constante chaine de longueur nulle.
char Path[260];
change tes funcs ainsi:
BOOL SauverSousFichier(HWNDhwnd, char *pszPath);
ta func doit remplir pszPath et retouner 1 si fait sinon 0.
Idem pour le reste.
ciao...
0
jonathanmcdougall Messages postés 64 Date d'inscription dimanche 9 février 2003 Statut Membre Dernière intervention 7 mars 2003
18 févr. 2003 à 04:01
> Salut a tous, j'ai un blem de variable dans mon programme. Voici mon code source.
>

<snip>

>
> Bon, voila le problème est dans la variblale Path, a ce niveau
>
> case FICHIER_SAVEAS:
>MessageBoxEx(NULL,Path,"Error",MB_OK,0x040c);
>Path = SauverSousFichier(hWnd);
>MessageBoxEx(NULL,Path,"Error",MB_OK,0x040c);
>
> J'utilise deux messageBox pour tester, la première m'affiche donc une chaine vide et la deuxième le résultat retourné par la fonction SauverSousFichier. Jusqu'ici tout va bien mais lorsque je repasse par le même code:
>
>
> case FICHIER_SAVEAS:
>MessageBoxEx(NULL,Path,"Error",MB_OK,0x040c);
>Path = SauverSousFichier(hWnd);
>MessageBoxEx(NULL,Path,"Error",MB_OK,0x040c);
>
> La première messageBox me réaffiche une chaine vide alors que je souhaiterais quelle m'affiche la chaine quelle m'avais affiché au passage précédent.
> Je ne comprends pas, c'est comme si la variable Path était vidé après chaque appel de la fonction WndProc.
> Comment faire pour que le contenu de cette variable ne se vide pas après chaque passage dans cette fonction?
>

Faudrait voir le code de SauverSousFichier(), mais voilà ce que je pense être ton code :

char *SauverSousFichier(HWND hwnd)
{
// ...
return "mon path";

// ou encore

char path[32];
//.. mettre qqch dans 'path'
return path;
}

Dans ces deux cas, la valeur de retour est une string *temporaire*, c'est-à-dire qu'elle est locale à la fonction. En faisant

Path = SauverSousFichier(HWND hwnd);

tu stockes l'adresse d'une string qui *n'existe plus* dans Path. Tu vas répondre que des fois Path contient la bonne valeur, mais c'est un coup de chance. La mémoire à cette adresse n'a probablement pas été touchée. C'est un exemple typique de 'undefined behavior', comportement non-défini.

Tu as deux solutions : 1) utiliser des std::string ou 2) allouer ta chaine avec new.

1) # include <string>

//note : retour par valeur
std::string SauverSousFichier(HWND hwnd)
{
// ....
return std::string("mon path");

// ou

const char *monPath;
// ...
return std::string(monPath);
}

2)
char *SauverSousFichier(HWND hwnd)
{
const char* monPath;
//....

//allocation dynamique
// la longueur est strlen(monPath)
const char* pour_retourner = new char[strlen(monPath)];

//copie
strcpy(pour_retourner, monPath);

//retour
return pour_retourner;
}

Mais bien sûr, il ne faut pas oublier de faire un delete sur la variable qui stockera cette chaine. Ce qui fait que :

Path = SauverSousFichier(hwnd);
Path = SauverSousFichier(hwnd);
delete[] Path;

est un memory leak, puisque la chaine allouée avec new n'est pas deletée. La bonne manière sera celle-ci :

Path = SauverSousFichier(hwnd);
delete[] Path;
Path = SauverSousFichier(hwnd);
delete[] Path;

Mais la vraie bonne manière serait d'utiliser les std::string, ça t'enlèverait un paquet de problèmes. Note que les std::string se convertissent en const char* avec la fonction membre c_str().

Jonathan Mcdougal
Montréal, Québec
mcdougalljonathan@hotmail.com
http://www.multimania.com/utopiasoftware
0
cs_bouba Messages postés 518 Date d'inscription dimanche 2 décembre 2001 Statut Membre Dernière intervention 10 novembre 2007 3
18 févr. 2003 à 11:55
Vraiment, je te remercie, c'est super je suis enfin débloqué!!!!!
0
Rejoignez-nous