Click to See Complete Forum and Search --> : Bitmaps cutting off


Dispiacere
November 13th, 2009, 10:45 PM
I have a problem with bitmaps cutting off after being displayed. When another window moves over my program's window the bitmap is erased and the back of the window is visible.

Here's a pic to show what I mean


http://img23.imageshack.us/img23/1706/16493978.jpg


And here's the code I use to load the bitmap

int LoadFile(int XDest, int YDest, char *FileName, HWND hWnd)
{

static BITMAPFILEHEADER *pbmfh;
static BITMAPINFO *pbmi;
static BYTE *pBits;
static int cxDib, cyDib;

DWORD dwFileSize, dwHighSize, dwBytesRead;
HANDLE hFile;

char *NameOfFile;
NameOfFile = new char[50];
NameOfFile = FileName;

hFile = CreateFile (NameOfFile, GENERIC_READ,
FILE_SHARE_READ, NULL,
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL);

dwFileSize = GetFileSize (hFile, &dwHighSize);
pbmfh = (BITMAPFILEHEADER *) malloc (dwFileSize);
ReadFile (hFile, pbmfh, dwFileSize, &dwBytesRead, NULL);
pbmi = (BITMAPINFO *) (pbmfh + 1);
pBits = (BYTE *) pbmfh + pbmfh->bfOffBits;
cxDib = pbmi->bmiHeader.biWidth;
cyDib = abs(pbmi->bmiHeader.biHeight);
HDC hdc;
hdc = GetDC (hWnd);

SetDIBitsToDevice (hdc,
XDest,
YDest,
cxDib,
cyDib,
0,
0,
0,
cyDib,
pBits,
pbmi,
DIB_RGB_COLORS);
ReleaseDC (hWnd, hdc);
free (pbmfh);
return 0;
}

The function is called like this:

LoadFile(0, 0, "Graphics\\TITLE-SCREEN.BMP", hWnd);



What do I need to do to make the window retain it's contents when it goes behind other windows?

If it helps, here's the whole code.

#include <windows.h>
#include <malloc.h>

int Dude_Tile_X = 3;
int Dude_Tile_Y = 5;

int Dude_Pos_X;
int Dude_Pos_Y;

int LoadFile(int XDest, int YDest, char *FileName, HWND hWnd);
int DudePosX(void);
int DudePosY(void);

int DudePosX(int dudex)
{
return (dudex * 32) + 16;
}

int DudePosY(int dudey)
{
return (dudey * 32) + 16;
}

int LoadFile(int XDest, int YDest, char *FileName, HWND hWnd)
{

static BITMAPFILEHEADER *pbmfh;
static BITMAPINFO *pbmi;
static BYTE *pBits;
static int cxDib, cyDib;

DWORD dwFileSize, dwHighSize, dwBytesRead;
HANDLE hFile;

char *NameOfFile;
NameOfFile = new char[50];
NameOfFile = FileName;

hFile = CreateFile (NameOfFile, GENERIC_READ,
FILE_SHARE_READ, NULL,
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL);

dwFileSize = GetFileSize (hFile, &dwHighSize);
pbmfh = (BITMAPFILEHEADER *) malloc (dwFileSize);
ReadFile (hFile, pbmfh, dwFileSize, &dwBytesRead, NULL);
pbmi = (BITMAPINFO *) (pbmfh + 1);
pBits = (BYTE *) pbmfh + pbmfh->bfOffBits;
cxDib = pbmi->bmiHeader.biWidth;
cyDib = abs(pbmi->bmiHeader.biHeight);
HDC hdc;
hdc = GetDC (hWnd);

SetDIBitsToDevice (hdc,
XDest,
YDest,
cxDib,
cyDib,
0,
0,
0,
cyDib,
pBits,
pbmi,
DIB_RGB_COLORS);
ReleaseDC (hWnd, hdc);
free (pbmfh);
return 0;
}

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow )
{
WNDCLASS WndClass;
WndClass.style = 0;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 1;
WndClass.lpfnWndProc = WndProc;
WndClass.hInstance = hInstance;
WndClass.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
WndClass.hCursor = LoadCursor (NULL, IDC_ARROW);
WndClass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
WndClass.lpszMenuName = 0;
WndClass.lpszClassName = "WinProg";

RegisterClass(&WndClass);
HWND hWindow;
hWindow = CreateWindow("WinProg","Window",
WS_OVERLAPPEDWINDOW,
0,0,647,433,NULL,NULL,
hInstance, NULL);

ShowWindow (hWindow, nCmdShow);
UpdateWindow (hWindow);
MSG Message;

while (GetMessage(&Message, NULL, 0, 0))
{
DispatchMessage(&Message);
}
return (Message.wParam);
}
LRESULT CALLBACK WndProc (HWND hWnd, UINT uiMessage,
WPARAM wParam,LPARAM lParam)
{
switch(uiMessage)
{
case WM_LBUTTONDOWN:
LoadFile(0, 0, "Graphics\\SCREEN-PURGE.BMP", hWnd);
LoadFile(0, 0, "Graphics\\TITLE-SCREEN.BMP", hWnd);
return 0;
break;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
PostQuitMessage( 0 );
return 0;
break;
case VK_NUMPAD4:
//LEFT

if(Dude_Tile_X != 0)
{
LoadFile((DudePosX(Dude_Tile_X)), (DudePosY(Dude_Tile_Y)), "Graphics\\Tiles\\Null.bmp", hWnd);
Dude_Tile_X = Dude_Tile_X - 1;
LoadFile((DudePosX(Dude_Tile_X)), (DudePosY(Dude_Tile_Y)), "Graphics\\Tiles\\Dude_Obj.bmp", hWnd);
}

return 0;
break;
case VK_NUMPAD6:
//RIGHT
if(Dude_Tile_X != 17)
{
LoadFile((DudePosX(Dude_Tile_X)), (DudePosY(Dude_Tile_Y)), "Graphics\\Tiles\\Null.bmp", hWnd);
Dude_Tile_X = Dude_Tile_X + 1;
LoadFile((DudePosX(Dude_Tile_X)), (DudePosY(Dude_Tile_Y)), "Graphics\\Tiles\\Dude_Obj.bmp", hWnd);
}
return 0;
break;
case VK_NUMPAD8:
//UP
if(Dude_Tile_Y != 0)
{
LoadFile((DudePosX(Dude_Tile_X)), (DudePosY(Dude_Tile_Y)), "Graphics\\Tiles\\Null.bmp", hWnd);
Dude_Tile_Y = Dude_Tile_Y - 1;
LoadFile((DudePosX(Dude_Tile_X)), (DudePosY(Dude_Tile_Y)), "Graphics\\Tiles\\Dude_Obj.bmp", hWnd);
}
return 0;
break;
case VK_NUMPAD2:
//DOWN
if(Dude_Tile_Y != 7)
{
LoadFile((DudePosX(Dude_Tile_X)), (DudePosY(Dude_Tile_Y)), "Graphics\\Tiles\\Null.bmp", hWnd);
Dude_Tile_Y = Dude_Tile_Y + 1;
LoadFile((DudePosX(Dude_Tile_X)), (DudePosY(Dude_Tile_Y)), "Graphics\\Tiles\\Dude_Obj.bmp", hWnd);
}
return 0;
break;
case VK_NUMPAD5:
//WAIT
LoadFile(0, 0, "Graphics\\SCREEN-PURGE.BMP", hWnd);
LoadFile(0, 0, "Graphics\\HUD-RESET.BMP", hWnd);
LoadFile((DudePosX(Dude_Tile_X)), (DudePosY(Dude_Tile_Y)), "Graphics\\Tiles\\Dude_Obj.bmp", hWnd);
return 0;
break;
default:
return 0;
break;
}
LoadFile((DudePosX(Dude_Tile_X)), (DudePosY(Dude_Tile_Y)), "Graphics\\Tiles\\Dude_Obj.bmp", hWnd);
return 0;
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
default:
return DefWindowProc (hWnd, uiMessage,
wParam, lParam);
}
}

