Win32 No-MFC 中的消息映射

2024-01-02

我如何创建类似的结构来处理 Win32 消息,就像在 MFC 中一样?

In 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 http://www.zeusedit.com程序员编辑:

Step 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);

Step 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, WPARAM wParam, 
                LPARAM lParam, LRESULT &Result);

  //-- method for command message dispatching
  virtual void dispatchToCmdMap(xMessage *pMessage);

  //-- method for windows message dispatching
  virtual void dispatchToMsgMap(xMessage *pMessage);
};

Step 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);        \                              
     }                                         \                              
   };

Step 4:定义调度程序方法:

void xWindow::dispatch(HWND, UINT uMessageID, WPARAM wParam, 
                       LPARAM lParam, 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);
}

Step 5:定义静态窗口过程方法(NOTE:当类首次注册时,需要将此方法用作窗口类的窗口过程):

LRESULT CALLBACK xWindow::wndProc(HWND hwnd, UINT msg, 
                                  WPARAM wParam, 
                                  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, msg, wParam, 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, msg, wParam, lParam, lResult);
    }
    else
    {
      //-- leave the message to windows
      lResult = ::DefWindowProc(hwnd, msg, wParam, 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)
};

编辑:这段代码是如何工作的。

理解这段代码如何工作的秘诀是记住wndProc in the xWindow类只不过是一个Win32窗口过程传递给注册类Ex当 Win32 窗口注册时。

现在如果你看一下wndProc您会看到代码进行了一些设置和检查,但通常它只是将 Windows 消息发送到dispatch方法。

The dispatch方法甚至更简单,因为它只不过将 Windows 消息打包到一个易于移动结构,然后将其发送到调度消息映射 method.

现在看看MyWindow类 an 你会看到这样的代码:

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)

这段代码只是使用了之前定义的宏。如果您仔细查看这些宏,您会发现上面的代码实际上是创建一个调度消息映射方法。这是完全相同的调度消息映射调用的方法dispatch方法。

