/* worm.c copyright 1989, Sarmad Adnan, adnan@rice.edu copyright 1990, Sarmad Adnan, adnan@rice.edu */ #include #include #include "worm.h" HANDLE hInst; HDC screen; POINT segm[MAXSEG]; short head= -1, tail=MAXSEG; RECT wormcage; int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HWND hWnd; MSG msg; if(hPrevInstance) { MessageBox(NULL, "worm: your screen is already wormed", "Error", MB_OK); return(NULL); } if(!WormInit(hInstance)) { MessageBox(NULL, "Worm: class registration failed", "Error", MB_OK); return(NULL); } hInst = hInstance; hWnd = CreateWindow( WORM_APPNAME, WORM_TITLE, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL, hInstance, NULL ); if(!hWnd) { MessageBox(NULL, "worm: could not create window", "Error", MB_OK); return (NULL); } if(!GetScreenSize()) { MessageBox(hWnd, "worm: could not obtain screen handle", "Error", MB_OK); return(NULL); } if(!SetTimer(hWnd, NULL, 200, NULL) ) { MessageBox(hWnd, "worm: no timers available", "Error", MB_OK); return(NULL); } ShowWindow(hWnd, SW_MINIMIZE); UpdateWindow(hWnd); while( GetMessage( &msg, NULL, NULL, NULL) ) { TranslateMessage(&msg); DispatchMessage(&msg); } return(msg.wParam); } BOOL WormInit(HANDLE hInstance) { HANDLE hMemory; PWNDCLASS pWndClass; BOOL bSuccess; hMemory = LocalAlloc(LPTR, sizeof(WNDCLASS)); pWndClass = (PWNDCLASS) LocalLock(hMemory); pWndClass->style = NULL; pWndClass->lpfnWndProc = WormWndProc; pWndClass->hInstance = hInstance; pWndClass->hIcon = LoadIcon(hInstance, "worm"); pWndClass->hCursor = LoadCursor(NULL, IDC_CROSS); pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH); pWndClass->lpszMenuName = (LPSTR) NULL; pWndClass->lpszClassName = (LPSTR) WORM_APPNAME; bSuccess = RegisterClass(pWndClass); LocalUnlock(hMemory); LocalFree(hMemory); return(bSuccess); } long FAR PASCAL WormWndProc(HWND hWnd, unsigned message, WORD wParam, LONG lParam) { FARPROC lpProcAbout; HMENU hMenu; switch(message) { case WM_TIMER: WormUpdate(hWnd); break; case WM_SIZE: InvalidateRect(hWnd, NULL, TRUE); break; case WM_SYSCOMMAND: if(wParam == ID_ABOUT) { lpProcAbout = MakeProcInstance(About, hInst); DialogBox(hInst, "AboutBox", hWnd, lpProcAbout); FreeProcInstance(lpProcAbout); break; } else return(DefWindowProc(hWnd, message, wParam, lParam)); case WM_CREATE: hMenu = GetSystemMenu(hWnd, FALSE); ChangeMenu(hMenu, NULL, NULL, NULL, MF_APPEND | MF_SEPARATOR); ChangeMenu(hMenu, NULL, "A&bout Worm...", ID_ABOUT, MF_APPEND | MF_STRING); break; case WM_QUERYOPEN: return 0L; case WM_DESTROY: KillTimer(hWnd, NULL); DeleteDC(screen); PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, message, wParam, lParam)); } return(NULL); } BOOL FAR PASCAL About(HWND hDlg, unsigned message, WORD wParam, LONG lParam) { switch(message) { case WM_INITDIALOG: return (TRUE); case WM_COMMAND: if (wParam == IDOK) { EndDialog(hDlg, NULL); return (TRUE); } break; } return(FALSE); } void WormUpdate(HWND hWnd) { HDC hDc; static double dir=0.0; POINT prev; if(rand()<16384) dir+=INCREMENT; else dir-=INCREMENT; prev.x=segm[head].x; prev.y=segm[head].y; head--, tail--; if(head<0) head=MAXSEG-1; if(tail<0) tail=MAXSEG-1; Ellipse(screen, segm[head].x-SIZE, segm[head].y-SIZE, segm[head].x+SIZE, segm[head].y+SIZE); segm[head].x=prev.x+(int)(STEPSIZE*cos(dir)); segm[head].y=prev.y+(int)(STEPSIZE*sin(dir)); if(segm[head].xwormcage.right) segm[head].x=wormcage.left; if(segm[head].ywormcage.bottom) segm[head].y=wormcage.top; Ellipse(screen, segm[head].x-SIZE, segm[head].y-SIZE, segm[head].x+SIZE, segm[head].y+SIZE); } BOOL GetScreenSize() { POINT extent; DWORD test; int count; screen=CreateDC("DISPLAY", NULL, NULL, NULL); if(!screen) return(FALSE); wormcage.right=GetDeviceCaps(screen, HORZRES); wormcage.bottom=GetDeviceCaps(screen, VERTRES); wormcage.top=0; wormcage.left=0; for(count=0; count