Link to home
Start Free TrialLog in
Avatar of wangtao
wangtao

asked on

"SendMessage"can't work under VC release

My prog based on CDialog,it work well
under Debug Model.But when I changed to
release Model,it can't work correctly!
When send message,the error emerged.
Please help me.
Avatar of Vinayak Kumbar
Vinayak Kumbar

Hi,

Try the same thing using PostMessage() instead of SendMessage().

VinExpert
Can U post the code.

We need to see you code, but even without code there is some things you can check, for example in debug mode all your variables, pointers and so on initializet by compiler automaticaly but in release not.
ASKER CERTIFIED SOLUTION
Avatar of mikeblas
mikeblas

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of wangtao

ASKER

in CTestDlg.h
  add:#define WM_TEST (WM_USER+1);
      afx_msg void OnTest();

in CTestDlg.cpp
 add:BEGIN_MESSAGE_MAP(CTestDlg,CDialog)
      //{{AFX_MSG_MAP(CWwwwDlg)
      ...........
      ON_MESSAGE(WM_TEST,OnTest)
         ............
      //}}AFX_MSG_MAP
     END_MESSAGE_MAP()    


     void CWwwwDlg::OnTest()
     {
     }

That all!But it can't work in the release model.

Please help  me!
       
Hi,

Again from where U R calling the SendMessage()?. That code is not there!. And what r u doing in OnTest()?.

But have U tried with PostMessage(WM_TEST,0,0); instead of SendMessage(...)? It seems to solve Ur problem.(As I was trying, I got crash in release mode, and it is not coming after I use PostMessage()!!!). So Try it out.

VinExpert
Hi

I too faced the same problem .To resolve it I made a small change.

afx_msg void OnTest( WPARAM wParam, LPARAM lParam);


void CWwwwDlg::OnTest(WPARAM wParam, LPARAM lParam)
{
       
}


Now SendMessage is working Fine even in Release mode.
Avatar of wangtao

ASKER

hi,VinExpert:
  I have used PostMessage(),but it also
could not work.
  I use the sendMessage() in the procedure of OnOK() as follow:
  void CWwwwDlg::OnOK()
     {
      SendMessage(WM_TEST,NULL,NULL);
     }

Hi,

Shall I assume that, in OnOK(), U r not calling the CDialog::OnOK()?. So the function will look like
CWWWDlg::OnTest()
{
    SendMessage(WM_TEST, 0, 0);
}

I don't understand why U selected OnOk() to do that?. Well if that is the case then manipulate the function declaration as Bhat has suggested. That is another solution. That should solve Ur problem.

Cheers,
VinExpert
Like I guessed in my proposed answer, the prototype for your message handler is wrong.

You've coded this:

   ON_MESSAGE(WM_TEST,OnTest)

in your message map. So, MFC is expecting you'll have this prototype:

   LRESULT CWwwwDlg::OnTest(LPARAM lParam, WPARAM wParam)

You can get away with a bad prototype in a debug build because the compiler ends up emitting code that's a little sloppy--and as a side-effect, rather tolerant of your error. In a release build, no such tolerance is there. When the function returns, the stack is not setup as the calling code in MFC expects it. As a result, you crash.

bhat's suggestion is wrong; you need to return LRESULT, not void.

Your problem is completely unrelated to the use of PostMessage() or SendMessage().

It was quite lucky of me to guess your problem with so little information, but now that you've actually shown your code your bad prototype is doubtlessly the cuase of your trouble.

..B ekiM

Hi  mikeblas ,

I don't think U are absolutely right.
It is OK if I return void.
I have implemented and it is not giving me any problems.

Thanks
Avatar of wangtao

ASKER

Hi  mikeblas:
  thanks!It can work now.As bhat says,
his way is also ok to run.
  Could you tell me the reason why
my code crash in the release model in
detail?Following you said above,I am
not very clear!
  Thanks!
                wangtao
bhat> I don't think U [sic] are absolutely right.
 bhat> It is OK if I return void.

No, it's not. That's wrong.

 bhat> I have implemented and it is not giving me any problems.

You're lucky. It's incorrect to return void--read the MFC source code, if you don't believe me. And I'm absolutely correct. You should fix your code.  I fixed this problem for the next version of MFC, so your incorrect function prototype won't compile when you try to port your code to that version.

Still don't believe me? Then, RTFM!  Look up "ON_MESSAGE" in the online help. Click on the "User-Defined handlers" link to get to a topic with the same name. Read the function prototype for an ON_MESSAGE handler in the table.

_Still_ don't believe me? Then, keep doing research! Check out KnowledgeBase article Q195032, which matches this article exactly.

 wangtao> I am not very clear

When MFC tries to dispatch a message, it rips through the message maps in your application's CCmdTarget-based classes. It tries to find an appropriate handler in the message map so it knows which function to call. The message map entry information contains three things: the message ID you're going to handle (like, WM_PAINT or WM_COMMAND), the function name you're going to call, and the signature of the function that will be called.

MFC has a huge switch statement in it based on that function signature information. The code just places the correct call to the function based on the signature. Unfortunately, the casting that's going on allows you to make a function that doesn't match the signature--and that's what you've done.

You can read all about this mechanism starting at page 95 in my book.

The code compiles cleanly (which is a bug in MFC!) and lets the call go through. In a debug build, you're lucky: the compiler doesn't try to optimize the use of the stack and does a very forgiving cleanup on the stack when the function returns. In a release mode, the emitted code isn't so forgiving. The caller unpacks the stack and does so in a way that doesn't match the way the called function left the stack. The result is that the stack pointer is misaligned--so the next instruction that expects certain information on the stack (like the calling function's return address!) will cause a crash.

..B ekiM
Thanks