⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lifecontrol.cs

📁 windows mobile 开发实例wi ndows mobile 开发实例
💻 CS
字号:
//-----------------------------------------------------------------------------
// Code from _Programming the .NET Compact Framework with C#_
// and _Programming the .NET Compact Framework with VB_
// (c) Copyright 2002-2004 Paul Yao and David Durant. 
// All rights reserved.
//-----------------------------------------------------------------------------

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;

namespace LifeGame
{
   /// <summary>
   /// Summary description for LifeControl.
   /// The display control for a Life game.
   ///   Draws one generation.  this.genCurr 
   ///   is always the generation that will 
   ///   be drawn.
   /// Also handles mouse clicks that occur in
   ///   its client area.
   /// A reference to this is stored in the 
   ///   refFacade property of the LifeMain 
   ///   object.
   /// </summary>
   public class LifeControl : System.Windows.Forms.Control
   {
      #region Properties

      // Properties used for drawing.
      //    The current generation is the one that is displayed;
      //    the previous generation is used for optimization.
      //    They will be set by the LifeMain   object before this
      //    control is invalidated.
      internal LifeGeneration refCurr;
      internal LifeGeneration refPrev;

      #endregion

      #region Constructor

      public LifeControl()
      {
      }

      #endregion

      #region Base Class Overrides

      protected override void OnMouseUp(MouseEventArgs e)
      {
         // Determine the cell that was clicked.
         int displayLo = 
            (LifeMain.noofCells - LifeMain.noofDisplay) / 2;
         int xUnit = 
            (int)(ClientRectangle.Width / LifeMain.noofDisplay);
         int yUnit = 
            (int)(ClientRectangle.Height / LifeMain.noofDisplay);

         // Tell the current generation to toggle this cell.
         refCurr.FlipCell( 
            (e.Y / yUnit) + displayLo + 1, 
            (e.X / xUnit) + displayLo + 1);
         
         // Have the current display repainted, including
         //    a background erase.
         LifeMain.boolPaintAll = true;
         this.Invalidate();

         // Call the base class.
         base.OnMouseUp( e );
      }

      protected override void OnPaint(PaintEventArgs pe)
      {
         // If requested, erase the background.
         if( LifeMain.boolPaintAll ) 
            pe.Graphics.FillRectangle
               (new SolidBrush(this.BackColor),
                pe.ClipRectangle);

         // Draw the current generation.
         //   The previous generation is included for optimization 
         //   purposes only (only draw what has changed).
         if( refCurr != null )
         {
            this.DrawGeneration(refCurr, refPrev, pe.Graphics);
         }
      }

      protected override void OnPaintBackground
                                 (PaintEventArgs pe)
      {
         // Do NOT call the base class routine.  
         //    This control does its own erase
         //    background from within the paint
         //    event.
      }

      #endregion

      #region Drawing Routines

      // Draw the current generation.
      internal void DrawGeneration( 
         LifeGeneration genCurr, 
         LifeGeneration genPrev, 
         Graphics graphLifeGame)
         {
         // Calculate the range of rows to display.
         int displayLo = 
            genCurr.middle - ((LifeMain.noofDisplay-1)/2);
         int displayHi = 
            displayLo + (LifeMain.noofDisplay-1);

         // For each of those rows.
         for (int j = displayLo; j <= displayHi; j++)
         {
            // Only draw the row if necessary.
            if( LifeMain.boolPaintAll == true
               || genCurr.countGeneration <= 1
               || genCurr.Rows[j].CompareTo(genPrev.Rows[j]) 
                  != 0 )
            {
               this.DrawRow(genCurr.Rows[j], 
                            genPrev.Rows[j], 
                            j,
                            graphLifeGame);
            }
         }
      }

      // Draw the current row.
      internal void DrawRow( 
         LifeRow rowCurr, 
         LifeRow rowPrev, 
         int ixRow, 
         Graphics graphLifeGame)
      {
         // Calculate the range of rows to display.
         int displaySpan = LifeMain.noofDisplay;
         int displayLo = rowCurr.middle - ((displaySpan-1)/2) ;
         int displayHi = displayLo + (displaySpan-1);

         // Drawing tools
         int xUnit = 
            (int)(this.ClientRectangle.Width / displaySpan);
         int yUnit = 
            (int)(this.ClientRectangle.Height / displaySpan);
         SolidBrush brshLive = new SolidBrush(Color.Black);
         SolidBrush brshDead = new SolidBrush(Color.Tan);

         // This routine attemps to optimize the
         //    drawing of rows.  Rows are drawn
         //    using FillRect.  The three primary
         //    optimizations are:
         // 1.   Do not erase the background.
         // 2.   Draw contiguous cells of the same
         //      state (color) in a single FillRect
         //      call.
         // 3.   Do not call FillRect if the rectangle
         //      specified is already the correct
         //      color.  That is, if there is no 
         //      change in the range of cells since
         //      the previous generation.

         int ixStart = displayLo  // The left cell of the rect.
            , ixEnd = displayHi   // The right cell of the rect.
            , j = displayLo;      // The current cell.
         byte byteCurrent = rowCurr.cellsRow[displayLo];

         // Force the last cell of a row to end a rectangle.
         byte cellTemp = rowCurr.cellsRow[displayHi];
         rowCurr.cellsRow[displayHi] = 2;

         // Scan from the end of the previous rectangle until 
         //    a change in cell value occurs, indicating the
         //    need for a new rectangle.
         for (j = displayLo; j <= displayHi; j++)
         {
            if (rowCurr.cellsRow[j] != byteCurrent)
            {
               // Note the end of the rectangle.
               ixEnd = j-1;

               // Only call FillRect if nexessary.
               if ( LifeMain.boolPaintAll
                  || rowCurr.CompareTo(rowPrev, ixStart, ixEnd) != 0 ) 
               {
                  graphLifeGame.FillRectangle(
                     byteCurrent == 1 ? brshLive : brshDead,
                     (ixStart-displayLo)*xUnit,
                     (ixRow-displayLo)*yUnit,
                     ((ixEnd-ixStart)+1)*xUnit,
                     1*yUnit);
               }
               
               // Note the start of the next rectangle.
               ixStart = j;
               // Note the value of the new rectangle's
               //    starting cell.
               byteCurrent = rowCurr.cellsRow[j];
            }
         }

         // Restore the last cell to its origional value.
         rowCurr.cellsRow[displayHi] = cellTemp;
      }

      #endregion
   }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -