OK, Here we go again... I am now learning how to load and display bitmaps (DirectX). The code I have runs fine. The problem I am having is when I hit the ESC key to exit. The program shuts down just fine. I don't get the error message until after I get back to my desktop. Windows says that there is a problem and the program must be shut down (which it already is?!?) I assume it is either a memory allocation problem or something with one of the pointers, but I have not been able to find it.
Code:
#define WIN32_LEAN_AND_MEAN 

#define INITGUID // make sure directX guids are included

#include <windows.h>
#include <windowsx.h> 
#include <cstdio>
#include <ddraw.h>

#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
#define BITMAP_ID       0x4D42 // universal id for a bitmap

// container structure for bitmaps .BMP file
typedef struct BITMAP_FILE_TAG {
        BITMAPFILEHEADER bitmapfileheader;  // this contains the bitmapfile header
        BITMAPINFOHEADER bitmapinfoheader;  // this is all the info including the palette
        PALETTEENTRY     palette[256];      // we will store the palette here
        UCHAR            *buffer;           // this is a pointer to the data
} BITMAPFILE, *PTR_BITMAPFILE;

// 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 DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }

// GLOBALS /////////////////////////////////////////////////////////////////////

HWND      main_window_handle = NULL; // globally track main window
HINSTANCE hinstance_app      = NULL; // globally track hinstance
int       window_closed      = 0;

// directdraw stuff
LPDIRECTDRAW7         lpDD               = NULL; // dd object
LPDIRECTDRAWSURFACE7  lpDDPrimarySurface = NULL; // dd primary surface
LPDIRECTDRAWSURFACE7  lpDDBackSurface    = NULL; // dd back surface
LPDIRECTDRAWPALETTE   lpDDPalette        = NULL; // a pointer to the created dd palette
LPDIRECTDRAWCLIPPER   lpDDClipper        = NULL; // dd clipper
PALETTEENTRY          palette[256];              // color palette
PALETTEENTRY          save_palette[256];         // used to save palettes
DDSURFACEDESC2        DDSurfaceDesc;             // a direct draw surface description struct
DDBLTFX               DDbltfx;                   // used to fill
DDSCAPS2              DDSurfaceCaps;             // a direct draw surface capabilities struct
HRESULT               DDResultVal;               // result back from dd calls
DWORD                 start_clock_count = 0;     // used for timing
BITMAPFILE            bitmap;                    // holds the bitmap
 
// FUNCTION PROTOTYPES /////////////////////////////////////////////////////////

LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);
int Game_Init(void *parms = NULL, int num_parms = 0);
int Game_Main(void *parms = NULL, int num_parms = 0);
int Game_Shutdown(void *parms = NULL, int num_parms = 0);
int Flip_Bitmap(UCHAR*, int, int);
int Load_Bitmap_File(PTR_BITMAPFILE, char*); //
int Unload_Bitmap_File(PTR_BITMAPFILE); //
int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE7,int); //

// FUNCTION DEFINITIONS ////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// WINMAIN
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance,
					LPSTR lpcmdline, int ncmdshow) {
    WNDCLASSEX winclass; // this will hold the class we create
    HWND       hwnd;     // generic window handle
    MSG        msg;      // generic message
    HDC        hdc;      // graphics device context

    // first fill in the window class stucture
    winclass.cbSize         = sizeof(WNDCLASSEX);
    winclass.style	    = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
    winclass.lpfnWndProc    = WindowProc;
    winclass.cbClsExtra	    = 0;
    winclass.cbWndExtra	    = 0;
    winclass.hInstance      = hinstance;
    winclass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
    winclass.hCursor        = LoadCursor(NULL, IDC_ARROW); 
    winclass.hbrBackground  = (HBRUSH)GetStockObject(BLACK_BRUSH);
    winclass.lpszMenuName   = NULL;
    winclass.lpszClassName  = WINDOW_CLASS_NAME;
    winclass.hIconSm        = LoadIcon(NULL, IDI_APPLICATION);

    // save hinstance in global
    hinstance_app = hinstance;

    // register the window class
    if (!RegisterClassEx(&winclass))
	    return 0;

    // create the window
    if (!(hwnd = CreateWindowEx(0,                     // extended style
                                WINDOW_CLASS_NAME,     // class
                                "DirectDraw Demo",     // title
                                WS_POPUP,
                                0,0,                   // initial x,y
                                SCREEN_WIDTH, SCREEN_HEIGHT, // initial width, height
                                NULL,                  // handle to parent 
                                NULL,                  // handle to menu
                                hinstance,             // instance of this application
                                NULL) ) )              // extra creation parms
        return 0;

    // save main window handle
    main_window_handle = hwnd;

    // initialize game here
    Game_Init();

    // enter main event loop
    while(TRUE) {
        // test if there is a message in queue, if so get it
	    if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { 
    	   // test if this is a quit
           if (msg.message == WM_QUIT)
               break;
	
	       // translate any accelerator keys
	       TranslateMessage(&msg);

    	   // send the message to the window proc
	       DispatchMessage(&msg);
        } // end if
    
        // main game processing goes here
        Game_Main();
   	} // end while

    // closedown game here
    Game_Shutdown();

    // return to Windows like this
    return(msg.wParam);
} // end WinMain

