情不知所起,一往而深。生者可以死,死可以生。生而不可与死,死而不可复生者,皆非情之至也。

情悄然由心而生、愈来愈深、活着为情而死、死后随情而生、生却不肯为情而生、死后也不会得到重生、因为情未到深处也。(情到深处无怨尤)

武侠剧上看到许多武侠人士经过多年修炼最终达到人剑合一的境界,而现在我复用一下:我也走在“人剑合一”路上。最后达到情不知所起一往而深的深度,呵呵,想多了


        昨天晚上又开始翻回旧黄历看了看别人怎么剖析MFC封装windowsAPI编程的文章。随后调试发现 又是阵痛。恍惚半年、一年我经历了不下4次这样的阵痛,也许我就是那种好几次都走了同样带坑的路的人(呵呵 我都不知道我是自夸还是自嘲),是什么坑呢?先看看图(自制的 感觉着看吧)

// 我得说明一下MyBaseWndProc是CBaseWnd类的一个回调成员函数
LRESULT CALLBACK CBaseWnd::MyBaseWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{if(hWnd!=NULL){CBaseWnd* pWnd=CBaseWnd::FromHandle(hWnd);if(pWnd!=NULL)return pWnd->WindowProc(message, wParam, lParam);}return 0;
}

我想说什么呢?

        首先是这样的,windows开发中WinMain函数中会有一个数据结构WNDCLASSEX,而WNDCLASSEX的对象的一个成员lpfnWndProc必须得到一个回调函数,这个回调函数是什么样子的呢,let me have a look

LRESULT CALLBACK xxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{return ::DefWindowProc(hWnd, message, wParam, lParam);
}

也就是说正常的情况下,windows接收到键盘、系统的消息就应该是传到xxWndProc中的,但是如果CBaseWnd中使用了SetWindowLong来修改调用回调函数的方向,那应用程序的回调函数就是MyBaseWndProc了,此时xxWndProc属于old窗口回调函数。

那么问题来了?

不管是窗口回调函数(加个窗口修饰只是更明确此回调函数的意义,本质上还是回调函数)是xxWndProc还是MyBaseWndProc,从“源代码”中是根本找不到是哪个进程、哪个模块、哪个过程调用过他们。

        首先,得明确一下源代码指的是MFC提供的部分代码,windows本身也是一款软件,那么他的核心模块就是win32kernel模块,在此基础上为了提供消息驱动机制,在win32kernel模块的外围有封装了一层,这一层由user32.exe、gdi32.exe、ntdll.exe封装起来应该就是传说中的Ring2层,如果能看到这层代码的话,就应该能看到是哪个函数调用了当前应用程序的这个回调函数。我目测Ring2层为了封装windows的这个消息机制一定是花了好长时间来研究、设计函数调用走向,其目的就只有一个为Ring3级别提供接口,使开发人员不用自己设计消息驱动机制,同时二一个目的也是统一windows平台下的消息驱动接口。

        反观MFC中的部分代码设计,我猜想Ring2层也会有许多的设计思路甚至是代码风格都与MFC的相同。唯一不同的就是实实际际的实现(而不是逻辑)是猜不到的。

其实对于开发大项目是,都会遇到这个尴尬的问题,整个项目设计成3层架构,最底层肯定是用windowsAPI接口开发,开发完成之后一系列的接口函数和环境给第2级架构和接口使用,到了第2级架构上使用第一级架构提供的接口在加上自己的逻辑,最后在完成之后提供一系列的接口函数和环境给第3级架构使用。

 对于一个开发人员来讲,如何使用API绝对是一个最关键的中心点,不管你是使用windows提供的底层API、还是使用上面说到的项目的1级接口、2级接口,最起码你得知道某某API是干嘛用的,使用时有什么注意事项吧.虽然开发没多久、但也是知道要完成一个模块或者一个层级架构的设计得需要多少个API。

        所以最尴尬的问题是,当你将windowsAPI运用娴熟的情况下,如果此时你在上面项目的第3级架构上开发,即便你windowsAPI很是娴熟,但你仍是感到很吃力,为什么呢?又是一大堆2级架构提供的api,你能不用么,你用是不是得先熟悉啊?


        呵呵,扯到哪去了,总结一下。


        就是说windows设计就好比这三层架构,MFC就属于第3层,因为他是以第2层架构为基础的,所以在阅读第3级架构中的程序又是感到困惑这并不奇怪。关键是你现在怎么想象这个问题,怎么理解这个问题了。

既然某些地方理解不了,但是开发事确实是提供了很多便利,且在实际开发绝对不会因此导致自己设计的程序出现问题,。。。。。在好好想想。。。。这难道不是。。。。设计框架的初衷么。。。。。

        也许,其实就在写完上两段的时候我还不理解为什么要这么设计,但此时此刻我却恍然大悟。。。。如果要我设计一个3层架构,我又能怎么想呢?