Igor Vartanov
November 14th, 2009, 12:58 AM
Each time the window needs redrawing, the WM_PAINT message is sent to it. So you need to handle it and restore your current window state.

And this must bring in absolutely different logic. You must always modify a bitmap in memory dc but never in window dc directly. The window dc is updated from your memory dc on WM_PAINT.

Dispiacere
November 14th, 2009, 01:18 AM
So you're saying that I need to load the bitmaps into memory dc and WM_PAINT whenever the screen regains focus? I think I follow you, but I don't know much about using the tools of the trade. Is there any sample code out there that shows how to load a bitmap into a memory DC? I've done console programming for years but have only been using WinAPI for a few months. So much more complicated than simple cin/cout stuff.

Is what I'm doing is loading the bitmap directly into the window dc?

Snoopy07
November 14th, 2009, 06:46 AM
code snippet




case WM_PAINT:


Hdc=BeginPaint (hwnd,&ps);
hdcMem = CreateCompatibleDC (Hdc);

SelectObject(hdcMem, hBitmap);


BitBlt(Hdc,10,10,cxSource,cySource,hdcMem,0,0,SRCCOPY);


DeleteDC(hdcMem);
EndPaint (hwnd, &ps) ;

return 0;


Hope this helps

Igor Vartanov
November 14th, 2009, 01:10 PM
So you're saying that I need to load the bitmaps into memory dc and WM_PAINT whenever the screen regains focus?Well, not exactly. What I'm saying is: the logic of manipulations with the bitmaps should be adapted to the new requirement of being able always to restore window areas, and using memory dc is the technique you should learn an use.

I think I follow you, but I don't know much about using the tools of the trade. Is there any sample code out there that shows how to load a bitmap into a memory DC? Sure, see the attachment. The sample gives you a main idea: the image is stored all the time in the bitmap object (g_hbm) and painted to a window whenever it is needed involving memory dc.

Another idea related to the one above: to change the window image you apply the changes to the bitmap object (again by means of memory dc), but painting procedure remains intact.

I've done console programming for years but have only been using WinAPI for a few months. So much more complicated than simple cin/cout stuff.Basicly, yes. For the first glance. :)

Is what I'm doing is loading the bitmap directly into the window dc?Exactly. When you GetDC, make operations against it and ReleaseDC you operate directly with window dc.

Do you have Windows Platform SDK? Its Samples folder contains various sample programs you could read and dissect. But before doing this, you definitely need to read Charles Petzold's Programming Windows (http://www.amazon.com/Programming-Windows®-Fifth-Microsoft/dp/157231995X/ref=sr_1_1?ie=UTF8&s=books&qid=1258225525&sr=8-1) to catch the very basic principles of Windows.