【WCE7】 PreTranslateMessage中doModal打开窗口后,过一段时间PostMessage就接收不到了

shepher 2018-08-03 03:49:21
RT:
程序后台有一个线程,扫描矩阵键盘,并根据CWnd *dlgCurrent,发送按键消息
::PostMessage(dlgCurrent->m_hwnd, ...)

在主窗口和子窗口(Menu窗口)中都定义了PreTranslateMessage消息,
主窗体初始化时dlgCurrent = this。

运行程序后,主窗体可以接收相应的按键信息。
在按键消息中有一个是打开子窗体的
case MYKEY_MENU:
CMYMenu *dlgMenu = new CMYMenu();
dlgCurrent = dlgMenu;
dlgMenu.DoModal();
dlgCurrent = this;
...

刚打开Menu窗口时,键盘按键消息都正常。

不做任何操作,大约5分钟左右后,Menu窗口再也接收不到任何PostMessage的消息了。。。。

通过联调:
后台键盘扫描线程发送PostMessage时dlgCurrent数据正常(窗口指针什么的,都是指向Menu窗口的,前后对比);
Menu窗口正常显示;
Menu窗口析构函数增加了一段代码及断点,未见中断发生;
主窗体PreTranslateMessage里case MYKEY_MENU分支打开菜单窗口的前后都加了断点,未见异常退出发生。



为啥?
消息机制崩溃了吗?
该如何排查问题?
...全文
312 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
schlafenhamster 2018-08-14
  • 打赏
  • 举报
回复
为什么 PostMessage 而不是 SendMessage, 进一步· 窗口 收到 Message 后 要 回复 一个 消息,表示收到,
你这样 乱发 乱收 , 不会 掉 东西 吗 ?
shepher 2018-08-13
  • 打赏
  • 举报
回复
引用 9 楼 schlafenhamster 的回复:
硬件的 键盘 要 考虑 按键 抖动 。


防抖是考虑了的,用的延时。
shepher 2018-08-13
  • 打赏
  • 举报
回复
引用 10 楼 wwwfffhhh 的回复:
1.建议多线程程序发送消息的时候不要随便使用窗口指针,然后还要里面的窗口句柄,因为这个dlgCurrent在窗口切换的时候辅助线程可能不知道,所以你最少做一个临界区互斥吧

目前新打开窗口都是new出来的,new之后,马上就赋值dlgCurrent,然后domodal。domodal退出后,就恢复dlgCurrent的值。
仔细检查过没有中间其它的赋值情况。
这个地方做临界区?做成每个窗口去扫描键盘,而不是一个线程扫描发消息?

2.可能你的程序在某个地方修改了指针,或者指针无效了,所以这时候可能不好调试到异常错误,建议你每次PostMessage(....)时把目标窗口和句柄保存到一个Log文件中,然后也把弹出CMYMenu窗口也做个记录,时间最好能够记录到毫秒


写一个log看看,明天去试试。
shepher 2018-08-13
  • 打赏
  • 举报
回复
引用 8 楼 zhao4zhong1 的回复:
检查是否资源泄漏的办法之一:
在任务管理器 进程 查看 选择列 里面选择:内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象
让你的程序(进程)不退出,循环执行主流程很多遍,越多越好,比如1000000次甚至无限循环,记录以上各数值,再隔至少一小时,越长越好,比如一个月,再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加,则铁定有对应资源的资源泄漏!


买的板子带的Windows Embedded Compact 7里面没有这些。。。
牧童吃五谷 2018-08-13
  • 打赏
  • 举报
回复
1.建议多线程程序发送消息的时候不要随便使用窗口指针,然后还要里面的窗口句柄,因为这个dlgCurrent在窗口切换的时候辅助线程可能不知道,所以你最少做一个临界区互斥吧 2.可能你的程序在某个地方修改了指针,或者指针无效了,所以这时候可能不好调试到异常错误,建议你每次PostMessage(....)时把目标窗口和句柄保存到一个Log文件中,然后也把弹出CMYMenu窗口也做个记录,时间最好能够记录到毫秒
schlafenhamster 2018-08-13
  • 打赏
  • 举报
回复
硬件的 键盘 要 考虑 按键 抖动 。
赵4老师 2018-08-13
  • 打赏
  • 举报
回复
检查是否资源泄漏的办法之一:
在任务管理器 进程 查看 选择列 里面选择:内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象
让你的程序(进程)不退出,循环执行主流程很多遍,越多越好,比如1000000次甚至无限循环,记录以上各数值,再隔至少一小时,越长越好,比如一个月,再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加,则铁定有对应资源的资源泄漏!
shepher 2018-08-13
  • 打赏
  • 举报
回复
引用 3 楼 oyljerry 的回复:
把窗口句柄等也打印一下,看窗口句柄有没有变化


句柄时正常的,没有变。
shepher 2018-08-13
  • 打赏
  • 举报
回复
引用 2 楼 zgl7903 的回复:
看看 PostMessage 是否成功?
将 PostMessage 的消息 参数 TRACE出来 观察 参数变化


键盘扫描时,如果没有按键,我返回了0x00,有按键时就返回的按键值(根据行列查二维表),在按键释放时

if ((byteKey == 0x00) && (bytePriorKey > 0)) //抬起,才认为完成一次按键
{
//根据当前的窗口定向的发送按键消息
::PostMessage(dlgCurrent->m_hWnd, MYMSG_KEYDOWN, bytePriorKey, 0);
}
bytePriorKey = byteKey;

所以用的debug加断点,看发送消息,相关dlgCurrent的数据均正常。
PostMessage本身是否成功,倒是可以看看。
shepher 2018-08-13
  • 打赏
  • 举报
回复
引用 1 楼 zhao4zhong1 的回复:
搜“GDI泄露检测”?


不是GDI的问题。

1 所有的GDI有关的都在一个自定义的类里面,GetXX createXX 都有ReleaseXX DeleteXX进行对应。

2 主程序里面定时刷新界面显示数据,在登录后即不刷新了(甚至注释掉),打开Menu子窗口后,什么都不操作,几分钟后,还是一样的结果。


oyljerry 2018-08-08
  • 打赏
  • 举报
回复
把窗口句柄等也打印一下,看窗口句柄有没有变化
schlafenhamster 2018-08-08
  • 打赏
  • 举报
回复
"程序后台有一个线程,扫描矩阵键盘"
上传代码 ?
zgl7903 2018-08-04
  • 打赏
  • 举报
回复
看看 PostMessage 是否成功?
将 PostMessage 的消息 参数 TRACE出来 观察 参数变化
赵4老师 2018-08-03
  • 打赏
  • 举报
回复
搜“GDI泄露检测”?

15,978

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