////////////////////////////////////////////////////////////////////////////////
// this is the main message handler of the system
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
    PAINTSTRUCT      ps;                         // used in WM_PAINT
    HDC              hdc;                        // handle to a device context
    char buffer[80];                             // used to print strings

    // what is the message 
    switch(msg) {	
	    case WM_CREATE: {
		    // do initialization stuff here
        
            // return success
		    return 0;
		} break;
   
    	case WM_PAINT: {
    		// simply validate the window 
   	        hdc = BeginPaint(hwnd,&ps);	 
        
            // end painting
            EndPaint(hwnd,&ps);

            // return success
		    return 0;
   		} break;

    	case WM_DESTROY: {
    		// kill the application, this sends a WM_QUIT message 
	    	PostQuitMessage(0);

            // return success
    		return 0;
		} break;

	    default: break;

    } // end switch

    // process any messages that we didn't take care of 
    return (DefWindowProc(hwnd, msg, wparam, lparam));
} // end WinProc

////////////////////////////////////////////////////////////////////////////////
// this function opens a bitmap file and loads the data into a bitmap
int Load_Bitmap_File(PTR_BITMAPFILE bitmap, char *filename) {
    int      FileHandle,          // the file handle, duh...
             index;               // looping index
    UCHAR    *pTempBuffer = NULL; // used to convert 24 bit images to 16 bit
    OFSTRUCT FileData;            // the file data information
    
    // open the file if it exists
    if ( (FileHandle = OpenFile(filename, &FileData, OF_READ) ) == -1)
        return 0;
    
    // now load the bitmap file header
    _lread(FileHandle, &bitmap->bitmapfileheader, sizeof(BITMAPFILEHEADER) );
    
    // test if this is a bitmap file
    if (bitmap->bitmapfileheader.bfType != BITMAP_ID) {
        // close the file
        _lclose(FileHandle);
        
        // return error
        return 0;
    } // end if
    
    // now we know this is a bitmap, so read in all the sections
    
    // first the bitmap info header
    _lread(FileHandle, &bitmap->bitmapinfoheader, sizeof(BITMAPINFOHEADER) );
    
    // now load the color palette if there is one
    if (bitmap->bitmapinfoheader.biBitCount == 8) {
        _lread(FileHandle, &bitmap->palette, MAX_COLORS * sizeof(PALETTEENTRY) );
        
        // now set all the flags in the palette correctly and fix
        // the reversed BRG RGBQUAD data format
        for (int index = 0; index < MAX_COLORS; index++) {
            // reverse the red and green fields
            int temp_color                = bitmap->palette[index].peRed;
            bitmap->palette[index].peRed  = bitmap->palette[index].peBlue;
            bitmap->palette[index].peBlue = temp_color;
        
            // always set the flags word to this
            bitmap->palette[index].peFlags =PC_NOCOLLAPSE;
        } // end for index
    } // end if
    
    // finally, find the image data
    _llseek(FileHandle, -(int)(bitmap->bitmapinfoheader.biSizeImage), SEEK_END);
    
    // and read in the image
    if (bitmap->bitmapinfoheader.biBitCount == 8  ||
            bitmap->bitmapinfoheader.biBitCount == 16 ||
            bitmap->bitmapinfoheader.biBitCount == 24) {
        // delete the last image if there was one
        if (bitmap->buffer)
            free(bitmap->buffer);
        
        // allocate the memory for the image
        if (!(bitmap->buffer = (UCHAR*)malloc(bitmap->bitmapinfoheader.biSizeImage) ) ) {
            // close the file
            _lclose(FileHandle);
            
            // return error
            return 0;
        } // end if
        
        // now read it in
        _lread(FileHandle, bitmap->buffer, bitmap->bitmapinfoheader.biSizeImage);
    } else {
        // serious problem
        return 0;
    } // end if / else
    
    // close the file
    _lclose(FileHandle);
    
    // flip the bitmap
    Flip_Bitmap(bitmap->buffer,
                bitmap->bitmapinfoheader.biWidth * (bitmap->bitmapinfoheader.biBitCount / 8),
                bitmap->bitmapinfoheader.biHeight);
    
    // return success
    return 1;
} // end Load_Bitmap_File

