home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / MTHREAD.PAK / LINE.CPP < prev    next >
C/C++ Source or Header  |  1995-08-29  |  6KB  |  171 lines

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