/* ballblt.cpp Animated drawing with BitBlt()--preserving background */
#include <windows.h>
#include "ball.h" /* constants: VELOCITY, BALLRAD, MINRAD */
BOOL _bDrawOn = FALSE ; /* global to track if drawing is on or off */
int _nXSize, _nYSize ; /* window width and height */
HDC _hDC, _hMemDC; /* global screen and memory DC--used by drawball() & WndProc() */
int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
HWND hWnd ; /* the window's "handle" */
MSG msg ; /* a message structure */
WNDCLASS wndclass ; /* window class structure */
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = NULL;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = "MYMENU" ;
wndclass.lpszClassName = "MyClass" ;
if (!RegisterClass (&wndclass))
return 0 ;
hWnd = CreateWindow ("MyClass","Ballblt", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hWnd, nCmdShow) ;
UpdateWindow (hWnd) ;
while (TRUE) /* peek message loop */
{
if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT) /* if WM_QUIT, quit! */
return msg.wParam ;
else /* else, process message */
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
else if (_bDrawOn) /* no msg so paint ball..*/
DrawBall (hWnd) ; /* if drawing on */
}
}
LRESULT CALLBACK WndProc (HWND hWnd, UINT wMessage,
WPARAM wParam, LPARAM lParam)
{
static HBITMAP hBitmap, hBitmap1;
switch (wMessage) /* process windows messages */
{
case WM_CREATE: /* application starting, turn drawing off */
_bDrawOn = FALSE ;
break ;
case WM_SIZE : /* get window client area size */
_nXSize = LOWORD (lParam) ;
_nYSize = HIWORD (lParam) ;
break ;
case WM_COMMAND: /* menu items selected */
switch (LOWORD(wParam))
{
case IDM_SHOW:
if (_bDrawOn)
{
_bDrawOn = FALSE ; /* toggle drawing off */
DeleteDC(_hMemDC); /* get rid of DCs and bitmaps */
ReleaseDC(hWnd, _hDC);
DeleteObject(hBitmap);
DeleteObject(hBitmap1);
}
else
{
_bDrawOn = TRUE ; /* toggle drawing on */
/* set up DC, mem DC, and bitmaps for each */
_hDC=GetDC(hWnd);
_hMemDC=CreateCompatibleDC(_hDC);
hBitmap=CreateCompatibleBitmap(_hDC,_nXSize,_nYSize);
hBitmap1=CreateCompatibleBitmap(_hDC,_nXSize,_nYSize);
SelectObject(_hMemDC,hBitmap);
SelectObject(_hDC,hBitmap1);
}
break ;
case IDM_QUIT:
DestroyWindow (hWnd) ;
break ;
}
break ;
case WM_DESTROY:
if (_bDrawOn == TRUE)
{
DeleteDC(_hMemDC); /* get rid of DCs & bitmaps */
ReleaseDC(hWnd,_hDC);
DeleteObject(hBitmap);
DeleteObject(hBitmap1);
}
PostQuitMessage (0) ;
break ;
default:
return DefWindowProc (hWnd, wMessage, wParam, lParam) ;
}
return (0) ;
}
/* DrawBall() draws a red ball and a blue crosshatched background */
/* on an offscreen bitmap and BitBlts the bitmap to the screen */
/* each time the function is called. The ball is BALLRAD in radius. */
/* Motion is as in the ball.cpp program */
void DrawBall (HWND hWnd)
{
HBRUSH hBrush ;
static int nX = 2 * BALLRAD, nY = 2 * BALLRAD, /* starting X,Y */
nVelX = VELOCITY, nVelY = VELOCITY; /* X,Y velocity */
nX = nX + nVelX ; /* compute new center X,Y of ball */
nY = nY + nVelY ;
if (nY > _nYSize) /* check if user moved walls and hid ball */
nY = 2 * BALLRAD ; /* put ball back at the starting.. */
if (nX > _nXSize) /* position if it is not going to be..*/
nX = 2 * BALLRAD ; /* visible with the new window size */
if (nY < MINRAD || nY > _nYSize - MINRAD) /* check if ball hit wall*/
nVelY = -1 * nVelY ; /* if so, change direction */
if (nX < MINRAD || nX > _nXSize - MINRAD)
nVelX = -1 * nVelX ;
/* Create blue hatched brush for background */
hBrush = CreateHatchBrush (HS_DIAGCROSS, RGB (0, 0, 255)) ;
SelectObject (_hMemDC, hBrush) ; /* select into memory DC */
/* Tile brush across the offscreen bitmap */
PatBlt(_hMemDC, 0, 0, _nXSize, _nYSize, PATCOPY);
/* Delete the brush */
SelectObject(_hMemDC, GetStockObject(WHITE_BRUSH));
DeleteObject(hBrush);
hBrush = CreateSolidBrush(RGB(255,0,0)); /* red brush for ball */
SelectObject(_hMemDC, hBrush);
/* draw ball in new location on off-screen bitmap */
Ellipse (_hMemDC, nX-BALLRAD, nY-BALLRAD, nX+BALLRAD, nY+BALLRAD) ;
/* BitBlt to screen--note only one access to screen */
BitBlt(_hDC, 0, 0, _nXSize, _nYSize, _hMemDC, 0, 0, SRCCOPY);
/* Slow things down a bit */
Sleep(10) ;
/* delete objects */
SelectObject (_hMemDC, GetStockObject(WHITE_BRUSH)) ;
DeleteObject (hBrush) ;
}