   Bitmap Memory Management (basic)
  Hi,I''ve been programming for a while, but I''m new to C++ GUI programming.  I''ve read through tutorials and seen other code, but I''m a bit unclear on the exact process of memory management when it comes to bitmaps.  My code is up and running, but I have a feeling that I''m not destroying the images properly after they''re painted... would someone be so kind as to quickly check through my code and tell me if I''m forgetting something important?Basically I just don''t understand the process of the shuffling act that should be going on between bitmap and old bitmap files.  Is my code severely leaking memory?Thank you very much for your time.   #include <windows.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <fstream.h>#define WIN_WIDTH 632#define WIN_HEIGHT 632//functionsint init();int drawFirstMap();int loadImages(HINSTANCE hinstance);int testMove(int a);void drawMap();void drawChar();// Globals ---HWND hwnd;HDC hdc = NULL; // This will be our global device context for drawingHDC image_dc = NULL;HBITMAP old_bmp = NULL;//the images needed for drawingHBITMAP tile[4095];int map[100][100];int cx,cy,x,y,cxm,cym,chx,chy,chchx,chchy,cp;// Standard callback functionLRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow){    char class_name[] = "Test";   MSG msg;    WNDCLASSEX wndclassex = {0};// Fill the fields we care aboutwndclassex.cbSize = sizeof(WNDCLASSEX);    wndclassex.style = CS_HREDRAW | CS_VREDRAW;    wndclassex.lpfnWndProc = WinProc;    wndclassex.hInstance = hinstance;    wndclassex.hIcon = LoadIcon(NULL, IDI_APPLICATION);    wndclassex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);    wndclassex.lpszClassName = class_name;    RegisterClassEx(&wndclassex);// Register the window   hwnd = CreateWindowEx(NULL, // No extra window attributesclass_name,"Test",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, // Window will have default x posCW_USEDEFAULT, // Window will have default y posWIN_WIDTH,WIN_HEIGHT,NULL,NULL,hinstance,NULL);// Error checkif(!hwnd)return EXIT_FAILURE; // Something really bad happened!hdc = GetDC(hwnd); // Get the window''s device contextimage_dc = CreateCompatibleDC(hdc);//Error checkif(!hdc)return EXIT_FAILURE; // Couldn''t get window''s hdc    ShowWindow(hwnd, ishow);    ShowCursor(false); //hide the cursor    UpdateWindow(hwnd);loadImages(hinstance);init();  while(1){// Get message(s) if there is oneif(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){if(msg.message == WM_QUIT)break;TranslateMessage(&msg);DispatchMessage(&msg);}else{//background thinking}}// Free up global HDCReleaseDC(hwnd,hdc);UnregisterClass(class_name,hinstance); // Free up WNDCLASSEXreturn msg.wParam;}// The WinProcLRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam){PAINTSTRUCT ps;switch(message)    {case WM_KEYDOWN:switch(wparam) {   case VK_UP:  cp = 0;  if (testMove(1) == 1) { if ((cy > 0) && (chy == 160)) {cy--;drawMap(); } else if (chy > 32) {chy -= 32;drawMap(); }  } else { drawChar();  } break; case VK_RIGHT:   cp = 2;   if (testMove(2) == 1) {  if (((cx+10) < cxm) && (chx == 160)) { cx++; drawMap();  } else if (chx < 288) { chx += 32; drawMap();  }   } else {  drawChar();   }   break;    case VK_DOWN:  cp = 4;  if (testMove(3) == 1) {   if (((cy+10) < cym) && (chy == 160)) {  cy++;  drawMap();   } else if (chy < 288) {  chy += 32;  drawMap();   }   } else {  drawChar();   }    break; case VK_LEFT:  cp = 6;  if (testMove(4) == 1) { if ((cx > 0) && (chx == 160)) {cx--;drawMap(); } else if (chx > 32) {chx -= 32;drawMap(); }  } else { drawChar();  } break;  } // end of switch(wparam)return 0;  case WM_PAINT:  BeginPaint(hwnd,&ps);EndPaint(hwnd,&ps);return 0;   case WM_DESTROY:case WM_CLOSE:  PostQuitMessage(0);   return 0;    } // end of switch(message)    return DefWindowProc(hwnd, message, wparam, lparam);}int loadImages(HINSTANCE hinstance) {tile[0] = (HBITMAP)LoadImage(hinstance,"img/dbrick.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE); // dark bricktile[1] = (HBITMAP)LoadImage(hinstance,"img/lbrick.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE); //light bricktile[2] = (HBITMAP)LoadImage(hinstance,"img/window.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE); //windowtile[3] = (HBITMAP)LoadImage(hinstance,"img/shingle.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE); //shingletile[1000] = (HBITMAP)LoadImage(hinstance,"img/door.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE); //locked doortile[2000] = tile[1000]; //doortile[2001] = (HBITMAP)LoadImage(hinstance,"img/outside.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE); //area outside towntile[3000] = (HBITMAP)LoadImage(hinstance,"img/grass.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE); //grasstile[3001] = tile[1]; //light brickreturn 1;}int init() {cx = 0;cy = 5;x = 0;y = 0;   FILE *stream;   char line[100];   char toks[]   = ",";   char *token;   int  i, j;   i = 0;   j = 0;int t = 0;   if( (stream = fopen( "maps/1.map", "r" )) != NULL )   {   while (!feof(stream)) {   //if it''s a section divider (or the header), skip it   if (strncmp(line, "###", 3) == 0) {i++;   //otherwise, parse the map data   } else {   //load map[][]   if (i > 1) {   token = strtok(line, toks);   while( token != NULL ) {   /* While there are tokens in "string" */   map[i-2][j] = atoi(token);   t = i -2;   /* Get next token: */   token = strtok(NULL, toks);   j++;   }   j = 0;   i++;   }   }    if( fgets( line, 100, stream ) == NULL)  printf( "Lost World!\n" );   }   }//MessageBox(hwnd, line, "Error?", MB_OK);drawFirstMap();return 1;}int drawFirstMap() {int i = 0;int j = 0;    while (y < 760) {while (x < 760) {old_bmp = (HBITMAP)SelectObject(image_dc,tile[map[j+cy][i+cx]]);BitBlt(hdc,x,y,y+64,x+64,image_dc,0,0,SRCCOPY);    x = x + 64;    i++;}i = 0;x = 0;y = y + 64;j++;}return 1;}int testMove(int a) {return 1;}void drawMap() {}void drawChar() {}
  When you''re finished with the HBITMAP struct passit to DeleteObject. The definition of DeleteObject is:BOOL DeleteObject(HGDIOBJ hObject);;  Thanks for the reply, Daehrednud!Do you mean I would do something like this:old_bmp = (HBITMAP)SelectObject(image_dc,tile[map[j+cy][i+cx]]);BitBlt(hdc,x,y,y+64,x+64,image_dc,0,0,SRCCOPY);DeleteObject(old_bmp);(so, for each of the 100 or so tiles that I draw to the screen, starting in the upper left corner it would: 1. copy bitmap from array to old_bmp2. draw to screen3. DeleteObjectDo I have to clean up image_dc in any way, or does that take care of itself?This is starting to become a lot clearer -- thanks! 