Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: ThunderCls en 20 Noviembre 2010, 14:58 pm



Título: [ C++ ] Ayuda con esta clase!!!
Publicado por: ThunderCls en 20 Noviembre 2010, 14:58 pm
Un saludos amigos, a ver si me pueden sacar de esta. Trasteando con clases y otras cosas me han surgido algunos problemas con una clase y su implementacion. El codigo es el siguiente:

Código
  1. //---------------------------------------------------------------------------
  2. class a
  3. {
  4.  private:
  5.    WNDPROC lpPrevProc;
  6.    LRESULT CALLBACK NewProc(HWND, UINT, WPARAM, LPARAM);
  7.  
  8.  public:
  9.    void Hookea (HANDLE);
  10.    ...
  11. };
  12.  
  13. //---------------------------------------------------------------------------
  14. void a::Hookea (HANDLE hWnd)
  15. {
  16.  lpPrevProc = (WNDPROC)GetWindowLong((HWND__*)hWnd, GWL_WNDPROC);
  17.  
  18.  SetWindowLongA((HWND__*)hWnd, GWL_WNDPROC, (DWORD)NewProc);
  19.  // E2235 Member function must be called or its address taken Compiler error
  20.  // Probe con "(DWORD)&a::RealWinWndProc" pero me dice
  21.  // E2031 Cannot cast from 'type1' to 'type2' Compiler error
  22. }
  23.  
  24. //---------------------------------------------------------------------------
  25. LRESULT CALLBACK a::NewProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  26. {
  27.  switch(uMsg)
  28.  {
  29.    case WM_DESTROY:
  30.      MessageBox(hwnd, "Adios Mundo", "Bye!!!", MB_ICONINFORMATION);
  31.    break;
  32.  }
  33.  
  34.  return CallWindowProc(lpPrevProc, hwnd, uMsg, wParam, lParam);
  35. }
  36. //---------------------------------------------------------------------------

Alli estan los errores comentados que me tira el compilador, pero no entiendo el por que, pues he visto algun ejemplo en VC++ y justamente se hace esto:
Código
  1. SetWindowLongA(hWnd, GWL_WNDPROC, (DWORD)(&a::NewProc));

Pero cuando lo paso al CBuilder e intento compilar me sale con que:
E2031 Cannot cast from 'long (__stdcall a::*)(HWND__ *,unsigned int,unsigned int,long)' to 'unsigned long'

Ahora, si hago lo mismo, pero programando estructuradamente, o sea, sin clases, no hay problemas y me coge la linea de la siguiente forma sin quejarse:
Código
  1. SetWindowLongA((HWND__*)hWnd, GWL_WNDPROC, (DWORD)NewProc);

Mi pregunta, como puedo obtener el puntero al metodo a::NewProc para poder pasarlo como parametro en SetWindowLong como DWORD???, que estoy haciendo mal o que me falta por hacer???
Agradeceria cualquier ayuda al respecto, de verdad que esto ya me esta dando dolores de cabeza.  >:(
Gracias por leer
Saludos


Título: Re: [ C++ ] Ayuda con esta clase!!!
Publicado por: Littlehorse en 21 Noviembre 2010, 00:31 am
Cuando usas callbacks lo ideal es que utilices funciones estándar u miembros static. De otra forma aparecen estos errores, ya que un miembro de una clase no es lo mismo que una función, siendo que el primero tiene un parámetro oculto (this) y opera en el marco de un objeto.

 Si usas la clase a modo de contenedor siempre podes declarar todos los miembros static, pero no habría forma de acceder a las variables miembro por tanto tendrías que usar globales. No es una muy buena idea pero tal vez es la solución mas fácil, pero no tendría mucho sentido ya que seria como no utilizar una clase en absoluto.
 
 Otra es declarar el proc como static:
 
 
Código
  1. static LRESULT CALLBACK Proc(HWND, UINT, WPARAM, LPARAM);

y darle un par de vueltas al resto del código.
 
 O podes hacer un miembro static que haga como intermediario, algo así:
 
 
Código
  1. static LRESULT CALLBACK WrappingSome(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)//The tricky way...
  2. {
  3. a* ObjPtr = reinterpret_cast<a*>(GetWindowLong(hWnd, GWL_WNDPROC));
  4. return ObjPtr->NewProc( hWnd, uMsg, wParam, lParam );
  5. }
  6.  


Y hay otras formas mas, pero comienza buscando sobre punteros a miembros para tener claro el porque del error y el porque te funciona utilizando funciones y no miembros.

Saludos