【问题标题】:WTL window/form crashes after infinite message loop causes stack overflowWTL 窗口/表单在无限消息循环导致堆栈溢出后崩溃
【发布时间】:2011-12-17 08:35:42
【问题描述】:

我有一个遗留项目需要修复 WTL/VC++ 中的错误。问题之一 - 使用 Ctrl+X 或 Ctrl+Z 键后主窗口(当然,整个应用程序)崩溃。我没有为这些键分配任何自定义加速键。 我发现“致命”组合键会导致

的无限消息循环

uMsg == 273 (0x00000111)

最终因堆栈溢出错误而崩溃:

 Command Code: 5, ID: 29892, HANDLE:  0xe091aFirst-chance exception at 0x007f88fa 
 in <myApp>.exe: 0xC00000FD: Stack overflow.
 Unhandled exception at 0x007f88fa in <myApp>.exe: 0xC00000FD: Stack overflow.

我只是在消息处理函数中打了补丁-

BEGIN_MSG_MAP(CMDIChildWindowImpl)

    MESSAGE_HANDLER(WM_CREATE, OnCreate)
    MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
    MESSAGE_HANDLER(WM_CLOSE, OnClose)
    MESSAGE_HANDLER(WM_TIMER, OnTimer)

* *

    COMMAND_ID_HANDLER(ID_FILE_NEW, OnNewDownload)
    COMMAND_ID_HANDLER(ID_UPLOAD_FOLDER_SET, OnUploadFolderSet)
    COMMAND_ID_HANDLER(ID_OPEN_RECORD_BY_ID, OnOpenOnline)

* *

    NOTIFY_CODE_HANDLER(HLN_PORTAL_RECORD_DOWNLOAD, OnPortalPageNotify);
    NOTIFY_CODE_HANDLER(HLN_SELCHANGED, OnWebFormNotify);
    if(uMsg == 273)
     return false;
    else
     CHAIN_MSG_MAP(baseClass)

END_MSG_MAP()

但我对这个创可贴补丁不满意,如果能了解发生了什么会很好 - 我实际上希望这些组合键在我的表单上执行 Windows 默认操作,“剪切”和“撤消”

有关致命消息的更多信息:

Ctrl+X -

uMsg 273 无符号整数

wParam 123171 无符号整数

lParam 0 长

lParam 0 长

Ctrl+Z -

uMsg 273 无符号整数

wParam 123179 无符号整数

lParam 0 长

对不起,如果这没有意义,我的 VC++ 功夫相当生疏;如果有人能告诉我在哪里寻找这些想法,那将不胜感激。

谢谢!

哦。

【问题讨论】:

  • 273WM_COMMAND 并且您似乎一直在弹跳此命令,直到它填满堆栈。您上面的代码 sn-ps 并没有显示到底做错了什么。
  • 我明白了,WM_COMMAND - 所以我也应该小心检查 wParams,而不是过滤掉其他菜单/加速器等。谢谢,我应该更坚持找到代码是什么。我猜它会反弹,因为它没有在“基类”中处理并被转发回“子类”。至于代码 - 我真的不知道在这里发布什么会有帮助。再次感谢罗曼!
  • 正常的操作流程是COMMAND_ID_HANDLERCOMMAND_HANDLERWM_COMMAND 的任何处理程序处理消息并在那里终止处理。您可能拥有的是该处理程序启动了一些生成相同通知的活动,并且它会滚动到堆栈溢出。因此,处理程序很重要。而且您还有一个包含详细信息的调用堆栈。
  • 太棒了!在这个窗口/类和它的基础窗口/类中没有 WM_COMMAND 的 MESSAGE_HANDLER,并且存在导致无限循环的链式调用/重定向消息转发。感谢您的帮助!
  • 它仍然是一种未说出口的气味。我会说您在那里不需要处理程序行,而是应该寻找放置不正确的转发行来完成循环引用。

标签: visual-c++ wtl


【解决方案1】:

感谢@Roman R,找到了这个-在有问题的窗口中,没有 WM_COMMAND 消息的处理程序,并且在它的一个基类中,有一个函数通过将消息转发回生成无限循环活动窗口。所以我添加了这个处理程序 -

        if(uMsg == WM_COMMAND)
          return DefWindowProc(WM_COMMAND, wParam, lParam);

这对我来说似乎是一个很好的解决方案。

谢谢!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-15
    • 2012-05-26
    • 2021-07-07
    • 1970-01-01
    相关资源
    最近更新 更多