From: Paul N on
I was hoping to write a game in Windows, and as a first step I have
typed in the "bouncing ball" program from Petzold. But I'm not very
happy with it - while it shows a ball bouncing round the window, the
ball itself is very blurry at the edges. Whereas, if I manually move
the mouse cursor along side it at the same speed, the arrow looks rock
solid. Am I doing something wrong?

The WndProc is as follows:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc, hMemdc;

static HANDLE hBitmap;
static short xClient, yClient, xCentre, yCentre, xTotal, yTotal,
xRadius, yRadius, xMove, yMove, xPixel, yPixel;
HBRUSH hBrush;
short nScale;

switch (message)
{
case WM_CREATE:
hdc = GetDC(hWnd);
xPixel = GetDeviceCaps(hdc, ASPECTX);
yPixel = GetDeviceCaps(hdc, ASPECTY);
ReleaseDC(hWnd, hdc);
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_SIZE:
xCentre = (xClient = LOWORD(lParam)) / 2;
yCentre = (yClient = HIWORD(lParam)) / 2;

nScale = min(xClient * xPixel, yClient * yPixel) / 16;

xRadius = nScale / xPixel;
yRadius = nScale / yPixel;

xMove = max(1, xRadius/4);
yMove = max(1, yRadius/4);

xTotal = 2 * (xRadius + xMove);
yTotal = 2 * (yRadius + yMove);

if (hBitmap) DeleteObject (hBitmap);

hdc = GetDC(hWnd);
hMemdc = CreateCompatibleDC(hdc);
hBitmap = CreateCompatibleBitmap(hdc, xTotal, yTotal);
ReleaseDC(hWnd, hdc);

SelectObject(hMemdc, hBitmap);
Rectangle(hMemdc, -1, -1, xTotal+1, yTotal+1);

hBrush = CreateHatchBrush (HS_DIAGCROSS, 0L);
SelectObject(hMemdc, hBrush);
SetBkColor(hMemdc, RGB(255, 0, 255));
Ellipse(hMemdc, xMove, yMove, xTotal - xMove, yTotal-yMove);

DeleteDC(hMemdc);
DeleteObject (hBrush);
break;
case WM_TIMER:
if (!hBitmap) break;

hdc = GetDC(hWnd);
hMemdc = CreateCompatibleDC(hdc);
SelectObject(hMemdc, hBitmap);

BitBlt(hdc, xCentre - xTotal/2, yCentre - yTotal/2, xTotal, yTotal,
hMemdc, 0, 0, SRCCOPY);

ReleaseDC(hWnd, hdc);
DeleteDC(hMemdc);

xCentre += xMove;
yCentre += yMove;

if ((xCentre + xRadius >= xClient) || xCentre - xRadius <= 0) xMove
= -xMove;
if ((yCentre + yRadius >= yClient) || yCentre - yRadius <= 0) yMove
= -yMove;
break;






case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
if (hBitmap) DeleteObject (hBitmap);
KillTimer(hWnd, 1);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

and the timer is set up to trigger every 50ms (presumably actually
once every clock tick).

Thanks for any help.
Paul.