我知道这种处理 Windows 消息的方法确实有效,因为我在Windows 版宙斯 http://www.zeusedit.com editor.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Win32 No-MFC 中的消息映射 的相关文章

  • 如何从Python列表中的字符串中删除双引号?

    我正在尝试在字典列表中获取一些数据 数据来自 csv 文件 因此都是字符串 文件中的键都有双引号 但由于这些都是字符串 我想删除它们 这样它们在字典中看起来像这样 key value 而不是这个 key value 我尝试简单地使用 str
  • 具有键唯一性和按位置排序的 MFC 字典集合

    看着表上http msdn microsoft com en us library y1z022s1 28v vs 80 29 aspx core collection shape features http msdn microsoft
  • 为什么在读取字典时要锁定

    我对我正在阅读的一本关于线程的书 C 3 in a Nutshell 中的代码列表感到困惑 在 应用程序服务器中的线程安全 主题中 给出了以下代码作为 UserCache 的示例 static class UserCache static
  • 初始化 LPCTSTR /LPCWSTR [重复]

    这个问题在这里已经有答案了 我很难理解并使其正常工作 基本上归结为我无法成功初始化这种类型的变量 它需要有说的内容7 2E25DC9D 0 USB003 有人可以解释 展示这种类型的正确初始化和类似的值吗 我已查看此站点上的所有帮助 将项目
  • 使用 for 循环填充 python 字典列表

    我试图用 for 循环填充字典列表 但最终结果显示 for 循环填充的最后一个字典覆盖了所有先前字典的值 我尝试调整以下中提出的解决方案 如何使用循环填充 Python 字典 https stackoverflow com question
  • 如何保证对象只有一个线程

    我有以下代码 class Service public void start creates thread which creates window and goes to message loop void stop sends WM C
  • 根据第三个变量更改散点图中的标记样式

    我正在处理多列字典 我想绘制两列 然后根据第三列和第四列更改标记的颜色和样式 我很难改变 pylab 散点图中的标记样式 我的方法适用于颜色 不幸的是不适用于标记样式 x 1 2 3 4 5 6 y 1 3 4 5 6 7 m k l l
  • 使用 BitBlt 捕获程序窗口始终返回相同的图像

    我编写了以下代码 C Win32 来捕获游戏窗口屏幕并从图像中获取像素颜色数组 函数 autoB 完成这项工作 然后我将结果数组绘制到窗口中以直观地检查我得到的结果 问题是 这个程序在我启动计算机后只工作一次 在第一次 缓存 从游戏中获取的
  • 从字典的元素创建 Pandas 数据框

    我正在尝试从字典创建一个 pandas 数据框 字典设置为 nvalues y1 1 2 3 4 y2 5 6 7 8 y3 a b c d 我希望数据框仅包含 y1 and y2 到目前为止我可以使用 df pd DataFrame fr
  • 调整大小时在窗口中绘图留下未绘制的边框

    我遇到的问题看似微不足道 但我找不到解决的方法 这里是 我有一个窗口 里面有一些图形 为了简单起见 我们假设它是一个实心绿色矩形 填充了窗口的整个客户区域 我希望每次窗口改变大小时都重新绘制这个矩形并填充整个窗口 我最初做的就是这样的 我已
  • 提取证书中主题属性的所有值

    我目前正在使用CertGetNameString http msdn microsoft com en us library windows desktop aa376086 28v vs 85 29 aspx提取每个主题属性的值 如下所示
  • JAVA:如何搜索地图?

    我有一个 Map 其键为字符串 其值为集合 包含整数 假设我的钥匙看起来像 苹果 香蕉 橙色 等 用户输入文本 我将其保存为字符串变量 如何在我的地图中搜索相同的密钥 因此 如果用户输入 apple 我如何将该字符串提供给方法并让该方法在我
  • 如何使用 Win32 API 与 com 端口 (RS232) 通信

    我正在尝试使用 win32 API 与 com 端口对话 我找到了这个http www robbayer com files serial win pdf http www robbayer com files serial win pdf
  • 将目录压缩为单个文件的方法有哪些

    不知道怎么问 所以我会解释一下情况 我需要存储一些压缩文件 最初的想法是创建一个文件夹并存储所需数量的压缩文件 并创建一个文件来保存有关每个压缩文件的数据 但是 我不被允许创建许多文件 只能有一个 我决定创建一个压缩文件 其中包含有关进一步
  • “printf”在 Windows 非控制台应用程序中写入何处?

    如果我选择创建 Windows 非控制台应用程序 并实施printf cout在代码中 在哪里printf cout写 它是否写到stdout缓冲 如果是 有什么办法可以读取它stdout并将其打印到某个文本文件或执行MessageBox与
  • 如何在 Swift 3 中解析 JSON 数组 [重复]

    这个问题在这里已经有答案了 我从 Socket 获取了一些我想访问的数据 但收到错误消息 指出每次都无法将 NSArray 转换为 NSDictionary struct SocketEventHandler let event Strin
  • 使用 Visual C++ 在桌面上绘图

    我正在编写一个 opencv 应用程序 使用 Visual Studio VC 控制台应用程序使用激光束进行绘图 我想在桌面上画线 我知道绘图功能在 GDI32 dll 中可用 但对如何将 GDI32 dll 与我的 vc 代码集成感到困惑
  • OleLoadPicturePath 是否已以非向后兼容的方式更改?

    我最近遇到一个问题 我能够在一台 PC 上将图标添加到 VB6 表单 它运行良好 但他们无法在第二台 PC 上运行 编译它 结果发现图标文件是 32 位的 包括 Alpha 通道 这就是问题所在 但令我惊讶的是 这是一个依赖于系统的功能 在
  • Python模块可以访问英语词典,包括单词的定义[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个 python 模块 它可以帮助我从英语词典中获取单词的定义 当然有enchant 这可以帮助我检查该单词是否存在于英语中
  • Tkinter - 浮动窗口 - 调整大小

    灵感来自this https stackoverflow com a 22424245 13629335问题 我想为我的根窗口编写自己的调整大小函数 但我刚刚注意到我的代码显示了一些性能问题 如果你快速调整它的大小 你会发现窗口没有像我希望

随机推荐