Advertisement

Win32 MSG.message Property

Started by April 13, 2001 06:18 PM
21 comments, last by PyroBoy 23 years, 9 months ago
Another theory... Another thing that could cause the stuff I''ve been seeing would be if WM_CLOSE and other important messages aren''t processed through the message queue at all, but are sent directly to the window procedure... So PeekMessage never deals with them, but they end up in that MsgHandler function of mine, and get the default treatment without my app even getting a look at them.
Anyone know if this is in fact the case?

I had a similar problem and here''s how i solved it...

You have to modify your PeekMessage line (I was using GetMessage but it will probably be the same) from what you have:
PeekMessage(&message, winHandle, 0, 0, PM_REMOVE)

to this:
PeekMessage(&message, NULL, 0, 0, PM_REMOVE)

I don''t know exactly why this is, your guess is as good as mine. I suggest you try it tho.

good luck,
Ganster
Advertisement
I gave that a try, and that didn''t work either... The only difference is, now it catches a WM_CLOSE when I ctrl-alt-del and end the process in the close program dialog (the only way I can currently end my program).

I just did a bit of reading on MSDN... Here''s what MS says about the WM_CLOSE message...

http://msdn.microsoft.com/library/psdk/winui/windows_5uhx.htm

That line "A window receives this message through its WindowProc function." leads me to further suspect that WM_CLOSE never touches the regular message queue and is instead sent directly to the window procedure as soon as the user clicks on the close button.

This is bad news for my desired implementation, since I was looking to set it up so I could retrieve a valid, meaningful MSG structure via one call per frame and deal with all things windows in one place.

This is really starting to bug me!!!

The thing that really bugs me about this that I can catch WM_CLOSE in very much the same manner as you are trying to.

Have you tried explicitly sending WM_CLOSE somewhere in your code?

If that doesn''t work, maybe you could post your code somewhere (or you can e-mail it to me at: rabidocelot@hotmail.com). It''s alot easier to debug something when you have it right in front of you

Other than that, I''m clueless (not unusual).

-Rabid

Handle WM_DESTROY instead of WM_CLOSE.
Advertisement
It doesn't catch WM_DESTROY either...

Here's the relevant bits of the class and corresponding implementation. Try it on your systems too if you can't spot the bug just by looking at it.
(hope this code box displays properly...)

Here's CWindow.h:

      #include #include #define WIN32_LEAN_AND_MEAN#include using namespace std;//Enumeration decribing border styles for window creationenum WIN_BORDER_STYLE{	STYLE_NORMAL = WS_OVERLAPPEDWINDOW,	STYLE_POPUP = WS_OVERLAPPED,	STYLE_NONE = WS_POPUP};//Enumeration describing window stateenum WIN_SHOW_STATE{	SHOW_NORMAL = SW_SHOWNORMAL,	SHOW_MAXIMIZED = SW_MAXIMIZE,	SHOW_MINIMIZED = SW_MINIMIZE};//Window classclass CWindow{public:		CWindow();	~CWindow();	bool Create(HINSTANCE appInst,		    string caption,		    string className,		    WIN_BORDER_STYLE borderStyle,		    WIN_SHOW_STATE state,		    int xPos, int yPos,		    int Width, int Height);                void Show();	bool GetMessage(MSG *messPtr);	void DefaultMessageHandler(MSG *messPtr);private:	static LRESULT CALLBACK MsgHandler(HWND hWnd, 					   UINT Msg, 					   WPARAM wParam, 					   LPARAM lParam);	WNDCLASSEX winClass;					WIN_SHOW_STATE showState;	HWND winHandle;	MSG message;							HDC winDC;	HINSTANCE inst;							string className;						int x;								int y;								int width;							int height;						}; 


And here's the implementation file, CWindow.cpp:

