MyXiLo
Messages postés57Date d'inscriptionvendredi 21 mai 2004StatutMembreDernière intervention28 juillet 2006
-
1 juin 2006 à 20:51
ymca2003
Messages postés2070Date d'inscriptionmardi 22 avril 2003StatutMembreDernière intervention 3 juillet 2006
-
2 juin 2006 à 09:41
Bonsoir,
Mon soucis est que, lorsque je cast le resultat d'un GetWindowLong en un pointeur, l'appel d'une fonction virtuelle de l'objet pointe provoque une erreur lors de l'execution ("Unhandled exception at 0x0040149c in Ivy.exe: 0xC0000005: Access violation reading location 0x00000000.", avec VS 2005).
class MaClasse
{
virtual void MaFonction();
}
static LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
MaClasse *MonObjet=(MaClasse *)GetWindowLong(hwnd, GWL_USERDATA);
MonObjet->MaFonction(); // Genere une erreur si MaFonction est déclarée virtual
}
(Je precise que ma WindowProcedure est bien definie pour une WNDCLASSEX appartenant à MaClasse(dans cet exemple)).
Ce serait une erreur de debutant que ca n'aurait rien d'etonnant puisque j'en suis un :}.
vecchio56
Messages postés6535Date d'inscriptionlundi 16 décembre 2002StatutMembreDernière intervention22 août 201014 1 juin 2006 à 21:08
C'est plutot bizarre ca... Pour tester, tu peux essayer ca:
MaClasse* o1 = new ...;
LPARAM l = (LPARAM)o1;
MaClasse* o2 = (MaClasse)l;
o2->MaFonction();
Au pire, compare les adresse des objets de départ (au moment du SetWindowLong) et à l'arrivée (GetWindowLong). Je suppose qu'ils seront différents
(c'est comme ca que j'avais détecté le problème quand je l'avais eu)
vecchio56
Messages postés6535Date d'inscriptionlundi 16 décembre 2002StatutMembreDernière intervention22 août 201014 1 juin 2006 à 20:56
J'ai déja eu ce problème. Au moment du SetWindowLong, il faut que tu castes en (MaClasse*) (j'imagine que le vrai type de l'objet n'est pas MaClasse, mais un sous-type de MaClasse)
MyXiLo
Messages postés57Date d'inscriptionvendredi 21 mai 2004StatutMembreDernière intervention28 juillet 2006 1 juin 2006 à 21:04
Je cast deja en (MaClasse *) au moment du SetWindowLong en realite.
Effectivement c'est un sous-type, mais, meme si MaClasse n'est pas derivee, ca pose tout de meme un probleme.
MyXiLo
Messages postés57Date d'inscriptionvendredi 21 mai 2004StatutMembreDernière intervention28 juillet 2006 1 juin 2006 à 22:41
En fin de compte je viens de me rendre compte que c'est mon SetWindowLong qui ne fonctionnait pas. Je castais en (long) le pointeur que jobtenais precedement avec GetWindowLong en (MaClasse *). Mais, comme SetWindowLong n'etais pas encore appele au moment du GetWindowLong, cela renvoyait 0, que je passais ensuite a SetWindowLong apres l'avoir caste en (long). Ce qui etait donc tres stupide.
Du coup j'ai mis mon SetWindowLong juste après le CreateWindowEx, en lui passant (long)this en troisieme parametres, et ca marche parfaitement.
ymca2003
Messages postés2070Date d'inscriptionmardi 22 avril 2003StatutMembreDernière intervention 3 juillet 20067 2 juin 2006 à 09:41
Attention également à la façon de gérer cette sauvegarde de ptr dans le GWL_USERDATA.
Si le ptr à savegarder dans est passé lors de CreateWindow, il sera dans la structure CREATESTRUCT pointée pr lParam lors du traitement des message WM_NCCREATE et WM_CREATE.
Le piège c'est qu'avant ces messages, d'autres sont susceptible d'être traité (je sais plus lesquels)donc le ptr n'est pas encore mis dans GWL_USERDATA. Il faut dont testé le ptr avant...