又一个Debug/release问题?

ahphone 2002-05-18 03:46:54
最近给朋友做界面时碰到的。界面是这样的:
SDI , 窗口被静态分割成左右两部分,右边用作试图切换。左边上部是个TabCtrl,下边是几个按钮。左边的TabCtrl是竖向排列的,所以我专门做了个基于CTabCtrl的类CKxTabCtrl.该类说起来比较简单,初始化时new几个对话框(Child,None board),然后把对话框移到TabCtrl的客户区.
问题出在:我重载了CTabCtrl的鼠标双击的消息映射函数,在该函数中向左边视图发了个消息,希望双击TabCtrl的ItemHead时,右边的视图能切换到相应的视图。
左边视图的指针是CKxTabCtrl初始化时传到CKxTabCtrl的,消息WM_MY_TABDBCLICK。想来不会有什么问题。m_pView->PostMessage(WM_MY_TANDBCLICK,(WPARAM)GetCurSel());
然后在左边视图类中处理消息,根据wParam的值进行切换。
这一切在Debug下运行得很好,然而一到release下,只要双击TabCtrl的ItemHead,视图切换过去后不到1秒就出错!
我检查了该类的GetDocument(),和Document类的变量。没什么异常,该初始化的都做到位了。
我特意在左边加了一排按钮来尝试切换,release非常正常!
最后,我把m_pView->PostMessage(WM_MY_TANDBCLICK,(WPARAM)GetCurSel());屏蔽掉,release正常!但不能切换了.
我尝试减少PostMessage的参数,没用!
我干脆让m_pView->PostMessage(WM_MY_TANDBCLICK,(WPARAM)GetCurSel());有效,但左边视图不处理该消息。正常!

这条路就走到这里了。双击切换的功能最后我在左边视图内通过处理CTabCtrl的Onclick(),配合定时器做出来了。
但为什么我在release下就不能像debug下那么发消息?


上面的程序在Win2k下VC++6.0(No service pack)完成。以上提到的函数可能有误,请相信我的程序里写的是正确的。

欢迎大家讨论。如果认为我某些地方没讲清楚,请跟贴,或者直接发到ahphone@263.net.
这个油箱已经转为收费油箱了。


...全文
118 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
ahphone 2002-05-21
  • 打赏
  • 举报
回复
已经试过了,pView->PostMessage(WM_COMMAD,WM_MYMSG,0);
ON_COMMAND(...)
就可以了,那么为什么
m_pView->PostMessage(WM_MY_TANDBCLICK,(WPARAM)GetCurSel());就不行呢?

微软的BUG???起码DEBUG下是可行的啊。
freelybird 2002-05-20
  • 打赏
  • 举报
回复
至于消息映射: ON_COMMAND(...)
freelybird 2002-05-20
  • 打赏
  • 举报
回复
据我分析,与这个有关(WPARAM)GetCurSel(), 这个传递的东东对吗?应该确保无误
ahphone 2002-05-19
  • 打赏
  • 举报
回复
我还是觉得wened(阿坟) 的回答可能离答案很近。
pView->PostMessage(WM_COMMAD,WM_MYMSG,0);
可怎么处理消息映射函数呢?我得回去看看MSDN了。
晚安!~~~~~~~~~~~
ahphone 2002-05-19
  • 打赏
  • 举报
回复
我来说几句吧:
To: ytweiwei(最近正在学VB) ,你的方法我试过了,没用,这片文章我看的是英文。^_^,你的中文版我好像在www.vchelp.net上见过。

jiangsheng(蒋晟卧病中) :你可真能在csdn混,我们都撤了,你居然还在。好同志!身体要紧。你的文章我回头仔细琢磨一下。
难道m_pView->PostMessage(WM_MY_TANDBCLICK,(WPARAM)GetCurSel());有什么特别不妥?
怎么觉得贴出来的跟问题不太相关,不过也许你是对的。

wened(阿坟) :我回去试试看看,说不定还真是这么回事。

freelybird(阿愚) :直接的源代码不便给你,没办法,我也知道那堆代码没什么秘密可言。不过我凭记忆和我以前的资料重现了问题。如果wened(阿坟) 的方法也无效的话,我把演示工程寄给你。


还有谁也有空去研究这个代码的话,可以留下email.

今天极其不爽,跟我合租房子的小伙子居然也不打声招呼就搬走了。搞得我一直没心情,所以晚上才来。

eaststar 2002-05-18
  • 打赏
  • 举报
回复
有没有人干脆出来把DEBUG与RELEASE的版本区别所在说清楚?
蒋晟 2002-05-18
  • 打赏
  • 举报
回复
Knowledge Base Articles

PRB: Incorrect Function Signatures May Cause Problems in Release
Q195032


--------------------------------------------------------------------------------
The information in this article applies to:

