在这几天的编程里,我发现了一个程序如果是基于事件驱动的,那么编程起来将会很简单。比如在输入命令行遇到回车时向框架发送一个ON_CMD_OK消息,那么框架就会立即处理ON_CMD_OK消息,而无需再去检测命令输入到了什么地方,在框架定时器到达时,框架也会呼叫我们事先约定好的处理程序,为我们省略了很多细节的麻烦。 要编写基于事件的程序,首先需要理解函数指针,和char指针一样,它保存了一个函数的地址,调用指针指向的函数和调用函数一样。例如:(我的例程是这样的) typedef void (*PROC)(MESSAGE_STYLE style,MESSAGE param);// 定义函数类型,形参为MESSAGE枚举; PROC fun; static void nullFunction(MESSAGE_STYLE style,MESSAGE param)// 空函数 { printf("nullFunction is called ."); } void main() { fun = nullFunction;// 将指针指向nullFunction; fun(ON_KEYDOWN,WM_0);// 通过指针调用函数 } 那么,在这个主程序里,nullfunction将收到ON_KEYDOWN和WM_0,意思是按键0被按下,调用nullFunction处理。 ON_KEY_DOWN是一个我们预先定义的消息类型枚举,WM_0也一样。 当然了,在实际的编程里不会像这个那么简单,我们需要一个数组来保存指针,然后将消息逐个派遣,让想知道这个消息的所有程序都能知道这个按键被按下了,然后进行相应的处理。 是否明白点了呢?.... 后来我有个重大发现 一直以来,我都是使用形参来传递消息参数,我的PROC原来是这样定义的:PROC (*fun)(MESSAGE_TYPE type, MESSAGE param); 在我的Delegate里,消息通过send()函数将会历遍所有消息回调,如果我在第一个回调里增加了一个回调,那么在这个回调结束后,新增加的回调也会收到这个消息,这不是我希望的结果(我在菜单里选择了2号菜单,而2号菜单是个命令提示符,那么在增添命令提示符后字符'2'这个消息会传递给CMD,那么在进入CMD程序之前,CMD实际上已经添加了2这个字符在命令行里)。经过我的反复思考,我参考了C#的做法,把后面两个参数改为引用类型,改为:PROC (*fun)(MESSAGE_TYPE &type, MESSAGE ¶m); 那么在第一个回调里增加另外一个回调的同时,把param设置为WM_NULL,就不会发生上面的情况,而且将更加灵活,我增加了WM_HANDLED,在框架检测到这个消息后,会放弃之后的回调,因为框架已经知道这个消息已经不再需要后面的程序处理了。呵呵,总算解决了一个问题。也算是从C#里发现的一个重大收获。经过这样的改造,CPU占用率更低了,而且深度的内存堆栈也少了些,可以使用更多的内存做别的任务。 八卦一下 PT2313。这是我的第二个AVR的作品。我用MEGA8是因为它的功能深深的吸引着我。以前用51的时候,I2C需要单独来编写一个程序来驱动,ADC需要外置。现在好了,MEGA8为我解决了这个问题,使得我现在的版本比以前有了很大的进步,无论是在体积上还是性能上都有显著的提高。让大家来分享一下
上一篇:STC单片机外扩RAM及8255需要注意的问题
下一篇:指针在c语言中的妙用
推荐阅读最新更新时间:2024-03-16 13:06