为什么莫名其妙的就被调用了相关推荐

  1. Android doc|Getting Started| Training部分 --翻译 Working with System Permissions

    Working with System Permissions To protect the system's integrity and the user's privacy, Android ru ...

  2. jquery自带的赋值函数html

    背景:最近改造前台界面,需要动态改变提示框的内容,我定义了一个div标签,利用jquery获取到这个div,然后赋值调用的html("数据")函数,死活赋值不上. 上图这样取值也莫 ...

  3. wordpress ajax 调用wpdb_莫名其妙的调用Roboto字体又莫名其妙的恢复的过程

    周末把防止WordPress自动将站点标题中"-"自动转义成"–" – 程门立学 https://www.iappi.cn/2019_05/2019728.ht ...

  4. C#调用C/C++动态库Dll时几个注意事项:PInvoke错误

    经常需要封装一些C/C++函数放入动态库中给C#程序调用,通常情况下直接写成如下形式即可: C#封装调用: [DllImport("depressor.dll")] //错误调用方 ...

  5. python 中使用 global 引发了莫名其妙的问题

    定义全局变量的方法: console=None def log_info(logstr): global console if console is None: console = logging.S ...

  6. 函数调用通过函数名字符串调用函数【C语言版】

    在写这篇文章之前,xxx已经写过了几篇关于改函数调用主题的文章,想要了解的朋友可以去翻一下之前的文章 问题引入 在C中,函数先定义,后使用.举个简单的例子 /********************* ...

  7. android+jni+构造函数,在JNI中调用构造函数失败Android

    我想从我的JNI Android代码调用构造函数;但不知何故,它失败,以下例外.. 我相信我失去了一些非常小的东西;但我无法弄清楚......任何人都可以请指出?在JNI中调用构造函数失败Androi ...

  8. vsc提示只有一行_Solution:连续调用BAPI出错,以及BAPI提示成功但数据库没有数据...

    作者:孙亮 声明:本文章仅代表原作者观点,仅用于SAP软件的应用与学习,不代表SAP公司和本微信公众号.注:文中所示截图来源SAP软件,相应著作权归SAP所有. 在群里看大家交流技术问题,曾记下了一条 ...

  9. 多线程调用同一个方法,局部变量会共享吗

    对于一个局部变量应该是各线程独立的,一个线程不会改变另一个线程的临时变量. 多线程时, 几个线程间输出信息是交叉在一起的, 但你又没有区分是哪个线程输出的, 所以你自己就误认为是同一个线程输出的东西被 ...

最新文章

  1. 互联网项目管理要点(转)
  2. 如何使用sed在文件中确定行插入带有变量的字符串
  3. pthread_mutex_lock用法
  4. [Spring5]IOC容器_Bean管理注解方式_完全注解开发
  5. P4062 [Code+#1]Yazid 的新生舞会(分治做法)
  6. Golang笔记——map
  7. 《Storm企业级应用:实战、运维和调优》——1.6 本章小结
  8. 使用SoapUI生成wsdl文件客户端(二)
  9. JavaScript内置对象之Array对象总结(附实例)
  10. setpythonhome_python的set,和字典的详细使用方法,以及部分习题
  11. build lavas 失败_vue lavas的项目在IE下显示空白
  12. NISP题库(八套模拟题)
  13. 上传图片到淘宝接口调用展示
  14. 面试题:给定一个数组,数组中只包含0和1。请找到一个最长的子序列,其中0和1的数量是相同的
  15. windows7 安装哪个版本的vs_轻钢龙骨vs木龙骨 吊顶安装选哪个好,看完立刻做出了选择...
  16. Mac应用程序无法打开提示不明开发者或文件损坏的处理方法
  17. 8.1 幽灵(no.1~no.10)
  18. VSRX防火墙安装与部署
  19. 你想知道的2022年广东PMP考试报名时间来咯!
  20. 关于CAD2022重装显示已安装,需要删除注册表中的CAD文件(需仔细)

热门文章

  1. pyqt5 不报错退出_最新版本Python图形化开发环境Anaconda(Python3.7) +PyQT5+Eric6
  2. java选择结构二星期几_java4选择结构 二
  3. python装饰器模式带参数_python 装饰器模式 我的理解
  4. 反序列化对象列表发生异常_Apache Thrift系列详解:序列化机制
  5. mysql相互密码_去掉mysql命令行密码不安全的提示
  6. Hadoop2——SSH免密登录功能配置
  7. KMP算法、AC自动机算法的原理介绍以及Python实现
  8. tabpanel中autoload方法传递参数
  9. CSDN怎样编辑公式
  10. 吴恩达深度学习3.1笔记_Structuring Machine Learning Projects_机器学习策略(1)