WTL 拆分器示例中的调试断言

Posted

技术标签:

【中文标题】WTL 拆分器示例中的调试断言【英文标题】:Debug assertion in WTL splitter sample 【发布时间】:2017-06-23 12:00:25 【问题描述】:

在用vs2013编译的WTL sample的主机菜单中点击读取或清除剪贴板时

CHAIN_COMMANDS_MEMBER(m_wndFormatList) 将消息从主机传递到成员列表控件但消息为空?

堆栈跟踪:

WTLClipSpy.exe!ATL::CWindowImplRoot<WTL::CListViewCtrlT<ATL::CWindow> ::SetMsgHandled(int bHandled) Line 3213   C++
WTLClipSpy.exe!CClipSpyListCtrl::ProcessWindowMessage(HWND__ * hWnd, unsigned int uMsg, unsigned int wParam, long lParam, long & lResult, unsigned long dwMsgMapID) Line 30 C++
WTLClipSpy.exe!CMainFrame::ProcessWindowMessage(HWND__ * hWnd, unsigned int uMsg, unsigned int wParam, long lParam, long & lResult, unsigned long dwMsgMapID) Line 41   C++

调试输出:

调试断言失败!

程序:...nloads\source\WTL4MFC7_demo\WTLClipSpy.\Debug\WTLClipSpy.exe 文件:c:\program files (x86)\microsoft visual studio 12.0\vc\atlmfc\include\atlwin.h 线路:3213

表达式:pMsg != 0

【问题讨论】:

【参考方案1】:

这可能是一个不太流行的CHAIN_COMMANDS_MEMBER 宏的回归问题。

解决方法可能如下所示:

    //CHAIN_COMMANDS_MEMBER(m_wndFormatList)
    if(uMsg == WM_COMMAND)
    
        lResult = m_wndFormatList.SendMessage(uMsg, wParam, lParam);
        if(lResult == 0)
            return TRUE;
    

或者,如果您更喜欢绕过SendMessage API(有意义),那么您将需要注意链式控件中的m_pCurrentMsg 初始化。更好但更长的修复。

【讨论】:

感谢您的回答。 “照顾链式控件中的 m_pCurrentMsg 初始化”是什么意思? WTL 窗口过程(WindowProcDialogProc 实现)在执行实际的映射处理程序之前初始化各个消息映射处理程序的m_pCurrentMsg,然后适当地清除变量。 CHAIN_COMMANDS_MEMBER 不这样做并直接执行处理程序。这会导致您报告的问题。需要更新宏代码以添加缺少的变量初始化,或者我上面建议的方式也或多或少没问题。 #define CHAIN_COMMANDS_MEMBER(theChainMember) \ theChainMember.m_pCurrentMsg = m_pCurrentMsg; \ if(uMsg == WM_COMMAND) \ CHAIN_MSG_MAP_MEMBER(theChainMember) 在 atlwinx.h 似乎工作。

以上是关于WTL 拆分器示例中的调试断言的主要内容,如果未能解决你的问题,请参考以下文章

如何防止 WTL CSplitterWindow 调整大小?

MFC 拆分器窗口中的多个文档/视图

断言与 C/C++ 中的调试有啥关系? [关闭]

mfc140ud.dll 中的调试断言失败

有啥方法可以避免 C++ 中的“调试断言失败”窗口?

在 mfc vs2010 运行时替换拆分器窗口中的视图