关于Debug和Release版本的程序的问题

tyjzq 2002-05-10 11:04:08
Debug版本的程序能够正常运行,但Release版本的就不能,跟踪了半天是在一处发送消息的地方有非法访问操作

SendMessage(MYMESSAGE,0,0);
或者:::SendMessage(this->m_hWnd,MYMESSAGE,0,0);
...全文
21 点赞 收藏 7
写回复
7 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
keenhaung 2002-05-12
自定义消息要将返回值和参数写完整:
afx_msg LRESULT OnXXXXXX(WPARAM wParam,LPARAM lParam);
回复
蒋晟 2002-05-12
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.



MORE INFORMATION

Steps to Reproduce Behavior
Create a new Application Wizard MFC dialog project named Sample with default settings.


Add the following line of code to the dialog header file above the line class Sample:



#define WM_MYMSG WM_USER+555
Add a custom message handler to the dialog class with incorrect function signature, for example:



afx_msg void OnMyMsg(void); //in header file
void CSampleDlg::OnMyMsg(void) {} //in source file
Add the following line of code inside of the message handler:



AfxMessageBox("Got WM_MYMSG");
Add a ON_MESSAGE entry in the message map in the dialog source file, for example:



ON_MESSAGE(WM_MYMSG, OnMyMsg)
Add the following line of code inside of the OnInitDialog of the class after CDialog::OnInitDialog();:



SendMessage(WM_MYMSG);
In debug builds, the message box appears and no invalid page fault occurs. In release builds, the message box appears and an invalid page fault in Mfc42.dll occurs after you dismiss the message box.



REFERENCES
ON_MESSAGE() in the Visual C++ Product Documentation.

ON_REGISTERED_MESSAGE() in the Visual C++ Product Documentation.

ON_THREAD_MESSAGE() in the Visual C++ Product Documentation.

ON_REGISTERED_THREAD_MESSAGE() in the Visual C++ Product Documentation.

(c) Microsoft Corporation 1998, All Rights Reserved. Contributions by Nathan Manis, Microsoft Corporation.

© Microsoft Corporation 1998, All Rights Reserved.
Contributions by Nathan Manis, Microsoft Corporation


Additional query words: crash access violation release debug message map

Keywords : kbMFC kbVC400 kbVC410 kbVC420 kbVC500 kbVC600 kbGrpDSMFCATL
Issue type : kbprb
Technology : kbAudDeveloper kbMFC


Last Reviewed: July 17, 2001



--------------------------------------------------------------------------------

Send feedback to Microsoft

© 2002 Microsoft Corporation. All rights reserved.


回复
Hover 2002-05-11
Debug和Release版本对变量的初始化方式也有所不同
回复
loyee 2002-05-11
1)运行环境是否在多线程环境中?调用SendMessage(...)时要确定目的窗口是否已经DESTORY了.或者在消息处理中调用了其他线程的资源? DEBUG模式下因为运行速度相对慢,一般不出现问题.在Release下会出现.应该仔细考虑线程的同步.

2)若不是要等MESSAGE的执行结果,可以考虑用PostMessage(...).

回复
lbird 2002-05-11
我遇到过:
在用SendMessage发送自定义消息时,
该消息对应的函数没有WPARAM,LPARAM参数时,如:OnSend()
程序在RELEASE版本下会出错,在DEBUG下运行正常
后来函数修改为OnSend(WPARAM ,LPARAM)才可以,虽然这两个参数并没有用到

回复
tyjzq 2002-05-11
非常谢谢各位!
回复
Richuen22 2002-05-11
给你一个VC7下的MSDN例子
Example
// In a dialog-based app, if you add a minimize button to your
// dialog, you will need the code below to draw the icon.
void CMyDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon represented by handle m_hIcon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
回复
相关推荐
发帖
VC/MFC
创建于2007-09-28

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
帖子事件
创建了帖子
2002-05-10 11:04
社区公告

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