Advertisement

My Program Will Not Close Correctly

Started by December 10, 2002 08:49 PM
4 comments, last by Turt99 21 years, 11 months ago
I''m quite new to this, I know quite abit of programming but not much about game programming.. All this program is supposed to be doing is displaying a window, all I want it to do is when I press theESC key I want it to shut down, this works find but I''d like it to give a warning like it does when I click the X. the problem with clicking the X is that the program is still running and I have to use the task manager to exit it... Any help will be great Here is the code that I''m using, I know there is extra code in here for directX, this is because I was using it before and I''m just getting back to it
  
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <conio.h>
#include <ddraw.h>
#define WIN32_LEAN_AND_MEAN

// MACROS

#define INIT_DXSTRUCT(dxs) { ZeroMemory(&dxs, sizeof(dxs)); dx.dwSize = sizeof(dxs); }
#define KEYSTATE(key) ((GetAsyncKeyState(key) & 0x8000) ? true : false)

//*******************Global Variables*****************************
int xsize, ysize, xpos, ypos;
bool focus;

//Global Windows
HINSTANCE hMainInstance;
HWND hMainWindow;

//DirectDraw Globals
LPDIRECTDRAW7 lpdd7 = NULL;
LPDIRECTDRAWSURFACE7 lpddsPrimary = NULL;
LPDIRECTDRAWSURFACE7 lpddsBack = NULL;
LPDIRECTDRAWSURFACE7 lpddsTileSet = NULL;
DDSURFACEDESC2 ddsd;

/**********************
Creates a DirectDraw palette for a given bitmap on the disk
The parameter szbitmap is the file name of the bitmap.
***********************/
IDirectDrawPalette* DDLoadPalette(IDirectDraw7 *pdd, LPCSTR szBitmap)
{
	IDirectDrawPalette* ddpal;
	int i, n, fh;
	PALETTEENTRY ape[256];

	if (szBitmap && (fh = _lopen(szBitmap, OF_READ)) != -1)
	{
		BITMAPFILEHEADER bf;
		BITMAPINFOHEADER bi;

		_lread(fh, &bf, sizeof(bf));
		_lread(fh, &bi, sizeof(bi));
		_lread(fh, ape, sizeof(ape));
		_lclose(fh);

		if (bi.biSize != sizeof(BITMAPINFOHEADER))
			n = 0;
		else if (bi.biBitCount > 8)
			n = 0;
		else if (bi.biClrUsed == 0)
			n = 1 << bi.biBitCount;
		else
			n = bi.biClrUsed;

		//A DIB color table has its colors stored BGR not RGB so flip them

		for (i=0; i<n; i++)
		{
			BYTE r = ape[i].peRed;
			ape[i].peRed = ape[i].peBlue;
			ape[i].peBlue = r;
		}
	}
	if (pdd->CreatePalette(DDPCAPS_8BIT, ape, &ddpal, NULL) != DD_OK)
		return NULL;
	else
		return ddpal;
}

//Loading a bitmap from a resource

int LoadBitmapResource(LPDIRECTDRAWSURFACE7 lpdds, int xDest, int yDest, int nResID)
{
  HDC hSrcDC;           // source DC - memory device context

  HDC hDestDC;          // destination DC - surface device context

  HBITMAP hbitmap;      // handle to the bitmap resource

  BITMAP bmp;           // structure for bitmap info

  int nHeight, nWidth;  // bitmap dimensions


  // first load the bitmap resource

  if ((hbitmap = (HBITMAP)LoadImage(hMainInstance, MAKEINTRESOURCE(nResID),
                                    IMAGE_BITMAP, 0, 0,
                                    LR_CREATEDIBSECTION)) == NULL)
    return(FALSE);

  // create a DC for the bitmap to use

  if ((hSrcDC = CreateCompatibleDC(NULL)) == NULL)
    return(FALSE);

  // select the bitmap into the DC

  if (SelectObject(hSrcDC, hbitmap) == NULL)
  {
    DeleteDC(hSrcDC);
    return(FALSE);
  }

  // get image dimensions

  if (GetObject(hbitmap, sizeof(BITMAP), &bmp) == 0)
  {
    DeleteDC(hSrcDC);
    return(FALSE);
  }

  nWidth = bmp.bmWidth;
  nHeight = bmp.bmHeight;

  // retrieve surface DC

  if (FAILED(lpdds->GetDC(&hDestDC)))
  {
    DeleteDC(hSrcDC);
    return(FALSE);
  }

  // copy image from one DC to the other

  if (BitBlt(hDestDC, xDest, yDest, nWidth, nHeight, hSrcDC, 0, 0,
             SRCCOPY) == NULL)
  {
    lpdds->ReleaseDC(hDestDC);
    DeleteDC(hSrcDC);
    return(FALSE);
  }

  // kill the device contexts

  lpdds->ReleaseDC(hDestDC);
  DeleteDC(hSrcDC);

  // return success

  return(TRUE);
}

// Message Handling Procedure

LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	switch (Msg)
	{
	//If Window is resized

	case WM_SIZE:
		{
			xsize = LOWORD(lParam);
			ysize = HIWORD(lParam);
		}
	//If window is moved

	case WM_MOVE:
		{
			xpos = LOWORD(lParam);
			ypos = HIWORD(lParam);
			
		}
	//If the window becomes active or inactive

	case WM_ACTIVATE:
		{
			if (LOWORD(wParam) == WA_INACTIVE)
				focus = false;
			else
				focus = true;

			//Tell windows we handled it

			return(0);
		}
	//If an area of the window needs to be repainted

	case WM_PAINT:
		{
			PAINTSTRUCT ps;
			HDC hdc;
			hdc = BeginPaint(hWnd, &ps);

			//Painting goes here


			EndPaint(hWnd, &ps);
			//Tell Windows we took care of it

			return(0);
		}
	//if the program is going to close

	case WM_CLOSE:
		{
			if (MessageBox(hWnd, "Are you sure you want to quit?", "Notice", MB_YESNO | MB_ICONEXCLAMATION) == IDNO)
				return(0);
			//if they did want to quit then let it go

		}
	//case WM_DESTROY:

		//{

			// Send a WM_QUIT message, as we want the app to exit once the window is destroyed

			//PostQuitMessage(0);

		//}

		break;
	}
	// Use the default message handler

	return DefWindowProc(hWnd, Msg, wParam, lParam);
}

// Windows Main function

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	WNDCLASSEX WndClassEx;
	WndClassEx.cbSize			= sizeof(WndClassEx);
	WndClassEx.cbClsExtra		= 0;									// No extra storage

	WndClassEx.cbWndExtra		= 0;									// No extra storage

	WndClassEx.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);	// White background

	WndClassEx.hCursor			= LoadCursor(NULL, IDC_ARROW);			// Default arrow cursor

	WndClassEx.hIcon			= LoadIcon(NULL, IDI_APPLICATION);		// Default app icon

	WndClassEx.hIconSm			= LoadIcon(NULL, IDI_APPLICATION);		// Default app icon

	WndClassEx.hInstance		= hInstance;							// Application instance

	WndClassEx.lpfnWndProc		= WndProc;								// Message Procedure

	WndClassEx.lpszClassName	= "Window Class";						// Class name

	WndClassEx.lpszMenuName		= NULL;									// No menu

	WndClassEx.style			= CS_VREDRAW | CS_HREDRAW | CS_OWNDC;	// Class styles


	// Register the window class so it can be used

	if (!RegisterClassEx(&WndClassEx))
	{
		MessageBox(NULL, "Unable to register window class.", "Error", MB_ICONERROR);
		return 0;
	}


	// Create the window

	HWND hWnd = CreateWindowEx(NULL, "Window Class", "Turt99''s Application", WS_VISIBLE | WS_OVERLAPPEDWINDOW, 200, 200, 640, 480, NULL, NULL, hInstance, NULL);
	if (hWnd == NULL)
	{
		MessageBox(NULL, "Unable to create window.", "Error", MB_ICONERROR);
		return 0;
	}

	//Set Globals

	hMainInstance = hInstance;
	hMainWindow = hWnd;
	MSG Msg;

	//Game Function Loop

	while (true) {
		//Get the time to be later used to make sure the FPS is 30

		DWORD dwStart = GetTickCount();

		// Mssage pump

		if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
		{
			if (Msg.message == WM_QUIT)
				break;

			TranslateMessage(&Msg);
			DispatchMessage(&Msg);
		}

		//If the escape key is pressed then exit the program

		if (KEYSTATE(VK_ESCAPE))
			PostQuitMessage(0);

		//Set FPS to 30, 33ms per frame :)

		while ((GetTickCount() - dwStart) < 33);
	}

	CloseWindow(hWnd);
	return(Msg.wParam);
}
  
FOLLOW ME ON TWITTER OR MY BLOG
well, i'm not sure if you intentionally did it, but your PostQuitMessage(0) function is commented off, and it shouldnt be.

[ Demonic Pillbug ]

[edited by - Jbs8492 on December 10, 2002 10:10:01 PM]
Advertisement
In your Main while loop try to use a variable instead of true:

  bool ProgramRunning = true;int WinMain(..........){   while(ProgramRunning)   {      ...   }}LRESULT CALLBACK WndProc(........){   switch(msg)   {      case WM_QUIT:        ... // your message asking user "Are you sure"        if( user_is_sure )        {           ProgramRunning = false;           return 0;        }   }}  


if this method still doesn''t works try replacing "ProgramRunning = false"
by "exit(0)"

Kamikaze
Well Actually that was probably commented out when I was testing other things.. however that has fixed one of the problems, the program now seems to close fine when I click the X, however the program just plan old shuts down when I press ESC.. I would like a message to pop up

FOLLOW ME ON TWITTER OR MY BLOG

  LRESULT CALLBACK WndProc(........){   switch(msg)   {      case WM_KEYDOWN:         switch(wParam)         {            case VK_ESCAPE:               PostMessage( hWnd, WM_CLOSE, 0, 0 );               return 0;         }   }}  


Kamikaze
Excellent,
Although that wasn''t the way that my program was going about things, I was able to figure out was I was doing wrong..

Its seems that because I was posting a quit message and not a close message the system was not reacting the way I expected, however now that the ESC key is also sending a CLOSE message everything is working great..

thanks alot...

Please visit Turt99 Productions
FOLLOW ME ON TWITTER OR MY BLOG

This topic is closed to new replies.

Advertisement