#include "CWindow.h"CWindow::CWindow(){	x = 0;	y = 0;	width = 0;	height = 0;}CWindow::~CWindow(){}bool CWindow::Create(HINSTANCE appInst,		     string caption,		     string winClassName,		     WIN_BORDER_STYLE borderStyle,		     WIN_SHOW_STATE state,		     int xPos, int yPos,		     int Width, int Height){	//Record window info	showState = state;	x = xPos;	y = yPos;	width = Width;	height = Height;	inst = appInst;	className = winClassName;	//Fill in window class descriptor	winClass.cbSize = sizeof(WNDCLASSEX);	winClass.style =                          CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;               	winClass.lpfnWndProc = MsgHandler;	winClass.cbClsExtra = 0;	winClass.cbWndExtra = 0;	winClass.hInstance = appInst;	winClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);	winClass.hCursor = LoadCursor(NULL, IDC_ARROW);	winClass.hbrBackground =                         (HBRUSH)GetStockObject(BLACK_BRUSH);	winClass.lpszMenuName = NULL;	winClass.lpszClassName = className.data();	winClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);	//Register the window class	RegisterClassEx(&winClass);	//Decide on the window format	DWORD winStyle = borderStyle;	//Create the window	winHandle = CreateWindowEx(NULL, className.data(),               caption.data(), winStyle, xPos, yPos, Width, Height,             NULL, NULL, appInst, NULL);	if (winHandle == NULL) return false;	else return true;}bool CWindow::GetMessage(MSG *messPtr){	//Check message queue	if (PeekMessage(&message, winHandle, 0, 0, PM_REMOVE))	{			//Fill message structure at pointer		messPtr->message = message.message;		messPtr->hwnd = message.hwnd;		messPtr->wParam = message.wParam;		messPtr->lParam = message.lParam;		messPtr->time = message.time;		messPtr->pt = message.pt;				return true;	}	else return false;}void CWindow::DefaultMessageHandler(MSG *messPtr){	//Send message to handler	TranslateMessage(messPtr);	DispatchMessage(messPtr);}void CWindow::Show() {ShowWindow(winHandle, showState);}LRESULT CALLBACK CWindow::MsgHandler(HWND hWnd, UINT Msg, WPARAM                                      wParam, LPARAM lParam){	return DefWindowProc(hWnd, Msg, wParam, lParam);} 


And here's how I'm using it (this is the inside of WinMain):

//Create windowCWindow mainWin;mainWin.Create(hInst, "Hello World", "First Window",STYLE_NORMAL, SHOW_NORMAL, 320, 240, 300, 300);mainWin.Show();bool done = false;//Main loopwhile (!done){        //Check for windows messages	MSG mess;	if (mainWin.GetMessage(&mess))	{		//Handle messages		if (mess.message == WM_CLOSE) done = true;		else mainWin.DefaultMessageHandler(&mess);	}}return 0; 


So... I throw myself apon the mercy of anyone who reads this to tell me where I'm going wrong! The bug is this: The window comes up, works nicely (re-sizes, minimizes etc in response to the user) and closes when it's supposed to, but that while(!done) loop keeps on truckin' long after the window closes. I have to go into the close program dialog to get it to stop.

Anyone have any ideas??

Edited by - PyroBoy on April 18, 2001 3:15:14 PM

Edited by - PyroBoy on April 18, 2001 3:19:54 PM

Editing note - The source box feature on this site sucks quite a bit... :-)

Edited by - PyroBoy on April 18, 2001 3:23:01 PM
Side note - The "code" tag also sucks...

There''s a few editing and display quirks in there, like the includes not showing up, and the spacing getting screwed, but the general jist is there, and the relevant code is there.

Any and all suggestions are welcome, and shall be tried thouroughly until this freakin thing starts working!! :-)

It seems that the "WM_CLOSE" is very much analogus to Java''s "windowClosed event", so if you are trying to catch this event, with the reasoning that if you clicked on the application window''s exit button to generate the event (WM_CLOSE/windowClosed), you would have already exited that window(i.e that window has been destoryed), and no more events can be listened to or processed.
Do you follow me ...

The point is there exist in Java and hopefully(logically) in Win32 another event analogus to Java''s "windowClosing" event which is trigged while in the process of shutting down a window, which allows you to catch it before the destruction of that window.
Do you still follow me ...

The question now is "what then is the point of "WM_CLOSE" or "windowClosed" events?", and the answer is "think child windows"; example?, MS Word with mutiple Word docs opened,
destorying one of the currently opened Word document does not destory the main application, does it now?. The point is killing the child component(the Word docs) does not kill the main container(the Word app).

The implications is of course obvious, e.g you want to notify your container that one of your components in the container has been destoryed/quitted from etc...

I hope this has helped :>, try finding that WM_ analogus to windowClosing event.

It seems that the "WM_CLOSE" is very much analogus to Java''s "windowClosed event", so if you are trying to catch this event, with the reasoning that if you clicked on the application window''s exit button to generate the event (WM_CLOSE/windowClosed), you would have already exited that window(i.e that window has been destoryed), and no more events can be listened to or processed.
Do you follow me ...

The point is there exist in Java and hopefully(logically) in Win32 another event analogus to Java''s "windowClosing" event which is trigged while in the process of shutting down a window, which allows you to catch it before the destruction of that window.
Do you still follow me ...

The question now is "what then is the point of "WM_CLOSE" or "windowClosed" events?", and the answer is "think child windows"; example?, MS Word with mutiple Word docs opened,
destorying one of the currently opened Word document does not destory the main application, does it now?. The point is killing the child component(the Word docs) does not kill the main container(the Word app).

The implications is of course obvious, e.g you want to notify your container that one of your components in the container has been destoryed/quitted from etc...

I hope this has helped :>, try finding that WM_ analogus to windowClosing event.

This topic is closed to new replies.

Advertisement