   win32 + drawing
  I'm messing around with some win32 programming and I'm trying to get a gameloop working. I've created a function to drawbitmaps to the screen called drawBitmap. I'm calling this function within a gameloop but sometimes when I minimise the screen the bitmap dissappears. The rectangle which I have drawn with the standard Rectangle function in the game loop just sticks no matter what I do. Why does the rectangle stay on the screen but the bitmap dissappears?I've also noticed that sometimes I get some strange artifacts like the title bar of the window is not redrawn properly etc. Why?// Win32Test.cpp : Defines the entry point for the application.//// Win32Test.cpp : Defines the entry point for the application.//#include "stdafx.h"#include "Win32Test.h"#include <string>#include <sstream>#include <map>#include <vector>#include <iostream>using std::string;using std::stringstream;using std::map;using std::vector;using std::cout;using std::cin;using std::endl;#define MAX_LOADSTRING 100// Global Variables:HINSTANCE hInst;// current instanceTCHAR szTitle[MAX_LOADSTRING];// The title bar textTCHAR szWindowClass[MAX_LOADSTRING];// the main window class nameHWND gHwnd; //global handle to windows// Forward declarations of functions included in this code module:ATOMMyRegisterClass(HINSTANCE hInstance);BOOLInitInstance(HINSTANCE, int);LRESULT CALLBACKWndProc(HWND, UINT, WPARAM, LPARAM);INT_PTR CALLBACKAbout(HWND, UINT, WPARAM, LPARAM);// My functions for this programvoid drawBitmap(HDC &hdc, int x, int y, HBITMAP &hBitmap){BITMAP bitmap;HDC hBitmapDC = 0;hBitmapDC = CreateCompatibleDC(hdc);GetObject(hBitmap, sizeof(BITMAP), &bitmap);SelectObject(hBitmapDC, hBitmap);BitBlt(hdc, x, y, bitmap.bmWidth, bitmap.bmHeight, hBitmapDC, 0, 0, SRCCOPY);DeleteDC(hBitmapDC);}int gameLoop(){HDC hdc;HBITMAP hBitmap = hBitmap = (HBITMAP)LoadImage(NULL, ".\\bitmaps\\test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);hdc = GetDC(gHwnd);Rectangle(hdc, 600, 20, 800, 400);drawBitmap(hdc, 20, 5, hBitmap);ReleaseDC(gHwnd, hdc);return 0;}int GameShutdown(){return 0;}// Endint APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR    lpCmdLine, int  nCmdShow){UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine); // TODO: Place code here.MSG msg;HACCEL hAccelTable;// Initialize global stringsLoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);LoadString(hInstance, IDC_WIN32TEST, szWindowClass, MAX_LOADSTRING);MyRegisterClass(hInstance);// Perform application initialization:if (!InitInstance (hInstance, nCmdShow)){return FALSE;}hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32TEST));// Main message loop://while (GetMessage(&msg, NULL, 0, 0))while(true){if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){if(msg.message == WM_QUIT)break;if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)){TranslateMessage(&msg);DispatchMessage(&msg);}}else{gameLoop();}}GameShutdown();return (int) msg.wParam;}////  FUNCTION: MyRegisterClass()////  PURPOSE: Registers the window class.////  COMMENTS:////    This function and its usage are only necessary if you want this code//    to be compatible with Win32 systems prior to the 'RegisterClassEx'//    function that was added to Windows 95. It is important to call this function//    so that the application will get 'well formed' small icons associated//    with it.//ATOM MyRegisterClass(HINSTANCE hInstance){WNDCLASSEX wcex;HBRUSH hBrush = CreateSolidBrush((COLORREF)0x93DB70);//GetSysColorBrush (3);wcex.cbSize = sizeof(WNDCLASSEX);wcex.style= CS_HREDRAW | CS_VREDRAW;wcex.lpfnWndProc= WndProc;wcex.cbClsExtra= 0;wcex.cbWndExtra= 0;wcex.hInstance= hInstance;wcex.hIcon= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32TEST));wcex.hCursor= LoadCursor(NULL, IDC_ARROW);wcex.hbrBackground= hBrush;//(HBRUSH)(COLOR_WINDOW+1);wcex.lpszMenuName= MAKEINTRESOURCE(IDC_WIN32TEST);wcex.lpszClassName= szWindowClass;wcex.hIconSm= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));return RegisterClassEx(&wcex);}////   FUNCTION: InitInstance(HINSTANCE, int)////   PURPOSE: Saves instance handle and creates main window////   COMMENTS:////   In this function, we save the instance handle in a global variable and//   create and display the main program window.//BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){   HWND hWnd;   hInst = hInstance; // Store instance handle in our global variable   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);   if (!hWnd)   { return FALSE;   }   gHwnd = hWnd;   ShowWindow(hWnd, nCmdShow);   UpdateWindow(hWnd);   return TRUE;}////  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)////  PURPOSE:  Processes messages for the main window.////  WM_COMMAND- process the application menu//  WM_PAINT- Paint the main window//  WM_DESTROY- post a quit message and return////LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){int wmId, wmEvent;PAINTSTRUCT ps;HDC hdc;static HBITMAP hBitmap = 0;//must be static for wm_create to remember???//reason is that wndproc is called several times on intial call//sprites is set but on next call sprites is null again//and since wm_create is bypassed sprites is set to nothing.static map<string, HBITMAP> sprites;// = loadCardSprites();static HWND button;static HWND button2;static HWND label;switch (message){case WM_CREATE:break;case WM_COMMAND:wmId    = LOWORD(wParam);wmEvent = HIWORD(wParam);// Parse the menu selections:switch (wmId){case IDM_ABOUT:DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);break;case IDM_EXIT:DestroyWindow(hWnd);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}break;case WM_PAINT:hdc = BeginPaint(hWnd, &ps);// TODO: Add any drawing code here...EndPaint(hWnd, &ps);break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}return 0;}// Message handler for about box.INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){UNREFERENCED_PARAMETER(lParam);switch (message){case WM_INITDIALOG:return (INT_PTR)TRUE;case WM_COMMAND:if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL){EndDialog(hDlg, LOWORD(wParam));return (INT_PTR)TRUE;}break;}return (INT_PTR)FALSE;}
  Dont load the bitmap in your game loop, load it when the program starts or at least load it when you need it and keep it until you dont. Right now you are just leaking HBITMAPs all over the place and GDI does not like leaked objects.   ;  I moved the loadimage to the wm_create switch case and it seems to have fixed the problem.I would appreciated it if you or anyone else could provide a deeper explantation for why the program behaved the way it did?   ;  Actually I think I get it, the game loop is being called over and over again creating a new HBITMAP each time, I wasn't releasing these at the end of the game loop and so am running out of memory, possibly causing my program to behave strangely. I was wondering why when I tried to use print screen I kept getting a message telling me that there was not enough memory when I only had my program running.I guess I could make HBITMAP static or use a global variable instead.   