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

 

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

#include "stdafx.h"

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

void* g_lpObject = 0;

class BaseObject
{
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 TestDialog: public BaseObject
{
public:
    virtual gulong setupObject();

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


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

gulong TestDialog::OnChange(void *notebook1, void *page, unsigned int num)
{
    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;
}

int _tmain(int argc, _TCHAR* argv[])
{
    TestDialog* lpDialog = NULL;

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

    delete lpDialog;
    getchar();

    return 0;
}

 

原文地址:https://www.cnblogs.com/eaglexmw/p/3056924.html