🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: es.comp.lenguajes.c++
Article #16274

Re: CALLBACK como metodo de una clase

#16274
From: Manuel Ruiz Tienza
Date: Tue, 31 Dec 1996 00:00
115 lines
4662 bytes
In article <01bbf266$1a891cc0$914a4cc3@miguel>, mangel@purplesys.es says...
>
>
>
>Enrique Ventura P�rez <eventura@theos.es> escribi� en art�culo
><32be3dcb.3114980@noticias.ibernet.es>...
>> El dia 22 Dec 1996 21:11:50 GMT, "miguel" <mangel@purplesys.es>
>> escribio:
>> 
>> >Alguien sabe si es posible que una callback sea un metodo de una clase.
>> >
>> >Gracias por adelantado.
>> >
>> >mangel@purplesys.es
>>
>> 
>> **** Esto es Correcto *************************************************
>> El problema de utilizar una funcion de una clase como CALLBACK es el
>> parametro "this" oculto que tienen todas las funciones de clase que no
>> esten declaradas como "static". 
>> 
>> *** Esto no tanto, ya que un CALLBACK es llamado por windows directamemnte
>> *** con lo cual tu pierdes todo control sobre los parametros que se la
>> *** pasan.

>> Si tiene declaracion static no te encontraras ningun problema, pero te
>> obligara a pasar cmo parametro del callback el elemento de la clase
>> sobre el cual quieres efectuar la operacion
>> 
>> *** Si bien los metodos estaticos no pueden redefinirse (virtuales).
>> *** a ver si te sirve esto de forma que no se estatico y pude
>> *** permitirse la redefinicion. (OK ??).



Bien Miguel, la cosa no es tan facil como definir un metodo estatico o 
dinamico, si bien es cierto que todos lo miembros de una clase deben tener 
como primer parametro un puntero a la instanciacion (objeto) este peque�o 
problema se puede solucionar con un thunk.

Te preguntaras que es un thunk, bien, un thunk es una parte de codigo que funciona como un
router, es decir, recibe mensaje y los re-encamina (no se si estara bien escrito) hacia otra
parte. Veamos como puedes definirte un thunk.

class MiClase
{
    public:
       ....
       ....
       virtual long WndProc( HWND, INT, WPARAM, LPARAM );
};

long CALLBACK WndProc_Thunk( HWND hwnd, INT msg, WPARAM wp, LPARAM lp )
{
    MiClase *ptr;
    CREATESTRUCT FAR *cs; 

    ptr = (MiClase *)GetWindowWord( hwnd, 0 );
    if( !ptr )
    {
        if( msg == WM_CREATE )
        {
           cs = (CREATESTRUCT FAR *)lp;
           ptr = (MiClase *)lp->lpCreateParams;
           SetWindowWord( hwnd, 0, (LONG)ptr );
           return ptr->WndProc( hwnd, msg, wp, lp );
        }
        return DefWndProc( hwnd, msg, wp, lp );
    }   
    else
      return ptr->WndProc( hwnd, msg, wp, lp );
}


Este codigo te debera dejar claro como funciona un thunk, 
Ahora diras, como llegua hasta aqui el puntero al objeto !!!!.
Bien cuando llamas a CreateWindow() como ultimo parametros le puedes pasar lo que
tu quieras, bien, es ahi donde debes pone this, mas o menos sera:

CreateWindow( "la_clase_TUYA_que_tu_quieras",
              .....
              (LPSTR)this);

Cuando se llama a CreateWindow, en el mensaje WM_CREATE y en el parametro LPARAM va
una estructura de creacion, entre los datos de la estructura va los datos 
de usuario para la creacion. (lpCreateParam) y eso sera un puntero a el objeto 
que has instanciado de la clase MiClase.

Como ves es un poco enrrevesado, pero en este principio se basan tanto las MFC de
microsoft como las OWL de Borland.

Unas peque�as nota: 
Ten cuidado con los modelos de memoria que usas, pq en funcion de este deberas
usar una funcion GetWindowXXXX (Long si los puntero son de 4 Bytes, Word si los
puntero son de 2 Bytes, yo he asumido que el modelo usaba punteros de 2 Bytes ).

Cuando registres la clase debes pone en cbWndExtra el tama�o que ocupara el
puntero, ya que de otra forma no tendras sitio donde almacenar el puntero.


Espero haberte ayudado. Si tienes algun problema o duda no dudes en mandarme
un e-mail.


ha, y feliz a�o nuevo.			

-- 
**************************************
*                                    *
*        Manuel Ruiz Tienza          *
*  (University of Granada - Spain)   *
*      m.joca@bjz.servicom.es        *
*                                    * 
**************************************
Technical Details
Message-ID: <5a9okg$c12@wendy.mad.servicom.es>
Path: arc1-ca.pugleaf.net!unknown!not-for-mail
References: <01bbf04d$8440ae00$844a4cc3@miguel> <32be3dcb.3114980@noticias.ibernet.es> <01bbf266$1a891cc0$914a4cc3@miguel>

Show Full Headers
Complete Article Headers
X-Google-Language: SPANISH,ASCII
X-Google-Thread: f53ec,a128c13e93fff8df
X-Google-Attributes: gidf53ec,public
From: m.joca@bjz.servicom.es (Manuel Ruiz Tienza)
Subject: Re: CALLBACK como metodo de una clase
Date: 1996/12/31
Message-ID: <5a9okg$c12@wendy.mad.servicom.es>
X-Deja-AN: 206932217
references: <01bbf04d$8440ae00$844a4cc3@miguel> <32be3dcb.3114980@noticias.ibernet.es> <01bbf266$1a891cc0$914a4cc3@miguel>
content-type: Text/Plain; charset=ISO-8859-1
organization: (University Of Granada - Spain)
mime-version: 1.0
newsgroups: es.comp.lenguajes.c++