海阔天空

海阔凭鱼跃 天高任鸟飞

 

回调函数的使用

编程中,在处理功能相互独立但又需要协调的某些工作的时候,有时会用到回调函数来实现这些需
求。回调函数的实现实质是使用函数指针来调用相关的功能函数。这里简析一下回调函数基本的实
现框架。

一般比如进度显示的功能,有一个业务工作类和一个界面显示类,界面需要实时的来显示工作类的
进度。基本框架可以设计如下:

//
//业务工作类
//
class CAutoAdd;
//定义函数指针,这里该函数使用两个参数
typedef void (*AUTOSHOW) (int nCount,        //函数所用到的参数数据
   void *pCustomParam);        //用于指示相关的调用类

class CAutoAdd 
{
public:
 void Stop();       //暂停工作
 void Run();        //工作函数
 void SetCallback(AUTOSHOW  pa, void *pCustomParam);
 int m_nCount;
 bool m_bStop;
 CAutoAdd();
 virtual ~CAutoAdd();
private:
 AUTOSHOW _pAutoShow;
 void*  _pCustomParam;

};


//
//界面显示类
//
#include "AutoAdd.h"

class CCallBackDlg : public CDialog
{
// Construction
public:
 CAutoAdd m_auto;  //业务工作类的一个实例
 static void Set(int n,void *pCustomParam);//业务类中所要调用的界面显示函数
 void UpdateUI(CString ss);
 CCallBackDlg(CWnd* pParent = NULL); // standard constructor

// Dialog Data
 //{{AFX_DATA(CCallBackDlg)
 enum { IDD = IDD_CALLBACK_DIALOG };
 CButton m_btnShow;
 CButton m_btnStart;
 //}}AFX_DATA

 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CCallBackDlg)
 protected:
 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
 //}}AFX_VIRTUAL

// Implementation
protected:
 HICON m_hIcon;

 // Generated message map functions
 //{{AFX_MSG(CCallBackDlg)
 virtual BOOL OnInitDialog();
 afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
 afx_msg void OnPaint();
 afx_msg HCURSOR OnQueryDragIcon();
 afx_msg void OnButton1();
 afx_msg void OnButton2();
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};

解析一下关键的几点:
1)函数指针中用到的void *pCustomParam参数,该指针用于指示调用者;
typedef void (*AUTOSHOW) (int nCount, void *pCustomParam/*指示调用者*/);

2)CAutoAdd::SetCallback函数,在界面类初始化时调用该函数,pa传递相关的回调函数,
pCustomParam传递该界面类自身的指针;
void CAutoAdd::SetCallback(AUTOSHOW  pa, void *pCustomParam)
{
 _pAutoShow = pa;
 _pCustomParam = pCustomParam;
}

3)void CCallBackDlg::Set(int n,void *pCustomParam)
该函数在声明时须指定为static类型。否则将会产生编译错误:
rror C2664: 'SetCallback' : cannot convert parameter 1 from 'void (int,void *)' to

'void (__cdecl *)(int,void *)'
      None of the functions with this name in scope match the target type

4)CCallBackDlg::Set的实现;
void CCallBackDlg::Set(int n,void *pCustomParam)
{
 MSG    msg;
 CString str;
 str.Format("%d", n);

 //
 //由于static成员不能访问非static成员,所以通过pCustomParam指针得到当前界面
 CCallBackDlg *pDlg = (CCallBackDlg *)pCustomParam;
 pDlg->UpdateUI(str);

 //
 //使在执行业务逻辑处理的时候程序还能有暇去照顾其他消息响应
 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }
}

相关代码

posted on 2007-11-06 13:36  liuym  阅读(916)  评论(0编辑  收藏  举报

导航