HOOK: Problème de cast C2440

Résolu
RV2931 Messages postés 185 Date d'inscription samedi 21 mai 2005 Statut Membre Dernière intervention 16 juillet 2016 - 28 oct. 2007 à 14:43
RV2931 Messages postés 185 Date d'inscription samedi 21 mai 2005 Statut Membre Dernière intervention 16 juillet 2016 - 29 oct. 2007 à 22:35
Bonjour,

Je fais uen petite appli OpenGL. J'ai crée une classe qui affiche de l'OpenGL dans n'importe quel composant (HWND) de l'interface, bref. Je voudrais que la gestion des interactions clavier et souris sur le composant soit géré automatiquement par la classe et non par la WndProc du programmer principal. Je veux donc utiliser un hook mais je n'arrive pas :o(

J'ai vu sur un post qu'il fallait faire comme si on prenait la fonction de hook d'une DLL, ce qui explique le format de la fonction hook, sinon ça se présente comme ça pour le moment :

class OGLW
{
public:
    PIXELFORMATDESCRIPTOR pfd;
    int iFormat;
    HDC hDC;
    HGLRC hRC;
    HWND hWnd;
public:
    OGLW(GLvoid);
    OGLW(HWND hWnd,vector<float>*VerticesTab,vector<float>*ColorsTab);
    __declspec(dllexport) LRESULT CALLBACK HookWndProc(int nCode, WPARAM wParam, LPARAM lParam );
    bool InitGL(HWND hWnd,vector<float>*VerticesTab,vector<float>*ColorsTab);
    bool ReSizeGLScene(GLsizei width, GLsizei height);
    bool DrawGLScene(GLvoid)=0;
    ~OGLW(void);
};

bool OGLW::InitGL(HWND hWnd,vector<float>*VerticesTab,vector<float>*ColorsTab)
{
   
    InitGL(hWnd,VerticesTab,ColorsTab);
    //Mise en place du Hook
    this->hWnd=hWnd;
    HINSTANCE hExe = GetModuleHandle(NULL);
    SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)HookWndProc,hExe,NULL);
....
}

__declspec(dllexport) LRESULT CALLBACK OGLW::HookWndProc(int nCode, WPARAM wParam, LPARAM lParam )
{
    switch(nCode)
    {
       
    case WM_LBUTTONDOWN:MessageBox(hWnd,"Bouton Gauche","Hook",MB_OK);break;
    default:break;
    }
    return CallNextHookEx(hKeyHook, nCode,wParam,lParam);
}

Et là, c'est le drame :  error C2440: 'cast de type' : impossible de convertir de 'overloaded-function' en 'HOOKPROC' sous Visual C++

Donc voilà, je ne sais pas quoi faire pour résoudre le problème

Une solution ??

Merci

RV

L'intelligence est la chose la mieux répartie chez l'homme, car quoi qu'il en soit pourvu, il a toujours l'impression d'en avoir assez. "Descartes"

11 réponses

cs_juju12 Messages postés 966 Date d'inscription samedi 3 avril 2004 Statut Membre Dernière intervention 4 mars 2010 4
28 oct. 2007 à 16:22
Tu peux pas déclarer des fonctions membres de classe comme CALLBACK dans l'API Windows puisqu'elles sont __thiscall (nécessitent un pointeur this passé implicitement en premier paramètre par le compilo), Windows réclame du __stdcall. Une méthode courante est de stocker un pointeur sur la classe en paramètre avec SetWindowLong et GWL_USERDATA; après tu fais une fonction non-membre (éventuellement static) de hook qui se chargera de répartir dans la bonne classe :
GlobalHookWndProc(HWND hWnd,..)
{
OGWL* pClass=(OGWL*)GetWindowLong(hWnd,GWL_USERDATA);
pClass->HookWndProc(hWnd,...);
}

Sinon ce que tu pourrais faire c'est éviter le hook et passer par un sous-classement du contrôle, mais tu aura besoin du même genre de manips pour appeler une fonction membre de classe.
3
RV2931 Messages postés 185 Date d'inscription samedi 21 mai 2005 Statut Membre Dernière intervention 16 juillet 2016
28 oct. 2007 à 17:53
Ouay, ça me paraît compliqué, c'est dommage parce que c'est tout a fait ça que je voudrais faire, créer une fenêtre OpenGL totalement indépendante, mais je pense que je vais faire comme pour ma fonction DrawScene, je vais faire une petite fonction qu'on appelle dans la WndProc principale qui prend en paramètre le message et les wParam et lParam et je pense que je vais m'en sortir.

Merci

L'intelligence est la chose la mieux répartie chez l'homme, car quoi qu'il en soit pourvu, il a toujours l'impression d'en avoir assez. "Descartes"
0
RV2931 Messages postés 185 Date d'inscription samedi 21 mai 2005 Statut Membre Dernière intervention 16 juillet 2016
28 oct. 2007 à 17:55
Je t'ai mis réponse acceptée parce que je vais faire autrement, mais après réflexion, si tu peux être plus précis, et explicité le sous classement, ça pourra toujours servir à d'autres

