GetMessage/PeekMessage

I have just started writing my first windows gdi game and running into a small problem.

Unfortunately i don't have the code with me. I'll post it as soon as i get a chance.

Basically i just created a new Win32 application in vc6.net and then i wrote a draw function that creates 3 dc's. One for the window, one that gets a 64x64 bitmap loaded into it and one i use for a backbuffer. Then i BitBlt the bitmap onto the backbuffer and then copy the backbuffer to the window dc.

For this to work i'm using PeekMessage instead of GetMessage so i don't have to invalidate the window to make it redraw... I think that is the reason that the window doesnt' draw when i use GetMessage anyway???

With PeekMessage being used i can move the bmp around the screen (by getting keypresses from the WM_KEYDOWN message) but after about 1 minute (maybe less) the game slows down quickly until everything in the window stops. Task manager says it is using between 0 and 5% of the processor so i'd presume that it isn't in an infinite loop. Hitting ESC does quit it after a while.

When i replace PeekMessage with GetMessage then i can move the guy with the keys for 5 mins (without actually seeing it happen) and then when i hit esc the drawings flash up and the bmp is where it should be and it quits straight away.

Here's the source...

[code]
// WinPlatformer.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "WinPlatformer.h"
#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
HWND hWnd;
HBRUSH hbrScreen;
RECT rScreen;
struct PLAYER Player, *pPlayer;
const int SCREENX=640,SCREENY=480;
int quit;

// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int draw();

int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
int elapsed,time;
Player.x = 0;
Player.y = 0;
Player.w = 64;
Player.h = 64;
Player.health = 0;
Player.speed = 10;
rScreen.left=rScreen.top=0;
rScreen.right=SCREENX;
rScreen.bottom=SCREENY;

// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_WINPLATFORMER, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);

// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}

hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WINPLATFORMER);
quit=0;

do
{
// Main message loop:
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) && !quit)
// while (GetMessage(&msg, NULL, 0, 0) && !quit)
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
//get the current time
time = GetTickCount();

//put stuff on the screen
draw();

//find out how long the frame took to draw
elapsed = GetTickCount()-time;

//if it was less than 1/60th of a second, wait.
//if we don't do this, our program will suck up 100% of the CPU!
if (elapsed < 15)
Sleep(15-elapsed);
}while(!quit);
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;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_WINPLATFORMER);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

return RegisterClassEx(&wcex);
}

//
// FUNCTION: InitInstance(HANDLE, 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)
{
hInst = hInstance; // Store instance handle in our global variable

hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, SCREENX, SCREENY, NULL, NULL, hInstance, NULL);

if (!hWnd)
{
return FALSE;
}

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

return TRUE;
}

//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// 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)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
quit=1;
break;
case WM_KEYDOWN:
switch (wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
quit=1;
break;
case VK_RIGHT:
Player.x+=Player.speed;
break;
case VK_LEFT:
Player.x-=Player.speed;
break;
case VK_UP:
Player.y-=Player.speed;
break;
case VK_DOWN:
Player.y+=Player.speed;
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

int draw()
{
HDC hScreen = GetDC(hWnd);
HDC hBackbuffer = CreateCompatibleDC(NULL);
HDC hPlayer = CreateCompatibleDC(NULL);
HBITMAP hbmBackbuffer = CreateCompatibleBitmap(hScreen,SCREENX,SCREENY);
BITMAP bmPlayer;
HBITMAP hbmPlayer=LoadBitmap(hInst,MAKEINTRESOURCE(IDB_BMPlayer));
HGDIOBJ hgdPlayer = SelectObject(hPlayer,hbmPlayer);
HGDIOBJ hgdBackbuffer = SelectObject(hBackbuffer,hbmBackbuffer);
GetObject(hbmPlayer,sizeof(bmPlayer),&bmPlayer);

FillRect(hBackbuffer,&rScreen,hbrScreen);
TextOut(hBackbuffer, 50, 50, "WinPlatformer", 13);
BitBlt(hBackbuffer,Player.x,Player.y,Player.w,Player.h,hPlayer,0,0,SRCAND);
BitBlt(hScreen,0,0,SCREENX,SCREENY,hBackbuffer,0,0,SRCCOPY);

ReleaseDC(hWnd,hBackbuffer);
ReleaseDC(hWnd,hScreen);
ReleaseDC(hWnd,hPlayer);
return 0;
}


[/code]





Comments

  • I posted a solution to your problem in the other forum. See there!
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

In this Discussion