////////////////////////////////////////////////////////////////////////////////
// this function releases all memory associated with the bitmap
int Unload_Bitmap_File(PTR_BITMAPFILE bitmap) {
    if (bitmap->buffer) {
        // release the memory
        free(bitmap->buffer);
        
        // reset the pointer
        bitmap->buffer = NULL;
    } // end if
    
    // return success
    return 1;
} // end Unload_Bitmap_File

////////////////////////////////////////////////////////////////////////////////
// this function is used to flip bottom-up .BMP images
int Flip_Bitmap(UCHAR *image, int bytes_per_line, int height) {
    UCHAR *buffer; // used to perform the image processing
    int index;     // looping index

    // allocate the temporary buffer
    if (!(buffer = (UCHAR*)malloc(bytes_per_line * height) ) )
        return(0);

    // copy image to work area
    memcpy(buffer, image, bytes_per_line * height);

    // flip vertically
    for (index = 0; index < height; index++)
        memcpy(&image[( (height-1) - index) * bytes_per_line],
               &buffer[index * bytes_per_line], bytes_per_line);

    // release the memory
    free(buffer);

    // return success
    return 1;
} // end Flip_Bitmap

////////////////////////////////////////////////////////////////////////////////
//
int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE7 lpDDSurface, int color) {
    DDBLTFX DDBltFx; // this contains the DDBLTFX structure

    // clear out the structure and set the size field 
    DDRAW_INIT_STRUCT(DDBltFx);

    // set the dwfillcolor field to the desired color
    DDBltFx.dwFillColor = color; 

    // ready to blt to surface
    lpDDSurface->Blt(NULL,                        // ptr to dest rectangle
                     NULL,                        // ptr to source surface, NA            
                     NULL,                        // ptr to source rectangle, NA
                     DDBLT_COLORFILL | DDBLT_WAIT,// fill and wait                   
                     &DDBltFx);                   // ptr to DDBLTFX structure

    // return success
    return 1;
} // end DDraw_Fill_Surface

////////////////////////////////////////////////////////////////////////////////
// this is called once after the initial window is created and
// before the main event loop is entered, do all your initialization here
int Game_Init(void *parms, int num_parms) {
    // create IDirectDraw interface 7.0 object and test for error
    if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpDD, IID_IDirectDraw7, NULL) ) ) {
        return 0;
    }

    // set cooperation to fullscreen
    if (FAILED(lpDD->SetCooperativeLevel(main_window_handle, DDSCL_FULLSCREEN | 
                                                             DDSCL_ALLOWMODEX |
                                                             DDSCL_EXCLUSIVE  |
                                                             DDSCL_ALLOWREBOOT) ) ) {
        return 0;
    }

    // set display mode to 640x480x8
    if (FAILED(lpDD->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,
                                    0, 0) ) ) {
        return 0;
    }

    // clear ddsd and set size
    DDRAW_INIT_STRUCT(DDSurfaceDesc);
    
    // enable valid fields
    DDSurfaceDesc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;

    // set the backbuffer count field to 1, use 2 for triple buffering
    DDSurfaceDesc.dwBackBufferCount = 1;

    // request a complex, flippable
    DDSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;

    // create the primary surface
    if (FAILED(lpDD->CreateSurface(&DDSurfaceDesc, &lpDDPrimarySurface, NULL) ) ) {
        return 0;
    }

    // now query for attached surface from the primary surface

    // this line is needed by the call
    DDSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;

    // get the attached back buffer surface
    if (FAILED(lpDDPrimarySurface->GetAttachedSurface(&DDSurfaceDesc.ddsCaps, &lpDDBackSurface) ) ) {
        return 0;
    }

    // build up the palette data array
    for (int color = 1; color < 255; color++) {
        // fill with random RGB values
        palette[color].peRed   = rand()%256;
        palette[color].peGreen = rand()%256;
        palette[color].peBlue  = rand()%256;

        // set flags field to PC_NOCOLLAPSE
        palette[color].peFlags = PC_NOCOLLAPSE;
    } // end for color

    // now fill in entry 0 and 255 with black and white
    palette[0].peRed     = 0;
    palette[0].peGreen   = 0;
    palette[0].peBlue    = 0;
    palette[0].peFlags   = PC_NOCOLLAPSE;

    palette[255].peRed   = 255;
    palette[255].peGreen = 255;
    palette[255].peBlue  = 255;
    palette[255].peFlags = PC_NOCOLLAPSE;

    // create the palette object
    if (FAILED(lpDD->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE, 
                                   palette,&lpDDPalette, NULL) ) ) {
        return 0;
    }

    // finally attach the palette to the primary surface
    if (FAILED(lpDDPrimarySurface->SetPalette(lpDDPalette) ) ) {
        return 0;
    }

    // load the 8-bit image
    if (!Load_Bitmap_File(&bitmap, "MyBitMap.bmp") ) {
        return 0;
    }

    // load it's palette into directdraw
    if (FAILED(lpDDPalette->SetEntries(0, 0, MAX_COLORS, bitmap.palette) ) ) {
        return 0;
    }

    // clean the surface
    DDraw_Fill_Surface(lpDDPrimarySurface, 0);


    // return success or failure or your own return code here
    return 1;
} // end Game_Init

