/* balltime.cpp Demonstrates animated drawing using a timer */
#include <windows.h>
#include "ball.h"
HWND hWnd ; /* the window's "handle" */
BOOL _bDrawOn = FALSE ; /* global to track if drawing is on or off */
int _nXSize, _nYSize ; /* window width and height */
int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
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","balltime--ball with a timer",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hWnd, nCmdShow) ; /* display the window */
UpdateWindow (hWnd) ;
SetTimer (hWnd, 1, 50, NULL) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hWnd, UINT wMessage,
WPARAM wParam, LPARAM lParam)
{
switch (wMessage) /* process windows messages */
{
case WM_CREATE: /* app starting, turn drawing on */
_bDrawOn = FALSE ;
break ;
case WM_SIZE : /* save window client area size */
_nXSize = LOWORD (lParam) ;
_nYSize = HIWORD (lParam) ;
break ;
case WM_COMMAND: /* menu items */
switch (LOWORD(wParam))
{
case IDM_SHOW:
if (_bDrawOn)
_bDrawOn = FALSE ; /* toggle drawing on/off */
else
_bDrawOn = TRUE ;
break ;
case IDM_QUIT:
DestroyWindow (hWnd) ;
break ;
}
break ;
case WM_TIMER: /* timeout--draw next frame */
if (_bDrawOn) DrawBall(hWnd);
break;
case WM_DESTROY:
KillTimer (hWnd, 1) ;
PostQuitMessage (0) ;
break ;
default:
return DefWindowProc (hWnd, wMessage, wParam, lParam) ;
}
return (0) ;
}
/* DrawBall() draws a red ball on the window hWnd every time the */
/* function is called. The ball is BALLRAD in radius. The walls */
/* (client area size) are from 0,0 to nXSize,nYsize. The location */
/* is moved each time by VELOCITY units. The signs of the X and Y */
/* velocity terms nVelX,nVelY are reversed each time the ball gets */
/* within MINRAD units of a wall. This causes the ball to appear */
/* to bounce off the wall. Drawing the ball at the new location */
/* causes the old ball to be erased, as the ball is drawn using a */
/* white pen for the outline that is 1.5 * VELOCITY in width. The */
/* white pen ends up painting over any portion of the ball that is */
/* otherwise visible from the previous location. */
void DrawBall (HWND hWnd)
{
HDC hDC ;
HPEN hPen, hOldPen ;
HBRUSH hBrush, hOldBrush ;
static int bX = 2*BALLRAD, bY = 2*BALLRAD, /* ball start X,Y */
bVelX = VELOCITY, bVelY = VELOCITY; /* X,Y velocity */
bX = bX + bVelX ; /* compute new center X,Y of ball */
bY = bY + bVelY ;
if (bY > _nYSize) /* check if user moved walls and hid ball */
bY = 2 * BALLRAD ; /* put the ball back at the starting.. */
if (bX > _nXSize) /* position if it is not going to be.. */
bX = 2 * BALLRAD ; /* visible with the new window size */
if (bY < MINRAD || _nYSize - bY < MINRAD) /* check if hit wall */
bVelY = -1 * bVelY ; /* if so, change direction */
if (bX < MINRAD || _nXSize - bX < MINRAD)
bVelX = -1 * bVelX ;
hDC = GetDC (hWnd) ; /* get the device context handle */
/* Create a thick white pen and a red brush */
hPen = CreatePen (PS_SOLID, VELOCITY+VELOCITY/2, RGB(255,255,255));
hBrush = CreateSolidBrush (RGB (255, 0, 0)) ;
hOldPen = (HPEN)SelectObject (hDC, hPen) ; /* select into the DC */
hOldBrush = (HBRUSH)SelectObject (hDC, hBrush) ;
/* draw the ball in the new location */
/* the outline pen deletes around ball */
Ellipse (hDC, bX-BALLRAD, bY-BALLRAD, bX+BALLRAD, bY+BALLRAD) ;
/* delete all objects and free DC */
SelectObject (hDC, hOldPen) ;
DeleteObject (hPen) ;
SelectObject (hDC, hOldBrush) ;
DeleteObject (hBrush) ;
ReleaseDC (hWnd, hDC) ;
}