如何将GTK+-2.0的信号、回调处理映射成类成员函数的调用--VC中测试(虚拟继承类及多继承)

//  TestDelegate.cpp : 定义控制台应用程序的入口点。
//

#include  " stdafx.h "

typedef unsigned  long gulong;
typedef  char gchar;
typedef  void* gpointer;
typedef  long GObject;

void* g_lpObject =  0;


class Object
{
public:
    Object() {};
     virtual ~Object() {};
};

class BaseObject:  virtual  public Object
{
public:
    BaseObject();
     virtual ~BaseObject();

     /*  创建对象并绑定信号的接口  */
     virtual gulong setupObject() =  0;

// protected:
    typedef gulong (BaseObject::* CommonCallback)(GObject*instance, ...);

    typedef  struct tagOBJ_CALLBACK
    {
        BaseObject*     x_pThis;
        CommonCallback  x_pCallback;
        GObject*        x_pWidget;
    } ObjectCallbackInfo;

    GObject*    x_pObject;

    gulong ConnectSignal(gpointer instance,  const gchar *detailed_signal, CommonCallback c_handler);

// private:
    
// GSList* x_pObjectList;

     static gulong SignalProc( const ObjectCallbackInfo* lpObject, ...);
};

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

BaseObject::BaseObject():x_pObject(NULL)
{
}

BaseObject::~BaseObject()
{
     /*  释放所有分配的ObjectToMemFunc空间  */
}

gulong BaseObject::ConnectSignal(gpointer instance, 
                                  const gchar *detailed_signal,
                                 CommonCallback c_handler)
{
     /*  分配存放回调指针的空间  */
    ObjectCallbackInfo* lpObject = (ObjectCallbackInfo*)malloc( sizeof(ObjectCallbackInfo));
     if (NULL == lpObject)
    {
         return  0;
    }
    lpObject->x_pThis     =  this;
    lpObject->x_pCallback = c_handler;
    lpObject->x_pWidget   = (GObject*)instance;

    printf( " Object  :  0x%08x\n ", lpObject);
    printf( " This    :  0x%08x\n ", lpObject->x_pThis);
    printf( " Callback:  0x%08x\n ", lpObject->x_pCallback);
    printf( " Widget  :  0x%08x\n ", lpObject->x_pWidget);

     /*  将信息保存在slist中  */
     // x_pObjectList = g_slist_append(x_pObjectList, lpObject);

     /*  注册信号回调  */
     /*  return g_signal_connect_swapped(instance, detailed_signal, 
                                   &(BaseObject::SignalProc), lpObject);
*/
    g_lpObject = lpObject;
}

gulong BaseObject::SignalProc( const ObjectCallbackInfo* lpObject, ...)
{
    va_list pArgList;
    gulong ulRetcode;
     struct reserve_arg { gulong ulReserver[ 20];} *pstTemp;
    BaseObject* lpThis;
    CommonCallback pCallBack;

     /*  收到信号时,先判断指针  */
     if ( (NULL == lpObject) ) // || (NULL == lpObject->x_pCallback ) || (NULL == lpObject->x_pWidget))
    {
         return  0;
    }

    printf( " Object  :  0x%08x\n ", lpObject);
    printf( " This    :  0x%08x\n ", lpObject->x_pThis);
    printf( " Callback:  0x%08x\n ", lpObject->x_pCallback);
    printf( " Widget  :  0x%08x\n ", lpObject->x_pWidget);

     /*  取出this指针及成员函数指针  */
    va_start(pArgList, lpObject);
    pstTemp = ( struct reserve_arg*)pArgList;
    lpThis = lpObject->x_pThis;
    pCallBack = lpObject->x_pCallback;
    printf( " Param   :  %08x %08x %08x %08x\n ", pstTemp->ulReserver[ 0], pstTemp->ulReserver[ 1], pstTemp->ulReserver[ 2], pstTemp->ulReserver[ 3]);
    
     /*  调用成员函数  */
    ulRetcode = (lpThis ->* pCallBack)(lpObject->x_pWidget, *pstTemp);
    
    va_end(pArgList);

    printf( " Object  :  0x%08x\n ", lpObject);
    printf( " This    :  0x%08x\n ", lpObject->x_pThis);
    printf( " Callback:  0x%08x\n ", lpObject->x_pCallback);
    printf( " Widget  :  0x%08x\n ", lpObject->x_pWidget);

     return ulRetcode;
}

class TestDialog1:  public BaseObject
{
public:
     // virtual gulong setupObject();

protected:  
     virtual gulong __cdecl OnChange1( void *notebook1,  void *page, unsigned  int num);
};

class TestDialog2:  public BaseObject
{
public:
     // virtual gulong setupObject();
    
protected:  
     virtual gulong __cdecl OnChange2( void *notebook1,  void *page, unsigned  int num);
};


class TestDialog:  public TestDialog1,  public TestDialog2
{
public:
     virtual gulong setupObject();
    
protected:  
     // virtual gulong __cdecl OnChange1(void *notebook1, void *page, unsigned int num);
};

// 函数指针转换,可以把一种类型的数据直接转换成第二种类型的数据
template < class FuncPt1,  class FuncPt2>
inline FuncPt1 Func_Cast(FuncPt2 pt1)
{
    union __TranPt1ToPt2
    {
        FuncPt2 pointer2;
        FuncPt1 pointer1;
        unsigned  long data[ 5];
        unsigned  long* pt;
    } __Tran = {pt1};
    printf( " size of FuncPt1: %u\n "sizeof(FuncPt1));
    printf( " size of FuncPt2: %u\n "sizeof(FuncPt2));
    printf( " real value     : %08x, %08x, %08x, %08x\n ", __Tran.data[ 0], __Tran.data[ 1], __Tran.data[ 2], __Tran.data[ 3]);
    //printf( " pt   value     : %08x\n ", *(__Tran.pt));
     return __Tran.pointer1;
}

gulong TestDialog::setupObject()
{
    TestDialog2::ConnectSignal(( void*) 123" destroy ", Func_Cast<CommonCallback>(&TestDialog2::OnChange2));
    
     return  0;
}

gulong TestDialog1::OnChange1( void *notebook1,  void *page, unsigned  int num)
{
    printf( " TestDialog1::OnChange1\n ");
    printf( " this        : %08x\n "this);
    printf( " notebook    : %08x\n ", notebook1);
    printf( " page        : %08x\n ", page);
    printf( " Current Page: %d(%08x)\n ", num, num);
     return  0;
}


gulong TestDialog2::OnChange2( void *notebook1,  void *page, unsigned  int num)
{
    printf( " TestDialog2::OnChange2\n ");
    printf( " this        : %08x\n "this);
    printf( " Current Page: %d(%08x)\n ", num, num);
     return  0;
}

int main( int argc,  char* argv[])
{
    TestDialog* lpDialog = NULL;

    lpDialog =  new TestDialog;
    lpDialog->setupObject();
    BaseObject::SignalProc(( const BaseObject::ObjectCallbackInfo *)g_lpObject,  2344563);

    delete lpDialog;
    getchar();

     return  0;
}

 

注:在GCC中也调试通过(mingw32)

 

 

你可能感兴趣的:(gtk)