Jump to content


C++ (Win32) Process not closing.


  • You cannot reply to this topic
11 replies to this topic

#1 Jeremy Pridemore

    New Member

  • Members
  • Pip
  • 6 posts

Posted 26 May 2007 - 07:27 AM

Hello, as this is my first post on DevMasters.net, I'll introduce myself. My name is (obviously) Jeremy Pridemore, and I'm a aspiring game programmer in college right now. I'm beginning in Win32 and am having a problem I haven't seen an answer to yet.

First of all, I've done some research:
*I'm reading "Beginning Game Programming" by Jonathan S. Harbour
*I'm using GameTutorialsSquared from the GameTutorials website.
*I've searched online tutorials such as http://www.winprog.org/tutorial/
*I've searched this forum, and hope I'm not missing it.

I have what I hope is a simple problem. I've created my first window, a Hello World! Win32 app. It works fine, but when I close it, the process does not close as well. I'm not sure what could be causing this.

I'm using RegisterClassEx() and therefore using UnregisterClass(), and all my code matches what I've seen I think. If anyone has any tips, leads, comments to help me keep moving forward, I'd be grateful. Right now I'm working on my window, but I have to close the process from the Task Manager manually each time. If anyone wants to see the code, just ask.

Thank you,
Jeremy Pridemore

#2 dave_

    Senior Member

  • Members
  • PipPipPipPip
  • 584 posts

Posted 26 May 2007 - 11:17 AM

Without debugging it for you, we can't really tell. What do you mean by "the process does not close as well"?

You probably should be worrying about Windows programming. Its not really that important for games development.

To make things easier, just use something like SDL or GLUT or "EmptyProject " from the DX SDK

#3 Nautilus

    Senior Member

  • Members
  • PipPipPipPip
  • 326 posts

Posted 26 May 2007 - 01:35 PM

It's hard to tell what's wrong without seeing some code.

* A common mistake often resides in the Message Loop.
* Also doublecheck your WindowProcedure. Make sure to return the proper value for the messages your app responds too.

The final note is about unregistering your window class.
Manually unregistering, as you do, doesn't hurt.
But know that the System will automatically ditch the window class for you as soon as the app terminates.

Ciao ciao : )
-Nautilus

(readin' this? perhaps you should get out more -- give it a thought)


#4 Jeremy Pridemore

    New Member

  • Members
  • Pip
  • 6 posts

Posted 26 May 2007 - 03:31 PM

The book and class I'm working with both require that I am able to get some basic Windows programming going, as from what I read I'll be using WinProc quite a bit during my game development. I'm trying to get myself up to speed by the end of the weekend so I can start diving into DirectX.(I know I won't be that proficient at Win32 programming, but at least enough to run my game from it).

I meant that everytime I run my program, a process is created for it (As visible through the Task Manager Processes tab) and when I close the program, the process is left there until I manually close it. This means that I have to keep Task Manager up so I can close the process after running it each time so I can build it again. I'm also fairly certain that this will continue once I get into my DirectX (And eventually OpenGL) programming due to it still being started through a Win32 program.

I've been following all the tutorials I can, to conform my code to normal standards, so unless I'm still just missing something, I'm not sure how to fix this.

#5 Reedbeta

    DevMaster Staff

  • Administrators
  • 4979 posts
  • LocationBellevue, WA

Posted 26 May 2007 - 05:55 PM

Make sure you call PostQuitMessage from within the WM_DESTROY handler of your message procedure. Failing to do this is usually the cause of the process not exiting when the window is closed. You might also need to handle WM_CLOSE and make sure it calls DestroyWindow, else clicking the close button may just hide the window and not actually destroy it.
reedbeta.com - developer blog, OpenGL demos, and other projects

#6 Jeremy Pridemore

    New Member

  • Members
  • Pip
  • 6 posts

Posted 26 May 2007 - 06:06 PM

Thanks very much for the help so far guys! I'll try to do a bit of searching and give back a bit to the commnity here. *smiles* I've been looking around for a good forum community to join in regards to programming. I'm a tutor at my college, and love teaching it. Just gotta get my own skills up there too!

As a response to Reedbeta:
Here's my WinProc(). I'm actually handling both of those. I've been following examples from a number of sources and this is the best I'm at so far. I yoinked the WM_PAINT code I had, because it's not really relevant to the problem I'm having. I appreciate any input I might get.


LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)

{


	switch(msg)

	{

	case WM_CLOSE:

		DestroyWindow(hWnd);

		break;

	case WM_DESTROY:

		PostQuitMessage(0);

		break;

	default:

		return DefWindowProc(hWnd, msg, wParam, lParam);

	}

	return 0;

}



#7 Reedbeta

    DevMaster Staff

  • Administrators
  • 4979 posts
  • LocationBellevue, WA

Posted 26 May 2007 - 06:27 PM

Well, that looks right to me. Can we see your message loop? (The last section of WinMain, with while(GetMessage(...)) and that stuff.)
reedbeta.com - developer blog, OpenGL demos, and other projects

#8 Nautilus

    Senior Member

  • Members
  • PipPipPipPip
  • 326 posts

Posted 26 May 2007 - 09:44 PM

Please Jeremy,
re-post your WinProc() including the "case WM_PAINT:" handler.
I'd also like to see *all* the lines of code past the call to CreateWindowEx(), inside the WinMain().

Thank you very much,
Ciao ciao : )
-Nautilus