/////////////////////////////////////////////////////////////////////////////////
// this is called after the game is exited and the main event
// loop while is exited, do all you cleanup and shutdown here
int Game_Shutdown(void *parms, int num_parms) {
    // this is called after the game is exited and the main event
    // loop while is exited, do all you cleanup and shutdown here

    // first the palette
    if (lpDDPalette) {
        lpDDPalette->Release();
        lpDDPalette = NULL;
    } // end if

    // now the back buffer surface
    if (lpDDBackSurface) {
        lpDDBackSurface->Release();
        lpDDBackSurface = NULL;
    } // end if

    // now the primary surface
    if (lpDDPrimarySurface) {
        lpDDPrimarySurface->Release();
        lpDDPrimarySurface = NULL;
    } // end if

    // now blow away the IDirectDraw4 interface
    if (lpDD) {
        lpDD->Release();
        lpDD = NULL;
    } // end if

    // return success or failure or your own return code here
    return 1;
} // end Game_Shutdown

////////////////////////////////////////////////////////////////////////////////
// this is the main loop of the game, do all your processing here
int Game_Main(void *parms, int num_parms) {
    // make sure this isn't executed again
    if (window_closed)
        return 0;

    // for now test if user is hitting ESC and send WM_CLOSE
    if (KEYDOWN(VK_ESCAPE) ) {
        window_closed = 1;
        SendMessage(main_window_handle, WM_CLOSE, 0, 0);
    }

    // copy the bitmap image to the primary buffer line by line
    // note this is a good candidate operation to make into a function - hint!

    // lock the primary surface
    lpDDPrimarySurface->Lock(NULL, &DDSurfaceDesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);

    // get video pointer to primary surfce
    UCHAR *primary_buffer = (UCHAR*)DDSurfaceDesc.lpSurface;       

    // test if memory is linear
    if (DDSurfaceDesc.lPitch == SCREEN_WIDTH) {
        // copy memory from double buffer to primary buffer
        memcpy( (void*)primary_buffer, (void*)bitmap.buffer, SCREEN_WIDTH * SCREEN_HEIGHT);
    } else { 
        // non-linear
        // make copy of source and destination addresses
        UCHAR *dest_ptr = primary_buffer;
        UCHAR *src_ptr  = bitmap.buffer;

        // memory is non-linear, copy line by line
        for (int y = 0; y < SCREEN_HEIGHT; y++) {
            // copy line
            memcpy( (void*)dest_ptr, (void*)src_ptr, SCREEN_WIDTH);

            // advance pointers to next line
            dest_ptr += DDSurfaceDesc.lPitch;
            src_ptr  += SCREEN_WIDTH;
        } // end for

    } // end if / else

    // now unlock the primary surface
    if (FAILED(lpDDPrimarySurface->Unlock(NULL) ) ) {
        return 0;
    }


    // do nothing -- look at pretty picture


    // wait a sec so everything does not fly by so quick
    //Sleep(30);

    // return success or failure or your own return code here
    return 1;
} // end Game_Main