winapi – Win32 No-MFC中的消息映射
我怎么能创建类似的结构来处理Win32消息,就像在MFC中一样?
在MFC; BEGIN_MESSAGE_MAP(CSkinCtrlTestDlg,CDialog) //{{AFX_MSG_MAP(CSkinCtrlTestDlg) ON_BN_CLICKED(IDC_BROWSE,OnBrowse) ON_BN_CLICKED(IDC_DEFAULTSKIN,OnChangeSkin) ON_WM_DRAWITEM() ON_WM_MEASUREITEM() ON_WM_COMPAREITEM() ON_BN_CLICKED(IDC_CHECK3,OnCheck3) //}}AFX_MSG_MAP END_MESSAGE_MAP() BEGIN_MESSAGE_MAP宏处理此行为.怎么做纯Win32?
以下是我在
Zeus程序员编辑器中执行此操作的代码的简要总结:
步骤1:定义一些消息结构以保存Windows消息详细信息: typedef struct { MSG msg; LRESULT lResult; } xMessage; struct xWM_COMMAND { HWND hwnd; UINT Msg; WORD ItemID; WORD NotifyCode; HWND Ctl; LRESULT lResult; }; //-- unpack a message buffer #define MSG_UNPACK(var,id,msg) x##id *var = (x##id *)(msg); 第2步:使用一些特殊方法定义基本窗口类: class xWindow { protected: //-- windows callback function static LRESULT CALLBACK wndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam); //-- a message dispatch method void dispatch(HWND hwnd,UINT uMessageID,LPARAM lParam,LRESULT &Result); //-- method for command message dispatching virtual void dispatchToCmdMap(xMessage *pMessage); //-- method for windows message dispatching virtual void dispatchToMsgMap(xMessage *pMessage); }; 步骤3:定义一些宏来分派Windows消息: #define BEGIN_MSG_MAP protected: virtual void dispatchToMsgMap(xMessage *msg) { if (msg->msg.message == WM_NULL) { return; } #define MSG_HANDLER(meth,wm_msg) else if (msg->msg.message == wm_msg) { this->meth(msg); return; } #define END_MSG_MAP(base) else if (msg->msg.message == WM_COMMAND) { this->dispatchToCmdMap(msg); return; } else if (msg->msg.message == WM_NOTIFY) { this->dispatchToNotifyMap(msg); return; } base::dispatchToMsgMap(msg); }; #define BEGIN_CMD_MAP virtual void dispatchToCmdMap(xMessage *msg) { MSG_UNPACK(Cmd,WM_COMMAND,msg); if (Cmd->ItemID == 0) { /* not allowed */ } #define CMD_HANDLER(meth,cmd_id) else if (Cmd->ItemID == cmd_id) { this->meth(Cmd->ItemID); } #define END_CMD_MAP(base) else { base::dispatchToCmdMap(msg); } }; 第4步:定义调度程序方法: void xWindow::dispatch(HWND,LRESULT &Result) { xMessage message; //-- build up a message packet message.msg.message = uMessageID; message.msg.wParam = wParam; message.msg.lParam = lParam; message.lResult = 0; //-- dispatch the message this->dispatchToMsgMap(&message); } 步骤5:定义静态窗口过程方法(注意:首次注册类时,此方法需要用作窗口类的Window过程): LRESULT CALLBACK xWindow::wndProc(HWND hwnd,LPARAM lParam) { LRESULT lResult = 0; //-- look for the creation message if (msg == WM_NCCREATE) { CREATESTRUCT *pCreateData = (CREATESTRUCT*)lParam; //-- get the window object passed in xWindow *pWindow = (xWindow)pCreateData->lpCreateParams; if (pWindow) { //-- attach the window object to the hwnd SetWindowLong(hwnd,pWindow); //-- let the window object dispatch the message pWindow->dispatch(hwnd,msg,wParam,lParam,lResult); } else { //-- leave the message to windows lResult = DefWindowProc(hwnd,lParam); } } else if (hwnd) { //-- get the object attached to the hwnd xWindow *pWindow = (xWindow *)GetWindowLong(hwnd); //-- check to see if we have an object window attached to the handle if (pWindow) { //-- let the window object dispatch the message pWindow->dispatch(hwnd,lResult); } else { //-- leave the message to windows lResult = ::DefWindowProc(hwnd,lParam); } } return lResult; } 现在,使用这个基类可以定义一个如下所示的新窗口类: class MyWindow : public xWindow { protected: //-- the WM_COMMAND message handlers virtual void onAdd(int); virtual void onDelete(int); //-- the WM_CLOSE message handler virtual void onClose(xMessage *pMessage); //-- the WM_SIZE message handler virtual void onSize(xMessage *pMessage); public: //-- ctor and dtor MyWindow(); virtual ~MyWindow(); BEGIN_MSG_MAP //-- command message handlers CMD_HANDLER(onAdd,IDPB_ADD ) CMD_HANDLER(onDelete,IDPB_DELETE) //-- other message handling MSG_HANDLER(onClose,WM_CLOSE) MSG_HANDLER(onSize,WM_SIZE ) END_MSG_MAP(xWindow) }; 编辑:此代码的工作原理. 理解这段代码如何工作的秘诀是要记住xWindow类中的wndProc只是在注册Win32窗口时传递给RegisterClassEx的Win32 Window程序. 现在,如果您查看wndProc代码,您会看到它进行了一些设置和检查,但通常只会将Windows消息发送到调度方法. 调度方法甚至更简单,因为它只是将Windows消息打包成易于移动的结构,然后将其发送到dispatchToMsgMap方法. 现在看看MyWindow类,你会看到这段代码: BEGIN_MSG_MAP //-- command message handlers CMD_HANDLER(onAdd,IDPB_ADD ) CMD_HANDLER(onDelete,IDPB_DELETE) //-- other message handling MSG_HANDLER(onClose,WM_CLOSE) MSG_HANDLER(onSize,WM_SIZE ) END_MSG_MAP(xWindow) 此代码仅使用前面定义的宏.如果你仔细看看这些宏,你会发现上面的代码实际上是在创建一个dispatchToMsgMap方法.这与dispatch方法调用的dispatchToMsgMap方法完全相同. 我知道这种处理Windows消息的方法确实有效,因为我在Zeus for Windows编辑器中使用了这种完全相同的方法. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- windows – 如何让SQL Server释放内存?
- win10企业2016和2019长期服务版本激活密钥和下载地址
- windows – RAD工作室需要很长时间才能打开
- windows-xp – Windows XP EOL / EOS对于企业及其域名意味着
- 如何在Windows 2016上正确设置docker网络?
- windows-phone-7 – 导航到详细信息页面 – 共享视图模型或
- windows – 打包使用ImageMagick C API的应用程序
- winapi – Windows的低级键盘输入
- window []和eval()之间的区别 – Javascript
- Windows Phone 7 – WP7应用程序版本
- windows – 是否有针对Microsoft堆栈的推荐自动化
- group-policy – 如何在GPO中禁用“重新启动计算
- Windows – Symantec Endpoint Protection(SEP /
- 解决:IIS的:DCOM?遇到错误“重叠?I/O?操作在进
- Batch unlock AD account using PowerShell
- windows – MEMORY_BASIC_INFORMATION结构中的Ba
- 如何在多台计算机上自动安装Windows XP?
- windows-server-2008 – Windows Server备份D:卷
- windows-phone-7 – 如何在WP7上以编程方式打开/
- windows – getCPUTime只返回两个值(0或15625000