   Direct Draw : unhandled exception at exit
  I've been studying Direct Draw lately with my book, and I pretty much got the basics of a full screen app working. This source code below draws random colored pixels across the screen. In the beginning, I see a little hesitation but it runs smoothly after a few seconds. When I exit, I get the following exception:Unhandled exception at 0x0041204b in DirectX Application.exe: 0xC0000005: Access violation writing location 0x000002c4.Any help would be great. Thanks,dxfoo#define WIN32_LEAN_AND_MEAN// say no to mfc overhead#define INITGUID// Init guids#include <windows.h>// contains all window header files#include <windowsx.h>// window macros#include <iostream>// standard c++ stuff#include "ddraw.h"// Direct Draw header#define KEYDOWN(vk_code) (GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0#define KEYUP(vk_code) (GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1#define SCREEN_WIDTH 800#define SCREEN_HEIGHT 600#define SCREEN_BPP 8// Globalsconst char g_szWinTitle[] = "DirectX Application";// Window titleconst char g_szClassName[] = "WNDCLASS1";// Parent window classconst int  WIDTH = 800;// Screen Widthconst int  HEIGHT = 600;// Screen HeightHWND g_hWnd = NULL;// Global handle to parent windowHINSTANCE g_hInstance = NULL;// Global instance to application// DirectX Instances LPDIRECTDRAW7 lpdd = NULL;LPDIRECTDRAWSURFACE7 lpddsprimary = NULL;LPDIRECTDRAWPALETTE lpddpal;DDSURFACEDESC2 ddsd;PALETTEENTRY palette[256];// PrototypesLRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);void Game_Init();void Game_Main();void Game_Destroy();// Main entry point for the applicationint WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdArgs, int nCmdShow){HWND hWnd = NULL;// Handle to parent windowMSG msg;// Message structure// Define window class  WNDCLASSEX wc;wc.cbClsExtra = 0;// Extra class space infowc.cbWndExtra = 0;// Extra window space infowc.cbSize = sizeof(WNDCLASSEX);// Size of the window class structurewc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);// Background colorwc.hCursor = LoadCursor(NULL, IDC_ARROW);// Cursor wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);// Icon (32x32)wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);// Icon (16x16)wc.hInstance = hInstance;// Window's instancewc.lpfnWndProc = WndProc;// Window procedure  wc.lpszClassName = g_szClassName;// Class namewc.lpszMenuName = NULL;// Menu wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;  // Window style// Register window classif (!RegisterClassEx(&wc)) {MessageBox(NULL, "Registering Class Window Failed!", g_szWinTitle, MB_OK | MB_ICONERROR);return 0;}// Create WindowhWnd = CreateWindowEx(NULL, g_szClassName, g_szWinTitle, WS_POPUP | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, hInstance, NULL);// Check for window creation errorif (hWnd == NULL) {MessageBox(NULL, "Creating parent window failed!", g_szWinTitle, MB_OK | MB_ICONERROR);return 0;}// Show & Update WindowShowWindow(hWnd, nCmdShow);UpdateWindow(hWnd);// Set globalsg_hWnd = hWnd;g_hInstance = hInstance;Game_Init();// Initialize game// Message Loopwhile (TRUE){if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {// Check for a quitif (msg.message == WM_QUIT) return 0;TranslateMessage(&msg);// Translate any accelerated keysDispatchMessage(&msg);// Dispatch the message}// Do game logic hereGame_Main();}Game_Destroy();return (int) msg.wParam;}// Window ProcedureLRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){PAINTSTRUCT ps;HDC hDC;// check the given messageswitch (msg){case WM_CREATE:{}break;case WM_PAINT:{hDC = BeginPaint(hWnd, &ps);EndPaint(hWnd, &ps);}break;case WM_DESTROY:{PostQuitMessage(WM_QUIT);}break;default: break;}// Send back any unhandled events return DefWindowProc(hWnd, msg, wParam, lParam);}// Initialize game resources herevoid Game_Init(){ // Create a direct draw 7.0 object interfaceDirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL);// Set the cooperative level to full screenlpdd->SetCooperativeLevel(g_hWnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWMODEX |DDSCL_ALLOWREBOOT);// Set display modelpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, 0, 0);// Clear ddsd and set sizememset(&ddsd, 0, sizeof(ddsd));ddsd.dwSize = sizeof(ddsd);ddsd.dwFlags = DDSD_CAPS;ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;// Create primary surfacelpdd->CreateSurface(&ddsd, &lpddsprimary, NULL);// Fill a 8.8.8 palette entryfor (int color = 1; color < 255; color++){palette.peRed = rand() % <span class="cpp-number">256</span>;palette.peGreen = rand() % <span class="cpp-number">256</span>;palette.peBlue = rand() % <span class="cpp-number">256</span>;palette.peFlags = PC_NOCOLLAPSE;}<span class="cpp-comment">// Set black palette color position</span>palette[<span class="cpp-number">0</span>].peRed = <span class="cpp-number">0</span>;palette[<span class="cpp-number">0</span>].peGreen = <span class="cpp-number">0</span>;palette[<span class="cpp-number">0</span>].peBlue = <span class="cpp-number">0</span>;palette[<span class="cpp-number">0</span>].peFlags = PC_NOCOLLAPSE;<span class="cpp-comment">// Set white palette color position</span>palette[<span class="cpp-number">255</span>].peRed = <span class="cpp-number">255</span>;palette[<span class="cpp-number">255</span>].peGreen = <span class="cpp-number">255</span>;palette[<span class="cpp-number">255</span>].peBlue = <span class="cpp-number">255</span>;palette[<span class="cpp-number">255</span>].peFlags = PC_NOCOLLAPSE;<span class="cpp-comment">// Create palette</span>lpdd-&gt;CreatePalette(DDPCAPS_INITIALIZE | DDPCAPS_ALLOW256 | DDPCAPS_8BIT, palette, &amp;lpddpal, NULL);<span class="cpp-comment">// Set palette to primary surface</span>lpddsprimary-&gt;SetPalette(lpddpal);}<span class="cpp-comment">// Game logic here</span><span class="cpp-keyword">void</span> Game_Main(){<span class="cpp-keyword">if</span> (KEYDOWN(VK_ESCAPE))SendMessage(g_hWnd, WM_CLOSE, <span class="cpp-number">0</span>, <span class="cpp-number">0</span>);<span class="cpp-comment">// clean ddsd and set its size</span>memset(&amp;ddsd, <span class="cpp-number">0</span>, <span class="cpp-keyword">sizeof</span>(ddsd));ddsd.dwSize = <span class="cpp-keyword">sizeof</span>(ddsd);lpddsprimary-&gt;Lock(NULL, &amp;ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);<span class="cpp-keyword">int</span> mempitch = (<span class="cpp-keyword">int</span>)ddsd.lPitch;UCHAR *video_buffer = (UCHAR *)ddsd.lpSurface;<span class="cpp-comment">// Plot 1000 random pixels to the primary surface</span><span class="cpp-keyword">for</span> (<span class="cpp-keyword">int</span> index = <span class="cpp-number">0</span>; index &lt; <span class="cpp-number">1000</span>; index++){UCHAR color = rand()%<span class="cpp-number">256</span>;<span class="cpp-keyword">int</span> x = rand()%SCREEN_WIDTH;<span class="cpp-keyword">int</span> y = rand()%SCREEN_HEIGHT;video_buffer[x + y * mempitch] = color;}lpddsprimary-&gt;Unlock(NULL);Sleep(<span class="cpp-number">30</span>); <span class="cpp-comment">// sleep a bit</span>}<span class="cpp-comment">// Destroy game resources here</span><span class="cpp-keyword">void</span> Game_Destroy(){<span class="cpp-keyword">if</span> (lpdd) {lpdd-&gt;Release();lpdd = NULL;} <span class="cpp-keyword">if</span> (lpddsprimary){lpddsprimary-&gt;Release();lpddsprimary = NULL;}<span class="cpp-keyword">if</span> (lpddpal){lpddpal-&gt;Release();lpddpal = NULL;}}  </pre></div><!–ENDSCRIPT–> 
  I think you're getting that exception because you're not releasing the resources in the correct order. I got a similar error when I was learning Direct Draw, and that was my problem. Try releasing the pallette first, then the surface, and lastly release the interface pointer. Hope this helps!   ;  Did you try walking through the code with your debugger?  Attach a breakpoint to the general area where you think it fails (probably in your Game_Destroy() function), and then see where it crashes.  That should help you to find the source of the problem.   ;  Thanks, I was just thinking that and put it in the right order now, but the same exception shows up. I checked the debugger. this is what it found:color  =  127  = unsignedmempitch = 2089890440 = intvideo_buffer = 0x7c90ee18 "(random ascii characters) = unsignedx = 2089890433 = inty = 10551296 (IN RED HIGHLIGHT) = intOn second try, it said this all in red:color = 13 = unsignedmempitch = -1073741819 = intvideo_buffer = 0x6c65525c <Bad Ptr> = unsignedx = 233128856 = inty = 13 = intA yellow arrow was pointing at this line:video_buffer[x + y * mempitch] = color;;  Change 'return 0' to 'break' in your main loop. Also, you should set a flag on WM_CLOSE to let your app know that the window is being destroyed. If you try to render after the WM_CLOSE/WM_DESTROY is processed, you will have problems.;  The break was a good idea; however, the problem still occures. Here's the source code from the book. Maybe you can help pinpoint what I'm doing different then. I'll do the same.// DEMO6_3.CPP basic full-screen pixel plotting DirectDraw demo// INCLUDES ///////////////////////////////////////////////#define WIN32_LEAN_AND_MEAN  // just say no to MFC#define INITGUID // make sure directX guids are included#include <windows.h>   // include important windows stuff#include <windowsx.h> #include <mmsystem.h>#include <iostream.h> // include important C/C++ stuff#include <conio.h>#include <stdlib.h>#include <malloc.h>#include <memory.h>#include <string.h>#include <stdarg.h>#include <stdio.h> #include <math.h>#include <io.h>#include <fcntl.h>#include <ddraw.h> // include directdraw// DEFINES ////////////////////////////////////////////////// defines for windows #define WINDOW_CLASS_NAME "WINCLASS1"// default screen size#define SCREEN_WIDTH    640  // size of screen#define SCREEN_HEIGHT   480#define SCREEN_BPP 8    // bits per pixel#define MAX_COLORS 256  // maximum colors// TYPES //////////////////////////////////////////////////////// basic unsigned typestypedef unsigned short USHORT;typedef unsigned short WORD;typedef unsigned char  UCHAR;typedef unsigned char  BYTE;// MACROS /////////////////////////////////////////////////#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)#define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)// initializes a direct draw struct#define DD_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }// GLOBALS ////////////////////////////////////////////////HWND main_window_handle = NULL; // globally track main windowHINSTANCE hinstance_app = NULL; // globally track hinstance// directdraw stuffLPDIRECTDRAW7    lpdd    = NULL;   // dd objectLPDIRECTDRAWSURFACE7  lpddsprimary = NULL;   // dd primary surfaceLPDIRECTDRAWSURFACE7  lpddsback    = NULL;   // dd back surfaceLPDIRECTDRAWPALETTE   lpddpal = NULL;   // a pointer to the created dd paletteLPDIRECTDRAWCLIPPER   lpddclipper  = NULL;   // dd clipperPALETTEENTRYpalette[256];// color palettePALETTEENTRYsave_palette[256];// used to save palettesDDSURFACEDESC2   ddsd;   // a direct draw surface description structDDBLTFXddbltfx;// used to fillDDSCAPS2    ddscaps;// a direct draw surface capabilities structHRESULTddrval; // result back from dd callsDWORD  start_clock_count = 0; // used for timing// these defined the general clipping rectangleint min_clip_x = 0, // clipping rectanglemax_clip_x = SCREEN_WIDTH-1,    min_clip_y = 0,    max_clip_y = SCREEN_HEIGHT-1;// these are overwritten globally by DD_Init()int screen_width  = SCREEN_WIDTH,  // width of screen    screen_height = SCREEN_HEIGHT, // height of screen    screen_bpp    = SCREEN_BPP;    // bits per pixelchar buffer[80]; // general printing buffer// FUNCTIONS //////////////////////////////////////////////LRESULT CALLBACK WindowProc(HWND hwnd,UINT msg,    WPARAM wparam,    LPARAM lparam){// this is the main message handler of the systemPAINTSTRUCTps;// used in WM_PAINTHDChdc;// handle to a device contextchar buffer[80];   // used to print strings// what is the message switch(msg){case WM_CREATE:    {// do initialization stuff here   // return successreturn(0);} break;   case WM_PAINT: {// simply validate the window   hdc = BeginPaint(hwnd,&ps);  // end painting   EndPaint(hwnd,&ps);   // return successreturn(0);   } break;case WM_DESTROY: {// kill the application, this sends a WM_QUIT message PostQuitMessage(0);   // return successreturn(0);} break;default:break;    } // end switch// process any messages that we didn't take care of return (DefWindowProc(hwnd, msg, wparam, lparam));} // end WinProc///////////////////////////////////////////////////////////int Game_Main(void *parms = NULL, int num_parms = 0){// this is the main loop of the game, do all your processing// here// for now test if user is hitting ESC and send WM_CLOSEif (KEYDOWN(VK_ESCAPE))   SendMessage(main_window_handle,WM_CLOSE,0,0);// plot 1000 random pixels to the primary surface and return// clear ddsd and set size, never assume it's cleanmemset(&ddsd,0,sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd);if (FAILED(lpddsprimary->Lock(NULL, &ddsd,    DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,    NULL)))   {   // error   return(0);   } // end if// now ddsd.lPitch is valid and so is ddsd.lpSurface// make a couple aliases to make code cleaner, so we don't// have to castint mempitch   = (int)ddsd.lPitch;UCHAR *video_buffer = (UCHAR *)ddsd.lpSurface;// plot 1000 random pixels with random colors on the// primary surface, they will be instantly visiblefor (int index=0; index < 1000; index++)    {    // select random position and color for 640x480x8    UCHAR color = rand()%256;    int x = rand()%640;    int y = rand()%480;    // plot the pixel    video_buffer[x+y*mempitch] = color;  } // end for index// now unlock the primary surfaceif (FAILED(lpddsprimary->Unlock(NULL)))   return(0);// sleep a bitSleep(30);// return success or failure or your own return code herereturn(1);} // end Game_Main////////////////////////////////////////////////////////////int Game_Init(void *parms = NULL, int num_parms = 0){// this is called once after the initial window is created and// before the main event loop is entered, do all your initialization// here// create IDirectDraw interface 7.0 object and test for errorif (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)))   return(0);// set cooperation to full screenif (FAILED(lpdd->SetCooperativeLevel(main_window_handle,    DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX |    DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))   {   // error   return(0);   } // end if// set display mode to 640x480x8if (FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,0,0)))   {   // error   return(0);   } // end if// clear ddsd and set sizememset(&ddsd,0,sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd);// enable valid fieldsddsd.dwFlags = DDSD_CAPS;// request primary surfaceddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;// create the primary surfaceif (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL)))   {   // error   return(0);   } // end if// build up the palette data arrayfor (int color=1; color < 255; color++)    {    // fill with random RGB values    palette.peRed   = rand()%<span class="cpp-number">256</span>;<br>    palette.peGreen = rand()%<span class="cpp-number">256</span>;<br>    palette.peBlue  = rand()%<span class="cpp-number">256</span>;<br><br>    <span class="cpp-comment">// set flags field to PC_NOCOLLAPSE</span><br>    palette.peFlags = PC_NOCOLLAPSE;<br>    } <span class="cpp-comment">// end for color</span><br><br><span class="cpp-comment">// now fill in entry 0 and 255 with black and white</span><br>palette[<span class="cpp-number">0</span>].peRed   = <span class="cpp-number">0</span>;<br>palette[<span class="cpp-number">0</span>].peGreen = <span class="cpp-number">0</span>;<br>palette[<span class="cpp-number">0</span>].peBlue  = <span class="cpp-number">0</span>;<br>palette[<span class="cpp-number">0</span>].peFlags = PC_NOCOLLAPSE;<br><br>palette[<span class="cpp-number">255</span>].peRed   = <span class="cpp-number">255</span>;<br>palette[<span class="cpp-number">255</span>].peGreen = <span class="cpp-number">255</span>;<br>palette[<span class="cpp-number">255</span>].peBlue  = <span class="cpp-number">255</span>;<br>palette[<span class="cpp-number">255</span>].peFlags = PC_NOCOLLAPSE;<br><br><span class="cpp-comment">// create the palette object</span><br><span class="cpp-keyword">if</span> (FAILED(lpdd-&gt;CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | <br>  DDPCAPS_INITIALIZE, <br>  palette,&amp;lpddpal, NULL)))<br>{<br><span class="cpp-comment">// error</span><br><span class="cpp-keyword">return</span>(<span class="cpp-number">0</span>);<br>} <span class="cpp-comment">// end if</span><br><br><span class="cpp-comment">// finally attach the palette to the primary surface</span><br><span class="cpp-keyword">if</span> (FAILED(lpddsprimary-&gt;SetPalette(lpddpal)))<br>    {<br>    <span class="cpp-comment">// error</span><br>    <span class="cpp-keyword">return</span>(<span class="cpp-number">0</span>);<br>    } <span class="cpp-comment">// end if</span><br><br><span class="cpp-comment">// return success or failure or your own return code here</span><br><span class="cpp-keyword">return</span>(<span class="cpp-number">1</span>);<br><br>} <span class="cpp-comment">// end Game_Init</span><br><br><span class="cpp-comment">/////////////////////////////////////////////////////////////</span><br><br><span class="cpp-keyword">int</span> Game_Shutdown(<span class="cpp-keyword">void</span> *parms = NULL, <span class="cpp-keyword">int</span> num_parms = <span class="cpp-number">0</span>)<br>{<br><span class="cpp-comment">// this is called after the game is exited and the main event</span><br><span class="cpp-comment">// loop while is exited, do all you cleanup and shutdown here</span><br><br><span class="cpp-comment">// first the palette</span><br><span class="cpp-keyword">if</span> (lpddpal)<br>   {<br>   lpddpal-&gt;Release();<br>   lpddpal = NULL;<br>   } <span class="cpp-comment">// end if</span><br><br><span class="cpp-comment">// now the primary surface</span><br><span class="cpp-keyword">if</span> (lpddsprimary)<br>   {<br>   lpddsprimary-&gt;Release();<br>   lpddsprimary = NULL;<br>   } <span class="cpp-comment">// end if</span><br><br><span class="cpp-comment">// now blow away the IDirectDraw4 interface</span><br><span class="cpp-keyword">if</span> (lpdd)<br>   {<br>   lpdd-&gt;Release();<br>   lpdd = NULL;<br>   } <span class="cpp-comment">// end if</span><br><br><span class="cpp-comment">// return success or failure or your own return code here</span><br><span class="cpp-keyword">return</span>(<span class="cpp-number">1</span>);<br><br>} <span class="cpp-comment">// end Game_Shutdown</span><br><br><span class="cpp-comment">// WINMAIN ////////////////////////////////////////////////</span><br><br><span class="cpp-keyword">int</span> WINAPI WinMain(HINSTANCE hinstance,<br>HINSTANCE hprevinstance,<br>LPSTR lpcmdline,<br><span class="cpp-keyword">int</span> ncmdshow)<br>{<br><br>WNDCLASSEX winclass; <span class="cpp-comment">// this will hold the class we create</span><br>HWND   hwnd; <span class="cpp-comment">// generic window handle</span><br>MSG   msg; <span class="cpp-comment">// generic message</span><br>HDC   hdc; <span class="cpp-comment">// graphics device context</span><br><br><span class="cpp-comment">// first fill in the window class stucture</span><br>winclass.cbSize    = <span class="cpp-keyword">sizeof</span>(WNDCLASSEX);<br>winclass.style= CS_DBLCLKS | CS_OWNDC | <br> CS_HREDRAW | CS_VREDRAW;<br>winclass.lpfnWndProc= WindowProc;<br>winclass.cbClsExtra= <span class="cpp-number">0</span>;<br>winclass.cbWndExtra= <span class="cpp-number">0</span>;<br>winclass.hInstance= hinstance;<br>winclass.hIcon= LoadIcon(NULL, IDI_APPLICATION);<br>winclass.hCursor= LoadCursor(NULL, IDC_ARROW); <br>winclass.hbrBackground= (HBRUSH)GetStockObject(BLACK_BRUSH);<br>winclass.lpszMenuName= NULL;<br>winclass.lpszClassName= WINDOW_CLASS_NAME;<br>winclass.hIconSm   = LoadIcon(NULL, IDI_APPLICATION);<br><br><span class="cpp-comment">// save hinstance in global</span><br>hinstance_app = hinstance;<br><br><span class="cpp-comment">// register the window class</span><br><span class="cpp-keyword">if</span> (!RegisterClassEx(&amp;winclass))<br><span class="cpp-keyword">return</span>(<span class="cpp-number">0</span>);<br><br><span class="cpp-comment">// create the window</span><br><span class="cpp-keyword">if</span> (!(hwnd = CreateWindowEx(NULL,   <span class="cpp-comment">// extended style</span><br>   WINDOW_CLASS_NAME,<span class="cpp-comment">// class</span><br>    <span class="cpp-literal">"DirectDraw Full-Screen Demo"</span>, <span class="cpp-comment">// title</span><br>    WS_POPUP | WS_VISIBLE,<br><span class="cpp-number">0</span>,<span class="cpp-number">0</span>,  <span class="cpp-comment">// initial x,y</span><br>    SCREEN_WIDTH,SCREEN_HEIGHT,  <span class="cpp-comment">// initial width, height</span><br>    NULL,  <span class="cpp-comment">// handle to parent </span><br>    NULL,  <span class="cpp-comment">// handle to menu</span><br>    hinstance,<span class="cpp-comment">// instance of this application</span><br>    NULL)))<span class="cpp-comment">// extra creation parms</span><br><span class="cpp-keyword">return</span>(<span class="cpp-number">0</span>);<br><br><span class="cpp-comment">// save main window handle</span><br>main_window_handle = hwnd;<br><br><span class="cpp-comment">// initialize game here</span><br>Game_Init();<br><br><span class="cpp-comment">// enter main event loop</span><br><span class="cpp-keyword">while</span>(<span class="cpp-keyword">TRUE</span>)<br>{<br>    <span class="cpp-comment">// test if there is a message in queue, if so get it</span><br><span class="cpp-keyword">if</span> (PeekMessage(&amp;msg,NULL,<span class="cpp-number">0</span>,<span class="cpp-number">0</span>,PM_REMOVE))<br>   { <br>   <span class="cpp-comment">// test if this is a quit</span><br>  <span class="cpp-keyword">if</span> (msg.message == WM_QUIT)<br> <span class="cpp-keyword">break</span>;<br><br>   <span class="cpp-comment">// translate any accelerator keys</span><br>   TranslateMessage(&amp;msg);<br><br>   <span class="cpp-comment">// send the message to the window proc</span><br>   DispatchMessage(&amp;msg);<br>   } <span class="cpp-comment">// end if</span><br>    <br>  <span class="cpp-comment">// main game processing goes here</span><br>  Game_Main();<br>  <br>} <span class="cpp-comment">// end while</span><br><br><span class="cpp-comment">// closedown game here</span><br>Game_Shutdown();<br><br><span class="cpp-comment">// return to Windows like this</span><br><span class="cpp-keyword">return</span>(msg.wParam);<br><br>} <span class="cpp-comment">// end WinMain</span><br><br><span class="cpp-comment">///////////////////////////////////////////////////////////</span><br><br></pre></div><!–ENDSCRIPT–> ;  The difference is your WM_DESTROY handler falls through to the 'return DefWindowProc()', whereas the book code's handler does a 'return(0)'. This prevents the default handler from actually destroying (and thus invalidating) the window before you get the WM_QUIT. (Which is why I recommended the flag.)   ;  Okay, I found a solution, although it's different from the book's source code. Before, you had to press escape and it would send a WM_CLOSE message. But still it had to go through all that code in the block. So, I moved the escape check to the bottom of the code block. When I ran the program, it closed fine. I wonder what I'm doing different then if his source code works fine with the escape check on the top.   ;  Thanks Dave, I'll look into that.   ;  That was it! I never did my message processing his way before, but it makes sense now. If I process a message I'm looking for, I should return 0 before DefWindowProc tries to return something. Thanks again.   