Advertisement

Message Handling and WM_QUIT/WM_DESTROY

Started by September 10, 2002 10:45 PM
5 comments, last by bower12345 22 years, 3 months ago
Hi Folks, I finally got around to writing my first little Windows program which uses the native Windows GDI to plot random pixels of random colors over a 1024X768 surface, but I have one problem, when I click the "X" on my window, the program window will close and nothing will show up on the task manager, but if I try and recompile later on, it tells me that it cannot access the .EXE file, which I have taken to mean that the program is still running. If anyone can help I would appreciate it a lot. Here is my source:
  
// Basic Program to Draw a Window


#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <stdlib.h>
#include <time.h>
	
LRESULT CALLBACK MsgHandler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
	if(msg == WM_PAINT)
	{
		PAINTSTRUCT ps;
		HDC hdc;
		hdc = BeginPaint(hwnd, &ps);
		EndPaint(hwnd, &ps);
		return(0);
	}
	return(DefWindowProc(hwnd, msg, wparam, lparam));
}

int WINAPI WinMain(HINSTANCE hInstance,
				   HINSTANCE hPrevInstance,
				   LPSTR lpCmdLine,
				   int nCmdShow)
{
	int x, y, red, green, blue;
	srand((unsigned)time(NULL));
	HDC hdc;
    MSG msg;
	WNDCLASSEX BasicWindow;

	BasicWindow.cbSize = sizeof(WNDCLASSEX);
	BasicWindow.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
	BasicWindow.lpfnWndProc = MsgHandler;
	BasicWindow.cbClsExtra = 0;
	BasicWindow.cbWndExtra = 0;
	BasicWindow.hInstance = hInstance;
	BasicWindow.hIcon = LoadIcon(NULL, IDI_WINLOGO);
	BasicWindow.hCursor = LoadCursor(NULL, IDC_ARROW);
	BasicWindow.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	BasicWindow.lpszMenuName = NULL;
	BasicWindow.lpszClassName = "Basic Window";
	BasicWindow.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
	
	RegisterClassEx(&BasicWindow);

	HWND hwnd;
	if(!(hwnd = CreateWindowEx(NULL,
							   "Basic Window",
							   "Basic Window",
							   WS_VISIBLE | WS_CAPTION | WS_TILEDWINDOW,
							   0,
							   0,
							   1024,
							   768,
							   NULL,
							   NULL,
							   hInstance,
							   NULL)))
	{
		return(0);
	}

	hdc = GetDC(hwnd);
	while(TRUE)
	{
		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if(msg.message == WM_QUIT)
			{
				break;
			}
			if(msg.message == WM_DESTROY)
			{
				PostQuitMessage(0);
				return(0);
			}
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		x = rand() % 1024 + 1;
		y = rand() % 768 + 1;
		red = rand() % 255 + 1;
		green = rand() % 255 + 1;
		blue = rand() % 255 + 1;
		SetPixel(hdc, x, y, RGB(red, green, blue));
	}
	return(msg.wParam);
}
  
Mikehttp://cs.wpunj.edu/~bowersom
When you click the X to close your program, Windows sends a WM_DESTROY message to destroy the program, but doesn't actually close the window.

You need to include the WM_DESTROY message in your WinProc handler, and if that message is received, then do a PostQuitMessage(0); like this.


    LRESULT CALLBACK MsgHandler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam){   switch(msg)   {      case WM_PAINT:      {         PAINTSTRUCT ps;         HDC hdc;         hdc = BeginPaint(hwnd, &ps);         EndPaint(hwnd, &ps);         return(0);         break;      }      case WM_DESTROY:      {         PostQuitMessage(0);         return(0);         break;      }      default:      {}   }      return(DefWindowProc(hwnd, msg, wparam, lparam));}    


Now, I've only written one windows program myself, so If I'm wrong, sorry =)

~~~~~~~~~~~
Chris Vogel
~~~~~~~~~~~


