A question about exceptions (new problem)

Started by
5 comments, last by Azune 18 years, 8 months ago
Does throwing an exception from the main window's CALLBACK WndProc and catching the exception in the WinMain, where the PeekMessage is at, is really not good? I have some bizzar behaviour and I think its because of this. Should I do a try and catch insinde the CALLBACK WndProc for exception throwen from inside the WndProc? [Edited by - The C modest god on July 28, 2005 12:38:13 PM]
It's all about the wheel.Never blindly trust technoligy.I love my internal organs.Real men don't shower.Quote:Original post by Toolmaker Quote:Original post by The C modest godHow is my improoved signature?It sucks, just like you.
Advertisement
What does your code look like? If you throw an exception your catch block in WinMain will be called BEFORE WndProc returns its result. I can imagine that this might lead to unwanted things unless you handle it properly.

In other words, some thing you do in your catch block might rely on WndProc having already returned. which woudl be a bad thing.
well if you throw an exception the method you throw it from never returns a result if you don't catch the exception in the same method as the exception causes a stack unwind.

Note the MFC framework has a catch wrapper around its mesage map. Though it doesn't sound like your using it.

Throwing from your message loop and catching it in winmain shouldn't be a problem. We have a couple of applications that do that.

Cheers
Chris
CheersChris
It sounds like you might be throwing an exception inside C++ code that is being called from C code. This is bad mojo. C code generally doesn't understand C++ exceptions and may trigger a meltdown if a C++ exception is thrown.
Quote:Original post by SiCrane
It sounds like you might be throwing an exception inside C++ code that is being called from C code. This is bad mojo. C code generally doesn't understand C++ exceptions and may trigger a meltdown if a C++ exception is thrown.

I really didnt understand this. What do you mean by C code? Its all C++. Do you mean that the function CALLBACK is "C code"?

I have solved this problem anyway, but I have a new problem.
Consider the following code:
BOOL gBException = FALSE;DirectXError gGeneralError;LRESULT CALLBACKWndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){    switch (msg)	{	case WM_ACTIVATEAPP:		bActivate = (BOOL)(wParam);		if (!bActivate)		{			bRestore = TRUE;			bMinimized = TRUE;		}		else		{			if (bRestore)			{				try				{//				RestoreControl();					throw DefaultError(0x201);					RestoreHandle::Restore ();					bMinimized = FALSE;				}				catch (const DirectXError & Excp) {					gBException = TRUE;					gGeneralError = Excp;				}			}		}		break;...}int WINAPIWinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR cmdline, int cmdshow){...		    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 			{				if (!TranslateAccelerator(msg.hwnd, accel, &msg))					DispatchMessage(&msg);				if (msg.message == WM_DESTROY)					break;				if (gBException)					throw DirectXError(gGeneralError); // <=Error			}	    }	}	catch (const Direct3DError & D3DErr) {		GlobalError::ReportError (ErrH.D3DErr.GetError (D3DErr.code), hThisInstance, hWnd, LogF);	}	catch (const DirectInputError & DIErr) {		GlobalError::ReportError (ErrH.DIErr.GetError (DIErr.code), hThisInstance, hWnd, LogF);	}	catch (const DefaultError & DefErr) {		GlobalError::ReportError (ErrH.DefErr.GetError (DefErr.code), hThisInstance, hWnd, LogF);	}     	catch (const DirectSoundError & DSErr) {		GlobalError::ReportError (ErrH.DSErr.GetError (DSErr.code), hThisInstance, hWnd, LogF);	}        DestroyWindow(hWnd);	return msg.wParam;}class DirectXError {	public:		DirectXError ();		DirectXError (const DirectXError & Source);		HRESULT code;};class Direct3DError:public DirectXError {	public:		Direct3DError (HRESULT code);};class DirectInputError:public DirectXError {	public:		DirectInputError (HRESULT code);};class DirectSoundError:public DirectXError {	public:		DirectSoundError (HRESULT code);};class DefaultError:public DirectXError {	public:		DefaultError (HRESULT code);};


I get a runtime error on the second throw in the code.
However if I replace it for throw DefaultError (0x201) for instance, everything works.
Why do I get a runtime error?

"Unhandled exception in V0.exe(KERNEL32.DLL):0xE06D7363: Microsoft C++ Exception"
It's all about the wheel.Never blindly trust technoligy.I love my internal organs.Real men don't shower.Quote:Original post by Toolmaker Quote:Original post by The C modest godHow is my improoved signature?It sucks, just like you.
Ok, the exception is the exception I throwed.
My question is, how do I keep the exception in the first throw?
Do I have to create a variable for each type of excpetion?
It's all about the wheel.Never blindly trust technoligy.I love my internal organs.Real men don't shower.Quote:Original post by Toolmaker Quote:Original post by The C modest godHow is my improoved signature?It sucks, just like you.
All the exception types are hurting my eyes :\. If all you're going to do upon catching an exception is report it you might as well throw a generic exception with a descriptor field explaining the exception. On the other hand if you are going to recover then have specific types for each recoverable exception as you're doing at the moment.

In regards to your new problem, you might try handling the exceptions you've thrown or you will, unsurprisingly, get "unhandled exception" errors at run time. Adding the following catch block to WinMain should do the trick:

    catch (const DirectXError& e) {        // Do stuff ...    }


AFTER THOUGHT:
Quote:
I really didnt understand this. What do you mean by C code? Its all C++. Do you mean that the function CALLBACK is "C code"?

All your code is C++, but Windows was written in C. When you call DispatchMessage you are telling the API to call WndProc with the message (which is why it's a callback function). So what SiCrane was suggesting is that having an exception thrown in WndProc propagate back through the C code in the API that called it could be causing problems. I'm not sure whether this is the case or not, you'd need to step through the assembly carefully in a debugger (as well as sound knowledge of how exception handling works under the hood) to find out. I've got a feeling that it's not a good idea though. It may appear to work sometimes and then crash when you least expect it.

[Edited by - Azune on July 30, 2005 10:09:43 AM]

This topic is closed to new replies.

Advertisement