The Microsoft Foundation Classes (MFC), used with:
Microsoft Visual C++, 32-bit Editions, versions 4.0, 4.1
Microsoft Visual C++, 32-bit Enterprise Edition, version 4.2
Microsoft Visual C++, 32-bit Professional Edition, version 4.2
Microsoft Visual C++, 32-bit Enterprise Edition, version 5.0
Microsoft Visual C++, 32-bit Professional Edition, version 5.0
Microsoft Visual C++, 32-bit Enterprise Edition, version 6.0
Microsoft Visual C++, 32-bit Professional Edition, version 6.0
Microsoft Visual C++, 32-bit Learning Edition, version 6.0

--------------------------------------------------------------------------------
SYMPTOMS
When developing applications in Visual C++ with MFC, you may receive an invalid page fault in Mfc42.dll in release builds due to an incorrect function signature for any of the following MFC macros:

ON_MESSAGE()
ON_REGISTERED_MESSAGE()
ON_THREAD_MESSAGE()
ON_REGISTERED_THREAD_MESSAGE()



CAUSE
The message handlers for ON_MESSAGE(), ON_REGISTERED_MESSAGE(), ON_THREAD_MESSAGE(), and ON_REGISTERED_THREAD_MESSAGE() require the programmer to have the correct function signatures. By not having a correct function signature for the handler, an invalid page fault in Mfc42.dll results after the handler executes in release builds. A crash in debug builds does not occur because the stack frame is set up differently for debug builds than it is for release builds.



RESOLUTION
Make sure your message handlers for ON_MESSAGE(), ON_REGISTERED_MESSAGE(), ON_THREAD_MESSAGE(), and ON_REGISTERED_THREAD_MESSAGE() have the correct signatures.

The correct signature for ON_MESSAGE() is:


afx_msg LRESULT OnMyMsg(WPARAM, LPARAM)
The correct signature for ON_REGISTERED_MESSAGE is:

afx_msg LRESULT OnMyRegisteredMsg(WPARAM, LPARAM)
The correct signature for ON_THREAD_MESSAGE is:

afx_msg void OnMyThreadMsg(WPARAM, LPARAM)
The correct signature for ON_REGISTERED_THREAD_MESSAGE is:

afx_msg void OnMyRegisteredThreadMsg(WPARAM, LPARAM)
For signatures for other versions of Visual C++, please consult help for ON_MESSAGE(), ON_REGISTERED_MESSAGE(), ON_THREAD_MESSAGE() and ON_REGISTERED_THREAD_MESSAGE().

To get a compile-time error when using these macros, you can re-define the macros after the "#include <afxwin.h>" line in your Stdafx.h file. The code below uses the static_cast<> operator to aid the compiler and developer by doing strict type conversion on the function pointer:

#undef ON_MESSAGE
#define ON_MESSAGE(message, memberFxn) \
{ message, 0, 0, 0, AfxSig_lwl, \
(AFX_PMSG) (AFX_PMSGW) (static_cast< LRESULT (AFX_MSG_CALL
CWnd::*)(WPARAM, LPARAM) > (&memberFxn)) },


#undef ON_REGISTERED_MESSAGE
#define ON_REGISTERED_MESSAGE(nMessageVariable, memberFxn) \
{ 0xC000, 0, 0, 0, (UINT)(UINT*)(&nMessageVariable), \
(AFX_PMSG)(AFX_PMSGW)(static_cast<LRESULT (AFX_MSG_CALL
CWnd::*)(WPARAM, LPARAM)>(&memberFxn)) },


#undef ON_THREAD_MESSAGE
#define ON_THREAD_MESSAGE(message, memberFxn) \
{ message, 0, 0, 0, AfxSig_vwl, \
(AFX_PMSG)(AFX_PMSGT)(static_cast<void (AFX_MSG_CALL
CWinThread::*)(WPARAM, LPARAM)>(&memberFxn)) },


#undef ON_REGISTERED_THREAD_MESSAGE
#define ON_REGISTERED_THREAD_MESSAGE(nMessageVariable, memberFxn) \
{ 0xC000, 0, 0, 0, (UINT)(UINT*)(&nMessageVariable), \
(AFX_PMSG)(AFX_PMSGT)(static_cast<void (AFX_MSG_CALL
WinThread::*)(WPARAM, LPARAM)>(&memberFxn)) },
The ON_MESSAGE(), ON_REGISTERED_MESSAGE(), ON_THREAD_MESSAGE() and ON_REGISTERED_THREAD_MESSAGE() macros are defined in \mfc\include\afxmsg_.h.



STATUS
Microsoft has confirmed this to be a problem in the Microsoft products listed at the beginning of this article.


wened 2002-05-18
  • 打赏
  • 举报
回复
我也遇到这样的情况,向View里发自定义消息是在Debug下是好的,在Release下出错,最后我没招了,只好把View里的消息改成Command消息,在发送时,用pView->PostMessage(WM_COMMAD,WM_MYMSG,0);这样就好了,怪死了
freelybird 2002-05-18
  • 打赏
  • 举报
