DECLARE_MSG_MAP参考实例

本文介绍了一个名为CModule的类,该类定义了消息映射机制,用于处理Windows消息和自定义请求。通过宏定义和结构体实现了消息与成员函数的绑定,提高了消息处理的灵活性和扩展性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#pragma once
#include <wtypes.h>
#include <afxmsg_.h>

class CModule;

typedef BOOL(CModule::*MODULE_PMSG)(LPCONTEXT_HEAD lpContext, LPREQUEST lpRequest);

struct MODULE_MSGMAP_ENTRY
{
    UINT nMessage;   // windows message
    MODULE_PMSG pfn;    // routine to call (or special value)
};

struct MODULE_MSGMAP
{
    const MODULE_MSGMAP* (PASCAL* pfnGetBaseMap)();
    const MODULE_MSGMAP_ENTRY* lpEntries;
};

#define DECLARE_MSG_MAP()                                         \
protected:                                                        \
    static const MODULE_MSGMAP* PASCAL GetThisMessageMap();       \
    virtual const MODULE_MSGMAP* GetMessageMap() const;

#define ON_MSG(message, memberFxn)                                              \
    { message,(MODULE_PMSG)(memberFxn) },

#define BEGIN_MSG_MAP(theClass, baseClass)                    \
    PTM_WARNING_DISABLE                                       \
    const MODULE_MSGMAP* theClass::GetMessageMap() const      \
        { return GetThisMessageMap(); }                       \
    const MODULE_MSGMAP* PASCAL theClass::GetThisMessageMap() \
    {                                                         \
        typedef theClass ThisClass;                           \
        typedef baseClass TheBaseClass;                       \
        static const MODULE_MSGMAP_ENTRY _messageEntries[] =  \
        {

#define END_MSG_MAP() \
            {0, (MODULE_PMSG)0 }                                   \
        };                                                         \
        static const MODULE_MSGMAP messageMap =                    \
        { &TheBaseClass::GetThisMessageMap, _messageEntries };     \
        return &messageMap;                                        \
    }                                                              \
    PTM_WARNING_RESTORE

class CModule
{
    DECLARE_MSG_MAP()
public:
    CModule();
    virtual ~CModule();
    BOOL OnRequest(LPCONTEXT_HEAD lpContext, LPREQUEST lpRequest);

};

#include "stdafx.h"
#include "Module.h"


CModule::CModule()
{
}


CModule::~CModule()
{
}

const MODULE_MSGMAP* CModule::GetMessageMap() const
{
    return GetThisMessageMap();
}

const MODULE_MSGMAP* CModule::GetThisMessageMap()
{
    static const MODULE_MSGMAP_ENTRY _messageEntries[] =
    {
        { 0, 0 }     // nothing here
    };
    static const MODULE_MSGMAP messageMap =
    {
        NULL,
        _messageEntries
    };
    return &messageMap;
}

#ifndef iHashMax
// iHashMax must be a power of two
#define iHashMax 512
#endif
struct MODULE_MSG_CACHE
{
    UINT nMsg;
    const MODULE_MSGMAP_ENTRY* lpEntry;
    const MODULE_MSGMAP* pMessageMap;
};
MODULE_MSG_CACHE _MsgCache[iHashMax] = { 0 };

const MODULE_MSGMAP_ENTRY* FindMessageEntry(const MODULE_MSGMAP_ENTRY* lpEntry, UINT nMsg)
{
    while (lpEntry->nMessage != 0)
    {
        if (lpEntry->nMessage == nMsg)
        {
            return lpEntry;
        }
        lpEntry++;
    }
    return NULL;
}

BOOL CModule::OnRequest(LPCONTEXT_HEAD lpContext, LPREQUEST lpRequest)
{
    UINT message = lpRequest->head.nRequest;

    const MODULE_MSGMAP* pMessageMap = GetMessageMap();
    UINT iHash = (LOWORD((DWORD_PTR)pMessageMap) ^ message) & (iHashMax - 1);
    MODULE_MSG_CACHE* pMsgCache = &_MsgCache[iHash];
    const MODULE_MSGMAP_ENTRY* lpEntry;
    if (message == pMsgCache->nMsg && pMessageMap == pMsgCache->pMessageMap)
    {
        lpEntry = pMsgCache->lpEntry;

    }
    else
    {
        pMsgCache->nMsg = message;
        pMsgCache->pMessageMap = pMessageMap;

        for (; pMessageMap->pfnGetBaseMap != NULL;
            pMessageMap = (*pMessageMap->pfnGetBaseMap)())
        {
            // Note: catches BEGIN_MSG_MAP(CMyClass, CMyClass)!
            ASSERT(pMessageMap != (*pMessageMap->pfnGetBaseMap)());
            if ((lpEntry = FindMessageEntry(pMessageMap->lpEntries, message)) != NULL)
            {
                pMsgCache->lpEntry = lpEntry;
                break;
            }

        }
    }
    if (lpEntry == NULL)
        return FALSE;

    return (this->*lpEntry->pfn)(lpContext, lpRequest);
}

### 关于MFC对话框开发的示例代码与教程 MFC(Microsoft Foundation Class Library)是一种用于Windows应用程序开发的C++类库,其核心功能之一就是支持基于对话框的应用程序开发。以下是有关MFC对话框开发的一些关键概念以及示例代码。 #### 创建基本的MFC对话框应用 在MFC中,可以通过向导工具快速创建一个基于对话框的应用程序项目。完成后,可以自定义对话框资源并绑定控件到成员变量上。以下是一个简单的示例代码展示如何初始化和显示一个对话框: ```cpp #include "stdafx.h" #include "resource.h" class CMyDialog : public CDialogEx { public: CMyDialog() : CDialogEx(IDD_DIALOG1) {} protected: afx_msg void OnBnClickedOk(); DECLARE_MESSAGE_MAP() }; BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx) ON_BN_CLICKED(IDC_BUTTON_OK, &CMyDialog::OnBnClickedOk) END_MESSAGE_MAP() void CMyDialog::OnBnClickedOk() { AfxMessageBox(_T("Button Clicked!")); } int main() { CWinApp theApp; theApp.InitInstance(); CMyDialog dlg; dlg.DoModal(); return 0; } ``` 上述代码展示了如何继承`CDialogEx`来实现自己的对话框类,并处理按钮点击事件[^2]。 #### 多线程技术支持下的对话框响应优化 当涉及耗时操作时,为了保持界面流畅性,通常会采用多线程技术。MFC提供了`CWinThread`作为所有线程对象的基础类。开发者可以根据需求派生工作线程或UI线程以执行特定任务。例如,在后台计算的同时更新进度条状态: ```cpp UINT MyWorkerFunction(LPVOID pParam){ // Simulate a long process. Sleep(5000); return 0; } void CMyDialog::StartWorkInThread(){ AfxBeginThread(MyWorkerFunction, NULL); } ``` 这里调用了`AfxBeginThread`函数启动一个新的工作线程去完成某些长时间运行的任务[^1]。 #### 总结 以上介绍了两个方面:一是构建基础对话框及其交互逻辑;二是借助多线程改善用户体验的方法论。对于初学者而言,建议先掌握静态/动态控件属性设置、消息映射机制等内容后再深入研究高级特性如异步通信等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值