周末闲着没事干,想想很久没有自己给自己写程序了。去年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

评论