L'intelligence est la chose la mieux répartie chez l'homme, car quoi qu'il en soit pourvu, il a toujours l'impression d'en avoir assez. "Descartes"
0
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
28 oct. 2007 à 18:10
Salut,
De toute façon, pour un hook de type WH_GETMESSAGE, tu seras obligé d'utiliser une DLL externe. Un hook global avec la  fonction de hook intégrée dans l'exécutable ne fonctionne qu'avec les types WH_KEYBOARD_LL et WH_MOUSE_LL.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
RV2931 Messages postés 185 Date d'inscription samedi 21 mai 2005 Statut Membre Dernière intervention 16 juillet 2016
28 oct. 2007 à 18:12
J'ai trouvé un truc pas mal sur le sous classement, assez simple mais j'ai pas encore testé si ça fonctionnait juste comme ça pour ce que j'ai envie de faire

http://www.cppfrance.com/codes/WIN32-BOUTON-BITMAP-SUBCLASSING_35623.aspx

Sinon, question annexe, comment fait on pour récupérer le hWnd de l'objet sur lequel l'utilisateur vient de cliquer, ou celui qui le focus... ???

L'intelligence est la chose la mieux répartie chez l'homme, car quoi qu'il en soit pourvu, il a toujours l'impression d'en avoir assez. "Descartes"
0
RV2931 Messages postés 185 Date d'inscription samedi 21 mai 2005 Statut Membre Dernière intervention 16 juillet 2016
28 oct. 2007 à 18:15
Ben à la limite, si tu as un exemple de code pour les WH_KEYBOARD_LL et WH_MOUSE_LL, ça pourrait me servir je pense...

L'intelligence est la chose la mieux répartie chez l'homme, car quoi qu'il en soit pourvu, il a toujours l'impression d'en avoir assez. "Descartes"
0
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
28 oct. 2007 à 18:32
Regarde mon dernier code source dans lequel j'utilise un hook WH_KEYBOARD_LL:
http://www.cppfrance.com/codes/DETOURNER-FRAPPE-CLAVIER_43964.aspx
Pour le sous-classement, voici une réponse que j'ai posté dans le forum:
http://www.cppfrance.com/infomsg_BLOQUER-TOUCHE-ENTREE_327459.aspx
0
cs_juju12 Messages postés 966 Date d'inscription samedi 3 avril 2004 Statut Membre Dernière intervention 4 mars 2010 4
28 oct. 2007 à 18:42
Sinon pour récupérer le hWnd ben c'est simplement celui qui est fourni à la WndProc du contrôle en question...
Pour le focus il y a peut-être GetFocus() mais je l'ai jamais essayé je sais pas si ca renvoie la fenêtre principale ayant le focus ou bien le contrôle (je penche pour le 2 tout de même).
0
RV2931 Messages postés 185 Date d'inscription samedi 21 mai 2005 Statut Membre Dernière intervention 16 juillet 2016
28 oct. 2007 à 21:14
J'ai essayé la technique static WndProc et GWL_USERDATA mais je crois que mon pointeur est tronqué, mon OGLW* ne tient peut-être pas sur 32 bits

C'est bien comme ça :

static LRESULT CALLBACK OGLW::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

 {
    // Récupération du paramètre et donc du pointeur vers l'instance de la classe associée à l'objet hWnd
     OGLW*MyOGLW=(OGLW*)GetWindowLong(hWnd,GWL_USERDATA);
    // Accès à une donnée de l'instance de classe
    MyOGWL->MyVar=0;
    ...
}

bool OGLW::InitGL(HWND hWnd,float*VerticesTab,float*ColorsTab)
{
    // Remplacement de la fonction de traitement
    OldWndProc=(WNDPROC) SetWindowLong(hWnd,GWL_WNDPROC,(LPARAM)WndProc);
    // Mise du pointeur de l'instance de classe dans le user data de la fenêtre hWnd
    SetWindowLong(hWnd,GWL_USERDATA,(LONG)this);
       ....
}

ça fonctionne, mais petite subtilité, je suis obligé de faire un SetFocus(hWnd) pour récupéré les évênements Keyboard,
Est-ce normal ? pourquoi ? et peut-être y a-t-il une autre manière ???

L'intelligence est la chose la mieux répartie chez l'homme, car quoi qu'il en soit pourvu, il a toujours l'impression d'en avoir assez. "Descartes"
0
cs_juju12 Messages postés 966 Date d'inscription samedi 3 avril 2004 Statut Membre Dernière intervention 4 mars 2010 4
29 oct. 2007 à 20:15
Ca dépend si t'es en 32 ou 64 bits; mais de toutes façons Windows préconise d'utiliser GetWindowLongPtr et SetWindowLongPtr en lieu et place des précédentes; en fait c'est juste des macros pour pas avoir de problème de portage 32/64 bits.
Sinon j'ai cru comprendre que ça marchait, ce n'est pas le cas?
0
RV2931 Messages postés 185 Date d'inscription samedi 21 mai 2005 Statut Membre Dernière intervention 16 juillet 2016
29 oct. 2007 à 22:35
Oui oui

en fait ça fonctionne très bien, j'ai fait une fonction static WndProc dans ma classe et j'accède à la l'instance par le pointeur passé en paramètre au composant, nickel

Merci

L'intelligence est la chose la mieux répartie chez l'homme, car quoi qu'il en soit pourvu, il a toujours l'impression d'en avoir assez. "Descartes"
0
Rejoignez-nous