Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: BlackZeroX en 15 Enero 2011, 01:43 am



Título: [Duda] CallBack
Publicado por: BlackZeroX en 15 Enero 2011, 01:43 am
.
Puedo redirigir un proceso por medio de funciones normales, pero lo que realmente quiero es redirrecionar a un miembro (una funcion) dentro de la clase, pero me marca error.

Como se puede hacer un CallBack a un miembro( Funcion ) de una clase?.

Código
  1. /* Con y sin & me marca error */
  2. /* Intento cambiar el proceso que resive los mensajes de "this->v_hWinSock" a otro proceso/mienbro de una clase */
  3. this->v_PrevProc = SetWindowLongA( this->v_hWinSock , GWL_WNDPROC, (DWORD)&this->WndProc);
  4.  

Dulces Lunas!¡.
.


Título: Re: [Duda] CallBack
Publicado por: Eternal Idol en 16 Enero 2011, 21:08 pm
Tiene que ser un metodo estatico debido a la convencion de llamada.

http://foro.elhacker.net/programacion_cc/iquestcomo_accedo_a_this_desde_una_funcion_callback-t285522.0.html


Título: Re: [Duda] CallBack
Publicado por: BlackZeroX en 17 Enero 2011, 08:26 am
.
Es similar pero no me da solución, ya que no le puedo pasar cualquier cosa a este redirrecionamiento que busco es solo cambiar el CallWindowProc de una ventana creada con CreateWindowsEX. a un miembro (funcion) de una clase siendo la misma clase en su constructor cuando se creo la ventana y despues como ya dije redirrecionar los mensajes entrantes de esta ventana a el miembro de la funcion en cuention.

CreateWindowEx + SetWindowLong + GWL_WNDPROC

Código
  1.  
  2. LONG WINAPI SetWindowLong(
  3.  __in  HWND hWnd,
  4.  __in  int nIndex,
  5.  __in  LONG dwNewLong
  6. );
  7.  
  8.  

Este es el proceso... que resive los mensajes.

Código
  1.  
  2. LRESULT CALLBACK cls_socket::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3. {
  4.  ... Codigo
  5. }
  6.  
  7.  

P.D.: Usare una solucion cutre haber que tal me va.

Dulces Lunas!¡.
.


Título: Re: [Duda] CallBack
Publicado por: Eternal Idol en 17 Enero 2011, 09:08 am
No se puede usar un metodo comun, tiene que ser estatico por la convencion de llamada, CALLBACK es un alias de __stdcall y esta convencion no pasa el puntero this. Podrias GWL_USERDATA para escribir y leer el puntero al objeto ...


Título: Re: [Duda] CallBack
Publicado por: BlackZeroX en 17 Enero 2011, 10:06 am
.
Esto ya esta solucionado con GWL_WNDPROC+GWL_USERDATA me las apañare perfectamente inclusive quitare ese feo vector con ese feo For.

Dulces Lunas!¡.


Título: Re: [Duda] CallBack
Publicado por: Eternal Idol en 17 Enero 2011, 11:03 am
De nada.


Título: Re: [Duda] CallBack
Publicado por: ThunderCls en 17 Enero 2011, 17:49 pm
.
Esto ya esta solucionado con GWL_WNDPROC+GWL_USERDATA me las apañare perfectamente inclusive quitare ese feo vector con ese feo For.

Dulces Lunas!¡.

Hola BlackZeroX▓▓▒▒░░, hace un tiempo tuve el mismo problema y busque en cada rincon y en cada foro que pude, pero las soluciones que encontre no me sirvieron, al final deje a un lado lo que intentaba hacer por si me surgia alguna solucion. Por lo que leo, al final sabes como lograrlo. Podias exponer el metodo que usastes en algo de codigo y asi ver si asi saco esta espina que tengo :(
Saludos y gracias de antemano ;)


Título: Re: [Duda] CallBack
Publicado por: Eternal Idol en 17 Enero 2011, 17:57 pm
¿Te referis a esto?
https://foro.elhacker.net/programacion_cc/c_ayuda_con_esta_clase-t311243.0.html

La solucion es la misma que te dieron en ese hilo, si queres usar la clase entonces el metodo tiene que ser estatico (como dije en este mismo hilo para pasar el puntero this podes usar GWL_USERDATA). Lee todo con atencion, incluidos los enlaces e hilos relacionados.


Título: Re: [Duda] CallBack
Publicado por: ThunderCls en 17 Enero 2011, 18:22 pm
¿Te referis a esto?
https://foro.elhacker.net/programacion_cc/c_ayuda_con_esta_clase-t311243.0.html

La solucion es la misma que te dieron en ese hilo, si queres usar la clase entonces el metodo tiene que ser estatico (como dije en este mismo hilo para pasar el puntero this podes usar GWL_USERDATA). Lee todo con atencion, incluidos los enlaces e hilos relacionados.

Eternal Idol, recuerdo haber leido la respuesta de Littlehorse, pero al final me parece que no pude lograr hacerlo como queria, igual deberia seguir intentandolo y leyendo, aunque bueno...un pedacito de codigo sencillo como el ejemplo que puse en ese hilo, pero funcional, no me vendria mal, por eso le pedi algun ejemplo a BlackZeroX▓▓▒▒░░ que al parecer lo consiguio en su codigo.
De todas formas gracias por responder  ;-)
Saludos


Título: Re: [Duda] CallBack
Publicado por: Eternal Idol en 17 Enero 2011, 18:43 pm
En los enlaces hay varios ejemplos. Lo unico que tenes que hacer es declarar el metodo como estatico, llamar a Set/GetWindowLong con GWL_USERDATA y hacer algun casting.


