Windows程序设计——两个重要的参数wParam和lParam

windows的消息具有以下两个参数:

(1)字参数(wParam)
(2)长参数(lParam)
  字参数和长参数都是32位整数,用于提供消息的附带消息,是消息传递过程中参数的载体。附加信息的消息号取决于消息号。

一、wParam和lParam消息 :部分说明需要查看MSDN

例如:

1 WM_PAINT消息,LOWORD(lParam)是客户区的宽,HIWORD(lParam)是客户区的高。
2 滚动条WM_VSCROLL或WM_HSCROLL消息,LOWORD(wParam)指出了鼠标对滚动条的操作。比如上、下、左、右、翻页、移动等。
3 击键消息,有WM_SYSKEYDOWN、WM_SYSKEYUP、WM_KEYUP、WM_KEYDOWN,其中wParam是虚拟键代码,lParam是包含属于击键的其他信息。lParam消息参数分为6个域,有重复计数、环境代码、键的先前状态等。
4 字符消息WM_CHAR、WM_DEADCHAR、WM_SYSCHAR、WM_SYSDEADCHAR,lParam消息参数跟击键消息的lParam消息参数内容相同,wParam参数是ANSI或Unicode字符代码
5 客户区鼠标消息WM_LBUTTONDOWN、WM_LBUTTONUP、WM_RBUTTONDOWN、WM_RBUTTONUP、WM_MBUTTONDOWN、WM_MBUTTONUP,lParam参数的低位是鼠标的客户区x坐标,高位是客户区y坐标。wParam参数是指示鼠标键及Shift和Ctrl键的状态。wParam&MK_SHIFT或MK_CTRL,如果返回TRUE就意味着有按下Shift或Ctrl键。
6 非客户区消息,wParam参数指明移动或者单击鼠标键的非客户区位置,以HT开头,lParam参数低位指出了鼠标所在屏幕坐标的x坐标,高位指出了鼠标所在屏幕坐标的y坐标。
7 鼠标轮滚动消息,WM_MOUSEWHEEL消息,lParam

为了将`afx_msg LRESULT CModbusComm::OnRecvData(WPARAM _wParam, LPARAM _lParam)`这个消息映射函数放入独立线程中运行,你需要做以下几个步骤: ### 一、理解现有机制 首先明确一点的是,在MFC框架下,像`afx_msg LRESULT CModbusComm::OnRecvData(...)`这样的声明意味着这是一个窗口过程的消息处理程序。它通常用于响应特定的消息(例如用户自定义消息),并在主线程上下文中被执行。 如果你想让其工作在一个单独的工作线程里而不是UI线程,则需要改变思路——因为直接把消息处理函数放进另一个线程是不可能也不合适的;相反地,你应该考虑如何设计你的应用程序架构使得数据接收可以在后台完成而不会阻塞GUI界面。 ### 二、创建工作者线程并分离任务 #### 第一步:启动一个新的线程 可以使用Win32 API `CreateThread()` 或者更现代的方式如C++11 标准库里的 `<thread>` 库来开启新的线程。对于本案例来说,我们建议采用较为简便易维护的做法 - 使用 MFC 的 `_beginthreadex(NULL,...);` ```cpp UINT __stdcall ThreadFunction(LPVOID lpParam) { // 这里放置你想在线程内循环执行的数据监听逻辑, // 每次接收到新数据后通知主窗体更新状态等操作。 while (!bStopFlag /* 停止标志 */) { if (CheckForNewMessage()) { // 自己实现该检查是否有新消息到来的方法 PostMessage(hwndMainForm, WM_USER+100, wParam, lParam); } Sleep(500); // 防止CPU占用过高 } return 0; } // 启动线程的地方 AfxBeginThread(ThreadFunction, NULL); ``` 注意这里通过`PostMessage`向主线程发送了一个非队列式的消息(`WM_USER + n`)。这是因为在Windows平台上跨线程间通信时推荐做法之一就是利用消息传递机制来进行同步通讯。 #### 第二步:修改原消息处理器成为普通成员函数 现在原本的 OnRecvData 成员不再作为消息映射的一部分了,而是变成了一个普通的静态或实例方法: ```cpp class CModbusComm : public ... { public: static LRESULT ProcessReceivedData(WPARAM wParam, LPARAM lParam); protected:// 移除原先的消息宏关联部分... }; ``` 然后在这个新的ProcessReceivedData()里面去做之前OnRecvData应该做的事情即可。不过要注意两点区别: * 参数来源变了 – 现在是从Post过来的消息参数拿到信息; * 因为是static所以如果涉及到访问类变量的话记得加锁保护共享资源的安全性。 最后别忘了给原有地方添加对上述变化的支持代码,比如注册消息映射表项等细节调整... ### 示例完整版伪代码结构概览: ```cpp // .h 文件 添加字段及声明 private: volatile bool m_bStopping; // 表示是否停止工作的布尔值 public: void StartProcessing(); static UINT WINAPI WorkerThreadProc(LPVOID pParam); static LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); // .cpp文件 实现具体业务逻辑 void CModbusComm::StartProcessing() { m_bStopping = false; AfxBeginThread(&WorkerThreadProc, this); } UINT WINAPI CModbusComm::WorkerThreadProc(LPVOID param) { auto selfPtr = reinterpret_cast<CModbusComm*>(param); while(!selfPtr->m_bStopping){ if(/*有新数据到达*/){ ::PostMessage(selfPtr->GetSafeHwnd(), UWM_NEW_DATA_COMES_IN, /*...*/,/*...*/ ); } std::this_thread::sleep_for(std::chrono::milliseconds{1}); } return 0; } LRESULT CModbusComm::WindowProcedure(...) {// 主要负责转发从其他进程发来的消息到对应的处理流程中去 switch(uMsg): case UWM_NEW_DATA_COMES_IN:{ // 转交给真正的“原”OnReciveData来做实际的事情 break;} default:return DefWindowProc(hwnd,uMsg,wParam,lParam);} } ``` 以上只是简化的例子,真实项目中还需要更多的错误处理其他必要的优化措施。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清河大善人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值