home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bc45 / gdidemo.pak / LINE.CPP < prev    next >
C/C++ Source or Header  |  1997-07-23  |  6KB  |  172 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1991, 1993 by Borland International
  3. //   MoveToLineTo demo window
  4. //----------------------------------------------------------------------------
  5. #include <owl\owlpch.h>
  6. #include <owl\dc.h>
  7. #include "line.h"
  8. #include <math.h>
  9.  
  10. DEFINE_RESPONSE_TABLE1(TMoveToLineToWindow, TBaseDemoWindow)
  11.   EV_WM_SIZE,
  12. END_RESPONSE_TABLE;
  13.  
  14. IMPLEMENT_CASTABLE1(TMoveToLineToWindow, TBaseDemoWindow);
  15.  
  16. TMoveToLineToWindow::TMoveToLineToWindow() : TBaseDemoWindow()
  17. {
  18.   Rotation = 0;
  19.   PointCount = MaxPoints;
  20.   Iconized = FALSE;
  21.   RotatePoints();
  22. }
  23.  
  24. void
  25. TMoveToLineToWindow::EvSize(UINT sizeType, TSize& size)
  26. {
  27.   TBaseDemoWindow::EvSize(sizeType, size);
  28.   Invalidate();
  29.  
  30.   if (sizeType == SIZE_MINIMIZED) {
  31.     if (!Iconized) {
  32.       Rotation = 0;
  33.       Iconized = TRUE;
  34.       PointCount = IconicPoints;
  35.       RotatePoints();
  36.     }
  37.  
  38.   } else {
  39.     if (Iconized) {
  40.       Rotation = 0;
  41.       Iconized = FALSE;
  42.       PointCount = MaxPoints;
  43.       RotatePoints();
  44.     }
  45.   }
  46. }
  47.  
  48. void
  49. TMoveToLineToWindow::TimerTick()
  50. {
  51.   RotatePoints();
  52.   if (Iconized) {
  53.     // Iconized windows don't process paint messages, so we'll manually
  54.     // update the image here.  Doing this painting during the timer tick
  55.     // will slow things down a bit, especially with several of these
  56.     // windows iconized at the same time.
  57.     //
  58.     Paint(TClientDC(*Parent), FALSE, TRect());
  59.  
  60.   } else {
  61.     // In terms of Windows resources and system wide performance, letting
  62.     // paint do the work is 'faster' because it reduces the CPU time spent
  63.     // handling each timer tick.  Paint messages are low priority, so other
  64.     // messages like mouse clicks and other user input get processed first.
  65.     // The downside is that the paint messages are handled last, when
  66.     // there's nothing else to do, which can make animation look a bit jerky
  67.     // on a busy machine.
  68.     //
  69.     Invalidate(FALSE);    // Let the Paint method draw the new figure...
  70.   }
  71. }
  72.  
  73. void
  74. TMoveToLineToWindow::RotatePoints()
  75. {
  76.   // NOTE: all figures are in radians
  77.   const float M_2PI = 2 * M_PI;           // 2 pi radians in a circle
  78.   float StepAngle = M_2PI / PointCount;   // angular distance between points
  79.  
  80.   Rotation += M_PI / 32;   // Increment the angle of rotation of figure
  81.   if (Rotation > StepAngle)
  82.     Rotation -= StepAngle;   // Keep rotation less than distance between points
  83.  
  84.   // The loop below has i walking through the Points array, while j walks
  85.   // simultaneously through the angles to each point on the circle.  
  86.   // Incrementing j by StepAngle moves j to the next point on the circle with
  87.   // no complicated arithmetic (everything has been set up in advance of the
  88.   // loop).  Initializing j with Rotation causes the entire figure to shift
  89.   // clockwise a small amount.
  90.  
  91.   int i;
  92.   float j;
  93.   for (i = 0, j = Rotation; i < PointCount; i++, j += StepAngle) {
  94.     Points[i].X = cos(j);   // These values will be multiplied by the
  95.     Points[i].Y = sin(j);   // current radius at display time.
  96.   }
  97. }
  98.  
  99. void
  100. TMoveToLineToWindow::Paint(TDC& dc, BOOL, TRect&)
  101. {
  102.   TRect rect;
  103.   if (Iconized)
  104.     Parent->GetClientRect(rect);
  105.   else
  106.     GetClientRect(rect);
  107.  
  108.   int centerX = rect.right / 2;
  109.   int centerY = rect.bottom / 2;
  110.   int radius = min(centerY, centerX);
  111.  
  112.   // The follow memory DC operations are not required to draw lines, but
  113.   // were added to reduce screen flicker and speed up screen updates.
  114.   //
  115.   TMemoryDC  memDC(dc);
  116.  
  117.   TBitmap bitmap(dc, radius*2, radius*2);
  118.   memDC.SelectObject(bitmap);
  119.  
  120.   // Initiallize the new bitmap to all white.
  121.   //
  122.   memDC.PatBlt(0, 0, radius*2, radius*2, WHITENESS);
  123.  
  124.   // The Ellipse and the loop are all that's really needed to draw.  If you
  125.   // substitute dc for memDC, the draws will go directly to the screen.
  126.   // (Though the figure would no longer be centered, since the figure is drawn
  127.   // on a memDC bitmap, and the bitmap is then centered on the dc...)
  128.   // Since this line window is animated, it is frequently updated, which would
  129.   // cause the window to spend most of its time flickering if the dc were
  130.   // used.  Thus, the need for memory DC operations.  If the window were not
  131.   // animated, drawing onto the dc would look just fine.
  132.   //
  133.   memDC.Ellipse(0, 0, radius*2, radius*2);
  134.   int i,j;
  135.   for (i = 0; i < PointCount; i++) {
  136.     for (j = i + 1; j < PointCount; j++) {
  137.       memDC.MoveTo(radius + floor(Points[i].X * radius),
  138.                    radius + floor(Points[i].Y * radius));
  139.       memDC.LineTo(radius + floor(Points[j].X * radius),
  140.                    radius + floor(Points[j].Y * radius));
  141.     }
  142.   }
  143.  
  144.   // Now transfer what was drawn on the (invisible) memory DC onto the visible
  145.   // dc.  This one BitBlt transfer is much faster than the many 
  146.   // individual operations that were performed above.
  147.   //
  148.   dc.BitBlt(centerX-radius, centerY-radius, radius*2, radius*2, 
  149.             memDC, 0, 0, SRCCOPY);
  150.  
  151.   // Restore original bitmap before leaving
  152.   //
  153.   memDC.RestoreBitmap();
  154.                
  155.   // Footnotes:  Drawing this figure doesn't require a memory DC.  Animating
  156.   // the figure requires a memory DC only to reduce flicker to a tolerable 
  157.   // level.
  158.   // To make the animation faster still, (but use more memory, too),
  159.   // you could keep that memory DC hanging around between screen paints -
  160.   // constructing a DC takes some effort, and we're constructing one every 
  161.   // time we get a timer message.   You'd get the biggest improvement in 
  162.   // animation speed by calculating a sequence of bitmaps, then just 
  163.   // displaying them in the proper sequence.  This demo reconstructs the
  164.   // points list and redraws the figure for every timer message - a lot of
  165.   // work for the CPU, but it's code is simpler and doesn't use as much
  166.   // memory as more elaborate schemes might.
  167.  
  168.   // A challenge:  Turn the rotating figure into a ball that bounces off the
  169.   // walls of the window.  Don't forget the english (spin) the ball should 
  170.   // pick up when bouncing off the wall...
  171. }
  172.