MFC中应该有两类回调函数:一类是源自C的传统回调函数,此类回调函数若非定义为全局函数,而定义在类中的话,要添加static约束,常见的有EnumXXX();一类是消息响应函数,通过成员函数指针实现回调。

设想一种情况,基类A触发某事件E后,回调某定义好的函数F进行事件处理(MFC中表现为消息响应函数)。继承于类A的子类B和C,可能对于E有不同的处理方式,于是需要对基类A的函数F进行改写。自然而然的,我们想到将F定义为以virtual修饰的虚函数。

——————————————————————————————————————————————————————

回调函数的简单定义就是你定义的由Windows来调用。以下两个函数摘自《Programming Windows with MFC》,这里暂且不管函数的具体作用,在FillListBox中有一个API函数,它调用的回调函数是EnumFontFamProc,回调函数的声明形式一般都是相对固定的,具体可以参考MSDN。

  1. static int CALLBACK EnumFontFamProc (ENUMLOGFONT* lpelf,NEWTEXTMETRIC* lpntm, int nFontType, LPARAM lParam);
  2. void CMainWindow::FillListBox ()
  3. {
  4. m_wndListBox.ResetContent ();
  5. CClientDC dc (this);
  6. ::EnumFontFamilies ((HDC) dc, NULL, (FONTENUMPROC) EnumFontFamProc,(LPARAM) this);
  7. }
  8. int CALLBACK CMainWindow::EnumFontFamProc (ENUMLOGFONT* lpelf,NEWTEXTMETRIC* lpntm, int nFontType, LPARAM lParam)
  9. {
  10. CMainWindow* pWnd = (CMainWindow*) lParam;
  11. if ((pWnd->m_wndCheckBox.GetCheck () == BST_UNCHECKED) || (nFontType & TRUETYPE_FONTTYPE))
  12. pWnd->m_wndListBox.AddString (lpelf->elfLogFont.lfFaceName);
  13. return 1;
  14. }

请注意这里的函数EnumFontFamilies中的最后一个参数传递的是this即该CMainWindow对象的指针,为什么要这样呢,可以看到EnumFontFamProc的声明是static,在C++中static函数是不能调用非static成员的,所以这里传递一个this就不是很奇怪了。但是为什么要将该函数声明为static呢,这就要归咎于C++的特殊性了,众所周知C++编译器在编译的时候都会在对象中添加一个this指针,在成员函数调用中又会附加一个参数保存this指针,但是Windows的回调函数有严格的定义就是必须按照参数列表传递的参数,加了this指针后参数列表就会与Windows期望的参数列表不一致了,因此这里将其声明为static(static成员函数不会传递this指针,这点说起来总是知道,但是真正用时总是忘了,唉)。

另外在Windows中使用callback函数很常见,恰好许多支持回调函数的API函数都像这里的EnumFontFamilies一样支持自定义的LPARAM参数,刚好可以传递this,如果使用的API函数不支持这样的自定义的LPARAM参数,就需要其他的方法了,一种比较简单的方法是将this复制为global变量使得回调函数可以使用。

 
 