回复
下班了,我要回去了,现解决了吗?
freelybird 2002-05-18
  • 打赏
  • 举报
回复
关于断点技巧,细说有许多,关键是平常一般不太用,例如可以指定这些情况break:在某个函数调用时,某个内存地址,某个变量发生变量时,内存地址值发生变化时,某个窗口消息出现时.在每一种情况下,都可以指定条件(即出现多少次这样的情况就会break)
freelybird 2002-05-18
  • 打赏
  • 举报
回复
以前我遇到一个更好趣的怪事,就是Debug运行相安无事,而release则在特定条件下程序会自动退出,并不报异常
你知道什么原因引起的吧?就是一个buffer分配小了,在写这个buffer时超出,覆盖了别的对象,但为什么Debug没关系呢,而relese则不行呢?是因为局部变量在压栈的顺序不一样,恰好debug时,覆盖的是另一块buffer,而release时,则覆盖了一个CString对象,所以在Debug虽然导致另一个buffer中的数据不对,但问题不大,可release下则灾难发生了.所以说,出现这种现象,还是程序有bug,可能逻辑不对


ytweiwei 2002-05-18
  • 打赏
  • 举报
回复


在VC中当整个工程较大时,软件时常为出现在DEBUG状态下能运行而在RELEASE状态下无法运行的情况。由于开发者通常在DEBUG状态下开发软件,所以这种情况时常是在我们辛苦工作一两个月后,满怀信心的准备将软件发行时发生。为了避免无谓的损失,我们最好进行以下的检查:
1、时常测试软件的两种版本。

2、不要轻易将问题归结为DEBUG/RELEASE问题,除非你已经充分对两种版本进行了测试。

3、预处理的不同,也有可能引起这样的问题。
出现问题的一种可能性是在不同版本的编译间定义了不同的预处理标记。请对你的DEBUG版本的软件试一下以下改动:

在"Project Setting(ALT-F7)" 中的C/C++项中设置目录(category)为"General",并且改动"_DEBUG"定义为"NDEBUG".
设置目录为"Preprocessor"并且添加定义"_DEBUG到"Undefined Symbols"输入框.
选择Rebuild ALL,重新编译.
如果经过编译的程序产生了问题,请对代码进行如下改动:

将ASSERT() 改为 VERIFY().
找出定义在"#ifdef _DEBUG"中的代码,如果在RELEASE版本中需要这些代码请将他们移到定义外。
查找TRACE(...)中代码,因为这些代码在RELEASE中也不被编译。
所以请认真检查那些在RELEASE中需要的代码是否并没有被便宜。

4、变量的初始化所带来的不同,在不同的系统,或是在DEBUG/RELEASE版本间都存在这样的差异,所以请对变量进行初始化。

5、是否在编译时已经有了警告?请将警告级别设置为3或4,然后保证在编译时没有警告出现.

6、是否改动了资源文件.

7、此外对RELEASE版本的软件也可以进行调试,请做如下改动:

在"Project Settings" 中 "C++/C " 项目下设置 "category" 为 "General" 并且将"Debug Info"设置为 "Program Database".
在"Link"项目下选中"Generate Debug Info"检查框。
"Rebuild All"
如此做法会产生的一些限制:

无法获得在MFC DLL中的变量的值。
必须对该软件所使用的所有DLL工程都进行改动。
另:
MS BUG:MS的一份技术文档中表明,在VC5中对于DLL的"Maximize Speed"优化选项并未被完全支持,因此这将会引起内存错误并导致程序崩溃。

freelybird 2002-05-18
  • 打赏
  • 举报
回复
你可以调试找出bug所在呀!
ahphone 2002-05-18
  • 打赏
  • 举报
回复
I will try!
ahphone 2002-05-18
  • 打赏
  • 举报
回复
回去看看。
ahphone 2002-05-18
  • 打赏
  • 举报
回复
关于设置各种断点的技巧,愿闻其详,反正是讨论。
freelybird 2002-05-18
  • 打赏
  • 举报
回复
你可以调试找出bug所以呀!
freelybird 2002-05-18
  • 打赏
  • 举报
回复

关于变量自动置0的问题,当在栈上时,显然不会;在全局时,应该会设置为NULL.
其实看一下汇编代码就明白了
ahphone 2002-05-18
  • 打赏
  • 举报
回复
To freelybird(阿愚) :
刚才掉线了,写了一堆都白搭。
我觉得该说的都说了,只是条理可能不清。我没怎么提右边的视图。问题其实集中在左边。
你说的方法我以前就见过,以前用过。
freelybird 2002-05-18
  • 打赏
  • 举报
回复

在调试时,注意设置各种断点的技巧
加载更多回复(4)

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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