[edited by - Radagar on September 10, 2002 12:01:06 AM]
WyrmSlayer RPG - In Early Development
Advertisement
No, that''s correct. You definitely need to test for WM_DESTROY, because clicking the ''X'' to close the window only removes it from the screen. When you send a PostQuitMessage(0), that tells Windows to kill the program itself.

John.
Hey Again,

I tried compiling again, and still when I click the ''X'', the program closes, but still runs in the background. I''m really confused now. My code looks fine and shouldn''t have ANY problems?
Mikehttp://cs.wpunj.edu/~bowersom
bower12345:

Did you put the WM_DESTROY block in your MsgHandler function? I don''t think that Windows will know to let the program end if you''ve got it in WinMain().

John.
Yes, I moved my code from WinMain to the MsgHandler function. I also thought that maybe since I wasn''t releasing the device context at the end of my program that that might have been the problem, but I still see no change in the program. Here is the updated code:


  // Basic Program to Draw a Window#define WIN32_LEAN_AND_MEAN#include <windows.h>#include <windowsx.h>#include <stdlib.h>#include <time.h>	LRESULT CALLBACK MsgHandler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam){	switch(msg)	{		case WM_PAINT:			{				PAINTSTRUCT ps;				HDC hdc;				hdc = BeginPaint(hwnd, &ps);				EndPaint(hwnd, &ps);				return(0);			}		case WM_QUIT:			{				return(0);				break;			}		case WM_DESTROY:			{				PostQuitMessage(0);				return(0);				break;			}		default:			{				return(DefWindowProc(hwnd, msg, wparam, lparam));			}		}}int WINAPI WinMain(HINSTANCE hInstance,				   HINSTANCE hPrevInstance,				   LPSTR lpCmdLine,				   int nCmdShow){	int x, y, red, green, blue;	srand((unsigned)time(NULL));	HDC hdc;    MSG msg;	WNDCLASSEX BasicWindow;	BasicWindow.cbSize = sizeof(WNDCLASSEX);	BasicWindow.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;	BasicWindow.lpfnWndProc = MsgHandler;	BasicWindow.cbClsExtra = 0;	BasicWindow.cbWndExtra = 0;	BasicWindow.hInstance = hInstance;	BasicWindow.hIcon = LoadIcon(NULL, IDI_WINLOGO);	BasicWindow.hCursor = LoadCursor(NULL, IDC_ARROW);	BasicWindow.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);	BasicWindow.lpszMenuName = NULL;	BasicWindow.lpszClassName = "Basic Window";	BasicWindow.hIconSm = LoadIcon(NULL, IDI_WINLOGO);		RegisterClassEx(&BasicWindow);	HWND hwnd;	if(!(hwnd = CreateWindowEx(NULL,							   "Basic Window",							   "Basic Window",							   WS_VISIBLE | WS_CAPTION | WS_TILEDWINDOW,							   0,							   0,							   1024,							   768,							   NULL,							   NULL,							   hInstance,							   NULL)))	{		return(0);	}	hdc = GetDC(hwnd);	while(TRUE)	{		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))		{			TranslateMessage(&msg);			DispatchMessage(&msg);		}		x = rand() % 1024 + 1;		y = rand() % 768 + 1;		red = rand() % 255 + 1;		green = rand() % 255 + 1;		blue = rand() % 255 + 1;		SetPixel(hdc, x, y, RGB(red, green, blue));	}	ReleaseDC(hwnd, hdc);	return(msg.wParam);}  


Any help would be appreciate greatly. Thanks!
Mikehttp://cs.wpunj.edu/~bowersom
Advertisement
Hi,
actually the PostQuitMessage() only sends WM_QUIT to your window
it does nothing to your program. The point is that your app is
running an infinite loop:

while (true) {...}

you should use something like

while(bRunApp) {...}

and in your messagehandler:

if (message=wm_quit) bRunApp=false;

I think that''ll work.
good luck.

--::[Madhed]::-

This topic is closed to new replies.

Advertisement