OVH Cloud OVH Cloud

LRESULT CALLBACK WndProc(HWND hWnd, ....) en parametre

7 réponses
Avatar
dark poulpo
lu, voila,

jai une classe x qui doit comporter la fonction en tant que public
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM
lParam)

et jai besoin de passer cette fonction de la classe x a un parametre d'un
fonction public de la classe y

tagada(WNDPROC lpFunc);

par y.tagada(x.WndProc); // jai essayé aussi y.tagada((WNDPROC )x.WndProc);

seulement jai bo essayé jai toujours un probleme de casting, jai essayé des
tas de possibilité jarrive jamais a trouver la bonne.

merci d'avance de m'aiguiller

--
-----
http://dark.freezee.org/
- Dark Update v1.0
- Dark Emule v0.44b r4
- Dark Desktop 3D (en cours)

7 réponses

Avatar
Vincent Burel
"dark poulpo" wrote in message
news:41ec1f09$0$25775$
lu, voila,

jai une classe x qui doit comporter la fonction en tant que public
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM
lParam)



oulah !!! la drolerie ! :-)

Si votre fonction WndProc est une fonction membre, alors son vrai prototype
est

WndProc(ClassX lpThis, HWND , UINT , WPARAM , LPARAM )

le premier paramètre (caché) est un pointeur sur votre object x... hors ce
n'est pas ce que window considère comme être un WNDPROC. (et bien sur aucun
CAST ne marchera , quand bien même il y aura grande chance d'avoir un crash
au premier appel, car le système appelera une fonction avec 4 paramètres qui
en comporte en réalité 5 ... usuellement ca fait BOOM sur RET - epression de
programmeur - )

vous n'avez pas d'autre choix que de sortir votre WndProc de votre objet.
cette callback ne peut tout simplement pas être une fonction membre d'un
objet ++.

VB
Avatar
dark poulpo
daccord!!!!!!!!!!!!!!! tout s'explique!!!!

merci, je suis un peu deg, va falloir coder pas propore du coup, mais bon,
je dirais que c la faute a eux!!!! ;-p


--
-----
http://dark.freezee.org/
- Dark Update v1.0
- Dark Emule v0.44b r4
- Dark Desktop 3D (en cours)
Avatar
Arnaud Debaene
dark poulpo wrote:
daccord!!!!!!!!!!!!!!! tout s'explique!!!!

merci, je suis un peu deg, va falloir coder pas propore du coup, mais
bon, je dirais que c la faute a eux!!!! ;-p



Vincent a raison de dire que tu ne peux passer directement de fonction
membre comme WndProc. Ca ne veut pas dire qu'il n'est pas possible de faire
des mécanismes objets pour les fenêtres : La preuve, tous les frameworks de
manipulation de fenêtres le font! Ceci-dit, ce n'est pas trivial.

Je connais 3 façons de faire çà (si vous en connaissez d'autres, je suis
preneur) : Dans les 3 cas, je vais appeler CWindow la classe C+ qui doit
wrapper le HWND.

- Utiliser SetWindowLong pour stocker dans le HWND un pointeur vers l'objet
CWindow (ou dérivé) correspondant. La fonction statique WndProc se contente
de récupérer le pointeur en question avec GetWindowLong et d'appeler la
fonction virtuelle qui va bien sur l'instance en question.

- Utiliser une table globale de correspondance HWND <-->objet C++ CWindow.
Ensuite, pareil que pour le cas précédent : Une fonction WndProc statique
recherche dans cette table l'objet correspondant à son paramètre HWND et
invoque la méhode virtuelle qui va bien. C'est la méthode utilisée par les
MFC (avec une table par thread au lieu d'une table globale).

- Utiliser un thunk (petit bout de code en assembleur généré dynamiquement)
comme WndProc. Ce thunk remplace dans la pile courante le paramètre HWND
d'une WndProc "normale" par le pointeur "this" de l'objet CWindow
correspondant, puis il fait un JMP sur la fonction membre de l'objet en
question. La constitution de la stack frame est faite de telle façon que la
fonction en question reçois alors bien tous ses paramètres. Voire ATL, qui
utilise cette méthode, pour les détails gore.
Cette méthode est la plus trash et délicate à mettre en oeuvre (et hautement
indéfinie par rapport à la norme C++!), ceci dit c'est la plus efficace (pas
de fonction virtuelle).

Arnaud
MVP - VC
Avatar
dark poulpo
> Vincent a raison de dire que tu ne peux passer directement de fonction
membre comme WndProc. Ca ne veut pas dire qu'il n'est pas possible de


faire
des mécanismes objets pour les fenêtres : La preuve, tous les frameworks


de
manipulation de fenêtres le font! Ceci-dit, ce n'est pas trivial.

Je connais 3 façons de faire çà (si vous en connaissez d'autres, je suis
preneur) : Dans les 3 cas, je vais appeler CWindow la classe C+ qui doit
wrapper le HWND.