(readin' this? perhaps you should get out more -- give it a thought)


#9 Jeremy Pridemore

    New Member

  • Members
  • Pip
  • 6 posts

Posted 26 May 2007 - 11:12 PM

Again, thank you guys very much for the help. I'll post the code I have, it's just supposed to be a simple window...well with my WM_PAINT case I'm playing with. It doesn't work right yet (still playing with it), so don't be too hard on me for it! :) Right now it's kind of a pain to work on because I have to kill the process in Task Manager every time I want to try to rebuild it because it can't open it for writing.

WinMain() past CreateWindowEx()
As requested by Nautilus

hWnd = CreateWindowEx(

		NULL,									//Extended Windows Style

		CLASSNAME,								//Class to use to make the window with.

		L"Hello World! - Win32 Application",	//Title-Bar text

		WS_OVERLAPPEDWINDOW,					//The style of the window. This is a normal window.

		CW_USEDEFAULT,							//X-Value of where to create the window

		CW_USEDEFAULT,							//Y-Value of where to create the window

		300,									//Width of window in pixels

		200,									//Height of window in pixels

		NULL,									//Pointer to parent window

		NULL,									//Pointer to menu

		hInstance,								//Instance of application

		NULL);									//Pointer to object that WinProc shares


	if(hWnd == NULL) //Ensure that the window was created.

    {

        MessageBox(NULL, L"Window Creation Failed!", L"Error!",

            MB_ICONEXCLAMATION | MB_OK);

        return 0;

    }


	//ShowWindow() and UpdateWindow() are both used to display the window onto the screen.

	ShowWindow(hWnd, nCmdShow);

	UpdateWindow(hWnd);


	while(true)

	{

		if(GetMessage(&msg, NULL, 0, 0) > 0)

		{

			TranslateMessage(&msg);

			DispatchMessage(&msg);

		}

	}


	UnregisterClass(CLASSNAME, hInstance);


	return msg.wParam;

}


WinProc()
With WM_PAINT included

LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)

{


	PAINTSTRUCT ps;

	RECT rt;

	HDC hDC;

	wchar_t *szHelloWorld = L"Hello World!";


	COLORREF 

		cRef = RGB(255, 255, 255),

		setColor = RGB(255, 255, 255);


	switch(msg)

	{

	case WM_PAINT:

		GetClientRect(hWnd, &rt);

		hDC = BeginPaint(hWnd, &ps);

		DrawText(hDC, szHelloWorld, wcslen(szHelloWorld), &rt, DT_CENTER);

		for(int y = 0, colorChange = 0; y < rt.bottom; y++, colorChange++)

		{

			for(int x = 0; x < rt.right; x++)

			{

				if(colorChange == 0)

				{

					if(cRef == RGB(255, 0, 0))

					{

						setColor = RGB(255, 255, 255);

					}

					else

					{

						setColor = RGB(255, 0, 0);

					}

				}

				cRef = setColor;


				if(x < 80 && ( (y > 15) && (y < 50) ) )

				{

					cRef = RGB(0,0,255);

				}

				

				if(y > 15)

				{

					SetPixel(hDC, x, y, cRef);

				}

				colorChange %= 10;


			}//End for(int x = 0; x < rt.right; x++)


		}// End for(int y = 0, colorChange = 0; y < rt.bottom; y++, colorChange++)


		EndPaint(hWnd, &ps);

		break;

	case WM_CLOSE:

		DestroyWindow(hWnd);

		break;

	case WM_DESTROY:

		PostQuitMessage(0);

		break;

	default:

		return DefWindowProc(hWnd, msg, wParam, lParam);

	}

	return 0;

}


Thanks again for any help!

#10 Reedbeta

    DevMaster Staff

  • Administrators
  • 4979 posts
  • LocationBellevue, WA

Posted 26 May 2007 - 11:27 PM

The problem is your message loop.
while(true)
{
	if(GetMessage(&msg, NULL, 0, 0) > 0)
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
}

The while(true) makes an infinite loop. This loop will never quit, which is why your application continues running until you kill it from outside. The message loop should look like this:
while (GetMessage(&msg, NULL, 0, 0))
{
	TranslateMessage(&msg);
	DispatchMessage(&msg);
}
GetMessage returns zero after WM_QUIT is handled (this is the message posted by PostQuitMessage), so the application will then terminate.
reedbeta.com - developer blog, OpenGL demos, and other projects

#11 Jeremy Pridemore

    New Member

  • Members
  • Pip
  • 6 posts

Posted 26 May 2007 - 11:55 PM

Ah, I see now. I originally had that, but had tried to switch to PeekMessage() using an if statement to break if WM_QUIT was found from another tutorial before I could build it. So I forgot to go back on that one afterwards. I had no idea that an infinite loop wouldn't be killed along with the window of the program itself. Thank you so very much for this help! I'm hoping that with enough studying I'll be creating *something* with DirectX by the end of the night.

As a side note, I've been browsing the forums, but it looks like I'm for the most part a bit low-level among my peers as there aren't too many I understand very well, and very few I could have helped with if I had seen in time. Is the average level of skill on this forum professional programmers, or close to professional?

#12 Reedbeta

    DevMaster Staff

  • Administrators
  • 4979 posts
  • LocationBellevue, WA

Posted 27 May 2007 - 12:12 AM

Yeah, the process exits when it reaches the end of WinMain, so you have to break out of the message loop for a graceful shutdown. If you use PeekMessage, you should insert an if-statement to check for WM_QUIT and break out of the loop manually after it's processed.

In my own programs I use a more complex message loop that includes checks to see if the renderer is active, and uses the PeekMessage version if it's active and GetMessage if it's not. This lets me minimize the window (which deactivates rendering) and avoid going into a busy-wait. Using exclusively PeekMessage causes the app to busy-wait, which means it consumes 100% of the CPU even when it's minimized and not actually doing anything.
reedbeta.com - developer blog, OpenGL demos, and other projects





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users