#include #include #include #include #include "polybez.h" /* * Include the LSAPI header file. */ #include "lsapi.h" // global variables HANDLE hInst; // Instance handle static HCURSOR hHourGlass = NULL; // handle for hourglass cursor char szAppIcon[] = APPICON; // icon name char szAppName[] = APPNAME; // application name char szAppTitle[] = APPTITLE; // application title char szAppLicName[] = APPLICNAME; char szAppProducer [] = APPPRODUCER; char szAppVersion [] = APPVERSION; char szAppLicErrMsg [] = APPLICERRMSG; char szAppNoLicense [] = APPNOLICENSE; char szAppNoLicRelease [] = APPNOLICRELEASE; time_t tAppRelease; BOOL grantHeld = FALSE; // permits redundant CloseApp calls LS_HANDLE hLicense; // bounce grant handle LS_CHALLENGE hChallenge; // challenge handle // function prototypes //int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance, LPSTR lppszCmdLine, int nCmdShow); void InitApp (HANDLE hInstance, HANDLE hPrevInstance, int nCmdShow); void InitAppFirst (HANDLE hInstance); void InitAppEvery (HANDLE hInstance, int nCmdShow); BOOL OpenApp (HANDLE hInstance); void CloseApp (HANDLE hInstance); /* ** WINDOW ROUTINES (wininfo.c) */ BOOL FAR AllocWindowInfo(HWND,WORD); PVOID FAR LockWindowInfo(HWND); BOOL FAR UnlockWindowInfo(HWND); BOOL FAR FreeWindowInfo(HWND); DWORD FAR lRandom(VOID) { static DWORD glSeed = (DWORD)-365387184; glSeed *= 69069; return(++glSeed); } /********************************************************************* * Main Window Procedure ********************************************************************* */ int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lppszCmdLine, int nCmdShow) { MSG msg; if (!OpenApp (hInstance)) // closing routine return (FALSE); InitApp (hInstance, hPrevInstance, nCmdShow); while (GetMessage (&msg, NULL, 0, 0)) // main loop { // terminated by quit message TranslateMessage (&msg); // translate virtual keys DispatchMessage (&msg); // send message to window proc } CloseApp (hInstance); // closing routine return (msg.wParam); // exit & return } /********************************************************************* * OpenApp - open application ********************************************************************* */ BOOL OpenApp (HANDLE hInstance) { char szCaption [255]; char szText [255]; HCURSOR hCursor = NULL; LS_STATUS_CODE ulGrantStatus = LS_SUCCESS, messageStatus = LS_SUCCESS; unsigned long unitsGranted = 0; LS_STR errorText[255]; /* load hourglass cursor, save current cursor, display the hour glass */ hHourGlass = LoadCursor (NULL, IDC_WAIT); hCursor = SetCursor (hHourGlass); ShowCursor (TRUE); /* Try to obtain a license */ ulGrantStatus = LSRequest( (LS_STR FAR *) LS_ANY, (LS_STR FAR *) szAppProducer, (LS_STR FAR *) szAppLicName, (LS_STR FAR *) szAppVersion, (LS_ULONG) LS_DEFAULT_UNITS, (LS_STR FAR *) "Making a request", &hChallenge, &unitsGranted, &hLicense); /* display the cursor */ ShowCursor (FALSE); SetCursor (hCursor); ShowCursor (TRUE); /* if no license, display an error message */ if ( LS_SUCCESS != ulGrantStatus ) { lstrcpy( szCaption, szAppName ); lstrcat( szCaption, szAppLicErrMsg ); lstrcpy( szText, szAppNoLicense ); lstrcat( szText, "\n" ); messageStatus = LSGetMessage( hLicense, ulGrantStatus, errorText, 255 ); if ( LS_SUCCESS != messageStatus ) lstrcat( szText, "LSGetMessage Failed!" ); else lstrcat( szText, (char FAR *) errorText ); MessageBox( NULL, szText, szCaption, MB_ICONEXCLAMATION | MB_OK ); LSFreeHandle( hLicense ); return( FALSE ); } /* successfully obtained a license */ grantHeld = TRUE; return (TRUE); } /********************************************************************* * InitApp - program initialization ********************************************************************* */ void InitApp (HANDLE hInstance, HANDLE hPrevInstance, int nCmdShow) { if (!hPrevInstance) InitAppFirst (hInstance); // first instance only InitAppEvery (hInstance, nCmdShow); // every instance } /********************************************************************* * InitAppFirst - first instance initialization ********************************************************************* */ void InitAppFirst (HANDLE hInstance) { WNDCLASS wcApp; // setup application window class structure wcApp.style = CS_HREDRAW | CS_VREDRAW; wcApp.lpfnWndProc = PolyProc; wcApp.cbClsExtra = 0; wcApp.cbWndExtra = 0; wcApp.hInstance = hInstance; wcApp.hIcon = LoadIcon (hInstance, szAppIcon); wcApp.hCursor = LoadCursor (NULL, IDC_ARROW); wcApp.hbrBackground = GetStockObject (BLACK_BRUSH); wcApp.lpszMenuName = NULL; wcApp.lpszClassName = szAppName; RegisterClass (&wcApp); // register the window class } /********************************************************************* * InitAppEvery - every instance initialization ********************************************************************* */ void InitAppEvery (HANDLE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // save instance handle hWnd = CreateWindow (szAppName, // window class szAppTitle, // window caption WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // initial x pos CW_USEDEFAULT, // initial y pos CW_USEDEFAULT, // initial x size CW_USEDEFAULT, // initial y size NULL, // parent window NULL, // window menu handle hInstance, // program instance handle NULL); // creation parameters if (!SetTimer (hWnd, 1, 50, NULL)) { MessageBox (hWnd, "Too Many clocks or timers!", szAppName, MB_ICONEXCLAMATION | MB_OK); } ShowWindow (hWnd, nCmdShow); UpdateWindow (hWnd); } /********************************************************************* * CloseApp - close application ********************************************************************* */ void CloseApp (HANDLE hInstance) { HCURSOR hCursor = NULL; char errorText[50]; LS_STATUS_CODE ulGrantStatus = LS_SUCCESS, messageStatus = LS_SUCCESS; char szCaption [255]; char szText [255]; /* return if grant already released */ if ( FALSE == grantHeld ) return; /* display the hour glass */ hCursor = SetCursor (hHourGlass); ShowCursor (TRUE); /* release the grant */ ulGrantStatus = LSRelease( hLicense, LS_DEFAULT_UNITS, (LS_STR FAR *) "Making a release"); LSFreeHandle( hLicense ); /* display the cursor */ ShowCursor (FALSE); SetCursor (hCursor); ShowCursor (TRUE); /* check the return status from the LSRelease call */ if ( LS_SUCCESS != ulGrantStatus ) { lstrcpy( szCaption, szAppName ); lstrcat( szCaption, szAppLicErrMsg ); lstrcpy( szText, szAppNoLicense ); lstrcat( szText, "\n" ); messageStatus = LSGetMessage( hLicense, ulGrantStatus, errorText, 50 ); if ( LS_SUCCESS != messageStatus ) lstrcat( szText, "LSGetMessage Failed!" ); else lstrcat( szText, (char FAR *) errorText ); MessageBox( NULL, szText, szCaption, MB_ICONEXCLAMATION | MB_OK ); } grantHeld = FALSE; /* added with licensing, because app wouldn't terminate */ PostQuitMessage(0); } /*---------------------------------------------------------------------------*\ | CREATE BEZIER WINDOW PROCEDURE | Create the bezier MDI-child window. \*---------------------------------------------------------------------------*/ HWND FAR CreatePolyWindow(HWND hWndClient, int nItem) { HANDLE hInstance; MDICREATESTRUCT mcs; // hInstance = GETINSTANCE(hWndClient); /* ** Initialize the MDI create struct for creation of the ** test window. */ mcs.szClass = POLYCLASS; mcs.szTitle = POLYTITLE; // mcs.hOwner = hInstance; mcs.hOwner = hWndClient; mcs.x = CW_USEDEFAULT; mcs.y = CW_USEDEFAULT; mcs.cx = CW_USEDEFAULT; mcs.cy = CW_USEDEFAULT; mcs.style = 0l; mcs.lParam = (LONG)nItem; return((HWND)SendMessage(hWndClient,WM_MDICREATE,0,(LONG)(LPMDICREATESTRUCT)&mcs)); } /*---------------------------------------------------------------------------*\ | POLYBEZIER WINDOW PROCEDURE | This is the main window function for the polybezier demo window. \*---------------------------------------------------------------------------*/ LONG APIENTRY PolyProc(HWND hWnd, UINT wMsg, WPARAM wParam, LONG lParam) { switch(wMsg) { case WM_CREATE: PolyCreateProc(hWnd); break; case WM_COMMAND: PolyCommandProc(hWnd,wParam,lParam); break; case WM_MOVE: PolyRedraw(hWnd); break; case WM_TIMER: PolyDrawBez(hWnd); break; case WM_PAINT: PolyPaintProc(hWnd); break; case WM_QUERYENDSESSION: return (1L); case WM_CLOSE: CloseApp (hInst); break; case WM_ENDSESSION: if (0 != wParam) CloseApp (hInst); break; case WM_DESTROY: PolyDestroyProc(hWnd); break; default: return(DefWindowProc(hWnd,wMsg,wParam,lParam)); } return(0l); } /*---------------------------------------------------------------------------*\ | POLYBEZIER CREATE PROCEDURE | Create the polybezier window for the demo application. This is a child | of the MDI client window. Allocate the extra object information for | handling of the polybezier demo. \*---------------------------------------------------------------------------*/ BOOL PolyCreateProc(HWND hWnd) { PPOLYDATA ppd; if(AllocWindowInfo(hWnd,sizeof(POLYDATA))) { if(ppd = (PPOLYDATA)LockWindowInfo(hWnd)) { ppd->nBezTotal = 20; ppd->nBezCurr = 0; ppd->nColor = 0; ppd->hBezBuffer = GlobalAlloc(GHND,(DWORD)(sizeof(BEZBUFFER) * MAX_BEZIER)); UnlockWindowInfo(hWnd); PolyInitPoints(hWnd); SetTimer(hWnd,1,50,NULL); return(TRUE); } FreeWindowInfo(hWnd); } return(FALSE); } /*---------------------------------------------------------------------------*\ | POLYBEZIER COMMAND PROCEDURE | Process polybezier commands. This is a NOP for now. But who knows what | tomorrow may bring. \*---------------------------------------------------------------------------*/ BOOL PolyCommandProc(HWND hWnd, WPARAM wParam, LONG lParam) { hWnd = hWnd; wParam = wParam; lParam = lParam; return(TRUE); } /*---------------------------------------------------------------------------*\ | POLYBEZIER PAINT PROCEDURE | Repaint the bezier window. All we really do here is validate our window, | and reset the array of bezier objects. \*---------------------------------------------------------------------------*/ VOID PolyPaintProc(HWND hWnd) { HDC hDC; PAINTSTRUCT ps; if(hDC = BeginPaint(hWnd,&ps)) EndPaint(hWnd,&ps); PolyRedraw(hWnd); return; } /*---------------------------------------------------------------------------*\ | POLYBEZIER DESTROY PROCEDURE | Kill the polybezier demo. Free up the resources allocated on behalf of | this object. \*---------------------------------------------------------------------------*/ VOID PolyDestroyProc(HWND hWnd) { PPOLYDATA ppd; KillTimer(hWnd,1); if(ppd = (PPOLYDATA)LockWindowInfo(hWnd)) { GlobalFree(ppd->hBezBuffer); UnlockWindowInfo(hWnd); } FreeWindowInfo(hWnd); /* added with licensing, because app wouldn't terminate */ PostQuitMessage(0); return; } /*---------------------------------------------------------------------------*\ | GET NEW VELOCITY | This routine creates a new velocity for the bezier points. Each bezier | point is randomly chosen. The two inside points should have a speed | less then the endpoints (most of the time-better effect). \*---------------------------------------------------------------------------*/ int PolyNewVel(int i) { int nRet; if ((i == 1) || (i == 2)) nRet = (int)((lRandom() % VELMAX) / 3) + VELMIN; else nRet = (int)(lRandom() % VELMAX) + VELMIN; return((nRet < 0) ? -nRet : nRet); } /*---------------------------------------------------------------------------*\ | INITIALIZE POLYBEZIER POINTS | This routine initializes the polybezier points for the first object. This | is performed on startup of the window. \*---------------------------------------------------------------------------*/ VOID PolyInitPoints(HWND hWnd) { PPOLYDATA ppd; LPBEZBUFFER lpBez; int idx; RECT rect; if(ppd = (PPOLYDATA)LockWindowInfo(hWnd)) { if(lpBez = (LPBEZBUFFER)GlobalLock(ppd->hBezBuffer)) { GetClientRect(hWnd,&rect); for(idx=0; idx < BEZ_PTS-1; idx++) { lpBez->pPts[idx].x = lRandom() % rect.right; lpBez->pPts[idx].y = lRandom() % rect.bottom; ppd->pVel[idx].x = PolyNewVel(idx); ppd->pVel[idx].y = PolyNewVel(idx); } GlobalUnlock(ppd->hBezBuffer); } UnlockWindowInfo(hWnd); } return; } /*---------------------------------------------------------------------------*\ | POLYBEZIER REDRAW | This routine resets the bezier curves and redraws the poly-bezier client | area. \*---------------------------------------------------------------------------*/ VOID PolyRedraw(HWND hWnd) { PPOLYDATA ppd; LPBEZBUFFER lpBez,lpCurr; HDC hDC; int i,j; RECT rect; if(ppd = (PPOLYDATA)LockWindowInfo(hWnd)) { if(lpBez = (LPBEZBUFFER)GlobalLock(ppd->hBezBuffer)) { if(hDC = GetDC(hWnd)) { /* ** Save the current bezier. Set the first bezier in the ** array to that curve, and use it as a basis for the next ** series. */ lpCurr = lpBez+ppd->nBezCurr; *lpBez = *lpCurr; ppd->nBezCurr = 0; /* ** Clean the curves (all but the first curve). */ for(j=1; j < ppd->nBezTotal; j++) { for(i=0; i < BEZ_PTS; i++) { (lpBez+j)->pPts[i].x = -1; (lpBez+j)->pPts[i].y = 0; } } /* ** Clear the display. */ GetClientRect(hWnd,&rect); BitBlt(hDC,0,0,rect.right, rect.bottom,(HDC)0,0,0,0); /* ** Draw the first curve in the bezier array. */ #if defined(_WIN32) && defined(WIN32) PolyBezier(hDC,lpBez->pPts,BEZ_PTS); #else Polyline(hDC,lpBez->pPts,BEZ_PTS); #endif ReleaseDC(hWnd,hDC); } GlobalUnlock(ppd->hBezBuffer); } UnlockWindowInfo(hWnd); } return; } VOID PolyDrawBez(HWND hWnd) { PPOLYDATA ppd; LPBEZBUFFER lpBez,lpCurr,lpPrev; int idx,x,y; RECT rect; HDC hDC; HPEN hPen; static COLORREF crColor[] = {0x000000FF,0x0000FF00,0x00FF0000,0x0000FFFF, 0x00FF00FF,0x00FFFF00,0x00FFFFFF,0x00000080, 0x00008000,0x00800000,0x00008080,0x00800080, 0x00808000,0x00808080,0x000000FF,0x0000FF00, 0x00FF0000,0x0000FFFF,0x00FF00FF,0x00FFFF00}; if(ppd = (PPOLYDATA)LockWindowInfo(hWnd)) { if(lpBez = (LPBEZBUFFER)GlobalLock(ppd->hBezBuffer)) { if(hDC = GetDC(hWnd)) { GetClientRect(hWnd,&rect); lpPrev = lpBez+ppd->nBezCurr; ppd->nBezCurr += 1; if(ppd->nBezCurr >= ppd->nBezTotal) { ppd->nBezCurr = 0; ppd->nColor = (++ppd->nColor % 20); } lpCurr = lpBez+ppd->nBezCurr; if(lpCurr->pPts[0].x != -1) { hPen = SelectObject(hDC,GetStockObject(BLACK_PEN)); #if defined(_WIN32) && defined(WIN32) PolyBezier(hDC,lpCurr->pPts,BEZ_PTS); #else Polyline(hDC,lpCurr->pPts,BEZ_PTS); #endif SelectObject(hDC,hPen); } for(idx=0; idx < BEZ_PTS; idx++) { x = lpPrev->pPts[idx].x; y = lpPrev->pPts[idx].y; x += ppd->pVel[idx].x; y += ppd->pVel[idx].y; if(x >= rect.right) { x = rect.right - ((x - rect.right)+1); ppd->pVel[idx].x = -PolyNewVel(idx); } if(x <= rect.left) { x = rect.left + ((rect.left - x)+1); ppd->pVel[idx].x = PolyNewVel(idx); } if(y >= rect.bottom) { y = rect.bottom - ((y - rect.bottom)+1); ppd->pVel[idx].y = -PolyNewVel(idx); } if(y <= rect.top) { y = rect.top + ((rect.top - y)+1); ppd->pVel[idx].y = PolyNewVel(idx); } lpCurr->pPts[idx].x = x; lpCurr->pPts[idx].y = y; } hPen = SelectObject(hDC,CreatePen(PS_SOLID,1,crColor[ppd->nColor])); #if defined(_WIN32) && defined(WIN32) PolyBezier(hDC,lpCurr->pPts,BEZ_PTS); #else Polyline(hDC,lpCurr->pPts,BEZ_PTS); #endif DeleteObject(SelectObject(hDC,hPen)); #if defined(_WIN32) && defined(WIN32) SetROP2(hDC,R2_COPYPEN); #endif ReleaseDC(hWnd,hDC); } GlobalUnlock(ppd->hBezBuffer); } UnlockWindowInfo(hWnd); } }