- Utiliser SetWindowLong pour stocker dans le HWND un pointeur vers


l'objet
CWindow (ou dérivé) correspondant. La fonction statique WndProc se


contente
de récupérer le pointeur en question avec GetWindowLong et d'appeler la
fonction virtuelle qui va bien sur l'instance en question.

- Utiliser une table globale de correspondance HWND <-->objet C++ CWindow.
Ensuite, pareil que pour le cas précédent : Une fonction WndProc statique
recherche dans cette table l'objet correspondant à son paramètre HWND et
invoque la méhode virtuelle qui va bien. C'est la méthode utilisée par les
MFC (avec une table par thread au lieu d'une table globale).

- Utiliser un thunk (petit bout de code en assembleur généré


dynamiquement)
comme WndProc. Ce thunk remplace dans la pile courante le paramètre HWND
d'une WndProc "normale" par le pointeur "this" de l'objet CWindow
correspondant, puis il fait un JMP sur la fonction membre de l'objet en
question. La constitution de la stack frame est faite de telle façon que


la
fonction en question reçois alors bien tous ses paramètres. Voire ATL, qui
utilise cette méthode, pour les détails gore.
Cette méthode est la plus trash et délicate à mettre en oeuvre (et


hautement
indéfinie par rapport à la norme C++!), ceci dit c'est la plus efficace


(pas
de fonction virtuelle).




ca tombe bien que tu expliques cela parceque jai changé la structure de mes
classes de facon a avoir la fameuse fonction definit en privée dans la meme
classe qui en a besoin, mais le probleme est resté le meme.

donc si jai bien compris, comme je ne crée qu'ne seul fenetre,
dans ma classe, je crée la class WNDCLASS en y mettant une fonction globale
de base, et ensuite des que je crée ma fenetre je fait un
SetWindowLong(hWnd,GWL_WNDPROC,(long)WndProc); //WndProc etant une fonction
privée

c ca?

je vais essayer, des que possible.

merci!!!!!!


--
-----
http://dark.freezee.org/
- Dark Update v1.0
- Dark Emule v0.44b r4
- Dark Desktop 3D (en cours)
Avatar
dark poulpo
> donc si jai bien compris, comme je ne crée qu'ne seul fenetre,
dans ma classe, je crée la class WNDCLASS en y mettant une fonction


globale
de base, et ensuite des que je crée ma fenetre je fait un
SetWindowLong(hWnd,GWL_WNDPROC,(long)WndProc); //WndProc etant une


fonction
privée



dans la rubrique jai la boule, jai toujours le meme message derreur, ca
menerve, jai besoin de lavoir en methode parceque dedans jaccede a des
proprietes de la classe, et jai pas envi de faire un genre laclass.variable
pour y acceder.

mais bon, en attendant c ce que je vais faire, le temps davoir une solution.



merci,


--
-----
http://dark.freezee.org/
- Dark Update v1.0
- Dark Emule v0.44b r4
- Dark Desktop 3D (en cours)
Avatar
adebaene
dark poulpo wrote:
>

ca tombe bien que tu expliques cela parceque jai changé la structure


de mes
classes de facon a avoir la fameuse fonction definit en privée dans


la meme
classe qui en a besoin, mais le probleme est resté le meme.



Quelle fonction? WndProc? Le fait d'être en privé ou en public n'a
rien à voir avec le problème! Le vrai problème, c'est que la classe
WndProc doit-être soit une fonction globale, soit une fonction membre
statique de classe, de façon à éviter le paramètre supplémentaire
"this" dont a parlé Vincent.


donc si jai bien compris, comme je ne crée qu'ne seul fenetre,
dans ma classe, je crée la class WNDCLASS en y mettant une fonction


globale
de base, et ensuite des que je crée ma fenetre je fait un
SetWindowLong(hWnd,GWL_WNDPROC,(long)WndProc); //WndProc etant une


fonction
privée

c ca?


Non, pas du tout! Relis nos messages : WndProc doit être STATIQUE
(privée ou pas, c'est à toi de voir, ca n'a pas trop d'importance
pour l'instant). Cette fonction statique doit utiliser l'une des
méthodes que j'ai évoqué pour récupérer un pointeur this sur
l'instance correspondante au HWND, et appeler la méthode virtuelle
"WndProc_Implementation" de l'objet en question.

Arnaud
MVP - VC
Avatar
dark poulpo
merci,

lol,je viens de comprendre pourquoi ya 1an javais mis ca
SetProp(hWnd, "PROP_WNDPROC", (HANDLE) (this)); apres la creation de la
fenetre
et MACLASSE * Tool = (MACLASSE *) GetProp(hwnd, "PROP_WNDPROC"); dans
WndProc()

javais deja la solution dans mon code, comme quoi defois on sais plus
pourquoi on tape des choses. :-p


--
-----
http://dark.freezee.org/
- Dark Update v1.0
- Dark Emule v0.44b r4
- Dark Desktop 3D (en cours)