home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 2.ddi / GDIDEMO.ZIP / LINE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  6.2 KB  |  166 lines

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