[comp.windows.misc] Microsoft_Windows_is_SLOW

mcdonald@uxe.cso.uiuc.edu (09/23/88)

Well, I have finally delivered my little Microsoft Windows program to IBM.
Now I am thinking about converting my big one to it. Problem is,
I wrote the tiny test program listed below to see how slow it 
would be. Turns out to be about nine (9) times slower than my normal
graphics package. This thing just draws three balls on the screen,
and they go around in circles leaving tracks. It works fine except for
speed. I tried other methods of doing animation, but this seems to
be the only one that doesn't flicker badly; besides, my big program
needs a memory bitmap anyway as that is the only way to store the
screen for a repaint. Anyone out there know a way to speed this up?
(Besides trading my 16Mhz Model 80 for a 25Mhz model.)

 Doug McDonald (mcdonald@uiucuxe)


/* This is the BALLS.DEF file:
NAME     BALLS
DESCRIPTION 'Balls!'
STUB 'WINSTUB.EXE'
CODE MOVEABLE
DATA MOVEABLE MULTIPLE
HEAPSIZE 8192
STACKSIZE 8192
EXPORTS Microsoft_Windows_is_SLOW
*/
/* This batch file will create the program:
cl /c /Gsw /Zp /Os balls.c
link4 balls /noe,/al:16,,/nodef win87em slibcew slibw,balls.def;
*/


#include "windows.h"
#include <math.h>
#define PI (double)3.1415926

long FAR PASCAL Microsoft_Windows_is_SLOW(HWND, unsigned, WORD, LONG);
char            szAppName[] = "Balls";


int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
    HANDLE          hInstance, hPrevInstance;
    LPSTR           lpszCmdLine;
    int             nCmdShow;
{
HWND            hWnd;
MSG             msg;
WNDCLASS        wndclass;

    if (!hPrevInstance) {
	wndclass.style = CS_HREDRAW | CS_VREDRAW ;
	wndclass.lpfnWndProc = Microsoft_Windows_is_SLOW;
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.hInstance = hInstance;
	wndclass.hIcon = NULL;
	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
	wndclass.lpszMenuName = NULL;
	wndclass.lpszClassName = szAppName;

	if (!RegisterClass(&wndclass))
	    return (FALSE);

    }
    hWnd = CreateWindow(szAppName, "Balls!",
			WS_OVERLAPPEDWINDOW,
			CW_USEDEFAULT, 0,
			CW_USEDEFAULT, 0,
			NULL, NULL, hInstance, NULL);

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

    while (1) {
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
            if(msg.message == WM_QUIT)break;
   	    TranslateMessage(&msg);
	    DispatchMessage(&msg);
        } else DrawScreen(hWnd);
    }

    return msg.wParam;
}

static short xClient, yClient, xCenter, yCenter, xTotal, yTotal,
             xRadius, yRadius, xPixel, yPixel;
static int iturn, ifirst;
static int dx1, dy1, dx2, dy2, dx3, dy3;
static HBRUSH hBrush1, hBrush2, hBrush3, hBrush4;
static HPEN hPen1, hPen2, hPen3;
static HANDLE hBitmap;
static HDC hMemDC;

