Link to home
Start Free TrialLog in
Avatar of chump
chump

asked on

CWnd::PostMessage in dialog based app

Hi,
I'm writing a dialog based app using MFC (VC5). The main window is a Wizard (CPropertySheet). One page contains a modified CStatic control. This control sends notifications to it's parent window using GetParent()->PostMessage(...). On another page, I start a worker thread, which is also sending messages to the dialog using ::PostMessage(...) with the correct window handle.
If I'm creating a debug version with standard settings, everything works fine. But when I run the release version, I can exactly do ONE PostMessage. If it comes to the second one, the program crashes with an 0xC0000005: Access Violation in MFC42.DLL. The debugger stops in AFXCRIT.CPP, line 100. The call stack is CWnd::~CWnd -> AfxLockGlobals, if this information is helpfull...
What could be the cause for this strange behaviour?
Avatar of bfwizard
bfwizard

This is sort of an answer of why I believe this is happening in the release version and not the debug version.  In the debug version MFC allocates memory in such away that it sets up guard bytes that surround allocated memory...and sometimes this can fend off an access violations in the debug version and why they are caught in the release version.

2 options to help find errors:



The first option(if you are doing a lot of allocating/deallocating) is (if you know about where the error is), while you are in the debug version, to call the AfxCheckMemory function yourself.

ASSERT(AfxCheckMemory());
   
///the code where you think the error is occuring

ASSERT(AfxCheckMemory());

if the first ASSERT clears and the second one fails you know that the error is between this section of code.


Another option is if you put the statement in the application InitInstance function:

afxMemDF |= checkAlwaysMemDF;

it forces a call to AfxCheckMemory while in debug mode everytime you allocate and deallocate memory (every time new and delete are called).  If something goes wrong you wont get an assertion, but you will get a message in the debug window (while in debug mode): Damage Occurred! Block=xxxxx.  from there you should be able to trace down through in your code where it occurred.  But....if you have many things allocating/deallocating memory it might slow things down considerably.
Avatar of chump

ASKER

Sorry, your answer didn't help me.

> if you are doing a lot of allocating/deallocating

I'm not. I commented all the code inside the message handling and the message creating function (except PostMessage of course), still the error occurs.

> if you know about where the error is

I don't know. I put OutputDebugString("...") as the only statement in the function that handles the message, the string gets printed.

>afxMemDF |= checkAlwaysMemDF;

This does only work in debug mode - so the error doesn't occur.

Btw, I replaced the PostMessage calls with calls to SendMessage. In that case the same crash occurs, but already after the first call to SendMessage.
Avatar of chump

ASKER

Sorry, your answer didn't help me.

> if you are doing a lot of allocating/deallocating

I'm not. I commented all the code inside the message handling and the message creating function (except PostMessage of course), still the error occurs.

> if you know about where the error is

I don't know. I put OutputDebugString("...") as the only statement in the function that handles the message, the string gets printed.

>afxMemDF |= checkAlwaysMemDF;

This does only work in debug mode - so the error doesn't occur.

Btw, I replaced the PostMessage calls with calls to SendMessage. In that case the same crash occurs, but already after the first call to SendMessage.
Check the return value from GetParent(). Maybe it is returning NULL.
I hope you are aware of the standard precautions when using window handles between threads. Refer to MFC on-line help on multi-threading for more info.
Avatar of chump

ASKER

Actually, the code is:
if ( GetParent( ) )
   GetParent( )->PostMessage( WM_MYMESSAGE );
And, the message handling function gets called, the crash happens somewhere later.

Linking with the single threaded MFC Dll makes not difference, so in the first case, there's no multithreading.

I guess my point was that you were addressing something that is not allocated or was already deallocated...this doesn't always cause access violations in the debug version.  If you already know exactly where in the code this is happening then you are mostly there.
Avatar of chump

ASKER

Have to correct myself. VC didn't build a single threaded version.

But, I did message passing the same way in an MDI app (between a thread and a CView) and had no problems there...
1. Check if the handler function has the correct parameters passed and returns the correct type. This is not checked by the compiler and it works fine in debug version, but doesn't in the release version. I had the problem that my handler function had only one input parameter while it had to have two input parameters.

Next
I am not sure how U have modified the CStatic control.. But, this is what the documentation for CStatic says...

"A static control normally takes no input and provides no output; however, it can notify its parent of mouse clicks if it's created with SS_NOTIFY style."

1. So U may want to check if U have created the static control with the style

2. Posting a Message from another control but calls the same handler function and check if it is still giving a problem..

3. Since, it is happening after exactly after one PostMessage and occurs just after the SendMessage, I think it might be in the code that is handling the message, because, PostMessage returns as soon as the message is posted and does not wait for the message to be processed, but SendMessage waits for the message to get processed and so it may be in the handler also.
AFX_MANAGE_STATE(AfxGetStaticModuleState( )) at the start of the FN before you call the PostMessage ie put it as the first line of code and see if that helps.

Avatar of chump

ASKER

Sorry, Andy, doesn't help.
Avatar of chump

ASKER

t004024, I tried posting the message from another control.
I put the PostMessage call in the OnClick handler of a button on the same page. Now I can click this button _two_ times, clicking it for the _third_ time causes the crash.
The handler for the function doesn't execute any code (I commented it out).
Avatar of chump

ASKER

t004024, you're right. I was taking the wrong return type.
Thanks very much. Write an answer, and you'll get the points.

ASKER CERTIFIED SOLUTION
Avatar of lucidity
lucidity

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