Título: Re: [Duda] CallBack
Publicado por: BlackZeroX en 17 Enero 2011, 20:08 pm
.
Te dejo esto el proceso WndProc aun no lo pongo como miembro de la clase aun que sera facil tal cual a dicho Eternal Idol haciendo dicha funcion como Static ( yo mientras trabajare de esta manera para depurar mi codigo ).

Código
  1.  
  2. LRESULT CALLBACK    WndProc     (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  3.  
  4. cls_socket::cls_socket()
  5. {   /*  Constructor */
  6.    this->Event_RequestConection    = NULL;
  7.    this->Event_GetData             = NULL;
  8.    this->Event_Closed              = NULL;
  9.    this->Event_Connent             = NULL;
  10.    this->Event_Error               = NULL;
  11.    this->v_socket                  = INVALID_SOCKET;
  12.    this->State                     = sckError;
  13.  
  14.    this->RemoteHost                = NULL;
  15.    this->RemotePort                = 0;
  16.    this->LocalPort                 = 0;
  17.  
  18.    if ( WSAStartup( MAKEWORD(2,2) , &this->v_wsadata  ) != NO_ERROR )
  19.        return;
  20.    this->v_hWinSock = CreateWindowExA( 0 , "STATIC" , "SOCKET_WINDOW",0, 0, 0, 0, 0, 0, 0, 0,NULL);
  21.    if (this->v_hWinSock != NULL)
  22.        if ( SetWindowLongA( this->v_hWinSock , GWL_USERDATA , (LONG)this ) == 0 )
  23.            if ( (this->v_PrevProc = SetWindowLongA( this->v_hWinSock , GWL_WNDPROC, (DWORD)WndProc)) != 0 ) {
  24.                this->v_ItsOk = true;
  25.                this->State = sckClosed;
  26.            }
  27. }
  28. cls_socket::~cls_socket() {   /*  Destructor */
  29.    WSACleanup();
  30.    if ( this->v_PrevProc != 0 )
  31.        SetWindowLongA (this->v_hWinSock , GWL_WNDPROC, this->v_PrevProc);
  32.    if ( this->v_hWinSock != NULL )
  33.        DestroyWindow (this->v_hWinSock);
  34. }
  35.  
  36. LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  37.    char            *v_abuffer      = NULL;
  38.    char            v_buffer[1024]  = {};
  39.    int             v_res           = 0;
  40.    unsigned int    v_lenstr        = 0;
  41.    cls_socket      *thisClass      = NULL;
  42.    SOCKET          AceptSocket     = INVALID_SOCKET;
  43.  
  44.    if ( uMsg != 1025 )
  45.        return DefWindowProc(hWnd, uMsg, wParam, lParam);
  46.  
  47.    /* Recuperamos la Clase */
  48.    thisClass = (cls_socket*)GetWindowLongA ( hWnd , GWL_USERDATA );
  49.    if ( thisClass == NULL )
  50.        return DefWindowProc(hWnd, uMsg, wParam, lParam);
  51.    switch ( lParam ) {
  52.        case FD_CONNECT:
  53.            thisClass->State = sckConnected;
  54.            /* Evento */
  55.            if ( thisClass->Event_Connent != NULL )
  56.                thisClass->Event_Connent ( thisClass );
  57.            break;
  58.        case FD_READ:
  59.            v_res   = 0;
  60.            v_lenstr  = 0;
  61.            do {
  62.                v_res = recv(  thisClass->v_socket , &v_buffer[0] , 1024 , 0 );
  63.                if ( v_res > 0 ) {
  64.                    v_lenstr += v_res;
  65.                    v_abuffer = (char*)realloc(v_abuffer, sizeof(char) * (v_lenstr+1));
  66.                    memcpy( &v_abuffer[v_lenstr-v_res], &v_buffer[0] , v_res);
  67.                }
  68.            } while ( v_res > 0 );
  69.            if ( v_lenstr > 0 ) {
  70.                v_abuffer[v_lenstr] = '\0';
  71.                /* Evento */
  72.                if ( thisClass->Event_GetData != NULL )
  73.                    thisClass->Event_GetData ( v_abuffer , v_lenstr , thisClass );
  74.                free ( v_abuffer );
  75.            }   //  if
  76.            break;
  77.        case FD_WRITE:
  78.            break;
  79.        case FD_CLOSE:
  80.            thisClass->State = sckClosed;
  81.            closesocket( thisClass->v_socket );
  82.            thisClass->v_socket = INVALID_SOCKET;
  83.            /* Evento */
  84.            if ( thisClass->Event_Closed != NULL )
  85.                thisClass->Event_Closed ( thisClass );
  86.            break;
  87.        case FD_ACCEPT:
  88.            //sockaddr        SockAcept;
  89.            if ( ( AceptSocket = accept( thisClass->v_socket , NULL , NULL ) ) != INVALID_SOCKET )
  90.                /* Evento */
  91.                if ( thisClass->Event_RequestConection != NULL )
  92.                    thisClass->Event_RequestConection ( &AceptSocket , thisClass );
  93.            break;
  94.        default: break;
  95.    }   //  switch
  96.    return 0;
  97. }
  98.  
  99.  

Temibles Lunas!¡.
.


Título: Re: [Duda] CallBack
Publicado por: ThunderCls en 17 Enero 2011, 21:05 pm
Gracias Black, vere que hago con esta info  ;-)
Saludos