MFC的回调函数的更多相关文章

  1. Windows编程中回调函数的使用心得(MFC篇)

    回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数.回调函数不是由该函数的实现方直接调用,而是在特定 ...

  2. 回调函数中使用MFC类的成员或对话框控件的简单方法

    在MFC的很多程序中,常常需要在回调函数中调用MFC类的类成员变量.类成员函数,亦或者对话框控件的句柄.由于回调函数是基于C编程的Windows SDK的技术,而类成员又有this指针客观条件限制.. ...

  3. VC++ 回调函数及使用方法(转)

    转载:http://blog.csdn.net/vsooda/article/details/7435801 转载:http://blog.csdn.net/lincyang/article/deta ...

  4. C++中的Thunk技术 / 非静态类成员函数作为回调函数 的实现方法

    原文:https://blog.twofei.com/616/ 用我的理解通俗地解释一下什么是C++中的Thunk技术吧! Thunk技术就是申请一段可执行的内存, 并通过手动构造CPU指令的形式来生 ...

  5. 详解回调函数——以JS为例解读异步、回调和EventLoop

      回调,是非常基本的概念,尤其在现今NodeJS诞生与蓬勃发展中变得更加被人们重视.很多朋友学NodeJS,学很久一直摸不着门道,觉得最后在用Express写Web程序,有这样的感觉只能说明没有学懂 ...

  6. MFC的定时函数 SetTimer和结束killTimer

    什么时候我们需要用到SetTimer函数呢?当你需要每个一段时间执行一件事的的时候就需要使用SetTimer函数了. 使用定时器的方法比较简单,通常告诉WINDOWS一个时间间隔,然后WINDOWS以 ...

  7. c/c++:回调函数

    1:函数名为指针 首先,在C语言中函数是一种function-to-pointer的方式,即对于一个函数,会将其自己主动转换成指针的类型.如: 1 #include<stdio.h> 2 ...

  8. Settimer及回调函数的用法

    在网上看了settimer的一些用法发现能用的真没有,,,,可能是我没找对地方,大部分都是无脑复制粘贴,浪费了很多时间,如果你是一个对这种定时器一无所知的小白,那么请你看进来一定不会让你失望的! 实用 ...

  9. 小兔JS教程(三)-- 彻底攻略JS回调函数

    这一讲来谈谈回调函数. 其实一句话就能概括这个东西: 回调函数就是把一个函数当做参数,传入另一个函数中.传进去的目的仅仅是为了在某个时刻去执行它. 如果不执行,那么你传一个函数进去干嘛呢? 就比如说对 ...

随机推荐

  1. margin 负值问题

    * margin-top 和 margin-left 负值,自身元素向上.向左移动: * margin-right 负值,右侧元素左移,自身元素不受影响: * margin-bottom 负值,下方元 ...

  2. js匿名函数测试

    js匿名函数测试 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...

  3. Mamen所需要的jar包怎么生成

    Mamen所需要的jar包怎么生成 使用 mamen 难免碰到,不知道的 jar 包,不知道怎么在 pom 文件中写,分享一个网址,可以把你想要的 jar 包生成 pom 配置文件,个人感觉非常好用. ...

  4. Python模块学习之xlrd 读取Excel时传入formatting_info=True报错:NotImplementedError: formatting_info=True not yet implemented

    问题:xlrd读取Excel时传入 formatting_info=True 报错 之前我们使用读取xls文件的时候都是使用的xlrd库,但是这个库只能操作 .xls格式,对于后来的 .xlsx的版本 ...

  5. 【转】JMX之ObjectName

    原文链接:https://blog.csdn.net/yunlong34574/article/details/46563187 ObjectName 就是存储了一个domain(域)下的一些属性,属 ...

  6. 多条件异步搜索+分页(PHP、 AJAX、ThinkPHP)

    项目中遇到的多条件异步查询及数据分页问题,做了数次尝试,最终虽目的达到,略有繁琐,希望能有更好的处理方式 基于 tp框架 1.html页面代码 <div class="h_cityNa ...

  7. StaticInjectorError[Http]:

    报错:AppComponent.html:28 ERROR Error: StaticInjectorError[Http]: StaticInjectorError[Http]: 解决方法:

  8. PAT甲级——A1141 PATRankingofInstitution

    After each PAT, the PAT Center will announce the ranking of institutions based on their students' pe ...

  9. Java对象相等比较(Equals)

    以下代码显示如何实现equals()和hashCode()方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ...

  10. Safari的CSS HACK方法

    以前的文章里提到过IE6/IE7/IE8/IE9/.Firefox的CSS HACK方法,那么Safari的CSS HACK是什么呢?   请看以下CSS代码: .box { color: black ...