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分支打开菜单窗口的前后都加了断点,未见异常退出发生。为啥?
消息机制崩溃了吗?
该如何排查问题?

解决方案 »

  1.   

    搜“GDI泄露检测”?
      

  2.   

    看看 PostMessage 是否成功?
    将 PostMessage 的消息 参数 TRACE出来 观察 参数变化
      

  3.   


    不是GDI的问题。1 所有的GDI有关的都在一个自定义的类里面,GetXX  createXX 都有ReleaseXX   DeleteXX进行对应。2 主程序里面定时刷新界面显示数据,在登录后即不刷新了(甚至注释掉),打开Menu子窗口后,什么都不操作,几分钟后,还是一样的结果。
      

  4.   


    键盘扫描时,如果没有按键,我返回了0x00,有按键时就返回的按键值(根据行列查二维表),在按键释放时                        if ((byteKey == 0x00) && (bytePriorKey > 0)) //抬起,才认为完成一次按键
    {
    //根据当前的窗口定向的发送按键消息
    ::PostMessage(dlgCurrent->m_hWnd, MYMSG_KEYDOWN, bytePriorKey, 0);
    }
    bytePriorKey = byteKey;所以用的debug加断点,看发送消息,相关dlgCurrent的数据均正常。
    PostMessage本身是否成功,倒是可以看看。
      

  5.   

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

  6.   

    1.建议多线程程序发送消息的时候不要随便使用窗口指针,然后还要里面的窗口句柄,因为这个dlgCurrent在窗口切换的时候辅助线程可能不知道,所以你最少做一个临界区互斥吧
    2.可能你的程序在某个地方修改了指针,或者指针无效了,所以这时候可能不好调试到异常错误,建议你每次PostMessage(....)时把目标窗口和句柄保存到一个Log文件中,然后也把弹出CMYMenu窗口也做个记录,时间最好能够记录到毫秒
      

  7.   


    买的板子带的Windows Embedded Compact 7里面没有这些
      

  8.   


    写一个log看看,明天去试试。
      

  9.   

    为什么 PostMessage 而不是 SendMessage, 进一步· 窗口 收到 Message 后 要 回复 一个 消息,表示收到,
    你这样 乱发 乱收 , 不会 掉 东西 吗 ?