正文

函数回调,揭秘Windows消息处理机制2006-07-12 20:51:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/sgpro/16557.html

分享到:

    周末闲着没事干,想想很久没有自己给自己写程序了。去年8月份开发 SGWINDOW2.0的时候有一个很大的愿望就是使用回调机制来调用消息处理函数,回调是Windows程序所采用的,当时开发SGWINDOW的时候,一直是使用简单的直调处理,这个方法简单但是不灵活,而Windows的回调方法很灵活。 为了实现这个愿望,上个周末就着手试了试。在没有放弃直调的构架下,保证了兼容性的前提下。只作了一个增强外壳就实现了回调,我把它命名为SGWNDPLS. 实现代码很简短,但是我认为已经揭示了Windows那几个神秘的GetMessage, TranslateMessage, DispatchMessage函数, 在SGWNDPLS中,这几个函数的名字与Windows的一致。 SGWINDOW 2.0 直调方法:  while (TestMessageSource(window))/*当消息源存在时,进入消息循环*/ {  msg = WindowSend_Message(GetMessageSource(window));/*提取并发送消息*/  Dispatch_Message(msg);  /*处理消息*/ } 注意到:Dispatch_Message 是用户的定义消息处理函数,此处是在消息循环中直接调用。 void Dispatch_Message(WinMessage msg) /*消息处理函数*/{       int ObjectID = Get_MessagescrID(msg);      /*获取发送消息的对象的ID号*/       int MessageType = Get_MessagescrType(msg); /*获取该消息的类型*/ } 在Windows程序的回调方法当中:  while (GetMessage(&msg,NULL,0,0))  /*获取消息*/ {  TranslateMessage(&msg);     /*消息转译*/  DispatchMessage(&msg);     /*消息发送*/ } //下面是用户注册的消息处理函数 LRESULT CALLBACK WindowProcess(HWND whnd,UINT msg,WPARAMwpara,LPARAM lparam) { } 通过以上的比较可以清晰认识到直调与回调的差别 =======================     SGWNDPLS 在 SGWINDOW2.0的基础上改造直调到回调的代码: #include <sgwindow.h> typedef struct    /*窗体应用程序对象*/{ wndhnd form;   /*主窗体句柄*/ void (*WndProc)(Object,Event); /*消息处理函数*/}window; window AppWindow;   /*建立全局窗体对象*/ bool CreateWindow(wndhnd Form, void (*WndProc)(Object sender,Event e)){ int i = 0;  SGWindow_CatchException();  /*建立窗体程序对象之前,捕捉SGWINDOW异常*/  if ( Form != SGWND_NULL)  /*检查主窗体句柄是否存在*/ {  AppWindow.form = Form;  /*导入主窗体句柄到应用程序对象*/  AppWindow.WndProc = WndProc; /*导入消息处理函数到应用程序对象*/  return true;   /*成功建立窗体应用程序对象*/ } else {  return false;   /*创建失败*/ }} bool GetMessage(WinMessage *argMsg)  /*提取消息*/{ if ( AppWindow.form != SGWND_NULL) /*检查主窗体句柄是否存在*/ {  *argMsg = WindowSend_Message(GetMessageSource(AppWindow.form)); /*提取窗体应用程序的消息*/ }  return TestMessageSource(AppWindow.form); /*返回消息源测试状态*/} void TranslateMessage(WinMessage *argMsg) {     /*转译消息,目前未使用,尚无消息须转译*/} void DispatchMessage(WinMessage *argMsg)  /*发送消息*/{ Object  sender = Get_MessagescrID(*argMsg);  /*根据主消息解析消息发送对象*/ Event e    = Get_MessagescrType(*argMsg); /*根据主消息解析消息类型*/ AppWindow.WndProc(sender,e);    /*传入解析参数, 回调窗体应用程序的消息处理函数*/} ======================== 改造后消息循环的代码如下,与Windows方式一致,实现了回调  while (GetMessage(&msg)) {  TranslateMessage(&msg);  DispatchMessage(&msg); }} //消息处理函数,在消息循环中不直接调用,由用户注册 void  WndProc(Object sender, Event e)  // 是不是类似 C#.NET中事件处理中的参数呢?{ }  Copyright (C) 2006-7  sgpro

阅读(6153) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册