long far PASCAL Microsoft_Windows_is_SLOW(hWnd, iMessage, wParam, lParam)
    HWND            hWnd;
    unsigned        iMessage;
    WORD            wParam;
    LONG            lParam;
{

    HDC    hDC;
    short  nScale;
    PAINTSTRUCT ps;

    switch (iMessage) {
    case WM_CREATE:
        hDC = GetDC(hWnd);
        xPixel = GetDeviceCaps (hDC, ASPECTX);    
        yPixel = GetDeviceCaps (hDC, ASPECTY);
        hBrush1 = CreateSolidBrush(RGB(0,0,255)); 
        hPen1 = CreatePen(PS_SOLID, 1, RGB(0,0,255));
        hBrush2 = CreateSolidBrush(RGB(0,255,0));  
        hPen2 = CreatePen(PS_SOLID, 1, RGB(0,255,0));
        hBrush3 = CreateSolidBrush(RGB(255,0,0)); 
        hPen3 = CreatePen(PS_SOLID, 1, RGB(255,0,0));
        hBrush4 = CreateSolidBrush(RGB(0,0,0)); 
        ReleaseDC(hWnd, hDC);
        break;    
    case WM_SIZE:
        iturn = 0;
        ifirst = 0;
        xCenter = (xClient = LOWORD(lParam)) /2;
        yCenter = (yClient = HIWORD(lParam)) /2;
        nScale = min(xClient * xPixel, yClient * yPixel) /16;
        xRadius = nScale / xPixel;
        yRadius = nScale / yPixel;
        if(hBitmap != NULL)DeleteObject(hBitmap);
        if(hMemDC != NULL)DeleteDC(hMemDC);
        hDC = GetDC(hWnd);
        hBitmap = CreateCompatibleBitmap(hDC,xClient,yClient);
        hMemDC = CreateCompatibleDC(hDC);
        ReleaseDC(hWnd, hDC);
        SelectObject(hMemDC, hBitmap);
        SelectObject(hMemDC, hBrush4);
        SelectObject(hMemDC, GetStockObject(BLACK_PEN));
        Rectangle(hMemDC,0,0,xClient,yClient);
        break;
    case WM_PAINT:
        hDC = BeginPaint(hWnd,&ps);
        SelectObject(hDC, hBrush4);
        BitBlt(hDC,0,0,xClient,yClient,hMemDC,0,0,SRCCOPY);
        EndPaint(hWnd,&ps);
        break;
    case WM_DESTROY:
        DeleteObject(hBrush1);
        DeleteObject(hPen1);
        DeleteObject(hBrush2);
        DeleteObject(hPen2);
        DeleteObject(hBrush3);
        DeleteObject(hPen3);
        DeleteObject(hBrush4);
        if(hBitmap != NULL)DeleteObject(hBitmap);
        if(hMemDC != NULL)DeleteDC(hMemDC);
	PostQuitMessage(0);
	break;
    default:
	return DefWindowProc(hWnd, iMessage, wParam, lParam);
    }
    return 0L;
}

DrawScreen(hWnd)
HWND hWnd;
{
HDC   hDC;
        hDC = GetDC(hWnd);
        SelectObject(hMemDC, hBrush4);
        SelectObject(hMemDC, hPen1);
        SelectObject(hDC, hBrush4);
        if(ifirst)Ellipse(hMemDC, dx1 - xRadius, dy1 - yRadius, dx1 + xRadius ,
                      dy1 + yRadius);
        dx1 = xCenter + xRadius * 6 * cos((double)iturn * PI / 60);
        dy1 = yCenter + yRadius * 6 * sin((double)iturn * PI / 60);
        SelectObject(hMemDC, hBrush1);
        Ellipse(hMemDC, dx1 - xRadius, dy1 - yRadius, dx1 + xRadius ,
                      dy1 + yRadius);
        BitBlt(hDC,dx1 - xRadius * 2,dy1 - yRadius*2,xRadius*4,yRadius*4,
                  hMemDC,dx1 - xRadius * 2,dy1 - yRadius*2,SRCCOPY);
        SelectObject(hMemDC, hBrush4);
        SelectObject(hMemDC, hPen2);
        if(ifirst)Ellipse(hMemDC, dx2 - xRadius, dy2 - yRadius, dx2 + xRadius ,
                      dy2 + yRadius);
        dx2 = xCenter + xRadius * 6 * cos((double)(iturn + 40) * PI / 60);
        dy2 = yCenter + yRadius * 6 * sin((double)(iturn + 40) * PI / 60);
        SelectObject(hMemDC, hBrush2);
        Ellipse(hMemDC, dx2 - xRadius, dy2 - yRadius, dx2 + xRadius ,
                      dy2 + yRadius);
        BitBlt(hDC,dx2 - xRadius * 2,dy2 - yRadius*2,xRadius*4,yRadius*4,
                  hMemDC,dx2 - xRadius * 2,dy2 - yRadius*2,SRCCOPY);
        SelectObject(hMemDC, hBrush4);
        SelectObject(hMemDC, hPen3);
        if(ifirst)Ellipse(hMemDC, dx3 - xRadius, dy3 - yRadius, dx3 + xRadius ,
                      dy3 + yRadius);
        dx3 = xCenter + xRadius * 6 * cos((double)(iturn + 80) * PI / 60);
        dy3 = yCenter + yRadius * 6 * sin((double)(iturn + 80) * PI / 60);
        SelectObject(hMemDC, hBrush3);
        Ellipse(hMemDC, dx3 - xRadius, dy3 - yRadius, dx3 + xRadius ,
                      dy3 + yRadius);
        BitBlt(hDC,dx3 - xRadius * 2,dy3 - yRadius*2,xRadius*4,yRadius*4,
                  hMemDC,dx3 - xRadius * 2,dy3 - yRadius*2,SRCCOPY);
        ReleaseDC(hWnd,hDC);
        iturn += 1;
        ifirst = 1;
        if (iturn == 120) iturn = 0;
}